Chart.js line graph-removing labels on the line - chart.js

I am using chart.js with C# and Ajax calls. I am trying to develop my first line graph. I have circles, on the line, for each data point. However, each data point is showing the value inside the circle. How do I remove this value, so it is just a blue dot?
I am using the DataLabels library. I tried many options yesterday but could not remove the numbers from the points on the line.
This is the full function for my line graph:-
function LoadChart5() {
var processType = "";
var sdt = $("[id*=startDate]").val();
var edt = $("[id*=endDate]").val();
var sd = moment(sdt, "DD-MM-YYYY").format("YYYY-MM-DD");
var ed = moment(edt, "DD-MM-YYYY").format("YYYY-MM-DD");
$('[id*=processType] :selected').each(function (i, selected) {
if (i == 0) {
processType = $(selected).val();
}
else {
processType = processType + "\\',\\'" + $(selected).val();
}
});
$.ajax({
type: "POST",
url: "ewDashboard.aspx/GetChart5",
data: "{sd: '" + sd + "', ed: '" + ed + "', processType: '" + processType + "'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (r) {
var labels = r.d[0];
var series1 = r.d[1];
var data = {
labels: labels,
datasets: [{
label: 'Process Count',
data: series1,
fill: false,
borderColor: "blue",
color: "red",
backgroundColor: "blue",
radius: 10,
}
]
};
$("#dvChart5").html("");
var canvas = document.createElement('canvas');
$("#dvChart5")[0].appendChild(canvas);
var ctx2 = canvas.getContext('2d');
var piechart = new Chart(ctx2, {
type: 'line',
data: data,
options: {
title: {
display: false
},
scales: {
xAxes: [{
ticks: {
minRotation: 75,
maxRotation: 90,
fontFamily: "'Open Sans', sans-serif",
fontSize: 14,
fontStyle: "bold",
fontColor: "#545454",
autoSkip: false
}
}],
},
tooltips: {
},
legend: {
display: true,
position: 'bottom'
}
}
});
},
failure: function (response) {
alert('There was an error.');
}
});
}
thanks

Put this in option
plugins: {
datalabels: {
display: false,
},
}

This works:
options: {
legend: {
display: false
},
}

Related

Multiple bar charts side by side chartjs

I'm trying to create a bar chart that is grouped by the dataset rather than the label in chartjs3 and I'm having no luck. Before I switch over to building in D3, I wanted to check if this achievable within the confines of ChartJS.
Here is a link to a fiddle where I've been playing around with using different dataset structures and options from the Bar chart docs. I suspect that this is outside of the scope of the charting library, or is within the scope, but requires some custom components to be made – I would appreciate if anyone could direct me on what in particular I would need to extend (e.g. is it a case of a custom axes? or more?).
https://jsfiddle.net/f34ucs76/2/
const data = {
labels: [
'2000','2010','2020',
// 'Frogs','Monkeys','Squirrels','Bats'
],
datasets: [
{
label: 'Frogs',
data: [30.2,20.8,36.2],
backgroundColor: 'red',
//stack: 'Frogs',
},
{
label: 'Monkeys',
data: [16.3,13.0,22.3],
backgroundColor: 'blue',
//stack: 'Monkeys',
},
{
label: 'Squirrels',
data: [5.8,3.1,14.9],
backgroundColor: 'cyan',
//stack:'Squirrels',
},
{
label: 'Bats',
data: [0.1,3.6,2.6],
backgroundColor: 'aquamarine',
//stack:'Bats',
},
],
}
const options = {
maintainAspectRatio: false,
responsive: true,
interaction: {
intersect: false,
mode: 'index',
},
plugins: {
title: {
display: false,
},
subtitle: {
display: true,
align: 'start',
text: ['Source: Animals Index, June 2022'],
font: {
size: 12,
style: 'italic',
},
position: 'bottom',
padding: {
top: 20,
},
},
legend: {
display: true,
position: 'bottom',
},
tooltip: {
enabled: true,
},
},
scales: {
x: {
grid: {
display: false,
},
},
y: {
title: {
display: true,
text: 'Horsepower',
},
},
},
}
const mychart = new Chart(
document.getElementById('mychart'),
{
type: 'bar',
data: data,
options: options,
}
);
Your problem can be solved with Chart.js but the labels and the single dataset need to be generated.
Further you need to define your own legend by defining a plugins.legend.labels.generateLabels together with with a plugins.legend.labels.onClick function.
For further information, consult the Legend page from the Chart.js. documentation.
Please take a look at your amended and runnable code below and see how it works.
const baseData = {
labels: ['2000','2010','2020'],
datasets: [
{ label: 'Frogs', data: [30.2, 20.8, 36.2], bgColor: 'red', hidden: false },
{ label: 'Monkeys', data: [16.3, 13.0, 22.3], bgColor: 'blue', hidden: false },
{ label: 'Squirrels', data: [5.8,3.1, 14.9], bgColor: 'cyan', hidden: false },
{ label: 'Bats', data: [0.1, 3.6, 2.6], bgColor: 'aquamarine', hidden: false }
]
};
const iLastDs = baseData.datasets.length - 1;
const data = {
labels: baseData.datasets
.map(() => baseData.labels)
.map((labels, i) => i < iLastDs ? [...labels, null] : labels)
.flatMap(v => v),
datasets: [{
data: baseData.datasets
.map(ds => ds.data)
.map((data, i) => i < iLastDs ? [...data, null] : data)
.flatMap(v => v),
backgroundColor: baseData.datasets
.map(ds => ds.data.map(v => ds.bgColor))
.map((bgColors, i) => i < iLastDs ? [...bgColors, null] : bgColors)
.flatMap(v => v),
categoryPercentage: 1,
barPercentage: 0.9
}]
};
const options = {
maintainAspectRatio: true,
responsive: true,
interaction: {
intersect: true,
mode: 'index',
},
plugins: {
legend: {
position: 'bottom',
labels: {
generateLabels: chart => baseData.datasets.map((ds, i) => ({
datasetIndex: i,
text: ds.label,
fillStyle: ds.bgColor,
strokeStyle: 'lightgray',
hidden: baseData.datasets[i].hidden
}))
},
onClick: (event, legendItem, legend) => {
baseData.datasets[legendItem.datasetIndex].hidden = !baseData.datasets[legendItem.datasetIndex].hidden;
const iFirstValue = legendItem.datasetIndex + legendItem.datasetIndex * baseData.labels.length;
for (let i = iFirstValue; i < iFirstValue + baseData.labels.length; i++) {
legend.chart.toggleDataVisibility(i);
}
legend.chart.update();
}
},
tooltip: {
callbacks: {
title: ctx => {
const dsIndex = Math.floor(ctx[0].dataIndex / baseData.datasets.length);
return baseData.datasets[dsIndex].label + ' / ' + ctx[0].label;
}
}
}
},
scales: {
x: {
grid: {
display: false
}
},
y: {
title: {
display: true,
text: 'Horsepower',
}
}
}
};
new Chart('mychart', {
type: 'bar',
data,
options
});
span {
font-style: italic;
font-size: 12px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script>
<canvas id="mychart" height="100"></canvas>
<span>Source: Animals Index, June 2022</span>

Tooltip on each data point in Chartjs

Here is my code for putting different tooltip on each data point. I want to put different month on each point, but all the months get printed together. How do I separate them out?
function trendsChart(labels1, datasets1, chartId) {
var ctx =
document.getElementById(chartId).getContext('2d');
var MONTHS = ["January", "February", "March", "April", "May", "June"];
console.log(datasets1)
var data = {
labels: labels1,
datasets: datasets1,
};
// Tooltip
const titleTooltip = (tooltipItems) => {
let sum = 77;
MONTHS.forEach(function(tooltipItem) {
sum = tooltipItem;
})
return sum;
}
var randomScalingFactor = function() {
return (Math.random() > 0.5 ? 1.0 : 1.0) * Math.round(Math.random() * 100);
};
var line1 = [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()];
myChart = new Chart(ctx, {
type: 'line',
data: data,
options: {
maintainAspectRatio: false,
responsive: true,
scales: {
x: {
barPercentage: 1.6,
gridLines: {
drawBorder: false,
color: 'rgba(225,78,202,0.1)',
zeroLineColor: "transparent",
},
ticks: {
padding: 0,
fontColor: "#9a9a9a"
},
title: {
display: true,
text: 'Week Of'
}
},
y: {
barPercentage: 1.6,
gridLines: {
drawBorder: false,
color: 'rgba(225,78,202,0.1)',
zeroLineColor: "transparent",
},
ticks: {
padding: 0,
fontColor: "#9a9a9a"
},
stacked: false,
title: {
display: true,
text: 'Count'
}
}
},
plugins: {
tooltip: {
//yAlign: 'bottom',
callbacks: {
title: titleTooltip,
}
}
}
}
});
return myChart;
}
Inside titleTooltip in the pasted code, you replace sum with the last entry from MONTHS. The tooltip from the image however suggests that in the real code, you create an array with 77 and all entries from MONTHS, then you probably return 'Sum: ' + sum, which results in the string you can see in the tooltip.
In order to see all the months on a separate line, you could change your code as follows and return sum as an array:
const titleTooltip = ctx => {
let sum = ['Sum: 77'];
MONTHS.forEach(month => {
sum.push(month);
});
return sum;
}
The resulting tooltip still doesn't make much sense but you'll see all months on a different line. Therefore, you to extend the function titleTooltip in order to obtain the desired result.
Please take a loo at your amended code and see how it works.
function trendsChart(labels1, datasets1, chartId) {
var MONTHS = ["January", "February", "March", "April", "May", "June"];
var data = {
labels: labels1,
datasets: datasets1,
};
// Tooltip
const titleTooltip = ctx => {
let sum = ['Sum: 77'];
MONTHS.forEach(month => {
sum.push(month);
});
return sum;
}
var randomScalingFactor = function() {
return (Math.random() > 0.5 ? 1.0 : 1.0) * Math.round(Math.random() * 100);
};
var line1 = [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()];
myChart = new Chart(chartId, {
type: 'line',
data: data,
options: {
maintainAspectRatio: false,
responsive: true,
scales: {
x: {
barPercentage: 1.6,
gridLines: {
drawBorder: false,
color: 'rgba(225,78,202,0.1)',
zeroLineColor: "transparent",
},
ticks: {
padding: 0,
fontColor: "#9a9a9a"
},
title: {
display: true,
text: 'Week Of'
}
},
y: {
barPercentage: 1.6,
gridLines: {
drawBorder: false,
color: 'rgba(225,78,202,0.1)',
zeroLineColor: "transparent",
},
ticks: {
padding: 0,
fontColor: "#9a9a9a"
},
stacked: false,
title: {
display: true,
text: 'Count'
}
}
},
plugins: {
tooltip: {
//yAlign: 'bottom',
callbacks: {
title: titleTooltip,
label: ctx => ctx.label + ': ' + ctx.parsed.y
}
}
}
}
});
return myChart;
}
trendsChart(['created', 'tested', 'reviewed', 'approved'], [{ data: [1, 5, 3, 2]}], 'myChart');
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.8.0/chart.js"></script>
<canvas id="myChart"></canvas>

Always show last tooltip on all datasets, leave the rest to display on hover? ChartJS

I'm a little stuck on how I would achieve this since it's a little unorthodox in relation to what the plugin does.
I'm attempting for each dataset to keep the last tooltip open at all times and leave the rest to be displayed on hover.
Currently, I'm using this to keep them all displayed:
Chart.plugins.register({
beforeRender: function (chart) {
if (chart.config.options.showAllTooltips) {
chart.pluginTooltips = [];
chart.config.data.datasets.forEach(function (dataset, i) {
console.log(chart);
chart.getDatasetMeta(i).data.forEach(function (sector, j) {
console.log(sector);
chart.pluginTooltips.push(new Chart.Tooltip({
_chart: chart.chart,
_chartInstance: chart,
_data: chart.data,
_options: chart.options.tooltips,
_active: [sector]
}, chart));
});
});
chart.options.tooltips.enabled = false;
}
},
afterDraw: function (chart, easing) {
if (chart.config.options.showAllTooltips) {
if (!chart.allTooltipsOnce) {
if (easing !== 1) {
return;
}
chart.allTooltipsOnce = true;
}
chart.options.tooltips.enabled = true;
Chart.helpers.each(chart.pluginTooltips, function (tooltip) {
tooltip.initialize();
tooltip.update();
tooltip.pivot();
tooltip.transition(easing).draw();
});
chart.options.tooltips.enabled = false;
}
}
});
Is there a way to only do this for the last tooltip in each dataset?
I've come across a way to hide tooltips:
filter: function (tooltipItem, data) {
var label = data.labels[tooltipItem.index];
if (label === labels[labels.length - 1]) {
console.log(tooltipItem);
} else {
return true;
}
}
But this just doesn't display them whatsoever since it's returning false.
Ultimately it will look like this, with the other tooltips displaying on hover of the corresponding node:
Any help greatly appreciated.
I would try to use chartjs-plugin-datalabels for such task.
You can try it out directly on their pages - scriptable interactions
setup
Setting some random data:
var DATA_COUNT = 8;
var labels = [];
Utils.srand(100);
for (var i = 0; i < DATA_COUNT; ++i) {
labels.push('' + i);
}
var DATA_COUNT = 8;
var labels = [];
Utils.srand(100);
for (var i = 0; i < DATA_COUNT; ++i) {
labels.push('' + i);
}
config
Here I did some changes
{
type: 'line',
data: {
labels: labels,
datasets: [{
label: 'France',
backgroundColor: Utils.color(0),
borderColor: Utils.color(0),
data: Utils.numbers({
count: DATA_COUNT,
min: 10,
max: 100
}),
datalabels: {
align: function(context) {
return context.active ? 'start' : 'center';
}
}
}, {
label: 'Canada',
backgroundColor: Utils.color(1),
borderColor: Utils.color(1),
data: Utils.numbers({
count: DATA_COUNT,
min: 0,
max: 100
})
}, {
label: 'USA',
backgroundColor: Utils.color(2),
borderColor: Utils.color(2),
data: Utils.numbers({
count: DATA_COUNT,
min: 0,
max: 100
}),
datalabels: {
align: function(context) {
return context.active ? 'end' : 'center';
}
}
}]
},
options: {
plugins: {
datalabels: {
backgroundColor: function(context) {
return context.active ? context.dataset.backgroundColor : 'white';
},
borderColor: function(context) {
return context.dataset.backgroundColor;
},
borderRadius: function(context) {
return context.active ? 0 : 1;
},
borderWidth: 1,
color: function(context) {
return context.active ? 'white' : context.dataset.backgroundColor;
},
font: {
weight: 'bold'
},
formatter: function(value, context) {
value = Math.round(value * 100) / 100;
if (context.dataIndex === context.dataset.data.length - 1) {
return context.dataset.label + '\n' + value + '%';
} else {
return context.active
? context.dataset.label + '\n' + value + '%'
: ''
}
},
offset: 8,
padding: 0,
textAlign: 'center'
}
},
// Core options
aspectRatio: 5 / 3,
layout: {
padding: {
bottom: 16,
right: 40,
left: 8,
top: 40
}
},
hover: {
mode: 'index',
intersect: false
},
elements: {
line: {
fill: false
}
},
scales: {
yAxes: [{
stacked: true
}]
}
}
}
The main part here is:
formatter: function(value, context) {
value = Math.round(value * 100) / 100;
if (context.dataIndex === context.dataset.data.length - 1) {
return context.dataset.label + '\n' + value + '%';
} else {
return context.active
? context.dataset.label + '\n' + value + '%'
: ''
}
},
The formatter: where I show the label permanently only for context.dataIndex === context.dataset.data.length - 1.
In other cases if it is inactive I show only empty box in other case (hover) I show the information.
How does it look?
No hover
Hover with mouse
So this is the entire hmtl file with all relevant code. As I said, I am no programmer. This effort is from loads of trial and error, including several bits of code from stackoverflow questions.
<script>
$(document).ready(function () {
showtempGraph();
});
function showtempGraph()
{
{
$.post("temperaturedata.php",
function (data)
{
console.log(data);
var temptime = [];
var temp = [];
for (var i in data) {
temptime.push(data[i].timestamp);
temp.push(data[i].temperature);
}
var tempmin = Math.min(...temp);
var tempmax = Math.max(...temp);
var charttempdata = {
labels: temptime,
datasets: [
{
label: 'Temperatur',
pointRadius: 3,
backgroundColor: 'rgba(26, 137, 245, 0.2)',
borderColor: 'rgba(26, 137, 245, 1)',
hoverBackgroundColor: 'rgba(255, 255, 255, 1)',
hoverBorderColor: 'rgba(255, 255, 255, 1)',
pointBackgroundColor: 'rgba(12, 68, 122, 1)',
pointHoverBorderColor: "rgba(255, 255, 255, 0.8)",
data: temp
}
]
};
var graphtempTarget = $("#tempgraphCanvas");
var linetempGraph = new Chart(graphtempTarget, {
type: 'line',
data: charttempdata,
options: {
maintainAspectRatio: false,
tooltips: {
enabled: true,
custom: function(tooltip) {
if (!tooltip) return;
tooltip.displayColors = false;
},
callbacks: {
title: function(tooltipItems, tempdata) {
return 'Klokken: ' + tooltipItems[0].xLabel;
},
label: function(tooltipItem, tempdata) {
return 'Temperatur: ' + Number(tooltipItem.yLabel).toFixed(2) + '°C';
}
}
},
legend: {
display: false,
},
responsive: true,
scales: {
xAxes: [{
type: 'time',
time: {
displayFormats: {
hour: 'HH:mm'
},
tooltipFormat: 'HH:mm',
},
unit : 'day',
gridLines: {
color: '#999999',
lineWidth: 1
},
ticks: {
fontColor: "#fff",
}
}],
yAxes: [
{
type: 'linear',
position: 'left',
gridLines: {
color: '#999999',
lineWidth: 1
},
ticks: {
fontColor: "#fff",
}
}, {
type: 'linear',
position: "right",
afterUpdate: function(scaleInstance) {
console.dir(scaleInstance);
},
gridLines: {
color: '#999999)',
lineWidth: 0.5
},
ticks: {
stepSize: tempmax - tempmin,
min: tempmin,
max: tempmax,
mirror: true,
padding: -10,
fontColor: "#fff",
fontSize: 18,
callback: function(value) {
return value + '°C';
}
},
scaleLabel: {
display: true,
labelString: '°C',
fontColor: "#fff",
fontSize: 14
}
}]
},
}
});
});
}
}
</script>

Chartjs show hidden data on tooltip

Good Day,
I have a bar chart with multiple datasets for the chart. I would like to hide all the bars except for one (a Totals if you will), and on the Tooltip, I want to show all of the data in all the datasets. Unfortunately, the tooltip only shows the visible datasets. Does anyone know how to show all the data sets?
If you run this with
<canvas id="myChart" width="400" height="400"></canvas>
Hover over the chart and the first dataset (labeled 'First Label') is not shown. How do I show that in the tooltip? Does anyone know?
var ds1 = [], ds2 = [], ds3 = [], ds4 = [], ds5 = [], ds6 = [], labels = [];
for(var i = 0; i < 2; i++){
labels.push('Label: ' + i);
ds1.push(i);
ds2.push(i+1);
ds3.push(i+2);
ds4.push(i+3);
ds5.push(i+4);
ds6.push(i+5);
}
const dataSets = {
labels: labels,
datasets: [
{
label: 'First Label',
hidden: true,
data: ds1
},{
label: 'Second Label',
data: ds2
},{
label: 'Third Label',
data: ds3
},{
label: 'Fourth Label',
data: ds4
},{
label: 'Fifth Label',
data: ds5
},{
label: 'Totals',
data: ds6
}
]
}
var myChart = new Chart(ctx, {
type: 'horizontalBar',
data: dataSets,
elements: {
rectangle: {
borderWidth: 2
}
},
responsive: true,
legend: {
display: false
},
title: {
display: false
},
scales: {
yAxes: [
{
barThickness: 15
}
],
xAxes: [
{
ticks: {
suggestedMin: 0,
suggestedMax: 50
},
minBarLength: 5
}]
}
});
Thanks,
Tim
If you hide all bars except one, you can define a tooltips.callback function for label. This function collects the labels and appropriate values from all datasets using Array.map() and returns a string array.
tooltips: {
callbacks: {
label: (tooltipItem, chart) => dataSets.datasets.map(ds => ds.label + ': ' + ds.data[tooltipItem.index])
}
},
Please have a look at your amended code below:
var ds1 = [], ds2 = [], ds3 = [], ds4 = [], ds5 = [], ds6 = [], labels = [];
for (var i = 0; i < 2; i++) {
labels.push('Label: ' + i);
ds1.push(i);
ds2.push(i + 1);
ds3.push(i + 2);
ds4.push(i + 3);
ds5.push(i + 4);
ds6.push(5 * i + 10);
};
const dataSets = {
labels: labels,
datasets: [{
label: 'First Label',
hidden: true,
data: ds1
}, {
label: 'Second Label',
hidden: true,
data: ds2
}, {
label: 'Third Label',
hidden: true,
data: ds3
}, {
label: 'Fourth Label',
hidden: true,
data: ds4
}, {
label: 'Fifth Label',
hidden: true,
data: ds5
}, {
label: 'Totals',
data: ds6
}]
};
var myChart = new Chart('myChart', {
type: 'horizontalBar',
responsive: true,
data: dataSets,
elements: {
rectangle: {
borderWidth: 2
}
},
options: {
legend: {
display: false
},
title: {
display: false
},
tooltips: {
callbacks: {
label: (tooltipItem, chart) => dataSets.datasets.map(ds => ds.label + ': ' + ds.data[tooltipItem.index])
}
},
scales: {
xAxes: [{
ticks: {
min: 0,
stepSize: 1
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="myChart" height="100"></canvas>
If you wanted to display the legend and allow users to show additional bars through a mouse click on individual legend labels, the callback function would be invoked once for each visible bar. Therefore you would have to make sure to return the labels array only once and return null in all other cases. The following code would return the labels array only for the 'Totals' bar.
tooltips: {
callbacks: {
label: (tooltipItem, chart) => {
if (tooltipItem.datasetIndex == dataSets.datasets.length - 1) {
return dataSets.datasets.map(ds => ds.label + ': ' + ds.data[tooltipItem.index]);
}
return null;
}
}
},
This would not work however, if the user decides to hide the 'Totals' bar. The code could however be improved to also overcome this limitation.

Chart.js - displaying multiple line charts using multiple labels

I need to draw a chart with 2 lines using Chart.js.
Each of this line has a different label set.
i.e.
Chart 1:
1 -> 2
2 -> 4
3 -> 8
4 -> 16
Chart 2:
1 -> 3
3 -> 4
4 -> 6
6 -> 9
This following sample obviously does not work as it uses the labels from chart1. But is it possible to realize this with Chart.js?
var config = {
type: 'line',
data: {
labels: [1,2,3,4,5],
datasets: [{
label: 'Chart 1',
data: [2,4,8,16],
}, {
label: 'Chart 2',
data: [3,4,6,9],
}]
},
Other charting libs offers a (label/data) set as parameter so I could simply give a tupel as parameter
(ie. [(1->2),(2->4),(3->8)...]
for each chart and the lib will match everything.
Thanks
Edit: Detailed sample as requested:
var config = {
type: 'line',
data: {
labels: [1, 2, 3, 4, 5],
datasets: [{
label: 'Chart 1',
data: [2, 4, 8, 16],
}, {
label: 'Chart 2',
data: [3, 4, 6, 9],
}]
},
options: {
spanGaps: true,
responsive: true,
title: {
display: true,
text: 'Chart.js Line Chart'
},
tooltips: {
mode: 'index',
intersect: false,
},
hover: {
mode: 'nearest',
intersect: true
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Labels'
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Values'
},
ticks: {
min: 1,
max: 10,
}
}]
}
}
};
window.onload = function() {
var ctx = document.getElementById('canvas').getContext('2d');
window.myLine = new Chart(ctx, config);
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.min.js"></script>
<div style="width:90%;" class="container">
<canvas id="canvas"></canvas><br>
</div>
Use scatter type chart and showLine: true instead of line type with labels:
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'scatter',
data: {
datasets: [
{
label: 'Chart 1',
data: [{x: 1, y: 2}, {x: 2, y: 4}, {x: 3, y: 8},{x: 4, y: 16}],
showLine: true,
fill: false,
borderColor: 'rgba(0, 200, 0, 1)'
},
{
label: 'Chart 2',
data: [{x: 1, y: 3}, {x: 3, y: 4}, {x: 4, y: 6}, {x: 6, y: 9}],
showLine: true,
fill: false,
borderColor: 'rgba(200, 0, 0, 1)'
}
]
},
options: {
tooltips: {
mode: 'index',
intersect: false,
},
hover: {
mode: 'nearest',
intersect: true
},
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
},
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
<canvas id="myChart"></canvas>
What this code does is, it displays multi line graph using chart.js
Create a class for your labeling x and y values
//DataContract for Serializing Data - required to serve in JSON format
[DataContract]
public class LabelPoint
{
//Explicitly setting the name to be used while serializing to JSON.
[DataMember(Name = "label")]
public string Label { get; set; }
public DataPoint DataPoint { get; set; }
}
[DataContract]
public class DataPoint
{
[DataMember(Name = "x")]
public List<string> X { get; set; }
//Explicitly setting the name to be used while serializing to JSON.
[DataMember(Name = "y")]
public List<string> Y { get; set; }
}
Controller code to retrieve data
List<LabelPoint> dataPoints = GetProducts.ToList()
.GroupBy(p => p.ProductName,
(k, c) => new LabelPoint()
{
DataPoint = new DataPoint { X = c.Select(y => y.Date.ToString("dd/MM/yyyy HH:mm")).ToList(), Y = c.Select(cs => cs.Quantity).ToList() },
Label = k
}
).ToList();
ViewBag.DataPoints = dataPoints;
cshtml code to display chart and retrieve data
<canvas id="myChart"></canvas>
<script>
$(document).ready(function () {
// Get the data from the controller using viewbag
// so the data looks something like this [ { Label : "ABC" , DataPoint :[ { X: '222' , Y :60 } ] } ]
var data = #Html.Raw(Json.Encode(ViewBag.DataPoints));
// declare empty array
var dataSet = []; var qty= []; var dates= [];
// loop through the data and get the Label as well as get the created dates and qty for the array of object
for (var i = 0; i < data.length; i++) {
qty.push(data[i].DataPoint.Y);
for (var d = 0; d < data[i].DataPoint.X.length; d++) {
// we're setting this on the X- axis as the label so we need to make sure that we get all the dates between searched dates
dates.push(data[i].DataPoint.X[d]);
}
// we create an array of object, set the Lable which will display LocationName, The data here is the Quantity
dataSet.push(
{
label: data[i].Label,
data: data[i].DataPoint.Y,
fill: false,
borderColor: poolColors(qtyInLocations.length),
pointBorderColor: "black",
pointBackgroundColor: "white",
lineTension: 0.1
}
);
}
// this is the options to set the Actual label like Date And Quantity
var options = {
scales: {
xAxes: [{
scaleLabel: {
display: true,
labelString: "Date",
fontSize: 20
},
}],
yAxes: [{
ticks: {
beginAtZero:true
},
scaleLabel: {
display: true,
labelString: 'Quantity',
fontSize: 20
}
}]
}
};
// we need to remove all duplicate values from the CreatedDate array
var uniq = [ ...new Set(dates) ];
// get the canvas
var ctx = document.getElementById("myChart").getContext('2d');
// build the chart
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: uniq,
datasets:dataSet
},
options: options
});
});
/// will get get random colors each time
function dynamicColors() {
var r = Math.floor(Math.random() * 255);
var g = Math.floor(Math.random() * 255);
var b = Math.floor(Math.random() * 255);
return "rgba(" + r + "," + g + "," + b + ", 0.5)";
}
/// will display random colors each time
function poolColors(a) {
var pool = [];
for(i = 0; i < a; i++) {
pool.push(dynamicColors());
}
return pool;
}
</script>