I'm using ApexCharts to display data from a database, and it works perfectly fine until I have to create multiple data series. I get the data in the form of multiple arrays like so (nb: I don't get a list of fruits, it's for the sake of example)
var fruits = ["apple","apple","apple","apple","apple"]; // Name of the fruit
var dates = ["2019-04-01","2019-04-02","2019-04-03","2019-04-04","2019-04-05"];
var values = [14,9,17,5,11];
Where fruits[0] goes with dates[0] and values[0] (think of them as row in a database).
In this case I have only one data series to pass to ApexCharts and I can do it like this :
var matchedData = [];
// I create nested arrays in matchedData, each array corresponding to a tuple, like so : matched[0] = [dates[0],values[0]]
for(let i = 0; i < fruits.length; i++) {
date = new Date(dates[i]); // To transform the date string to Javascript timestamp
matchedData[i] = [date.getTime(),values[i]];
}
var options = {
chart: {
type: 'line'
},
series: [{
label: "Data",
data: matchedData
}],
xaxis: {
type: 'datetime'
},
}
var chart = new ApexCharts(document.getElementById('chart'), options);
chart.render();
But it only works when the "fruits" array contains solely one kind of fruit and not different kinds. So if my arrays are like this :
var fruits = ["apple","banana","apple","banana","strawberry"];
var dates = ["2019-04-01","2019-04-02","2019-04-03","2019-04-04","2019-04-05"];
var values = [14,9,17,5,11];
I have to dynamically create 3 arrays named each after a fruit (so in this case, "apple", "banana" and "strawberry"), each of them containing the corresponding date and value. Each array would look like this :
apple = [
["2019-04-01", 14], // I wrote the time in string for readability here but in reality it would be written in the JavaScript timestamp format
["2019-04-03", 17]
];
banana = [
["2019-04-02", 9],
["2019-04-04", 5]
];
strawberry = [
["2019-04-05",11]
];
And these data series would be passed to ApexCharts like this :
var options = {
chart: {
type: 'line'
},
series: [
{
label: "apple",
data: apple
},{
label: "banana",
data: banana
},{
label: "strawberry",
data: strawberry
}
],
xaxis: {
type: 'datetime'
},
}
var chart = new ApexCharts(document.getElementById('chart'), options);
chart.render();
My problem is the following :
I don't know how many series I will need to create until runtime, I don't know their name, and I don't know either how to pass them to ApexCharts dynamically (if there are N series, I need N {label/data} clauses).
I've got the start of a solution for dynamically creating an array for each fruit, it looks like this :
for(let i = 0; i < fruits.length; i++) {
if(fruits[i] in window) {
date = new Date(dates[i]);
window[fruits[i]].push([date.getTime(),values[i]]);
} else {
window[lines[i]] = [];
date = new Date(dates[i]);
window[lines[i]].push([date.getTime(),values[i]]);
}
}
And I can then later access each array but only if already know the different values there are in the "fruits" array.
I found myself. I used the window global object like I said earlier like so :
for(let i = 0; i < fruits.length; i++) {
if(!(fruits[i] in window)) {
window[fruits[i]] = [];
}
date = new Date(dates[i]);
window[fruits[i]].push([date.getTime(),values[i]]);
}
Then I made an array listing each unique name from the "fruits" array by using this function :
var fruitsName = fruits.unique();
Array.prototype.unique = function() {
return this.filter(function (value, index, self) {
return self.indexOf(value) === index;
});
}
And then I iterated on the unique names array to add each series to my chart from ApexCharts using the appendSeries() method like this :
for(let i = 0; i < fruitsName.length; i++) {
chart.appendSeries({
name: fruitsName[i],
data: window[fruitsName[i]]
});
}