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 | admin/js/chart-builder-admin-chartjs.js +175 -34 3.7.6 → 3.8.1 View file →
@@ -443,8 +443,21 @@
443 443 _this.chartObject.options.rotation = _this.chartSourceData.settings.start_angle;
444 444 _this.chartObject.update();
445 445 });
446 446
447 + _this.$el.find('#'+_this.htmlClassPrefix+'option-rotation-degree').on('input', function () {
448 + _this.chartSourceData.settings.rotation_degree = $(this).val();
449 + _this.chartObject.options.rotation = _this.chartSourceData.settings.rotation_degree;
450 + _this.chartObject.update();
451 + });
452 +
453 + _this.$el.find('#'+_this.htmlClassPrefix+'option-data-grouping-limit, #'+_this.htmlClassPrefix+'option-data-grouping-label, #'+_this.htmlClassPrefix+'option-data-grouping-color').on('input', function () {
454 + _this.chartSourceData.settings.data_grouping_limit = _this.$el.find('#'+_this.htmlClassPrefix+'option-data-grouping-limit').val();
455 + _this.chartSourceData.settings.data_grouping_label = _this.$el.find('#'+_this.htmlClassPrefix+'option-data-grouping-label').val();
456 + _this.chartSourceData.settings.data_grouping_color = _this.$el.find('#'+_this.htmlClassPrefix+'option-data-grouping-color').val();
457 + _this.chartObject.destroy();
458 + _this.loadChartBySource();
459 + });
447 460 // Slices settings
448 461 _this.$el.find('.'+_this.htmlClassPrefix+'option-slice-color').on('input', function () {
449 462 var id = $(this).attr('data-slice-id');
450 463 _this.chartSourceData.settings.slice_color[id] = $(this).val();
@@ -483,11 +496,17 @@
483 496 _this.chartObject.options.plugins.tooltip.bodyColor = _this.chartSourceData.settings.tooltip_text_color;
484 497 _this.chartObject.update();
485 498 });
486 499
500 + _this.$el.find('#'+_this.htmlClassPrefix+'option-tooltip-text').on('change', function () {
501 + _this.chartSourceData.settings.tooltip_text = $(this).val();
502 + _this.chartObject.options.plugins.tooltip.callbacks = _this.getTooltipCallbacks(_this.chartSourceData.settings.tooltip_text, _this.chartSourceData.settings.show_color_code);
503 + _this.chartObject.update();
504 + });
505 +
487 506 _this.$el.find('#'+_this.htmlClassPrefix+'option-show-color-code').on('change', function () {
488 507 _this.chartSourceData.settings.show_color_code = $(this).is(':checked') ? 'checked' : '';
489 - _this.updateTooltipColorCode();
508 + _this.chartObject.options.plugins.tooltip.callbacks = _this.getTooltipCallbacks(_this.chartSourceData.settings.tooltip_text, _this.chartSourceData.settings.show_color_code);
490 509 _this.chartObject.update();
491 510 });
492 511
493 512 _this.$el.find('#'+_this.htmlClassPrefix+'option-tooltip-italic').on('change', function () {
@@ -550,36 +569,44 @@
550 569 _this.chartObject.options.plugins.legend.labels.font.weight = _this.chartSourceData.settings.legend_bold ? 'bold' : 'normal';
551 570 _this.chartObject.update();
552 571 });
553 572
573 + // interactivity settings
574 + _this.$el.find('#'+_this.htmlClassPrefix+'option-enable-interactivity').on('change', function () {
575 + _this.chartSourceData.settings.enable_interactivity = $(this).is(':checked') ? 'checked' : '';
576 + _this.updateInteractivity();
577 + _this.chartObject.update();
578 + });
579 +
554 580 }
555 581
556 - ChartBuilderChartsJs.prototype.updateTooltipColorCode = function() {
582 + ChartBuilderChartsJs.prototype.updateInteractivity = function() {
557 583 var _this = this;
558 - var showColorCode = _this.chartSourceData.settings.show_color_code === 'checked';
584 + var enableInteractivity = _this.chartSourceData.settings.enable_interactivity === 'checked';
559 585
560 - _this.chartObject.options.plugins.tooltip.events = ['click'];
561 -
562 - if (showColorCode) {
563 - _this.chartObject.options.plugins.tooltip.callbacks = {
564 - label: function(context) {
565 - var label = context.label || '';
566 - var value = context.parsed || context.parsed.y || 0;
567 - var color = context.dataset.backgroundColor[context.dataIndex];
568 - return label + ': ' + value + ' (Color: ' + color + ')';
569 - }
586 + if (enableInteractivity) {
587 + // Enable tooltips and hover
588 + _this.chartObject.options.plugins.tooltip.enabled = true;
589 + _this.chartObject.options.hover = {
590 + mode: 'nearest',
591 + intersect: true
570 592 };
571 593 } else {
572 - _this.chartObject.options.plugins.tooltip.callbacks = {
573 - label: function(context) {
574 - var label = context.label || '';
575 - var value = context.parsed || context.parsed.y || 0;
576 - return label + ': ' + value;
577 - }
594 + // Disable tooltips and hover
595 + _this.chartObject.options.plugins.tooltip.enabled = false;
596 + _this.chartObject.options.hover = {
597 + mode: null,
598 + intersect: false
578 599 };
579 600 }
580 601 }
581 602
603 + ChartBuilderChartsJs.prototype.updateTooltipColorCode = function() {
604 + var _this = this;
605 + _this.chartObject.options.plugins.tooltip.events = ['click'];
606 + _this.chartObject.options.plugins.tooltip.callbacks = _this.getTooltipCallbacks(_this.chartSourceData.settings.tooltip_text, _this.chartSourceData.settings.show_color_code);
607 + };
608 +
582 609 ChartBuilderChartsJs.prototype.updateTooltipItalic = function() {
583 610 var _this = this;
584 611 var isItalic = _this.chartSourceData.settings.tooltip_italic === 'checked';
585 612
@@ -890,8 +917,9 @@
890 917 var dataTypes = _this.chartConvertData( getChartSource );
891 918
892 919 var settings = _this.chartSourceData.settings;
893 920 var nSettings = _this.configOptionsForCharts(settings);
921 + _this.applyPieDataGrouping(dataTypes, nSettings);
894 922
895 923 var ctx = document.getElementById(_this.htmlClassPrefix + '-canvas');
896 924
897 925 ctx.width = nSettings.chartWidth;
@@ -913,9 +941,9 @@
913 941 dataTypes.dataSets[0].backgroundColor = [];
914 942 dataTypes.dataSets[0].borderColor = [];
915 943
916 944 for (var i = 0; i < sliceCount; i++) {
917 - dataTypes.dataSets[0].backgroundColor[i] = nSettings.sliceColor?.[i] || nSettings.sliceColorDefault?.[i % nSettings.sliceColorDefault.length];
945 + dataTypes.dataSets[0].backgroundColor[i] = i === dataTypes.dataSets[0].groupedSliceIndex ? nSettings.dataGroupingColor : (nSettings.sliceColor?.[i] || nSettings.sliceColorDefault?.[i % nSettings.sliceColorDefault.length]);
918 946 dataTypes.dataSets[0].borderColor[i] = nSettings.slicesBorderColor?.[i] || 'transparent';
919 947 }
920 948 dataTypes.dataSets[0].borderWidth = nSettings.sliceBorderWidth;
921 949 _this.chartObject = new Chart(ctx, {
@@ -927,9 +955,9 @@
927 955 options: {
928 956 radius: nSettings.outerRadius,
929 957 spacing: nSettings.sliceSpacing,
930 958 circumference: nSettings.circumference,
931 - rotation: nSettings.startAngle,
959 + rotation: nSettings.rotationDegree,
932 960 borderColor: nSettings.sliceBorderColor,
933 961 plugins: {
934 962 maintainAspectRatio: false,
935 963 tooltip:{
@@ -952,20 +980,9 @@
952 980 weight: nSettings.tooltipBoldText === 'true' ? 'bold' : (nSettings.tooltipBoldText === 'false' ? 'normal' : undefined)
953 981 },
954 982 position: 'nearest',
955 983 events: ['click'],
956 - callbacks: nSettings.showColorCode ? {
957 - label: function(context) {
958 - var color = context.dataset.backgroundColor[context.dataIndex];
959 - return 'Color: ' + color;
960 - }
961 - } : {
962 - label: function(context) {
963 - var label = context.label || '';
964 - var value = context.parsed || 0;
965 - return label + ': ' + value;
966 - }
967 - }
984 + callbacks: _this.getTooltipCallbacks(nSettings.tooltipText, nSettings.showColorCode)
968 985 },
969 986 legend: {
970 987 position: nSettings.legendPosition,
971 988 reverse: nSettings.legendReverse,
@@ -1152,13 +1169,17 @@
1152 1169 newSettings.outerRadius = settings['outer_radius'];
1153 1170 newSettings.sliceSpacing = settings['slice_spacing'];
1154 1171 newSettings.circumference = settings['circumference'];
1155 1172 newSettings.startAngle = settings['start_angle'];
1173 + newSettings.rotationDegree = settings['rotation_degree'];
1156 1174 newSettings.sliceColor = settings['slice_color'];
1157 1175 newSettings.slicesBorderColor = settings['slices_border_color'];
1158 1176 newSettings.sliceColorDefault = settings['slice_colors_default'];
1159 1177 newSettings.sliceBorderWidth = settings['slice_border_width'];
1160 1178 newSettings.sliceBorderColor = settings['slice_border_color'];
1179 + newSettings.dataGroupingLimit = parseFloat(settings['data_grouping_limit']) / 100;
1180 + newSettings.dataGroupingLabel = settings['data_grouping_label'];
1181 + newSettings.dataGroupingColor = settings['data_grouping_color'];
1161 1182 newSettings.legendColor = settings['legend_color'];
1162 1183 newSettings.legendPosition = settings['legend_position'];
1163 1184 newSettings.legendAlignment = settings['legend_alignment'];
1164 1185 newSettings.legendFontSize = settings['legend_font_size'];
@@ -1165,15 +1186,50 @@
1165 1186 newSettings.legendItalicText = (settings['legend_italic'] == 'checked') ? true : false;
1166 1187 newSettings.legendBoldText = (settings['legend_bold'] == 'checked') ? true : false;
1167 1188 newSettings.legendReverse = settings['legend_reverse'];
1168 1189 newSettings.tooltipColor = settings['tooltip_text_color'];
1169 - newSettings.showColorCode = (settings['show_color_code'] == 'checked') ? true : false;
1190 + newSettings.showColorCode = settings['show_color_code'];
1170 1191 newSettings.tooltipItalicText = (settings['tooltip_italic'] == 'checked') ? true : false;
1171 1192 newSettings.tooltipFontSize = settings['tooltip_font_size'];
1172 1193 newSettings.tooltipBoldText = settings['tooltip_bold'];
1194 + newSettings.tooltipText = settings['tooltip_text'];
1173 1195 return newSettings;
1174 1196 }
1175 1197
1198 + ChartBuilderChartsJs.prototype.applyPieDataGrouping = function (dataTypes, settings) {
1199 + var groupingLimit = parseFloat(settings.dataGroupingLimit);
1200 + var dataSet = dataTypes && dataTypes.dataSets && dataTypes.dataSets[0];
1201 +
1202 + if (!(groupingLimit > 0) || !dataSet || !Array.isArray(dataSet.data)) {
1203 + return;
1204 + }
1205 +
1206 + var total = dataSet.data.reduce(function (sum, value) {
1207 + return sum + (Number(value) || 0);
1208 + }, 0);
1209 + var groupedValue = 0;
1210 + var groupedSlices = 0;
1211 + var labels = [];
1212 + var values = [];
1213 +
1214 + dataSet.data.forEach(function (value, index) {
1215 + var numericValue = Number(value) || 0;
1216 + if (total > 0 && numericValue / total < groupingLimit) {
1217 + groupedValue += numericValue;
1218 + groupedSlices++;
1219 + } else {
1220 + labels.push(dataTypes.labels[index]);
1221 + values.push(numericValue);
1222 + }
1223 + });
1224 +
1225 + if (groupedSlices > 0) {
1226 + dataTypes.labels = labels.concat([settings.dataGroupingLabel]);
1227 + dataSet.data = values.concat([groupedValue]);
1228 + dataSet.groupedSliceIndex = values.length;
1229 + }
1230 + }
1231 +
1176 1232 // Detect window resize moment to draw charts responsively
1177 1233 ChartBuilderChartsJs.prototype.resizeChart = function(){
1178 1234 var _this = this;
1179 1235
@@ -1221,8 +1277,49 @@
1221 1277 ChartBuilderChartsJs.prototype.updateChartData = function(){
1222 1278 var _this = this;
1223 1279 var newData = _this.chartConvertData( _this.chartData );
1224 1280
1281 + var settings = _this.chartSourceData.settings;
1282 + var nSettings = _this.configOptionsForCharts(settings);
1283 + var defaultColors = nSettings.sliceColorDefault || ['#36A2EB','#FF6384','#FF9F40','#FFCD56', '#4BC0C0','#0099c6','#dd4477','#66aa00', '#b82e2e','#316395','#994499','#22aa99', '#aaaa11','#6633cc','#e67300','#8b0707', '#651067','#329262','#5574a6','#3b3eac', '#b77322','#16d620','#b91383','#f4359e', '#9c5935','#a9c413','#2a778d','#668d1c', '#bea413','#0c5922','#743411'];
1284 +
1285 + var existingDatasets = _this.chartObject.data.datasets || [];
1286 + newData.dataSets = newData.dataSets.map((dataset, index) => {
1287 + var existingDataset = existingDatasets[index] || {};
1288 +
1289 + // Handle backgroundColor for pie charts (array of colors per data point)
1290 + if (_this.chartType === 'pie_chart' && Array.isArray(existingDataset.backgroundColor)) {
1291 + var newBgColor = [...existingDataset.backgroundColor];
1292 + for (var i = existingDataset.backgroundColor.length; i < dataset.data.length; i++) {
1293 + newBgColor[i] = nSettings.sliceColor?.[i] || defaultColors[i % defaultColors.length];
1294 + }
1295 + return {
1296 + ...dataset,
1297 + backgroundColor: newBgColor,
1298 + borderColor: existingDataset.borderColor || dataset.borderColor,
1299 + borderWidth: existingDataset.borderWidth !== undefined ? existingDataset.borderWidth : dataset.borderWidth
1300 + };
1301 + }
1302 +
1303 + // Handle backgroundColor for bar/line charts (single color per dataset)
1304 + var bgColor = existingDataset.backgroundColor;
1305 + var borderColor = existingDataset.borderColor;
1306 +
1307 + if (!bgColor) {
1308 + bgColor = defaultColors[index % defaultColors.length];
1309 + }
1310 + if (!borderColor) {
1311 + borderColor = bgColor;
1312 + }
1313 +
1314 + return {
1315 + ...dataset,
1316 + backgroundColor: bgColor,
1317 + borderColor: borderColor,
1318 + borderWidth: existingDataset.borderWidth !== undefined ? existingDataset.borderWidth : dataset.borderWidth
1319 + };
1320 + });
1321 +
1225 1322 _this.chartObject.data = {
1226 1323 ..._this.chartObject.data,
1227 1324 labels: newData?.labels,
1228 1325 datasets: newData?.dataSets,
@@ -1228,8 +1325,52 @@
1228 1325 datasets: newData?.dataSets,
1229 1326 },
1230 1327 _this.chartObject.update();
1231 1328 }
1329 +
1330 + ChartBuilderChartsJs.prototype.getTooltipCallbacks = function(tooltipText, showColorCode) {
1331 + var _this = this;
1332 + if (showColorCode === 'checked' || showColorCode === true) {
1333 + return {
1334 + label: function(context) {
1335 + var color = context.dataset.backgroundColor[context.dataIndex];
1336 + return ' Color: ' + color;
1337 + }
1338 + };
1339 + } else {
1340 + switch(tooltipText) {
1341 + case 'percentage':
1342 + return {
1343 + label: function(context) {
1344 + var label = context.label || '';
1345 + var value = context.parsed || 0;
1346 + var total = context.chart._metasets[context.datasetIndex].total;
1347 + var percentage = ((value / total) * 100).toFixed(1) + '%';
1348 + return ' ' + label + ': ' + percentage;
1349 + }
1350 + };
1351 + case 'both':
1352 + return {
1353 + label: function(context) {
1354 + var label = context.label || '';
1355 + var value = context.parsed || 0;
1356 + var total = context.chart._metasets[context.datasetIndex].total;
1357 + var percentage = ((value / total) * 100).toFixed(1) + '%';
1358 + return ' ' + label + ': ' + value + ' (' + percentage + ')';
1359 + }
1360 + };
1361 + case 'value':
1362 + default:
1363 + return {
1364 + label: function(context) {
1365 + var label = context.label || '';
1366 + var value = context.parsed || 0;
1367 + return ' ' + label + ': ' + value;
1368 + }
1369 + };
1370 + }
1371 + }
1372 + };
1232 1373
1233 1374 ChartBuilderChartsJs.prototype.addChartDataRow = function (element){
1234 1375 var _this = this;
1235 1376 var content = '';