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 +228 -14 3.7.6 → 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,12 +181,20 @@
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,
187 + hover: nSettings.enableInteractivity ? {
188 + mode: 'nearest',
189 + intersect: true
190 + } : {
191 + mode: null,
192 + intersect: false
193 + },
183 194 plugins: {
184 195 tooltip:{
196 + enabled: nSettings.enableInteractivity,
185 197 titleColor: nSettings.tooltipColor,
186 198 bodyColor: nSettings.tooltipColor,
187 199 footerColor: nSettings.tooltipColor,
188 200 titleFont: {
@@ -201,22 +213,122 @@
201 213 weight: nSettings.tooltipBoldText === 'true' ? 'bold' : (nSettings.tooltipBoldText === 'false' ? 'normal' : undefined)
202 214 },
203 215 position: 'nearest',
204 216 events: ['click'],
205 - callbacks: nSettings.showColorCode ? {
206 - label: function(context) {
207 - var label = context.label || '';
208 - var value = context.parsed || 0;
209 - var color = context.dataset.backgroundColor[context.dataIndex];
210 - 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'
211 229 }
212 - } : {
213 - label: function(context) {
214 - var label = context.label || '';
215 - var value = context.parsed || 0;
216 - return label + ': ' + value;
217 - }
218 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)
219 331 },
220 332 legend: {
221 333 position: nSettings.legendPosition,
222 334 align: nSettings.legendAlignment,
@@ -282,10 +394,18 @@
282 394 labels: dataTypes?.labels,
283 395 datasets: dataTypes?.dataSets,
284 396 },
285 397 options: {
398 + hover: nSettings.enableInteractivity ? {
399 + mode: 'nearest',
400 + intersect: true
401 + } : {
402 + mode: null,
403 + intersect: false
404 + },
286 405 plugins: {
287 406 tooltip:{
407 + enabled: nSettings.enableInteractivity,
288 408 titleColor: nSettings.tooltipColor,
289 409 bodyColor: nSettings.tooltipColor,
290 410 footerColor: nSettings.tooltipColor,
291 411 titleFont: {
@@ -370,10 +490,18 @@
370 490 datasets: dataTypes?.dataSets,
371 491 },
372 492 options: {
373 493 maintainAspectRatio: false,
494 + hover: nSettings.enableInteractivity ? {
495 + mode: 'nearest',
496 + intersect: true
497 + } : {
498 + mode: null,
499 + intersect: false
500 + },
374 501 plugins: {
375 502 tooltip:{
503 + enabled: nSettings.enableInteractivity,
376 504 titleColor: nSettings.tooltipColor,
377 505 bodyColor: nSettings.tooltipColor,
378 506 footerColor: nSettings.tooltipColor,
379 507 titleFont: {
@@ -425,13 +553,17 @@
425 553 newSettings.outerRadius = settings['outer_radius'];
426 554 newSettings.sliceSpacing = settings['slice_spacing'];
427 555 newSettings.circumference = settings['circumference'];
428 556 newSettings.startAngle = settings['start_angle'];
557 + newSettings.rotationDegree = settings['rotation_degree'];
429 558 newSettings.sliceColor = settings['slice_color'];
430 559 newSettings.slicesBorderColor = settings['slices_border_color'];
431 560 newSettings.sliceColorDefault = settings['slice_colors_default'];
432 561 newSettings.sliceBorderWidth = settings['slice_border_width'];
433 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'];
434 566 newSettings.legendPosition = settings['legend_position'];
435 567 newSettings.legendAlignment = settings['legend_alignment'];
436 568 newSettings.legendColor = settings['legend_color'];
437 569 newSettings.legendFontSize = settings['legend_font_size'];
@@ -442,11 +574,47 @@
442 574 newSettings.tooltipItalicText = (settings['tooltip_italic'] == 'italic') ? true : false;
443 575 newSettings.tooltipFontSize = settings['tooltip_font_size'];
444 576 newSettings.tooltipBoldText = settings['tooltip_bold'];
445 577 newSettings.showColorCode = (settings['show_color_code'] == 'checked') ? true : false;
578 + newSettings.tooltipText = settings['tooltip_text'];
579 + newSettings.enableInteractivity = (settings['enable_interactivity'] == 'off') ? false : true;
446 580 return newSettings;
447 581 }
448 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 +
449 617 // Detect window resize moment to draw charts responsively
450 618 ChartBuilderChartJs.prototype.resizeChart = function(){
451 619 var _this = this;
452 620
@@ -487,8 +655,54 @@
487 655 data: item.slice(1).map(Number),
488 656 }));
489 657
490 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 + }
491 705 }
492 706
493 707 // Update chart data and display immediately
494 708 ChartBuilderChartJs.prototype.updateChartData = function( newData ){