How do you create custom tooltips that doesn't repeat if the points are on the same (x,y)? Take a look at "C" here. I'd like to only show the tooltip label once. It's the same information in any tooltip that is going to be shown if the points are on the same X-value.
var labels = ["A", "B", "C", "D"];
var d1 = [1, 2, 3, 10];
var d2 = [3, 4, 3, 7];
var dd1 = 'y';
var dd2 = 'y';
var ctx = $("#lchart");
var lchart = new Chart(ctx, {
type: "line",
data: {
labels: labels,
datasets: [{
cubicInterpolationMode: "monotone",
label: "s1",
data: d1,
pointHoverRadius: 6,
pointRadius: 6,
pointBorderWidth: 3
},
{
cubicInterpolationMode: "monotone",
label: "s2",
data: d2,
pointHoverRadius: 6,
pointRadius: 6,
pointBorderWidth: 3,
}
]
},
options: {
legend: {
display: false
},
tooltips: {
yPadding: 15,
xPadding: 15,
backgroundColor: "yellow",
titleFontSize: 14,
titleFontColor: "#999",
bodyFontColor: '#000',
bodyFontSize: 12,
displayColors: false,
callbacks: {
label: function(tooltipItem, data) {
var labelrows = [
"Title:",
dd1,
"",
dd2
];
return labelrows;
}
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<body>
<canvas id="lchart"></canvas>
</body>
Dont hardcode your response for the label and it runs for every label, you will need to use the title callback and just use the data passed in the arg for the value of the item:
var labels = ["A", "B", "C", "D"];
var d1 = [1, 2, 3, 10];
var d2 = [3, 4, 3, 7];
var dd1 = 'y';
var dd2 = 'y';
var ctx = $("#lchart");
var lchart = new Chart(ctx, {
type: "line",
data: {
labels: labels,
datasets: [{
cubicInterpolationMode: "monotone",
label: "s1",
data: d1,
pointHoverRadius: 6,
pointRadius: 6,
pointBorderWidth: 3
},
{
cubicInterpolationMode: "monotone",
label: "s2",
data: d2,
pointHoverRadius: 6,
pointRadius: 6,
pointBorderWidth: 3,
}
]
},
options: {
legend: {
display: false
},
tooltips: {
yPadding: 15,
xPadding: 15,
mode: "index",
backgroundColor: "yellow",
titleFontSize: 14,
titleFontColor: "#999",
bodyFontColor: '#000',
bodyFontSize: 12,
displayColors: false,
callbacks: {
beforeBody: () => ('Title:'),
label: function(ttItem, data) {
return ttItem.yLabel;
}
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<body>
<canvas id="lchart"></canvas>
</body>
Related
Suppose x1={1,4,7,9} | y1={10,20,35,40} and x2={2,3,6,9} | y2={15,23,30,35}. Now I want to draw a line chart in chart.js for it.
P.S. Scatter chart is not a solution because my website is generating data dynamically so I have to provide data in array only and scatter requires the data in very sophisticated manner.
My simple question is by any way, can we have different x axis points in line chart for different lines??
code for your reference:
<!DOCTYPE html>
<html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>
<body>
<canvas id="myChart" style="width:100%;max-width:600px"></canvas>
<script>
var xValues1 = [50,60,70,80,90,100,110,120,130,140,150];
var yValues1 = [7,8,8,9,9,9,10,11,14,14,15];
var xValues2 = [54,64,74,84,94,104,114,124,134,144,154];
var yValues2 = [8,9,9,10,10,10,11,12,15,15,16];
new Chart("myChart", {
type: "line",
data: {
labels: xValues1,
datasets: [{
fill: false,
backgroundColor: "rgba(0,0,255,1.0)",
borderColor: "rgba(0,0,255,0.1)",
data: yValues1
},
{
fill: false,
backgroundColor: "rgba(0,0,255,1.0)",
borderColor: "rgba(0,0,255,0.1)",
data: yValues2
}
]
},
options: {
legend: {display: false},
scales: {
yAxes: [{ticks: {min: 6, max:16}}],
}
}
});
</script>
</body>
</html>
(for yvalues2, I want xvalues2)
You can add a second X axis for your other labels:
const xValues1 = [50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150];
const yValues1 = [7, 8, 8, 9, 9, 9, 10, 11, 14, 14, 15];
const xValues2 = [54, 64, 74, 84, 94, 104, 114, 124, 134, 144, 154];
const yValues2 = [8, 9, 9, 10, 10, 10, 11, 12, 15, 15, 16];
const options = {
type: 'line',
data: {
datasets: [{
label: '# of Votes',
data: yValues1,
borderColor: 'pink'
},
{
label: '# of Points',
data: yValues2,
borderColor: 'orange',
xAxisID: 'x2' // Match dataset to other axis
}
]
},
options: {
scales: {
xAxes: [{
type: 'category',
labels: xValues1,
id: 'x',
display: true // Set to false to hide the axis
},
{
type: 'category',
labels: xValues2,
id: 'x2',
display: true // Set to false to hide the axis
}
]
}
}
}
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/2.9.4/Chart.js"></script>
</body>
i use of chart.js package for create a chart.
my problem:
how change the color of label of each legends?
for example:
color of "legend1" be: red.
color of "legend2" be: blue.
my codes:
const ctx = document.getElementById('myChart').getContext('2d');
const myChart = new Chart(ctx, {
data: {
labels: ['۱۴۰۰/۰۱/۰۱', '۱۴۰۰/۰۱/۰۲', '۱۴۰۰/۰۱/۰۳', '۱۴۰۰/۰۱/۰۴', '۱۴۰۰/۰۱/۰۵', '۱۴۰۰/۰۱/۰۶'],
datasets: [{
type: 'line',
label: 'legend1',
backgroundColor: 'rgb(14, 156, 255)',
data: [6, 5.5, 4, 7, 5.4, 5.8],
fill: false,
borderColor: 'rgb(14, 156, 255)',
tension: 0
},
{
type: 'line',
label: 'legend2',
backgroundColor: 'rgb(22, 185, 156)',
data: [6.2, 5.7, 3.8, 7.2, 5.2, 5.9],
fill: false,
borderColor: 'rgb(22, 185, 156)',
tension: 0
}
] //end : datasets
}, // end: data
options: {
plugins: {
legend: {
labels: {
font: {
size: 18
} // end: font
} // end: labels
,
position: 'bottom',
rtl: true,
align: "start"
} // end: legend
}, // end: plugins
scales: {
y: {
beginAtZero: true,
display: false
} // end: y
,
x: {
grid: {
borderDash: [6, 5],
lineWidth: 1,
color: '#CCCCCC'
} // end: grid
} //end:x
} // end: scales
} //end: options
});
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.7.1/dist/chart.min.js"></script>
<canvas id="myChart" width="778" height="433"></canvas>
my problem is just that: how change the color of each legend's text?
color of "legend1" text and color of "legend2" text.
my codes result:
To achieve what you want you will need to use a custom generateLabels function like so:
const legendColors = ['red', 'blue']
const options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderColor: 'pink'
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
borderColor: 'orange'
}
]
},
options: {
plugins: {
legend: {
labels: {
generateLabels: (chart) => {
const datasets = chart.data.datasets;
const {
labels: {
usePointStyle,
pointStyle,
textAlign,
color
}
} = chart.legend.options;
return chart._getSortedDatasetMetas().map((meta, i) => {
const style = meta.controller.getStyle(usePointStyle ? 0 : undefined);
const borderWidth = Chart.helpers.toPadding(style.borderWidth);
return {
text: datasets[meta.index].label,
fillStyle: style.backgroundColor,
fontColor: legendColors[i],
hidden: !meta.visible,
lineCap: style.borderCapStyle,
lineDash: style.borderDash,
lineDashOffset: style.borderDashOffset,
lineJoin: style.borderJoinStyle,
lineWidth: (borderWidth.width + borderWidth.height) / 4,
strokeStyle: style.borderColor,
pointStyle: pointStyle || style.pointStyle,
rotation: style.rotation,
textAlign: textAlign || style.textAlign,
borderRadius: 0, // TODO: v4, default to style.borderRadius
// Below is extra data used for toggling the datasets
datasetIndex: meta.index
};
}, this);
}
}
}
}
}
}
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.7.1/chart.js"></script>
</body>
Did you try the hex format ?
For example, you could try replacing "rgb(14, 156, 255)" by "#0e9cff"
More info here : https://devsheet.com/code-snippet/change-color-of-the-line-in-chartjs-line-chart/
I need to create a customized external tooltip for my project.
This is how it looks like now >>
2nd image is how it should look like >>
My dataset:
datasets: [
//Systolic Avarage Line --------
{
label: 'Systolic Avarage Line',
backgroundColor: 'transparent',
data: bloodPressureData?.systolicAvarageLine?.data,
borderWidth: 2,
borderColor: 'rgb(0,0,0,0.15)',
pointBorderWidth: 0,
pointRadius: 1,
order: 9,
type: 'line'
},
//Diastolic Avarage Line --------
{
label: 'Diastolic Avarage Line',
backgroundColor: 'transparent',
data: bloodPressureData?.diastolicAvarageLine?.data,
borderWidth: 2,
borderColor: 'rgb(0,0,0,0.15)',
pointBorderWidth: 0,
pointRadius: 1,
order: 9,
type: 'line'
},
//Systolic Bar --------
{
label: 'Systolic Bar',
backgroundColor: bloodPressureData?.sysBar?.map((item) => {
const colorsArr = item?.colors;
const colorFound = colorsArr?.reduce((prev, current) =>
+prev?.riskScore > +current?.riskScore ? prev : current
);
return colorFound?.color;
}),
data: bloodPressureData?.sysBar?.map((v) => [v?.max, v?.min]),
barThickness: 14,
maxBarThickness: 14,
barPercentage: 1,
categoryPercentage: 1,
borderRadius: 50,
order: 2
},
//Diastolic Bar --------
{
label: 'Diastolic Bar',
backgroundColor: theme.palette.primary.main,
data: bloodPressureData?.diaBar?.map((v) => [v?.max, v?.min]),
barThickness: 14,
maxBarThickness: 14,
barPercentage: 1,
categoryPercentage: 1,
borderRadius: 50,
order: 8
},
//Systolic Min Scatter --------
{
label: 'Systolic Min Scatter',
backgroundColor: () => {
const selectedColorArr = bloodPressureData?.sysMin?.colors?.map(
(item) => {
const colorObj = item.reduce((prev, current) =>
+prev?.riskScore > +current?.riskScore ? prev : current
);
return colorObj?.color;
}
);
return selectedColorArr;
},
data: bloodPressureData?.sysMin?.data,
pointBorderColor: theme.palette.common.black[700],
pointBorderWidth: 0,
pointRadius: 7.5,
pointHoverRadius: 9,
order: 1,
type: 'scatter'
},
//Systolic Max Scatter --------
{
label: 'Systolic Max Scatter',
backgroundColor: () => {
const selectedColorArr = bloodPressureData?.sysMax?.colors?.map(
(item) => {
const colorObj = item?.reduce((prev, current) =>
+prev?.riskScore > +current?.riskScore ? prev : current
);
return colorObj?.color;
}
);
return selectedColorArr;
},
data: bloodPressureData?.sysMax?.data,
pointBorderColor: theme.palette.common.black[700],
pointBorderWidth: 0,
pointRadius: 7.5,
pointHoverRadius: 9,
order: 1,
type: 'scatter'
},
//Diastolic Min Scatter --------
{
label: 'Diastolic Min Scatter',
backgroundColor: theme.palette.primary.main,
data: bloodPressureData?.diaMin?.data,
pointBorderColor: theme.palette.common.black[700],
pointBorderWidth: 0,
pointRadius: 7.5,
pointHoverRadius: 9,
order: 6,
type: 'scatter'
},
//Diastolic Max Scatter --------
{
label: 'Diastolic Max Scatter',
backgroundColor: theme.palette.primary.main,
data: bloodPressureData?.diaMax?.data,
pointBorderColor: theme.palette.common.black[700],
pointBorderWidth: 0,
pointRadius: 7.5,
pointHoverRadius: 9,
order: 7,
type: 'scatter'
}
]
And my options.tooltips looks like below:
tooltips: {
enabled: true,
callbacks: {
title: (tooltipItem, data) => {
if (selectedTimeSpan === TimeSpan.TODAY) {
return `${data['labels'][tooltipItem[0]['index']]}:00`;
} else if (selectedTimeSpan === TimeSpan.WEEK) {
return `${getWeekHoverTitle(
data['labels'][tooltipItem[0]['index']]
)} ${moment(selectedDateTime).format('MMMM').slice(0,3)} ${
data['labels'][tooltipItem[0]['index']]
}`;
} else if (selectedTimeSpan === TimeSpan.MONTH) {
return `${data['labels'][tooltipItem[0]['index']]} ${moment(
selectedDateTime
).format('MMMM')} `;
} else {
return `${moment(
`${data['labels'][tooltipItem[0]['index']]}`,
'MM'
).format('MMMM')}`;
}
},
beforeLabel: function () {
return `Systolic`;
},
label: function (tooltipItem, data) {
return `${data['datasets'][2]['data'][tooltipItem['index']]} ${measurementValueKey}`;
// data['datasets'][0]['data'][tooltipItem['index']]
},
afterLabel: function (tooltipItem, data) {
return `${data['datasets'][2]['data'][tooltipItem['index']]} ${measurementValueKey}`;
// data['datasets'][0]['data'][tooltipItem['index']]
},
},
mode: 'index',
intersect: false,
caretSize: 6,
displayColors: true,
yPadding: 10,
xPadding: 20,
borderWidth: 0,
bodySpacing: 10,
titleFontSize: 16,
backgroundColor: '#6E759F',
titleFontColor: theme.palette.common.white,
bodyFontColor: theme.palette.common.white,
footerFontColor: theme.palette.common.white
},
How do I make the last element in the data active, specifically July, in a js diagram?
example https://codepen.io/pichugin/pen/eYgdvBx
[https://codepen.io/pichugin/pen/eYgdvBx][1]
With the new upcomming release of version 3 you can do this with the setActive elements.
Documentation: https://www.chartjs.org/docs/master/developers/api/#setactiveelementsactiveelements
var options = {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderWidth: 1,
hoverBackgroundColor: 'green',
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
borderWidth: 1,
hoverBackgroundColor: 'red',
}
]
},
options: {
scales: {}
}
}
var ctx = document.getElementById('chartJSContainer').getContext('2d');
const chart = new Chart(ctx, options);
chart.setActiveElements([{
datasetIndex: 0,
index: 1,
}, {
datasetIndex: 1,
index: 1,
}]);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.0.0-beta.10/chart.js" integrity="sha512-7igYTuENB1pHNsZ/SyzMYrcJAmRCk084yVOsxNNCQAdX1wSYvCeBOgSOMC6wUdKMO76kCJNOpW4jY3UW5CoBnA==" crossorigin="anonymous"></script>
</body>
While plotting a chart in chart js with y axes steps like 0 573 675 900. When i plot it the spacing is between adjacent points are. can i bring the points evenly spaced?
Consider the image
chart
In this image i want the number 7 to appear exactly in the middle and the chart to scale between 1 and 7 and also 7 and 10 accordingly.
Following is a sample code iam working on:
////////////////////////////////////////////////////////
document.addEventListener("DOMContentLoaded", function() {
var
example = document.getElementById('example1'),
hot;
var headers = ["Red", "Blue", "Yellow", "Green", "Purple", "Orange", "Pink", 'Brown'];
var myData = [
[5, 10, 3, 5, 2, 3, 5, 1],
[9, 9, 3, 10, 8, 7, 7, 2],
[5, 1, 10, 6, 7, 9, 4, 8]
];
var StepValues = [1,7,10];
var rowheaders = ['Mark', 'Anna', 'Diana']
hot = new Handsontable(example, {
data: myData,
rowHeaders: rowheaders,
colHeaders: headers,
readOnly: true,
colWidths: 88,
licenseKey: 'non-commercial-and-evaluation',
fillHandle: {
autoInsertRow: false,
}
});
var options = {
type: 'bar',
data: {
labels: headers,
datasets: [{
label: rowheaders[0],
data: myData[0],
borderWidth: 1,
backgroundColor: 'rgb(255, 236, 217)'
}, {
label: rowheaders[1],
data: myData[1],
borderWidth: 1,
backgroundColor: 'rgb(235, 224, 255)'
}, {
label: rowheaders[2],
data: myData[2],
borderWidth: 1,
backgroundColor: 'rgb(219, 242, 242)'
}]
},
options: {
scales: {
yAxes: [{
ticks: {
reverse: false,
callback: (label) =>{
if(StepValues.includes(label)){
return label;
}
}
}
}]
}
}
}
var ctx = document.querySelector('.chartJSContainer').getContext('2d');
var myChart = new Chart(ctx, options);
});
//////////////////////////////////////////////////////////////////