PluginProbe
Chartify – WordPress Chart Plugin / 3.8.1
Chartify – WordPress Chart Plugin v3.8.1
3.8.1 3.8.0 3.7.9 3.7.8 3.7.7 3.7.6 3.7.5 trunk 1.0.0 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 All 84 releases
← All changes | public/js/chart-builder-public-chartjs.js +201 -13 3.7.8 → 3.8.1 View file →
@@ -105,8 +105,11 @@
105 105 switch (_this.chartType) {
106 106 case 'pie_chart':
107 107 _this.pieChartView();
108 108 break;
109 + case 'donut_chart':
110 + _this.donutChartView();
111 + break;
109 112 case 'bar_chart':
110 113 _this.barChartView();
111 114 break;
112 115 case 'line_chart':
@@ -128,8 +131,9 @@
128 131 var dataTypes = _this.chartConvertData( getChartSource );
129 132
130 133 var settings = _this.dbData.options;
131 134 var nSettings = _this.configOptionsForCharts(settings);
135 + _this.applyPieDataGrouping(dataTypes, nSettings);
132 136
133 137 // var ctx = document.getElementById(_this.htmlClassPrefix + _this.uniqueId + '-canvas');
134 138 var parentId = _this.htmlClassPrefix + _this.chartType + '-' + _this.uniqueId;
135 139 var canvasId = parentId + '-canvas';
@@ -163,9 +167,9 @@
163 167 dataTypes.dataSets[0].backgroundColor = [];
164 168 dataTypes.dataSets[0].borderColor = [];
165 169
166 170 for (var i = 0; i < sliceCount; i++) {
167 - dataTypes.dataSets[0].backgroundColor[i] = nSettings.sliceColor?.[i] || nSettings.sliceColorDefault?.[i % nSettings.sliceColorDefault.length];
171 + dataTypes.dataSets[0].backgroundColor[i] = i === dataTypes.dataSets[0].groupedSliceIndex ? nSettings.dataGroupingColor : (nSettings.sliceColor?.[i] || nSettings.sliceColorDefault?.[i % nSettings.sliceColorDefault.length]);
168 172 dataTypes.dataSets[0].borderColor[i] = nSettings.slicesBorderColor?.[i] || 'transparent';
169 173 }
170 174 dataTypes.dataSets[0].borderWidth = nSettings.sliceBorderWidth;
171 175 _this.chartObject = new Chart(ctx, {
@@ -209,22 +213,122 @@
209 213 weight: nSettings.tooltipBoldText === 'true' ? 'bold' : (nSettings.tooltipBoldText === 'false' ? 'normal' : undefined)
210 214 },
211 215 position: 'nearest',
212 216 events: ['click'],
213 - callbacks: nSettings.showColorCode ? {
214 - label: function(context) {
215 - var label = context.label || '';
216 - var value = context.parsed || 0;
217 - var color = context.dataset.backgroundColor[context.dataIndex];
218 - return label + ': ' + value + ' (Color: ' + color + ')';
217 + callbacks: _this.getTooltipCallbacks(nSettings.tooltipText, nSettings.showColorCode)
218 + },
219 + legend: {
220 + position: nSettings.legendPosition,
221 + align: nSettings.legendAlignment,
222 + reverse: nSettings.legendReverse,
223 + labels: {
224 + color: nSettings.legendColor,
225 + font: {
226 + size: nSettings.legendFontSize,
227 + weight: nSettings.legendBoldText ? 'bold' : 'normal',
228 + style: nSettings.legendItalicText ? 'italic' : 'normal'
219 229 }
220 - } : {
221 - label: function(context) {
222 - var label = context.label || '';
223 - var value = context.parsed || 0;
224 - return label + ': ' + value;
225 - }
226 230 }
231 + }
232 + }
233 + }
234 + });
235 +
236 + _this.resizeChart();
237 + }
238 +
239 + // Load chart by pie chart
240 + ChartBuilderChartJs.prototype.donutChartView = function(){
241 + var _this = this;
242 + var getChartSource = _this.dbData.source;
243 +
244 + var dataTypes = _this.chartConvertData( getChartSource );
245 +
246 + var settings = _this.dbData.options;
247 + var nSettings = _this.configOptionsForCharts(settings);
248 + _this.applyPieDataGrouping(dataTypes, nSettings);
249 +
250 + // var ctx = document.getElementById(_this.htmlClassPrefix + _this.uniqueId + '-canvas');
251 + var parentId = _this.htmlClassPrefix + _this.chartType + '-' + _this.uniqueId;
252 + var canvasId = parentId + '-canvas';
253 +
254 + var parentElement = document.getElementById(parentId);
255 + var canvasElement = document.getElementById(canvasId);
256 +
257 + if (!canvasElement) {
258 + canvasElement = document.createElement('canvas');
259 + canvasElement.id = canvasId;
260 + parentElement.appendChild(canvasElement);
261 + }
262 +
263 + var ctx = canvasElement;
264 + ctx.width = nSettings.chartWidth;
265 + ctx.height = nSettings.chartHeight;
266 +
267 + if (nSettings.chartWidthFormat === 'px') {
268 + ctx.width = parseInt(nSettings.chartWidth);
269 + } else if (nSettings.chartWidthFormat === '%') {
270 + ctx.style.width = nSettings.chartWidth + '%';
271 + }
272 +
273 + if (nSettings.chartHeightFormat === 'px') {
274 + ctx.height = parseInt(nSettings.chartHeight);
275 + } else if (nSettings.chartHeightFormat === '%') {
276 + ctx.style.height = nSettings.chartHeight + '%';
277 + }
278 +
279 + var sliceCount = dataTypes?.dataSets[0]?.data?.length || 0;
280 + dataTypes.dataSets[0].backgroundColor = [];
281 + dataTypes.dataSets[0].borderColor = [];
282 +
283 + for (var i = 0; i < sliceCount; i++) {
284 + dataTypes.dataSets[0].backgroundColor[i] = nSettings.sliceColor?.[i] || nSettings.sliceColorDefault?.[i % nSettings.sliceColorDefault.length];
285 + dataTypes.dataSets[0].borderColor[i] = nSettings.slicesBorderColor?.[i] || 'transparent';
286 + }
287 + dataTypes.dataSets[0].borderWidth = nSettings.sliceBorderWidth;
288 + _this.chartObject = new Chart(ctx, {
289 + type: 'doughnut',
290 + data: {
291 + labels: dataTypes?.labels,
292 + datasets: dataTypes?.dataSets,
293 + },
294 + options: {
295 + radius: nSettings.outerRadius,
296 + spacing: nSettings.sliceSpacing,
297 + circumference: nSettings.circumference,
298 + rotation: nSettings.rotationDegree,
299 + borderColor: nSettings.sliceBorderColor,
300 + hover: nSettings.enableInteractivity ? {
301 + mode: 'nearest',
302 + intersect: true
303 + } : {
304 + mode: null,
305 + intersect: false
306 + },
307 + plugins: {
308 + tooltip:{
309 + enabled: nSettings.enableInteractivity,
310 + titleColor: nSettings.tooltipColor,
311 + bodyColor: nSettings.tooltipColor,
312 + footerColor: nSettings.tooltipColor,
313 + titleFont: {
314 + size: nSettings.tooltipFontSize || 12,
315 + style: nSettings.tooltipItalicText ? 'italic' : 'normal',
316 + weight: nSettings.tooltipBoldText === 'true' ? 'bold' : (nSettings.tooltipBoldText === 'false' ? 'normal' : undefined)
317 + },
318 + bodyFont: {
319 + size: nSettings.tooltipFontSize || 12,
320 + style: nSettings.tooltipItalicText ? 'italic' : 'normal',
321 + weight: nSettings.tooltipBoldText === 'true' ? 'bold' : (nSettings.tooltipBoldText === 'false' ? 'normal' : undefined)
322 + },
323 + footerFont: {
324 + size: nSettings.tooltipFontSize || 12,
325 + style: nSettings.tooltipItalicText ? 'italic' : 'normal',
326 + weight: nSettings.tooltipBoldText === 'true' ? 'bold' : (nSettings.tooltipBoldText === 'false' ? 'normal' : undefined)
327 + },
328 + position: 'nearest',
329 + events: ['click'],
330 + callbacks: _this.getTooltipCallbacks(nSettings.tooltipText, nSettings.showColorCode)
227 331 },
228 332 legend: {
229 333 position: nSettings.legendPosition,
230 334 align: nSettings.legendAlignment,
@@ -455,8 +559,11 @@
455 559 newSettings.slicesBorderColor = settings['slices_border_color'];
456 560 newSettings.sliceColorDefault = settings['slice_colors_default'];
457 561 newSettings.sliceBorderWidth = settings['slice_border_width'];
458 562 newSettings.sliceBorderColor = settings['slice_border_color'];
563 + newSettings.dataGroupingLimit = parseFloat(settings['data_grouping_limit']) / 100;
564 + newSettings.dataGroupingLabel = settings['data_grouping_label'];
565 + newSettings.dataGroupingColor = settings['data_grouping_color'];
459 566 newSettings.legendPosition = settings['legend_position'];
460 567 newSettings.legendAlignment = settings['legend_alignment'];
461 568 newSettings.legendColor = settings['legend_color'];
462 569 newSettings.legendFontSize = settings['legend_font_size'];
@@ -467,12 +574,47 @@
467 574 newSettings.tooltipItalicText = (settings['tooltip_italic'] == 'italic') ? true : false;
468 575 newSettings.tooltipFontSize = settings['tooltip_font_size'];
469 576 newSettings.tooltipBoldText = settings['tooltip_bold'];
470 577 newSettings.showColorCode = (settings['show_color_code'] == 'checked') ? true : false;
578 + newSettings.tooltipText = settings['tooltip_text'];
471 579 newSettings.enableInteractivity = (settings['enable_interactivity'] == 'off') ? false : true;
472 580 return newSettings;
473 581 }
474 582
583 + ChartBuilderChartJs.prototype.applyPieDataGrouping = function (dataTypes, settings) {
584 + var groupingLimit = parseFloat(settings.dataGroupingLimit);
585 + var dataSet = dataTypes && dataTypes.dataSets && dataTypes.dataSets[0];
586 +
587 + if (!(groupingLimit > 0) || !dataSet || !Array.isArray(dataSet.data)) {
588 + return;
589 + }
590 +
591 + var total = dataSet.data.reduce(function (sum, value) {
592 + return sum + (Number(value) || 0);
593 + }, 0);
594 + var groupedValue = 0;
595 + var groupedSlices = 0;
596 + var labels = [];
597 + var values = [];
598 +
599 + dataSet.data.forEach(function (value, index) {
600 + var numericValue = Number(value) || 0;
601 + if (total > 0 && numericValue / total < groupingLimit) {
602 + groupedValue += numericValue;
603 + groupedSlices++;
604 + } else {
605 + labels.push(dataTypes.labels[index]);
606 + values.push(numericValue);
607 + }
608 + });
609 +
610 + if (groupedSlices > 0) {
611 + dataTypes.labels = labels.concat([settings.dataGroupingLabel]);
612 + dataSet.data = values.concat([groupedValue]);
613 + dataSet.groupedSliceIndex = values.length;
614 + }
615 + }
616 +
475 617 // Detect window resize moment to draw charts responsively
476 618 ChartBuilderChartJs.prototype.resizeChart = function(){
477 619 var _this = this;
478 620
@@ -513,8 +655,54 @@
513 655 data: item.slice(1).map(Number),
514 656 }));
515 657
516 658 return {labels, dataSets};
659 + }
660 +
661 + ChartBuilderChartJs.prototype.getTooltipCallbacks = function(tooltipText, showColorCode) {
662 + var _this = this;
663 + if (showColorCode === true) {
664 + return {
665 + label: function(context) {
666 + var label = context.label || '';
667 + var value = context.parsed || 0;
668 + var color = context.dataset.backgroundColor[context.dataIndex];
669 + return ' ' + label + ': ' + value + ' (Color: ' + color + ')';
670 + }
671 + };
672 + } else {
673 + switch(tooltipText) {
674 + case 'percentage':
675 + return {
676 + label: function(context) {
677 + var label = context.label || '';
678 + var value = context.parsed || 0;
679 + var total = context.chart._metasets[context.datasetIndex].total;
680 + var percentage = ((value / total) * 100).toFixed(1) + '%';
681 + return ' ' + label + ': ' + percentage;
682 + }
683 + };
684 + case 'both':
685 + return {
686 + label: function(context) {
687 + var label = context.label || '';
688 + var value = context.parsed || 0;
689 + var total = context.chart._metasets[context.datasetIndex].total;
690 + var percentage = ((value / total) * 100).toFixed(1) + '%';
691 + return ' ' + label + ': ' + value + ' (' + percentage + ')';
692 + }
693 + };
694 + case 'value':
695 + default:
696 + return {
697 + label: function(context) {
698 + var label = context.label || '';
699 + var value = context.parsed || 0;
700 + return ' ' + label + ': ' + value;
701 + }
702 + };
703 + }
704 + }
517 705 }
518 706
519 707 // Update chart data and display immediately
520 708 ChartBuilderChartJs.prototype.updateChartData = function( newData ){