Horizontal floating bars with a time y-axis in Chart.js - chart.js

I'm trying to adapt https://www.chartjs.org/docs/latest/samples/bar/floating.html to create a kind of timeline chart, where the horizontal axis (the range data) are timestamps. Unfortunately I can't seem to get the data to display, and don't see any error messages, etc.
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/moment#^2"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js#^3"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment#^1"></script>
</head>
<body>
<div>
<canvas id="myChart"></canvas>
</div>
</body>
<script>
//const labels = ["a","b","c","d","fff","g","h"]
const labels = ["a","b"]
const data = {
labels: labels,
datasets: [
{
label: 'Dataset 1',
data: [[moment("2021-11-23T00:24:14Z"),moment("2021-11-23T00:34:03Z")],
[moment("2021-11-23T00:24:14Z"),moment("2021-11-23T00:26:35Z")]]
// This works fine (without 'yAxes' below):
//data: labels.map(() => {
//return [Math.random(), Math.random()];
//}),
//backgroundColor: Utils.CHART_COLORS.red,
},
]
};
const config = {
type: 'bar',
data: data,
options: {
yAxes: [{
type: 'time',
}],
indexAxis: 'y',
responsive: true,
plugins: {
legend: {
position: 'top',
},
title: {
display: true,
text: 'Chart.js Floating Bar Chart'
}
}
}
};
var ctx = document.getElementById("myChart").getContext("2d");
new Chart(ctx, config);
</script>
</html>
EDIT: JSFiddle: https://jsfiddle.net/r5ypuvks/

Mmm it seems my issues are:
not using proper axis format for chart.js 3
need to scale the graph myself
need to refer to horizontal axis as x
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/moment#^2"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js#^3"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment#^1"></script>
</head>
<body>
<div>
<canvas id="myChart"></canvas>
</div>
</body>
<script>
//const labels = ["a","b","c","d","fff","g","h"]
const labels = ["a","b"]
const data = {
labels: labels,
datasets: [
{
label: 'Dataset 1',
data: [[("2021-11-23T00:24:14Z"),("2021-11-23T00:34:03Z")],
[("2021-11-23T00:25:14Z"),("2021-11-23T00:26:35Z")]]
// This works fine (without 'yAxes' below):
//data: labels.map(() => {
//return [Math.random(), Math.random()];
//}),
//backgroundColor: Utils.CHART_COLORS.red,
},
]
};
const config = {
type: 'bar',
data: data,
options: {
scales: {
x: {
min: ("2021-11-23T00:20:14Z"),
max: ("2021-11-23T00:44:14Z") ,
type: 'time',
},
},
indexAxis: 'y',
responsive: true,
plugins: {
legend: {
position: 'top',
},
title: {
display: true,
text: 'Chart.js Floating Bar Chart'
}
}
}
};
var ctx = document.getElementById("myChart").getContext("2d");
new Chart(ctx, config);
</script>
</html>

Related

How to add a custom plugin to chart.js

I'm having a hard time creating my first plugin for chart.js
After watching a few tutorials, I made the code below expecting to get "chart" in the console but nothing happens.
What am I missing here?
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.jsdelivr.net/npm/chart.js#4.1.1/dist/chart.umd.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-annotation#2.1.1/dist/chartjs-plugin-annotation.min.js"></script>
</head>
<body>
<div>
<canvas id="myChart"></canvas>
</div>
<script>
const ctx = document.getElementById('myChart');
const tooltipNote = {
id: 'tooltipNote',
beforeDraw: chart => {
console.log('chart');
}
}
new Chart(ctx, {
type: 'line',
responsive: true,
data: {
labels: ['', '', '', '', '', ''],
datasets: [{
data: [42, 119, 53, 55, 62, 53],
}]
},
options: {
scales: {
y: {
suggestedMin: 0,
offset: true
},
},
plugins: {
legend: {
display: false
},
tooltipNote: {
},
},
},
});
</script>
</body>
</html>
You never register your plugin as documented here: https://www.chartjs.org/docs/latest/developers/plugins.html
You can either only register it specific chart instances like so:
const tooltipNote = {
id: 'tooltipNote',
beforeDraw: chart => {
console.log('chart');
}
};
new Chart(ctx, {
data: data,
options: options,
plugins: [tooltip note]
});
Or you can register it globally so it is available to all your instances:
const tooltipNote = {
id: 'tooltipNote',
beforeDraw: chart => {
console.log('chart');
}
}
Chart.register(tooltipNote);
What you did was only define the options as an empty object for your plugin.

The chart.js zoom and pan plugin is not working in WKWebView

I added the zoom and pan functionality to a graph.
This works in Chrome and Safari. But when embedded in a SwiftUI WKWebview the entire graph zooms as if it is an image. I do not get the proper axis scaling.
I basically followed this tutorial to add the zoom. https://www.youtube.com/watch?v=QUzVVPK1Nks&ab_channel=ChartJS
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.min.js" integrity="sha512-UXumZrZNiOwnTcZSHLOfcTs0aos2MzBWHXOHOuB0J/R44QB0dwY5JgfbvljXcklVf65Gc4El6RjZ+lnwd2az2g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-zoom/1.2.1/chartjs-plugin-zoom.min.js" integrity="sha512-klQv6lz2YR+MecyFYMFRuU2eAl8IPRo6zHnsc9n142TJuJHS8CG0ix4Oq9na9ceeg1u5EkBfZsFcV3U7J51iew==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</head>
<body>
<div id="container" style="position: relative; height:95vh; width:95vw">
<canvas id="myCanvas"></canvas>
</div>
<script>
//var incomingData = __#data__;
var ctx = document.getElementById("myCanvas").getContext('2d');
var gradient = ctx.createLinearGradient(0, 0, 0, 500);
gradient.addColorStop(0, 'rgba(158,200,62,1)');
gradient.addColorStop(1, 'rgba(188,190,50,1)');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ["5:30 PM","5:45 PM","6:00 PM","6:15 PM","6:30 PM","6:45 PM","7:00 PM","7:15 PM","7:30 PM","7:45 PM","8:00 PM","8:15 PM","8:30 PM","8:45 PM","9:00 PM","9:15 PM","9:30 PM","9:45 PM","10:00 PM","10:15 PM","10:30 PM","10:45 PM","11:00 PM","11:15 PM","11:30 PM","11:45 PM","12:00 AM","12:00 AM","12:15 AM","12:30 AM","12:45 AM","1:00 AM","1:15 AM","1:30 AM","1:45 AM","2:00 AM","2:15 AM","2:30 AM","2:45 AM","3:00 AM","3:15 AM","3:30 AM","3:45 AM","4:00 AM","4:15 AM","4:30 AM","4:45 AM","5:00 AM","5:15 AM","5:30 AM","5:45 AM","6:00 AM","6:15 AM","6:30 AM","6:45 AM","7:00 AM","7:15 AM","7:30 AM","7:45 AM","8:00 AM","8:15 AM","8:30 AM","8:45 AM","9:00 AM","9:15 AM","9:30 AM","9:45 AM","10:00 AM","10:15 AM","10:30 AM","10:45 AM","11:00 AM","11:15 AM","11:30 AM","11:45 AM","12:00 PM","12:15 PM","12:30 PM","12:45 PM","1:00 PM","1:15 PM","1:30 PM","1:45 PM","2:00 PM","2:15 PM","2:30 PM","2:45 PM","3:00 PM","3:15 PM","3:30 PM","3:45 PM","4:00 PM","4:15 PM","4:30 PM","4:45 PM","5:00 PM"],
datasets: [{
backgroundColor : gradient, // Put the gradient here as a fill color
label: 'Temp',
data: [21.62,21.54,21.66,21.39,23,22.31,21.18,21.12,28.18,22.1633333333333333,20.66,20.18,19.7266666666666667,19.35,32.04,30.9533333333333333,33.18,31.9733333333333333,43.035,32.6225,31.7033333333333333,48.32,33.58,33.64,22.37,20.9,20.56,20.56,20.43,20.39,20.25,20,19.87,19.68,19.62,19.5,19.355,19.18,19.06,19,18.87,18.79,18.68,18.68,18.62,18.56,18.5,18.385,18.25,18.12,18,17.91,17.81,17.75,17.62,17.5,17.5,17.5,17.5,18.43,18.68,18.85,19.12,19.25,19.31,19.37,19.43,NaN,NaN,NaN,NaN,19.6,19.68,19.81,19.87,19.9533333333333333,20,NaN,NaN,NaN,NaN,NaN,NaN,NaN,NaN,0,NaN,NaN,NaN,NaN,NaN,NaN,NaN,22.18,22.37,22.31],
borderColor: '#9ec83e',
borderWidth: '1',
fill: true,
}]
},
options: {
plugins: {
legend:{
display: false,
},
zoom: {
limits: {
x: {min: 0, max: 400, minRange: 50},
y: {min: 0, max: 200, minRange: 50}
},
pan: {
enabled: true,
mode: 'xy',
},
zoom: {
wheel: {
enabled: true,
},
pinch: {
enabled: true
},
mode: 'xy',
}
}
},
maintainAspectRatio: false,
animation: {
duration: 0, // general animation time
},
elements: {
point: {
radius: 0
}
},
scales: {
x: {
grid: {
display:false
}
},
y: {
grid: {
display:false
},
ticks: {
autoSkip: true,
maxTicksLimit: 4
}
}
},
}
});
Chart.register(zoomPlugin);
</script>
</body>
</html>
I have tried the following in Swift
wkWebview.scrollView.delegate = self
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return nil
}

Chart.js no data displayed with predefined units

I want to display values with predefined units. e.g.: 22.00B/s
The data structure looks like this:
['6.84KB/s', '4.49KB/s', '3.42KB/s']
But only such data are displayed:
['7.5', '4.3', '10.3']
How can I display such values?
3.42KB/s
(Without removing letters or special characters)
You will need to use a category scale for this:
const options = {
type: 'bar',
data: {
labels: ["val1", "val2", "val3"],
datasets: [{
label: '# of Votes',
data: ['6.84KB/s', '4.49KB/s', '3.42KB/s'],
backgroundColor: 'pink'
}]
},
options: {
scales: {
y: {
type: 'category',
labels: ['6.84KB/s', '4.49KB/s', '3.42KB/s'],
reverse: true
}
}
}
}
const ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.8.2/chart.js"></script>
</body>

Chartjs Polar Area Chart: Category missing

I just can't figure out why is there allways at least one category missing from my chart:
This does not happen when I switch chart type to type:'pie'.
Please find my code below:
<!DOCTYPE html>
<html>
<body>
<div style="width: 40%;">
<canvas id="polarAreaChart " width="400" height="400"></canvas>
</div>
<script>
var ctx = document.getElementById("polarAreaChart ");
var polarAreaChart = new Chart(ctx, {
type: 'polarArea',
options: {
legend: {
display: true,
position: 'bottom',
}
},
data: {
labels: ["D1","D2","D3"],
datasets: [{
label: 'Dimensiones',
data: [40, 20, 40],
backgroundColor: [
"#f8b195",
"#c06c84",
"#6c5b7b"
]
}]
}
});
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.4/Chart.bundle.min.js"></script>
</body>
</html>
Any comments will help.
Cheers!
Apparently it was just a bug.
Solved it by using a more recent version of Chartjs:
https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.bundle.min.js

Using CSS variables (color) with chart.js - "var(--primaryColor)" not working

I've got a web-app project that uses two stylesheets to define two color sets (day & night mode). Each stylesheet defines the same CSS variables with different colors (e.g. "--primaryColor: 'white'" in dayMode.css and "--primaryColor: 'black'" in nightMode.css. The stylesheet is toggled when clicking a button.
Now, all elements are colored by referring to these variables - both in the CSS and JS code. For example:
div {background-color: var(--primaryColor);}
$(this).css({backgroundColor: "var(--primaryColor)"});
When switching the stylesheet, all elements adjust to the new definitions. Now I set up my very first Chart.js and tried to color it with my variables, like:
yAxes: [{
ticks: {
fontColor: "var(--primaryTextColor)"
}
}]
But that doesn't work. Any idea how to fix this? Thanks in advance!
CSS variables are used in stylesheet, if you would access them in JS you can do like below snippet:
var style = getComputedStyle(document.body);
var primCol = style.getPropertyValue('--primaryColor');
$("#mydiv").text("primaryColor: " + primCol);
:root {
--primaryColor: #336699;
}
#mydiv {
background-color: var(--primaryColor);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="mydiv">
</div>
So in a chart.js:
var style = getComputedStyle(document.body);
var primCol = style.getPropertyValue('--primaryColor');
var chartCol = style.getPropertyValue('--chartColor');
var chartData = {
labels: ['a', 'b', 'c', 'd'],
datasets: [{
label: 'value',
backgroundColor: 'rgba(219, 20, 0, 0.2)',
borderColor: chartCol,
data: [30, 50, 25, 10]
}]
};
var ctx = document.getElementById("myChart").getContext("2d");
var myBar = new Chart(ctx, {
type: 'line',
data: chartData,
options: {
legend: { display: false },
scales: {
yAxes: [{
ticks: {
fontColor: primCol,
}
}],
xAxes: [{
ticks: {
beginAtZero: true
}
}],
}
}
});
:root {
--primaryColor: #00ff00;
--chartColor: #ff0000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="myChart" height="300" width="500"></canvas>