I'm trying to do a couple of things with ChartJS, but I can't find the information I need in the docs and they don't seem to have a forum or anywhere useful to ask questions.
The main thing I'm trying to accomplish is to have only one set of data displayed at a time. I was able to hide the one set on load, but when you click on it, I can't figure out how to hide the first. Eventually I might have 3 sets and would need to be sure the other two are hidden. I've read how to grab the click event, but I'm not sure what to return.
I'd also like to be able to customize the title & label text/layout, but I'm not sure if this is doable.
Here's what I have so far for code:
var ctx = $("#myChart");
var data = {
labels: ["LABEL1", "LABEL2", "LABEL3", "LABEL4", "LABEL5"],
datasets: [
{
label: "DATA1",
backgroundColor: "rgba(62,135,74,.5)",
pointBackgroundColor: "#34b44a",
data: [3, 3, 4, 2, 3]
},
{
label: "DATA2",
backgroundColor: "rgba(255,99,132,0.2)",
pointBackgroundColor: "rgba(255,99,132,1)",
data: [2, 2, 4, 4, 3],
hidden: true
}
]
};
var options = {
title: {
display: true,
fontColor: '#999',
fontStyle: 'regular',
fullWidth: false,
text: 'CHART TITLE'
},
legend: {
fullWidth: false,
labels: {
fontColor: '#fff',
boxWidth: 0
}
},
elements: {
line: {
}
},
scale: {
angleLines: {
color: '#666'
},
gridLines: {
color: '#666'
},
pointLabels: {
fontColor: '#fff'
},
ticks: {
min: 0,
max: 5,
stepSize: 1,
display: false
}
},
tooltips: {
enabled: false
}
};
var myRadarChart = new Chart(ctx, {
type: 'radar',
data: data,
options: options
});
You can see it here with the design on the right: http://codepen.io/haxen2000/pen/jBVMqK
Here's a pen to my solution: http://codepen.io/haxen2000/pen/evgwmB
I just took out what I needed and made them HTML elements so I could style as needed. Would be nice to see a solution from within the ChartJS code, but this will work.
<div class='header'>
<span class='title'>CHART TITLE</span>
<button id='data1'>DATA1</button>
<button id='data2'>DATA2</button>
</div>
Related
I am using "chart.js": "^3.7.1", along with react-chartjs-2 in react web app. I want to change the chart tooltip font family. Here is the options i am using in the chart. I am unable to apply font family to the line chart. i want to apply a custom font for the title in the tooltip. i have used props mentioned in the documentation of chart js
const options = {
animation,
plugins: {
tooltip: {
backgroundColor: "#fff",
displayColors: false,
borderColor: "#8b7a7a",
borderWidth: 0.5,
bodyColor: "#0000",
titleColor: "#8b7a7a",
// bodyFontColor: "#8b7a7a",
padding: 10,
footerSpacing: 0,
boxHeight: 10,
title: {
font: {
size: 50,
family: "'Work Sans',sans-serif",
},
},
callbacks: {
title: function (t, d) {
let datae = moment(t[0].label).format("MMM DD, YYYY");
const aa = t[0].dataset.label;
const val = t[0].formattedValue;
return `Date: ${datae.toString()}\n${aa}: ${val}`;
},
},
},
legend: {
display: false,
},
},
elements: {
line: {
tension: 0,
},
},
legend: {
display: false,
},
scales: {
x: {
grid: {
display: false,
},
},
y: {
grid: {
display: false,
},
},
},
};
As can be read here you need to configure the font for the tooltip title in the titleFont property and not in the title.font property:
var options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderColor: 'orange'
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
borderColor: 'pink'
}
]
},
options: {
plugins: {
tooltip: {
titleFont: {
family: 'commic-sans-ms'
}
}
}
}
}
var 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.7.1/chart.js"></script>
</body>
you can change the style of tooltip in the chart.js, in the options property of chart. Inside options you need to access tooltip inside of plugins object, so first you have to create it, then create tooltip object inside it. Now, you can change some features of tooltip according to the this link.
for example:
plugins: {
tooltip: {
titleFont: { size: 13.2, family: "Yekan" },
bodyFont: { size: 14.2, family: "Yekan" },
callbacks: {
// to change the label context
label: function (context) {
var label = context.parsed.y;
return label;
},
},
},
}
I am using chartjs v3 (latest) and I'm trying to render a graph with multiple datasets that share one y axis.
Currently I have the following code:
const buff = await defaultChartRenderer({
type: 'line',
data: {
labels: data.value.filter(v => v.type === 'online').map(v => moment(new Date(v._time)).format(data.format)),
datasets: [
{
data: allOnline,
borderColor: '#43b581',
backgroundColor: 'rgba(0,0,0,0)',
label: 'Online',
normalized: true
},
{
data: allOffline,
borderColor: '#ff0000',
backgroundColor: 'rgba(0,0,0,0)',
label: 'Offline',
normalized: true
},
{
data: allIdle,
borderColor: '#faa61a',
backgroundColor: 'rgba(0,0,0,0)',
label: 'Idle',
normalized: true
},
{
data: allDnd,
borderColor: '#f04747',
backgroundColor: 'rgba(0,0,0,0)',
label: 'DND',
normalized: true
}
]
},
options: {
scales: {
y: {
suggestedMax: Math.max(...[...allOffline, ...allOnline, ...allDnd, ...allIdle]),
suggestedMin: Math.min(...[...allOffline, ...allOnline, ...allDnd, ...allIdle]),
stacked: true,
ticks: {
beginAtZero: false,
precision: 0,
},
gridLines: {
zeroLineColor: "rgba(255, 255, 255, 0.8)",
color: "rgba(255, 255, 255, 0.4)"
},
stacked: true,
id: 0,
position: 'left'
},
},
legend: {
//display: false,
labels: {
fontColor: 'white',
fontSize: 20
}
},
tooltips: {
enabled: false
}
}
})
The defaultChartRenderer function does not modify my input at all.
The following data gets passed in as allOnline, allOffline, allIdle, and allDnd:
[
2, 2, 3, 3,
3, 2, 2
] [
4, 4, 4, 3,
4, 4, 3
] [
1, 1, 1, 1,
0, 0, 1
] [
1.5, 1, 2, 2,
2, 2, 2
]
I would expect this to output a graph with that data, but instead only the allOnline data shows properly. Everything else gets moved upwards.
Current Output: https://imgur.com/a/prGiyxy
Am I doing something wrong? I've tried adding yAxisID to all of the datasets and sharing one id between all of them, but that didn't work. I've also tried without normalize: true.
To make it work as expected, remove the option scales.y.stacked or set it to false.
For further information, please consult the chapter Stacking from the Chart.js documentation.
UPDATE
stacked: true is defined twice on your y-axis. Remove both of them, and it should work.
I need to plot a single value in line chart. Currently i am using charts.JS library for line graph purpose.
The data will be varied some times i'll get the single data inside the data set at that time i need to plot the single value in the line chart.
I had tried with the charts.js annotation plugin but it didn't meet my requirements. which is like it wis overlapping the plotted point in the graph area.
My code
createLineChart() {
this.lineChart = new Chart(this.lineCanvas.nativeElement, {
type: "line",
data: {
labels:[],
datasets: [
{
fill: false,
backgroundColor: "#0168FF",
borderColor: "#0168FF",
pointBackgroundColor: "white", // wite point fill
pointBorderWidth: 1, // point border width
lineTension: 0,
pointBorderColor: "blue",
pointRadius: 4,
},
],
},
options: {
scales: {
yAxes: [
{
ticks: {
padding: 20,
beginAtZero: true,
min: 0,
stepSize: 100,
},
gridLines: {
drawBorder: false,
},
},
],
xAxes: [
{
// offset: true,
ticks: {
display: false,
//beginAtZero: true,
min: 0,
},
gridLines: {
zeroLineColor: "transparent",
drawBorder: false,
display: false,
},
//offset:true,
},
],
legend: {
display: false,
},
tooltips: {
enabled: false,
},
},
drawTime: "afterDraw", // (default)
} as ChartOptions,
// plugins: [ChartAnnotation]
},
});
}
To plot the data dynamically:
generateRandomDataSet(size) {
let yaxisArr = [];
let xaxisArr = [];
let random_data:any = this.getRandomData(size)
let maxYTickVal = Math.max.apply(Math, random_data.map((val) => {return val.yaxis}));
let maxVal = Math.ceil((maxYTickVal+1) / 10) * 10
for(let data of random_data) {
yaxisArr.push(data.yaxis)
xaxisArr.push(data.xaxis)
}
this.lineChart.data.datasets[0].data = yaxisArr
this.lineChart.config.data.labels = []
this.lineChart.config.data.labels = xaxisArr
this.lineChart.config.options.scales.yAxes[0].ticks.max =maxVal
this.lineChart.config.options.scales.yAxes[0].ticks.stepSize = maxVal/2
this.lineChart.update()
}
What i required
What i am getting
Thankyou.
There exists different approaches to solve this problem.
According to the answer I gave to a similar question, you can define an animation.onComplete function to draw the line.
In a comment on before mentioned answer, Lakshmansundeep suggested an approach where he defines the same data value three times but makes sure, pointRadius for the leading and ending data point is zero.
datasets: [{
data: [120, 120, 120],
...
pointRadius: [0, 4, 0],
pointHoverRadius: [0, 4, 0],
}],
For the second approach, please have a look at the code below.
new Chart('line-chart', {
type: "line",
data: {
labels: [null, 'A', null],
datasets: [{
data: [120, 120, 120],
fill: false,
backgroundColor: "#0168FF",
borderColor: "#0168FF",
pointBackgroundColor: "white",
pointBorderWidth: 1,
lineTension: 0,
pointBorderColor: "blue",
pointRadius: [0, 4, 0],
pointHoverRadius: [0, 4, 0],
}],
},
options: {
legend: {
display: false
},
tooltips: {
enabled: false
},
scales: {
yAxes: [{
ticks: {
padding: 20,
min: 0,
stepSize: 100
},
gridLines: {
drawBorder: false
}
}],
xAxes: [{
ticks: {
display: false
},
gridLines: {
zeroLineColor: "transparent",
drawBorder: false,
display: false
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="line-chart" height="80"></canvas>
I have line chart with two lines. First line is static, second line builds dynamically. I need to fill area between first and second line if y value of second line above a y value of first line.
I used Charts.js library for chart building
Currently I have next result (Fill between two lines):
Expected result:
Very hackish way but it gives the expected result :D!
Fiddle -> http://jsfiddle.net/Lzo5g01n/28/
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ["Yellow", "Blue", "Green", "Orange", "Pink"],
datasets: [{
fill: false,
data: [0, 10, , 10, 0],
backgroundColor: 'black',
borderColor: 'black',
borderWidth: 1
}, {
data: [10, 10, 10, 10, 10],
fill: true,
backgroundColor: 'white',
borderColor: 'black',
borderWidth: 1
}, {
data: [, 10, 18, 10, ],
backgroundColor: 'black',
borderColor: 'black',
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
display: false,
ticks: {
beginAtZero: true
}
}],
xAxes: [{
display: false
}]
},
legend: {
display: false
},
tooltips: {
enabled: false
},
elements: {
point: {
radius: 0
}
}
}
});
I have drawn a line chart using chart.js. For the labels and datasets i am getting values from the database. I am new to chart.js and its very powerful library, yet i am unable to completely understand it. I want to draw multiples horizontal lines. Like where if mean of dataset, standard deviation and min and max. I have tried the question here in stackoverflow but these are giving errors or may be i am not able to understand the working. This is my chart.js code
function display_graph(id, label, data) {
var ctx = document.getElementById(id);
var data = {
labels: data.labels,
datasets: [
{
label: label,
fill: false,
lineTension: 0.1,
backgroundColor: "rgba(75,192,192,0.4)",
borderColor: "rgba(75,192,192,1)",
borderCapStyle: 'butt',
borderDash: [],
borderDashOffset: 0.0,
borderWidth: 1,
borderJoinStyle: 'miter',
pointBorderColor: "rgba(75,192,192,1)",
pointBackgroundColor: "#fff",
pointBorderWidth: 1,
pointHoverRadius: 5,
pointHoverBackgroundColor: "rgba(75,192,192,1)",
pointHoverBorderColor: "rgba(220,220,220,1)",
pointHoverBorderWidth: 2,
pointRadius: 1,
pointHitRadius: 10,
data: data.assay_value,
spanGaps: false
}
]
};
//options
var options = {
responsive: true,
title: {
display: true,
position: "top",
text: label,
fontSize: 18,
fontColor: "#111"
},
legend: {
display: true,
position: "bottom",
labels: {
fontColor: "#333",
fontSize: 16
}
}
};
var Blanks_Chart=null;
Blanks_Chart = new Chart(ctx, {
type: 'line',
data: data,
options: options
});}
You could use the chart.js annotation plugin to easily draw lines on your chart without having to mess with rendering pixels in your canvas manually (the old approach that is giving you errors). Note, the plugin is created/supported by the same team as chart.js and is mentioned in the chart.js docs.
Here is an example codepen demonstrating creating a line on a chart.
Once you add the plugin, you simply just set annotation properties in your chart config. Here is an example.
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ["January", "February"],
datasets: [{
label: 'Dataset 1',
borderColor: window.chartColors.blue,
borderWidth: 2,
fill: false,
data: [2, 10]
}]
},
options: {
responsive: true,
title: {
display: true,
text: 'Chart.js Draw Line On Chart'
},
tooltips: {
mode: 'index',
intersect: true
},
annotation: {
annotations: [{
type: 'line',
mode: 'horizontal',
scaleID: 'y-axis-0',
value: 5,
borderColor: 'rgb(75, 192, 192)',
borderWidth: 4,
label: {
enabled: false,
content: 'Test label'
}
}]
}
}
});
if you want to draw threshold line,easiest way is that using mixed line chart.
Note: Make an array filled with threshold value and the length should be same as your dataset.
var datasets = [1, 2, 3];
var ctx = document.getElementById('chart').getContext('2d');
var thresholdValue = 2;
var thresholdHighArray = new Array(datasets.length).fill(thresholdValue);
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: [],
datasets: [
{datasets}, thresholdHighArray]
},
options: {
responsive: true,
legend: {
position: 'bottom',
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Readings'
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Reading ( °C )'
}
}]
},
annotation: {
annotations: [
{
type: "line",
mode: "vertical",
scaleID: "x-axis-0",
borderColor: "red",
label: {
content: "",
enabled: true,
position: "top"
}
}
]
}
});
};
If you are using the NPM package chartjs-plugin-annotation.js, the important thing - which you may forget, is to register the plugin.
So first of all you installed the npm packages (here for React):
npm i react-chartjs-2 (depends on your framework)
npm i chartjs-plugin-annotation (always required)
See Vue.js or Angular for their framework depending packages.
Option 1: Global plugin registration
import { Line } from 'react-chartjs-2';
import Chart from 'chart.js';
import * as ChartAnnotation from 'chartjs-plugin-annotation';
Chart.plugins.register([ChartAnnotation]); // Global
// ...
render() {
return (
<Line data={chartData} options={chartOpts} />
)
}
Option 2: Per chart plugin registration
import { Line } from 'react-chartjs-2';
import * as ChartAnnotation from 'chartjs-plugin-annotation';
// ...
render() {
return (
{/* per chart */}
<Line data={chartData} options={chartOpts} plugins={[ChartAnnotation]} />
)
}
chartData is equivalent to the data: { section and chartOpts to options: { from jordanwillis answer. See this github post for further information.
There are many other plugins available for chart.js.
Here's an example of getting it working in a Rails view if you're using it with the Chartkick gem:
<%=
line_chart profit_per_day_chart_path(staff), xtitle: 'Day', ytitle: 'Profit',
library: {
annotation: {
annotations: [
{
type: 'line',
mode: 'horizontal',
scaleID: 'y-axis-0',
value: 20,
label: {
content: 'My Horizontal Line',
enabled: true
}
}
]
}
}
%>
Ensure that you've registered the chartjs-plugin-annotation.js plugin with Chart.js first:
import ChartAnnotationsPlugin from 'chartjs-plugin-annotation';
Chart.plugins.register(ChartAnnotationsPlugin);