问题
**The reference - https://www.amcharts.com/demos/stacked-area/ It only plots one single user on y axis whereas I want all users data in stacked line area.
I guess I need to create a function on data series, but really don't know how to do that. I want X axis to be Date , Y axis to be value scale showing multi-line users [A,B,C,D] **
< script >
var df = [{
"User": "A",
"Date": 1570492800000,
"value_act": 3.4
}, {
"User": "B",
"Date": 1570492800000,
"value_act": 1.6
}, {
"User": "C",
"Date": 1570492800000,
"value_act": 4.7
}, {
"User": "D",
"Date": 1570492800000,
"value_act": 0.0
}, {
"User": "A",
"Date": 1570579200000,
"value_act": 3.4
}, {
"User": "B",
"Date": 1570579200000,
"value_act": 1.6
}, {
"User": "C",
"Date": 1570579200000,
"value_act": 4.7
}, {
"User": "D",
"Date": 1570579200000,
"value_act": 0.0
}, {
"User": "A",
"Date": 1570838400000,
"value_act": 3.4
}, {
"User": "B",
"Date": 1570838400000,
"value_act": 1.6
}, {
"User": "C",
"Date": 1570838400000,
"value_act": 4.7
}, {
"User": "D",
"Date": 1570838400000,
"value_act": 0.0
}]
console.log(df);
am4core.ready(function() {
// Themes begin
am4core.useTheme(am4themes_animated);
// Themes end
var chart = am4core.create("lines1", am4charts.XYChart);
chart.data = df;
chart.dateFormatter.inputDateFormat = "yyyy";
var dateAxis = chart.xAxes.push(new am4charts.DateAxis());
dateAxis.renderer.minGridDistance = 60;
dateAxis.startLocation = 0.5;
dateAxis.endLocation = 0.5;
dateAxis.baseInterval = {
timeUnit: "Date",
count: 1
}
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis.tooltip.disabled = true;
var series = chart.series.push(new am4charts.LineSeries());
series.dataFields.dateX = "Date";
series.name = "User";
series.dataFields.valueY = "value_act";
series.tooltipText = "[#000]{valueY.value}[/]";
series.tooltip.background.fill = am4core.color("#FFF");
series.tooltip.getStrokeFromObject = true;
series.tooltip.background.strokeWidth = 3;
series.tooltip.getFillFromObject = false;
series.fillOpacity = 0.6;
series.strokeWidth = 2;
series.stacked = true;
chart.cursor = new am4charts.XYCursor();
chart.cursor.xAxis = dateAxis;
chart.scrollbarX = new am4core.Scrollbar();
// Add a legend
chart.legend = new am4charts.Legend();
chart.legend.position = "top";
});
// end am4core.ready()
<
/script>
<script src="https://www.amcharts.com/lib/4/core.js"></script>
<script src="https://www.amcharts.com/lib/4/charts.js"></script>
<script src="https://www.amcharts.com/lib/4/themes/animated.js"></script>
<div id="lines1"></div>
回答1:
to have multiple lines, need to add multiple series to the chart
each series needs a specific key in the data
so, instead of all having a key for "User"
,
we need 4 separate keys --> "UserA", "UserB", "UserC", "UserD"
var df = [{
"UserA": "A",
"Date": 1570492800000,
"value_act": 3.4
}, {
"UserB": "B",
"Date": 1570492800000,
"value_act": 1.6
}, {
"UserC": "C",
"Date": 1570492800000,
"value_act": 4.7
}, {
"UserD": "D",
"Date": 1570492800000,
"value_act": 0.0
}, {
see following working snippet...
am4core.ready(function() {
// Themes begin
am4core.useTheme(am4themes_animated);
// Themes end
var df = [{
"UserA": "A",
"Date": 1570492800000,
"value_act": 3.4
}, {
"UserB": "B",
"Date": 1570492800000,
"value_act": 1.6
}, {
"UserC": "C",
"Date": 1570492800000,
"value_act": 4.7
}, {
"UserD": "D",
"Date": 1570492800000,
"value_act": 0.0
}, {
"UserA": "A",
"Date": 1570579200000,
"value_act": 3.4
}, {
"UserB": "B",
"Date": 1570579200000,
"value_act": 1.6
}, {
"UserC": "C",
"Date": 1570579200000,
"value_act": 4.7
}, {
"UserD": "D",
"Date": 1570579200000,
"value_act": 0.0
}, {
"UserA": "A",
"Date": 1570838400000,
"value_act": 3.4
}, {
"UserB": "B",
"Date": 1570838400000,
"value_act": 1.6
}, {
"UserC": "C",
"Date": 1570838400000,
"value_act": 4.7
}, {
"UserD": "D",
"Date": 1570838400000,
"value_act": 0.0
}]
am4core.ready(function() {
// Themes begin
am4core.useTheme(am4themes_animated);
// Themes end
var chart = am4core.create("lines1", am4charts.XYChart);
chart.data = df;
chart.dateFormatter.inputDateFormat = "yyyy";
var dateAxis = chart.xAxes.push(new am4charts.DateAxis());
dateAxis.renderer.minGridDistance = 60;
dateAxis.startLocation = 0.5;
dateAxis.endLocation = 0.5;
dateAxis.baseInterval = {
timeUnit: "Date",
count: 1
}
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis.tooltip.disabled = true;
var series = chart.series.push(new am4charts.LineSeries());
series.dataFields.dateX = "Date";
series.name = "UserA";
series.dataFields.valueY = "value_act";
series.tooltipText = "[#000]{valueY.value}[/]";
series.tooltip.background.fill = am4core.color("#FFF");
series.tooltip.getStrokeFromObject = true;
series.tooltip.background.strokeWidth = 3;
series.tooltip.getFillFromObject = false;
series.fillOpacity = 0.6;
series.strokeWidth = 2;
series.stacked = true;
var series = chart.series.push(new am4charts.LineSeries());
series.dataFields.dateX = "Date";
series.name = "UserB";
series.dataFields.valueY = "value_act";
series.tooltipText = "[#000]{valueY.value}[/]";
series.tooltip.background.fill = am4core.color("#FFF");
series.tooltip.getStrokeFromObject = true;
series.tooltip.background.strokeWidth = 3;
series.tooltip.getFillFromObject = false;
series.fillOpacity = 0.6;
series.strokeWidth = 2;
series.stacked = true;
var series = chart.series.push(new am4charts.LineSeries());
series.dataFields.dateX = "Date";
series.name = "UserC";
series.dataFields.valueY = "value_act";
series.tooltipText = "[#000]{valueY.value}[/]";
series.tooltip.background.fill = am4core.color("#FFF");
series.tooltip.getStrokeFromObject = true;
series.tooltip.background.strokeWidth = 3;
series.tooltip.getFillFromObject = false;
series.fillOpacity = 0.6;
series.strokeWidth = 2;
series.stacked = true;
var series = chart.series.push(new am4charts.LineSeries());
series.dataFields.dateX = "Date";
series.name = "UserD";
series.dataFields.valueY = "value_act";
series.tooltipText = "[#000]{valueY.value}[/]";
series.tooltip.background.fill = am4core.color("#FFF");
series.tooltip.getStrokeFromObject = true;
series.tooltip.background.strokeWidth = 3;
series.tooltip.getFillFromObject = false;
series.fillOpacity = 0.6;
series.strokeWidth = 2;
series.stacked = true;
chart.cursor = new am4charts.XYCursor();
chart.cursor.xAxis = dateAxis;
chart.scrollbarX = new am4core.Scrollbar();
// Add a legend
chart.legend = new am4charts.Legend();
chart.legend.position = "top";
});
});
#lines1 {
width: 100%;
height: 500px;
}
<script src="https://www.amcharts.com/lib/4/core.js"></script>
<script src="https://www.amcharts.com/lib/4/charts.js"></script>
<script src="https://www.amcharts.com/lib/4/themes/animated.js"></script>
<div id="lines1"></div>
EDIT
to build the separate series dynamically,
let's first revert back to the original dataset,
where each row has the same "User"
key with a different value.
var df = [{
"User": "A",
"Date": 1570492800000,
"value_act": 3.4
}, {
"User": "B",
"Date": 1570492800000,
"value_act": 1.6
}, {
"User": "C",
"Date": 1570492800000,
"value_act": 4.7
}, {
...
first, we use an array to find the distinct user values. (A, B, C, D, etc...)
in this routine, we also modify the data, to create the separate keys we need for each series.
in other words, we create a new key by appending the value --> "UserA"
and delete the original "User"
key (although this may not be necessary).
var distinctUsers = [];
df.forEach(function (row, index) {
// find distinct user values
if (distinctUsers.indexOf(row.User) === -1) {
distinctUsers.push(row.User);
}
// create new key
df[index]['User' + row.User] = row.User;
// delete old key
delete df[index].User;
});
next, we need to combine rows, such that each date has only one row,
as follows...
var df = [{
"UserA": 3.4,
"UserB": 1.6,
"UserC": 4.7,
"UserD": 0.0,
"Date": 1570492800000,
}, {
"UserA": 3.4,
"UserB": 1.6,
"UserC": 4.7,
"UserD": 0.0,
"Date": 1570579200000,
}, {
"UserA": 3.4,
"UserB": 1.6,
"UserC": 4.7,
"UserD": 0.0,
"Date": 1570838400000,
}];
we can use the map method for this...
// combine date rows
df = distinctDates.map(function (date) {
// build new combined row
var combinedRow = {
Date: date
};
// add user values for date
distinctUsers.forEach(function (user) {
df.forEach(function (row) {
if ((row.hasOwnProperty("User" + user)) && (row.Date === date)) {
combinedRow["User" + user] = row["User" + user];
}
});
});
return combinedRow;
});
then we use the array of distinct values,
to create each unique series.
// create unique series
distinctUsers.forEach(function (user) {
var series = chart.series.push(new am4charts.LineSeries());
series.dataFields.dateX = "Date";
series.name = "User" + user; // <-- use new key for series
series.dataFields.valueY = "value_act";
series.tooltipText = "[#000]{valueY.value}[/]";
series.tooltip.background.fill = am4core.color("#FFF");
series.tooltip.getStrokeFromObject = true;
series.tooltip.background.strokeWidth = 3;
series.tooltip.getFillFromObject = false;
series.fillOpacity = 0.6;
series.strokeWidth = 2;
series.stacked = true;
});
see following working snippet...
am4core.ready(function() {
// Themes begin
am4core.useTheme(am4themes_animated);
// Themes end
var df = [{
"User": "A",
"Date": 1570492800000,
"value_act": 3.4
}, {
"User": "B",
"Date": 1570492800000,
"value_act": 1.6
}, {
"User": "C",
"Date": 1570492800000,
"value_act": 4.7
}, {
"User": "D",
"Date": 1570492800000,
"value_act": 0.0
}, {
"User": "A",
"Date": 1570579200000,
"value_act": 3.4
}, {
"User": "B",
"Date": 1570579200000,
"value_act": 1.6
}, {
"User": "C",
"Date": 1570579200000,
"value_act": 4.7
}, {
"User": "D",
"Date": 1570579200000,
"value_act": 0.0
}, {
"User": "A",
"Date": 1570838400000,
"value_act": 3.4
}, {
"User": "B",
"Date": 1570838400000,
"value_act": 1.6
}, {
"User": "C",
"Date": 1570838400000,
"value_act": 4.7
}, {
"User": "D",
"Date": 1570838400000,
"value_act": 0.0
}];
// find distinct users & dates, apply value to user key
var distinctUsers = [];
var distinctDates = [];
df.forEach(function (row, index) {
// find distinct user values
if (distinctUsers.indexOf(row.User) === -1) {
distinctUsers.push(row.User);
}
// find distinct date values
if (distinctDates.indexOf(row.Date) === -1) {
distinctDates.push(row.Date);
}
// create new key
df[index]['User' + row.User] = row.value_act;
// delete old key
delete df[index].User;
});
// combine date rows
df = distinctDates.map(function (date) {
// build new combined row
var combinedRow = {
Date: date
};
// add user values for date
distinctUsers.forEach(function (user) {
df.forEach(function (row) {
if ((row.hasOwnProperty("User" + user)) && (row.Date === date)) {
combinedRow["User" + user] = row["User" + user];
}
});
});
return combinedRow;
});
am4core.ready(function() {
// Themes begin
am4core.useTheme(am4themes_animated);
// Themes end
var chart = am4core.create("lines1", am4charts.XYChart);
chart.data = df;
chart.dateFormatter.inputDateFormat = "yyyy";
var dateAxis = chart.xAxes.push(new am4charts.DateAxis());
dateAxis.renderer.minGridDistance = 60;
dateAxis.startLocation = 0.5;
dateAxis.endLocation = 0.5;
dateAxis.baseInterval = {
timeUnit: "Date",
count: 1
}
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis.tooltip.disabled = true;
// create unique series
distinctUsers.forEach(function (user) {
var series = chart.series.push(new am4charts.LineSeries());
series.dataFields.dateX = "Date";
series.name = "User" + user;
series.dataFields.valueY = "User" + user;
series.tooltipText = "[#000]{valueY.value}[/]";
series.tooltip.background.fill = am4core.color("#FFF");
series.tooltip.getStrokeFromObject = true;
series.tooltip.background.strokeWidth = 3;
series.tooltip.getFillFromObject = false;
series.fillOpacity = 0.6;
series.strokeWidth = 2;
series.stacked = true;
});
chart.cursor = new am4charts.XYCursor();
chart.cursor.xAxis = dateAxis;
chart.scrollbarX = new am4core.Scrollbar();
// Add a legend
chart.legend = new am4charts.Legend();
chart.legend.position = "top";
});
});
#lines1 {
width: 100%;
height: 500px;
}
<script src="https://www.amcharts.com/lib/4/core.js"></script>
<script src="https://www.amcharts.com/lib/4/charts.js"></script>
<script src="https://www.amcharts.com/lib/4/themes/animated.js"></script>
<div id="lines1"></div>
来源:https://stackoverflow.com/questions/58854401/stacked-area-amchart-passing-dynamic-data