I'm drawing a pie chart using AmCharts V3 and am using the export plugin to export the data as a file. I'm displaying a percentage contibution of the sale in different countries and would like to also display this percentage when I export my data to a CSV or XLSX file, but I'm not able to do so.
Here is my code
var chart = AmCharts.makeChart("chartdivtaxes", {
type: "pie",
startDuration: 0,
theme: "light",
addClassNames: true,
labelText: "[[percents]]",
innerRadius: "30%",
labelFunction: function(value, valueText, valueAxis) {
valueText = parseFloat(valueText);
var percentageText = valueText
.toFixed(1)
.replace(/(\d)(?=(\d{3})+\.)/g, "$1,");
return percentageText + "%";
},
defs: {
filter: [
{
id: "shadow",
width: "200%",
height: "200%",
feOffset: {
result: "offOut",
in: "SourceAlpha",
dx: 0,
dy: 0
},
feGaussianBlur: {
result: "blurOut",
in: "offOut",
stdDeviation: 5
},
feBlend: {
in: "SourceGraphic",
in2: "blurOut",
mode: "normal"
}
}
]
},
dataProvider: [
{
countryName: "India",
country: "sale in india:",
litres: "800.00"
},
{
countryName: "africa",
country: "sale in africa:",
litres: "800.00"
},
{
countryName: "UK",
country: "sale in UK:",
litres: "800.00"
},
{
countryName: "US",
country: "sale in US:",
litres: "800.00"
}
],
valueField: "litres",
titleField: "country",
balloon: {
fixedPosition: false,
color: "#ffffff",
fillAlpha: 0.9,
fillColor: "#00000"
},
export: {
enabled: true,
divId: "exportLevy",
columnNames: {
litres: "TotalSale",
countryName: "Name"
},
menu: [
{
class: "export-main",
label: "Export",
menu: [
{
format: "XLSX"
},
{
format: "CSV"
}
]
}
],
exportFields: ["countryName", "litres", "percents"]
}
});
There are two ways you can go about this - both of which involve using the processData
callback offered by the export plugin.
1) Use processData
to add a percent property in your data and manually trigger a download with toCSV
or toXLSX
. Note that you will need to throw an exception to prevent the plugin from triggering the download multiple times:
var chart = AmCharts.makeChart("...", {
// ...
export: {
// ...
processData: function(data, cfg) {
//only for CSV and XLSX export. Wrap in an ignore call to prevent infinite loop
if ((cfg.format === "CSV" || cfg.format === "XLSX") && !cfg.ignoreThatRequest) {
var sum = data.reduce(function(accumulator, currentDataValue) {
return accumulator + parseFloat(currentDataValue.TotalSale);
}, 0);
data.forEach(function(currentDataValue) {
currentDataValue.percents =
(parseFloat(currentDataValue.TotalSale) / sum * 100).toFixed(1) + "%";
});
//will map to this.toCSV or this.toXLSX
this["to" + cfg.format]({
data: JSON.parse(JSON.stringify(data)),
ignoreThatRequest: true, //set ignore flag as processData will execute again when this is called
exportFields: ["Name", "TotalSale", "percents"]
},
function(output) {
this.download(output, cfg.mimeType, cfg.fileName + "." + cfg.extension);
}
);
throw "Invoked – Use custom handler (stop multiple download)"; //throw an exception to stop the multi-download attempt
}
return data;
}
}
});
2) Alternatively, add a dummy percents
property in your dataProvider with its value set to null and use processData
to fill it in before exporting the chart. This is simpler and doesn't require an exception workaround to prevent multiple downloads:
var chart = AmCharts.makeChart("...", {
// ...
export: {
// ...
processData: function(data, cfg) {
var sum = data.reduce(function(accumulator, currentDataValue) {
return accumulator + parseFloat(currentDataValue.TotalSale);
}, 0);
data.forEach(function(currentDataValue) {
currentDataValue.percents =
(parseFloat(currentDataValue.TotalSale) / sum * 100).toFixed(1) + "%";
});
return data;
}
}
});