Reputation: 348
I need to display AmCharts column chart with following data
[
{
month: "2017-03",
source: "TRW",
turnover: 0,
target: 1
},
{
month: "2017-04",
source: "TRW",
turnover: 2.22,
target: 1
},
{
month: "2017-03",
source: "CON",
turnover: 7.27,
target: 1
},
{
month: "2017-04",
source: "CON",
turnover: 1.53,
target: 1
}
]
Requirement is to group columns by the source (ex: TRW, CON) data while using month (ex: 2017-03, 2017-04 ) as the category axis
Please look at this picture which displays the desired chart.
Problem is I need the columns to be added dynamically based on the source data values (ex: source: "CON")
Every example I found on the internet shows that I need to add separate field in JSON for every column. for example
[
{
"month": " 2017-03 ",
"TRW": 0,
"CON": 7.27,
"target": 1
},
{
"month": " 2017-04 ",
"TRW": 2.22,
"CON": 1.53,
"target": 1
}
]
The project is API based and the JSON data set at the top is what I get from the API. In the future more sources may be added other than the existing two sources (ex: TRW, CON)
That is the main reason I need this columns to be auto populated based on the data.
Appreciate any support on this.
Thanks @xorspark
This is how it looks after applying your solution.
👍
Upvotes: 2
Views: 2112
Reputation: 16012
You can pre-process your data in JavaScript prior to creating the chart so that you convert it to the format that AmCharts needs (grouping by month and having fields for each source, as you've seen from the examples) and dynamically create the graph objects needed to render your columns for each new source and target line. This will handle your dynamic case where your external API adds additional source data.
Assuming you're getting your data over AJAX:
//GetAPIData abstracted as a fetch request to jsfiddle's echo endpoint
//for demonstrating external data workflow. See fiddle for details.
GetAPIData().then(function(response) {
if (response.ok) {
return response.json();
}
throw new Error("Response not OK");
}).then(function(data) {
var graphMap = {};
var graphs = [];
var dataMap = {};
var dataProvider = [];
//go through the data and create graphs based on the different sources
//and fill in the dataMap object to remap/convert later
data.forEach(function(dataItem) {
//create a new graph if we did not already create one
if (graphMap[dataItem.source] === undefined) {
graphMap[dataItem.source] = 1;
graphs.push({
valueField: dataItem.source,
title: dataItem.source,
type: 'column',
fillAlphas: 1,
balloonText: '<b>' + dataItem.source + '</b>: [[value]]'
});
}
//create a new object for the month if not already created
if (dataMap[dataItem.month] === undefined) {
dataMap[dataItem.month] = {month: dataItem.month};
}
//add new source information and set target information for that month.
dataMap[dataItem.month][dataItem.source] = dataItem.turnover;
dataMap[dataItem.month].target = dataItem.target;
});
//add the target line
graphs.push({
valueField: 'target',
title: 'Target',
balloonText: '<b>Target</b>: [[value]]'
});
//convert dataMap to an array sorted by date
Object.keys(dataMap).sort(function(lhs, rhs) {
return new Date(lhs) - new Date(rhs);
}).forEach(function(month) {
dataProvider.push(dataMap[month]);
});
//create the chart using the data/graphs created
AmCharts.makeChart('chartdiv', {
// ... other properties omitted ...
dataProvider: dataProvider,
graphs: graphs,
// ... other properties omitted ...
});
}).catch(function(error) {
alert(error.message);
});
Here's a fiddle: https://jsfiddle.net/g46qqf4c/4/
Upvotes: 2