103 lines
-4 Removals
109 lines
+22 Additions
(function(Chart) {
(function(Chart) {
var cloneArray = function(srcAry) {
var cloneArray = function(srcAry) {
var dstAry = [];
var dstAry = [];
var length = srcAry.length;
var length = srcAry.length;
for (var i = 0; i < length; i++) {
for (var i = 0; i < length; i++) {
dstAry.push(srcAry[i]);
dstAry.push(srcAry[i]);
}
}
return dstAry;
return dstAry;
};
};
var setOriginalData = function(data) {
var setOriginalData = function(data) {
data.originalData = data.datasets.map(function(dataset) {
data.originalData = data.datasets.map(function(dataset) {
return cloneArray(dataset.data);
return cloneArray(dataset.data);
});
});
};
};
// set calculated rate (xx%) to data.calculatedData
// set calculated rate (xx%) to data.calculatedData
var calculateRate = function(data) {
var calculateRate = function(data) {
var visibles = data.datasets.map(function(dataset) {
var visibles = data.datasets.map(function(dataset) {
if (!dataset._meta) return true;
if (!dataset._meta) return true;
for (var i in dataset._meta) {
for (var i in dataset._meta) {
return !dataset._meta[i].hidden;
return !dataset._meta[i].hidden;
}
}
});
});
var totals = Array.apply(null, new Array(data.datasets[0].data.length)).map(function(el, i) {
var totals = Array.apply(null, new Array(data.datasets[0].data.length)).map(function(el, i) {
return data.datasets.reduce(function(sum, dataset, j) {
return data.datasets.reduce(function(sum, dataset, j) {
var key = dataset.stack;
var key = dataset.stack;
if (!sum[key]) sum[key] = 0;
if (!sum[key]) sum[key] = 0;
sum[key] += dataset.data[i] * visibles[j];
sum[key] += (dataset.type === "line" ? 0 : dataset.data[i]) * visibles[j];
return sum;
return sum;
}, {});
}, {});
});
});
data.calculatedData = data.datasets.map(function(dataset, i) {
data.calculatedData = data.datasets.map(function(dataset, i) {
return dataset.data.map(function(val, i) {
return dataset.data.map(function(val, i) {
var total = totals[i][dataset.stack];
if(dataset.type === "line") {
return val && total ? Math.round(val * 1000 / total) / 10 : 0;
return val;
} else {
var total = totals[i][dataset.stack];
return val && total ? Math.round(val * 1000 / total) / 10 : 0;
}
});
});
});
});
};
};
var tooltipLabel = function(tooltipItem, data) {
var tooltipLabel = function(tooltipItem, data) {
var datasetIndex = tooltipItem.datasetIndex;
var datasetIndex = tooltipItem.datasetIndex;
var index = tooltipItem.index;
var index = tooltipItem.index;
var datasetLabel = data.datasets[datasetIndex].label || "";
var datasetLabel = data.datasets[datasetIndex].label || "";
var originalValue = data.originalData[datasetIndex][index];
var originalValue = data.originalData[datasetIndex][index];
var rateValue = data.calculatedData[datasetIndex][index];
var rateValue = data.calculatedData[datasetIndex][index];
return "" + datasetLabel + ": " + rateValue + "% (" + originalValue + ")";
return "" + datasetLabel + ": " + rateValue + "% (" + originalValue + ")";
};
};
var reflectData = function(srcData, datasets) {
var reflectData = function(srcData, datasets) {
if (!srcData) return;
if (!srcData) return;
srcData.forEach(function(data, i) {
srcData.forEach(function(data, i) {
datasets[i].data = data;
datasets[i].data = data;
});
});
};
};
var Stacked100Plugin = {
var Stacked100Plugin = {
id: "stacked100",
id: "stacked100",
beforeInit: function(chartInstance, pluginOptions) {
beforeInit: function(chartInstance, pluginOptions) {
if (!pluginOptions.enable) return;
if (!pluginOptions.enable) return;
var xAxes = chartInstance.options.scales.xAxes;
var xAxes = chartInstance.options.scales.xAxes;
var yAxes = chartInstance.options.scales.yAxes;
var yAxes = chartInstance.options.scales.yAxes;
var isVertical = chartInstance.config.type === "bar" || chartInstance.config.type === "line";
var isVertical = chartInstance.config.type === "bar" || chartInstance.config.type === "line";
[xAxes, yAxes].forEach(function(axes) {
[xAxes, yAxes].forEach(function(axes) {
axes.forEach(function(hash) {
axes.forEach(function(hash) {
hash.stacked = true;
if(hash.stacked === false) return;
hash.stacked = true;
});
});
});
});
(isVertical ? yAxes : xAxes).forEach(function(hash) {
(isVertical ? yAxes : xAxes).forEach(function(hash) {
if(hash.stacked === false) return;
hash.ticks.min = 0;
hash.ticks.min = 0;
hash.ticks.max = 100;
hash.ticks.max = 100;
});
});
chartInstance.options.tooltips.callbacks.label = tooltipLabel;
chartInstance.options.tooltips.callbacks.label = tooltipLabel;
},
},
beforeDatasetsUpdate: function(chartInstance, pluginOptions) {
beforeDatasetsUpdate: function(chartInstance, pluginOptions) {
if (!pluginOptions.enable) return;
if (!pluginOptions.enable) return;
setOriginalData(chartInstance.data);
setOriginalData(chartInstance.data);
calculateRate(chartInstance.data);
calculateRate(chartInstance.data);
reflectData(chartInstance.data.calculatedData, chartInstance.data.datasets);
reflectData(chartInstance.data.calculatedData, chartInstance.data.datasets);
},
},
afterDatasetsUpdate: function(chartInstance, pluginOptions) {
afterDatasetsUpdate: function(chartInstance, pluginOptions) {
if (!pluginOptions.enable) return;
if (!pluginOptions.enable) return;
reflectData(chartInstance.data.originalData, chartInstance.data.datasets);
reflectData(chartInstance.data.originalData, chartInstance.data.datasets);
}
}
};
};
Chart.pluginService.register(Stacked100Plugin);
Chart.pluginService.register(Stacked100Plugin);
}.call(this, Chart));
}.call(this, Chart));
Editor
Clear
Export as PDF