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 +203 -14 3.7.7 → 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, {
@@ -177,9 +181,9 @@
177 181 options: {
178 182 radius: nSettings.outerRadius,
179 183 spacing: nSettings.sliceSpacing,
180 184 circumference: nSettings.circumference,
181 - rotation: nSettings.startAngle,
185 + rotation: nSettings.rotationDegree,
182 186 borderColor: nSettings.sliceBorderColor,
183 187 hover: nSettings.enableInteractivity ? {
184 188 mode: 'nearest',
185 189 intersect: true
@@ -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,
@@ -449,13 +553,17 @@
449 553 newSettings.outerRadius = settings['outer_radius'];
450 554 newSettings.sliceSpacing = settings['slice_spacing'];
451 555 newSettings.circumference = settings['circumference'];
452 556 newSettings.startAngle = settings['start_angle'];
557 + newSettings.rotationDegree = settings['rotation_degree'];
453 558 newSettings.sliceColor = settings['slice_color'];
454 559 newSettings.slicesBorderColor = settings['slices_border_color'];
455 560 newSettings.sliceColorDefault = settings['slice_colors_default'];
456 561 newSettings.sliceBorderWidth = settings['slice_border_width'];
457 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'];
458 566 newSettings.legendPosition = settings['legend_position'];
459 567 newSettings.legendAlignment = settings['legend_alignment'];
460 568 newSettings.legendColor = settings['legend_color'];
461 569 newSettings.legendFontSize = settings['legend_font_size'];
@@ -466,12 +574,47 @@
466 574 newSettings.tooltipItalicText = (settings['tooltip_italic'] == 'italic') ? true : false;
467 575 newSettings.tooltipFontSize = settings['tooltip_font_size'];
468 576 newSettings.tooltipBoldText = settings['tooltip_bold'];
469 577 newSettings.showColorCode = (settings['show_color_code'] == 'checked') ? true : false;
578 + newSettings.tooltipText = settings['tooltip_text'];
470 579 newSettings.enableInteractivity = (settings['enable_interactivity'] == 'off') ? false : true;
471 580 return newSettings;
472 581 }
473 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 +
474 617 // Detect window resize moment to draw charts responsively
475 618 ChartBuilderChartJs.prototype.resizeChart = function(){
476 619 var _this = this;
477 620
@@ -512,8 +655,54 @@
512 655 data: item.slice(1).map(Number),
513 656 }));
514 657
515 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 + }
516 705 }
517 706
518 707 // Update chart data and display immediately
519 708 ChartBuilderChartJs.prototype.updateChartData = function( newData ){