Reputation: 267
I'm trying to add lines to a chart.js chart dynamically where I don't know how many datasets I have I've been banged my head on this for two days now...
I have a list containing Year, Month and Value:
public int Month { get; set; }
public int Year { get; set; }
public int Value { get; set; }
My HTML is just a canvas for the chart:
<div>
<canvas id="myChart"> </canvas>
</div>
I populate the chart like this:
var dataList = [];
var lableList = [];
@foreach (var dataInput in Model.TurnoverByReservation)
{
@:dataList.push("@dataInput.Value");
@:lableList.push("@dataInput.MonthName");
}
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: lableList,
datasets: [
{
label: 'Booking value',
data: dataList,
backgroundColor: backgroundColors,
borderColor: borderColors,
borderWidth: 1
}
]
},
options: {
scales: {
yAxes: [
{
ticks: {
beginAtZero: true,
callback: function(value, index, values) {
if (parseInt(value) >= 1000) {
return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
} else {
return value;
}
}
}
}
]
}
}
});
So the question is; how can I add different datasets to the chart so that I can use something like this?
@foreach (var year in Model.TurnoverByReservation.OrderBy(x =>x.Month).GroupBy(x => x.Year))
{
foreach (var value in year)
{
//Add the value to the dataset, somehow...
}
}
Upvotes: 3
Views: 6801
Reputation: 267
This is the final and working solution, big thanks to @tektiv for all assistance
var borderColors = [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
];
var backgroundColors = [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
];
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
label: "#value",
datasets: []
},
options: {
scales: {
yAxes: [
{
ticks: {
beginAtZero: true
}
}
]
}
}
});
@{StringBuilder valueObj = new StringBuilder();}
var objModel = new Object();
var myArray = [];
@foreach (var years in Model.TurnoverByReservation.OrderBy(x => x.Month).GroupBy(x => x.Year))
{
foreach (var value in years)
{
@:myArray.push("@value.Value");
}
@:objModel["@years.Key"] = myArray;
@:myArray = [];
}
var colorInt = 0; //Used to set a variable background and border color
for (year in objModel) {
// You create a new dataset with empty values and the year as the label
var newDataset = {
label: year,
data: [],
backgroundColor: backgroundColors[colorInt],
borderColor:borderColors[colorInt]
};
colorInt += 1;
// For every value for this specific year ..
for (value in objModel[year]) {
// You populate the newly created dataset
newDataset.data.push(objModel[year][value]);
}
// Then you add the dataset to the charts' ones
myChart.config.data.datasets.push(newDataset);
}
// Finally, make sure you update your chart, to get the result on your screen
myChart.update();
Upvotes: 2
Reputation: 14187
You can populate your datasets array whenever you want, even after calling the new Chart()
function by editing the array datasets
stored in myChart.config.data
.
Let's say you get something like this from your query
var model = {
2015: [20, 12, 32, 8, 25, 14, 20, 12, 32, 8, 25, 14],
2016: [17, 26, 21, 41, 8, 23, 17, 26, 21, 41, 8, 23],
2017: [23, 15, 8, 24, 38, 20, 23, 15, 8, 24, 38, 20]
};
You loop into it, and store every data you have in you new datasets :
// For every year in your data ...
for (year in model) {
// You create a new dataset with empty values and the year as the label
var newDataset = {
label: year,
data: []
};
// For every value for this specific year ..
for (value in model[year]) {
// You populate the newly created dataset
newDataset.data.push(model[year][value]);
}
// Then you add the dataset to the charts' ones
myChart.config.data.datasets.push(newDataset);
}
// Finally, make sure you update your chart, to get the result on your screen
myChart.update();
Make sure you initiate your chart with at least the following :
var myChart = new Chart(ctx, {
type: 'line',
data: {
// You need as much labels as the number of values you have
labels: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
// This makes sure you'll get something with `myChart.config.data.datasets`
datasets: []
}
});
If your model structure is different, you should still be able to change a bit the loop to get it working.
You can check a result with default data in this fiddle.
Upvotes: 6