I'm using amcharts "Pie chart with broken down slices" (/)
When I add two charts I have not render problems. The problem occurs when I click in the first chart. This chart is replaced by the second chart, and now I have 2 charts with the information of the second.
The source code of the first chart:
<div id="chartdevicesdiv" style="width: 100%; height: 500px"></div>
<script>
var chart;
var legend;
var selected;
var types = [{
type: "Smartphone",
percent: 45,
total: 150,
color: "#71c66b",
subs: [{
type: "iOS",
percent: 15
}, {
type: "Android",
percent: 35
}, {
type: "Other",
percent: 20
}]
}, {
type: "Tablet",
percent: 15,
total: 30,
color: "#f2a013",
subs: [{
type: "iOS",
percent: 15
}, {
type: "Android",
percent: 10
}, {
type: "Other",
percent: 5
}]
},
{
type: "Desktop",
percent: 40,
total: 75,
color: "#4f98f7",
subs: [{
type: "Windows",
percent: 15
}, {
type: "Mac",
percent: 10
}, {
type: "Linux",
percent: 5
}]
}];
function generateChartData() {
var chartData = [];
for (var i = 0; i < types.length; i++) {
if (i == selected) {
for (var x = 0; x < types[i].subs.length; x++) {
chartData.push({
type: types[i].subs[x].type,
percent: types[i].subs[x].percent,
color: types[i].color,
pulled: true
});
}
} else {
chartData.push({
type: types[i].type,
percent: types[i].percent,
color: types[i].color,
id: i
});
}
}
return chartData;
}
AmCharts.makeChart("chartdevicesdiv", {
"type": "pie",
"theme": "light",
"dataProvider": generateChartData(),
"labelText": "[[title]]: [[value]]%",
"balloonText": "[[title]]: [[value]]%",
"titleField": "type",
"valueField": "percent",
"outlineColor": "#FFFFFF",
"outlineAlpha": 0.8,
"outlineThickness": 2,
"colorField": "color",
"pulledField": "pulled",
"titles": [{
"text": "Devices stats"
}],
"listeners": [{
"event": "clickSlice",
"method": function(event) {
var chart = event.chart;
if (event.dataItem.dataContext.id != undefined) {
selected = event.dataItem.dataContext.id;
} else {
selected = undefined;
}
chart.dataProvider = generateChartData();
chart.validateData();
}
}],
"export": {
"enabled": true
}
});
</script>
and here, in the same page, the source of the second chart
<div id="chartsourcesdiv" style="width: 100%; height: 500px"></div>
<script>
var chart;
var legend;
var selected;
var types = [{
type: "tself",
percent: 70,
color: "#267be2",
}, {
type: "widget",
percent: 30,
color: "#aa9cb7",
}];
function generateChartData() {
var chartData = [];
for (var i = 0; i < types.length; i++) {
if (i == selected) {
for (var x = 0; x < types[i].subs.length; x++) {
chartData.push({
type: types[i].subs[x].type,
percent: types[i].subs[x].percent,
color: types[i].color,
pulled: true
});
}
} else {
chartData.push({
type: types[i].type,
percent: types[i].percent,
color: types[i].color,
id: i
});
}
}
return chartData;
}
AmCharts.makeChart("chartsourcesdiv", {
"type": "pie",
"theme": "light",
"dataProvider": generateChartData(),
"labelText": "[[title]]: [[value]]%",
"balloonText": "[[title]]: [[value]]%",
"titleField": "type",
"valueField": "percent",
"outlineColor": "#FFFFFF",
"outlineAlpha": 0.8,
"outlineThickness": 2,
"colorField": "color",
"pulledField": "pulled",
"titles": [{
"text": "Sources"
}],
"listeners": [{
"event": "clickSlice",
"method": function(event) {
var chart = event.chart;
if (event.dataItem.dataContext.id != undefined) {
selected = event.dataItem.dataContext.id;
} else {
selected = undefined;
}
chart.dataProvider = generateChartData();
chart.validateData();
}
}],
"export": {
"enabled": true
}
});
</script>
I'm using amcharts "Pie chart with broken down slices" (https://www.amcharts./demos/pie-chart-broken-slices/)
When I add two charts I have not render problems. The problem occurs when I click in the first chart. This chart is replaced by the second chart, and now I have 2 charts with the information of the second.
The source code of the first chart:
<div id="chartdevicesdiv" style="width: 100%; height: 500px"></div>
<script>
var chart;
var legend;
var selected;
var types = [{
type: "Smartphone",
percent: 45,
total: 150,
color: "#71c66b",
subs: [{
type: "iOS",
percent: 15
}, {
type: "Android",
percent: 35
}, {
type: "Other",
percent: 20
}]
}, {
type: "Tablet",
percent: 15,
total: 30,
color: "#f2a013",
subs: [{
type: "iOS",
percent: 15
}, {
type: "Android",
percent: 10
}, {
type: "Other",
percent: 5
}]
},
{
type: "Desktop",
percent: 40,
total: 75,
color: "#4f98f7",
subs: [{
type: "Windows",
percent: 15
}, {
type: "Mac",
percent: 10
}, {
type: "Linux",
percent: 5
}]
}];
function generateChartData() {
var chartData = [];
for (var i = 0; i < types.length; i++) {
if (i == selected) {
for (var x = 0; x < types[i].subs.length; x++) {
chartData.push({
type: types[i].subs[x].type,
percent: types[i].subs[x].percent,
color: types[i].color,
pulled: true
});
}
} else {
chartData.push({
type: types[i].type,
percent: types[i].percent,
color: types[i].color,
id: i
});
}
}
return chartData;
}
AmCharts.makeChart("chartdevicesdiv", {
"type": "pie",
"theme": "light",
"dataProvider": generateChartData(),
"labelText": "[[title]]: [[value]]%",
"balloonText": "[[title]]: [[value]]%",
"titleField": "type",
"valueField": "percent",
"outlineColor": "#FFFFFF",
"outlineAlpha": 0.8,
"outlineThickness": 2,
"colorField": "color",
"pulledField": "pulled",
"titles": [{
"text": "Devices stats"
}],
"listeners": [{
"event": "clickSlice",
"method": function(event) {
var chart = event.chart;
if (event.dataItem.dataContext.id != undefined) {
selected = event.dataItem.dataContext.id;
} else {
selected = undefined;
}
chart.dataProvider = generateChartData();
chart.validateData();
}
}],
"export": {
"enabled": true
}
});
</script>
and here, in the same page, the source of the second chart
<div id="chartsourcesdiv" style="width: 100%; height: 500px"></div>
<script>
var chart;
var legend;
var selected;
var types = [{
type: "tself",
percent: 70,
color: "#267be2",
}, {
type: "widget",
percent: 30,
color: "#aa9cb7",
}];
function generateChartData() {
var chartData = [];
for (var i = 0; i < types.length; i++) {
if (i == selected) {
for (var x = 0; x < types[i].subs.length; x++) {
chartData.push({
type: types[i].subs[x].type,
percent: types[i].subs[x].percent,
color: types[i].color,
pulled: true
});
}
} else {
chartData.push({
type: types[i].type,
percent: types[i].percent,
color: types[i].color,
id: i
});
}
}
return chartData;
}
AmCharts.makeChart("chartsourcesdiv", {
"type": "pie",
"theme": "light",
"dataProvider": generateChartData(),
"labelText": "[[title]]: [[value]]%",
"balloonText": "[[title]]: [[value]]%",
"titleField": "type",
"valueField": "percent",
"outlineColor": "#FFFFFF",
"outlineAlpha": 0.8,
"outlineThickness": 2,
"colorField": "color",
"pulledField": "pulled",
"titles": [{
"text": "Sources"
}],
"listeners": [{
"event": "clickSlice",
"method": function(event) {
var chart = event.chart;
if (event.dataItem.dataContext.id != undefined) {
selected = event.dataItem.dataContext.id;
} else {
selected = undefined;
}
chart.dataProvider = generateChartData();
chart.validateData();
}
}],
"export": {
"enabled": true
}
});
</script>
Share
Improve this question
asked Jan 27, 2017 at 12:13
MGEMGE
8532 gold badges12 silver badges23 bronze badges
0
1 Answer
Reset to default 7The problem is you're reusing the same variable names for both charts' data. When you redeclare the variable types
, you overwrite the previous declaration, so any click will use the second types
variable's data. A clean way to fix this is to change the types variables to have unique names and then modify your generateChartData
function (you only need one since they both do the same thing) to take a parameter.
var chart1types = [ /* data */ ];
var chart2types = [ /* data */ ];
function generateChartData(types) {
//same code from before
}
AmCharts.makeChart("chartdevicesdiv", {
// ...
"dataProvider": generateChartData(chart1types), //use first types variable
// ...
"listeners": [{
"event": "clickSlice",
"method": function(event) {
var chart = event.chart;
if (event.dataItem.dataContext.id != undefined) {
selected = event.dataItem.dataContext.id;
} else {
selected = undefined;
}
chart.dataProvider = generateChartData(chart1types); //use first types variable
chart.validateData();
}
}],
// ...
});
AmCharts.makeChart("chartsourcesdiv", {
// ...
"dataProvider": generateChartData(chart2types), //use second types variable
// ...
"listeners": [{
"event": "clickSlice",
"method": function(event) {
var chart = event.chart;
if (event.dataItem.dataContext.id != undefined) {
selected = event.dataItem.dataContext.id;
} else {
selected = undefined;
}
chart.dataProvider = generateChartData(chart2types); //use second types variable
chart.validateData();
}
}],
// ...
});
Here's a demo of the fix.