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-google.js +206 -23 3.1.5 → 3.8.1 View file →
@@ -166,8 +166,12 @@
166 166 _this.chartObj = new google.visualization.PieChart( document.getElementById(_this.htmlClassPrefix + _this.chartType + _this.uniqueId));
167 167
168 168 _this.chartObj.draw( _this.chartData, _this.chartOptions );
169 169 _this.resizeChart();
170 + // Fix ARIA attributes for accessibility compliance
171 + setTimeout(function() {
172 + _this.fixAriaAttributes();
173 + }, 100);
170 174 }
171 175 /* */
172 176 }
173 177
@@ -315,13 +319,49 @@
315 319 duration: nSettings.animationDuration,
316 320 easing: nSettings.animationEasing,
317 321 }
318 322 }
323 +
319 324
325 + if(_this.chartOptions.hAxis.format == 'percent' && nSettings.hAxisEnableDividePercent){
326 + for (var i = 0; i < dataTypes[0].length - 1; i++) {
327 + nSettings.seriesFormat[i] = '#%';
328 + }
329 +
330 + for (var row = 0; row < _this.chartData.getNumberOfRows(); row++) {
331 + for (var col = 0; col < _this.chartData.getNumberOfColumns(); col++) {
332 + var value = _this.chartData.getValue(row, col);
333 + if (typeof value === 'number' && !isNaN(value)) {
334 + var updatedValue = value / 100;
335 + _this.chartData.setValue(row, col, updatedValue);
336 + }
337 + }
338 + }
339 +
340 + }else {
341 + for (var i = 0; i < dataTypes[0].length - 1; i++) {
342 + if (nSettings.seriesFormat[i] === '#%') {
343 + nSettings.seriesFormat[i] = '';
344 + }
345 + }
346 + }
347 +
348 + for (var i = 1; i < dataTypes[0].length; i++) {
349 + if (nSettings.seriesFormat[i - 1]) {
350 + var formatter = new google.visualization.NumberFormat({
351 + pattern: nSettings.seriesFormat[i - 1]
352 + });
353 + formatter.format(_this.chartData, i);
354 + }
355 + }
320 356 _this.chartObj = new google.visualization.BarChart(document.getElementById(_this.htmlClassPrefix + _this.chartType + _this.uniqueId));
321 357
322 358 _this.chartObj.draw( _this.chartData, _this.chartOptions );
323 359 _this.resizeChart();
360 + // Fix ARIA attributes for accessibility compliance
361 + setTimeout(function() {
362 + _this.fixAriaAttributes();
363 + }, 100);
324 364 }
325 365 /* */
326 366 }
327 367
@@ -464,9 +504,40 @@
464 504 color: nSettings.seriesColor[i],
465 505 visibleInLegend: nSettings.seriesVisibleInLegend[i] == 'on' ? true : (typeof nSettings.seriesColor[i] !== 'undefined' ? false : true),
466 506 }
467 507 }
508 +
509 + if(_this.chartOptions.vAxis.format == 'percent' && nSettings.vAxisEnableDividePercent){
510 + for (var i = 0; i < dataTypes[0].length - 1; i++) {
511 + nSettings.seriesFormat[i] = '#%';
512 + }
513 +
468 514
515 + for (var row = 0; row < _this.chartData.getNumberOfRows(); row++) {
516 + for (var col = 0; col < _this.chartData.getNumberOfColumns(); col++) {
517 + var value = _this.chartData.getValue(row, col);
518 + if (typeof value === 'number' && !isNaN(value)) {
519 + var updatedValue = value / 100;
520 + _this.chartData.setValue(row, col, updatedValue);
521 + }
522 + }
523 + }
524 +
525 + }else {
526 + for (var i = 0; i < dataTypes[0].length - 1; i++) {
527 + if (nSettings.seriesFormat[i] === '#%') {
528 + nSettings.seriesFormat[i] = '';
529 + }
530 + }
531 + }
532 + for (var i = 1; i < dataTypes[0].length; i++) {
533 + if (nSettings.seriesFormat[i - 1]) {
534 + var formatter = new google.visualization.NumberFormat({
535 + pattern: nSettings.seriesFormat[i - 1]
536 + });
537 + formatter.format(_this.chartData, i);
538 + }
539 + }
469 540 if (nSettings.enableAnimation) {
470 541 _this.chartOptions.animation = {
471 542 startup: nSettings.animationStartup,
472 543 duration: nSettings.animationDuration,
@@ -477,8 +548,12 @@
477 548 _this.chartObj = new google.visualization.ColumnChart(document.getElementById(_this.htmlClassPrefix + _this.chartType + _this.uniqueId));
478 549
479 550 _this.chartObj.draw( _this.chartData, _this.chartOptions );
480 551 _this.resizeChart();
552 + // Fix ARIA attributes for accessibility compliance
553 + setTimeout(function() {
554 + _this.fixAriaAttributes();
555 + }, 100);
481 556 }
482 557 /* */
483 558 }
484 559
@@ -631,9 +706,38 @@
631 706 pointSize: nSettings.seriesPointSize[i],
632 707 pointShape: nSettings.seriesPointShape[i],
633 708 }
634 709 }
635 -
710 +
711 + if(_this.chartOptions.vAxis.format == 'percent' && nSettings.vAxisEnableDividePercent){
712 + for (var i = 0; i < dataTypes[0].length - 1; i++) {
713 + nSettings.seriesFormat[i] = '#%';
714 + }
715 +
716 + for (var row = 0; row < _this.chartData.getNumberOfRows(); row++) {
717 + for (var col = 0; col < _this.chartData.getNumberOfColumns(); col++) {
718 + var value = _this.chartData.getValue(row, col);
719 + if (typeof value === 'number' && !isNaN(value)) {
720 + var updatedValue = value / 100;
721 + _this.chartData.setValue(row, col, updatedValue);
722 + }
723 + }
724 + }
725 + }else {
726 + for (var i = 0; i < dataTypes[0].length - 1; i++) {
727 + if (nSettings.seriesFormat[i] === '#%') {
728 + nSettings.seriesFormat[i] = '';
729 + }
730 + }
731 + }
732 + for (var i = 1; i < dataTypes[0].length; i++) {
733 + if (nSettings.seriesFormat[i - 1]) {
734 + var formatter = new google.visualization.NumberFormat({
735 + pattern: nSettings.seriesFormat[i - 1]
736 + });
737 + formatter.format(_this.chartData, i);
738 + }
739 + }
636 740 if (nSettings.enableAnimation) {
637 741 _this.chartOptions.animation = {
638 742 startup: nSettings.animationStartup,
639 743 duration: nSettings.animationDuration,
@@ -645,8 +749,12 @@
645 749
646 750
647 751 _this.chartObj.draw( _this.chartData, _this.chartOptions );
648 752 _this.resizeChart();
753 + // Fix ARIA attributes for accessibility compliance
754 + setTimeout(function() {
755 + _this.fixAriaAttributes();
756 + }, 100);
649 757 }
650 758 /* */
651 759 }
652 760
@@ -728,8 +836,12 @@
728 836 _this.chartObj = new google.visualization.PieChart( document.getElementById(_this.htmlClassPrefix + _this.chartType + _this.uniqueId) );
729 837
730 838 _this.chartObj.draw( _this.chartData, _this.chartOptions );
731 839 _this.resizeChart();
840 + // Fix ARIA attributes for accessibility compliance
841 + setTimeout(function() {
842 + _this.fixAriaAttributes();
843 + }, 100);
732 844 }
733 845 /* */
734 846 }
735 847
@@ -779,8 +891,12 @@
779 891
780 892 _this.chartObj.draw( _this.chartData, _this.chartOptions );
781 893 _this.resizeChart();
782 894 _this.setOrgChartCustomStyles();
895 + // Fix ARIA attributes for accessibility compliance
896 + setTimeout(function() {
897 + _this.fixAriaAttributes();
898 + }, 100);
783 899 }
784 900
785 901 _this.$el.on('click', '.google-visualization-orgchart-node-small, .google-visualization-orgchart-node-medium, .google-visualization-orgchart-node-large', function(e) {
786 902 if (nSettings.orgSelectedClassname !== '') {
@@ -835,8 +951,10 @@
835 951 newSettings.groupWidthFormat = settings['group_width_format'] == '%' ? '%' : '';
836 952 newSettings.groupWidth = settings['group_width'] + newSettings.groupWidthFormat;
837 953 newSettings.hAxisTitle = settings['haxis_title'];
838 954 newSettings.vAxisTitle = settings['vaxis_title'];
955 + newSettings.hAxisEnableDividePercent = (settings['haxis_enable_divide_percent'] == 'on' && settings['haxis_format'] == 'percent') ? true : false;
956 + newSettings.vAxisEnableDividePercent = (settings['vaxis_enable_divide_percent'] == 'on' && settings['vaxis_format'] == 'percent') ? true : false;
839 957 newSettings.hAxisLabelFontSize = settings['haxis_label_font_size'];
840 958 newSettings.vAxisLabelFontSize = settings['vaxis_label_font_size'];
841 959 newSettings.hAxisLabelColor = settings['haxis_label_color'];
842 960 newSettings.vAxisLabelColor = settings['vaxis_label_color'];
@@ -880,8 +998,9 @@
880 998 newSettings.animationDuration = settings['animation_duration'];
881 999 newSettings.animationStartup = (settings['animation_startup'] == 'off') ? false : true;
882 1000 newSettings.animationEasing = settings['animation_easing'];
883 1001 newSettings.seriesColor = settings['series_color'];
1002 + newSettings.seriesFormat = settings['series_format'];
884 1003 newSettings.seriesVisibleInLegend = settings['series_visible_in_legend'];
885 1004 newSettings.seriesLineWidth = settings['series_line_width'];
886 1005 newSettings.seriesPointSize = settings['series_point_size'];
887 1006 newSettings.seriesPointShape = settings['series_point_shape'];
@@ -1082,34 +1201,45 @@
1082 1201 // Converting chart data for org chart type
1083 1202 ChartBuilderGoogleCharts.prototype.orgChartConvertData = function( data ){
1084 1203 var _this = this;
1085 1204 var dataTypes = [['Name', 'Manager', 'Tooltip', 'Url']];
1205 +
1206 + var ordering = (_this.dbData && Array.isArray(_this.dbData.source_ordering))
1207 + ? _this.dbData.source_ordering.slice()
1208 + : [];
1209 +
1210 + ordering = ordering.map(String);
1211 +
1212 + Object.keys(data).forEach(function(key) {
1213 + if (!ordering.includes(key)) {
1214 + ordering.push(key);
1215 + }
1216 + });
1217 +
1086 1218 // var name = "";
1087 1219 // Collect data in new array for chart rendering
1088 - for ( var key in data ) {
1089 - if ( data.hasOwnProperty( key ) ) {
1090 - if (key != 0) {
1091 - var name = data[key][0];
1092 - var description = data[key][1];
1093 - var image = (data[key].length > 6) ? data[key][2] : '';
1094 - var parent_name = (data[key].length > 6) ? data[key][3] : data[key][2];
1095 - var tooltip = (data[key].length > 6) ? data[key][4] : data[key][3];
1096 - var url = (data[key].length > 6) ? data[key][5] : '';
1097 -
1098 - if (description) {
1099 - name += _this.orgChartFormatName(description);
1100 - }
1101 - if (image && image != '') {
1102 - name = _this.orgChartFormatImage(image) + name;
1103 - }
1104 - name = {'v': data[key][0], 'f': name};
1105 - dataTypes.push([
1106 - name, parent_name, tooltip, url
1107 - ]);
1108 - }
1220 + ordering.forEach(function(key) {
1221 + if (!data.hasOwnProperty(key) || key == 0) return;
1222 +
1223 + var row = data[key];
1224 + var name = row[0];
1225 + var description = row[1];
1226 + var image = (row.length > 6) ? row[2] : '';
1227 + var parent_name = (row.length > 6) ? row[3] : row[2];
1228 + var tooltip = (row.length > 6) ? row[4] : row[3];
1229 + var url = (row.length > 6) ? row[5] : '';
1230 +
1231 + if (description) {
1232 + name += _this.orgChartFormatName(description);
1109 1233 }
1110 - }
1234 + if (image && image !== '') {
1235 + name = _this.orgChartFormatImage(image) + name;
1236 + }
1111 1237
1238 + name = {'v': row[0], 'f': name};
1239 + dataTypes.push([name, parent_name, tooltip, url]);
1240 + });
1241 +
1112 1242 return dataTypes;
1113 1243 }
1114 1244
1115 1245 ChartBuilderGoogleCharts.prototype.orgChartFormatName = function( description ){
@@ -1239,13 +1369,66 @@
1239 1369 e.innerHTML = input;
1240 1370 return e.childNodes[0].nodeValue;
1241 1371 }
1242 1372
1373 + // Fix ARIA attributes for WCAG compliance
1374 + ChartBuilderGoogleCharts.prototype.fixAriaAttributes = function() {
1375 + var _this = this;
1376 + var chartContainer = document.getElementById(_this.htmlClassPrefix + _this.chartType + _this.uniqueId);
1377 +
1378 + if (!chartContainer) {
1379 + return;
1380 + }
1381 +
1382 + // Find all divs with aria-label
1383 + var divsWithAriaLabel = chartContainer.querySelectorAll('div[aria-label]');
1384 + divsWithAriaLabel.forEach(function(div) {
1385 + // Check if this div contains a table (the data table representation)
1386 + if (div.querySelector('table')) {
1387 + // Add role="region" to the table container div
1388 + if (!div.hasAttribute('role')) {
1389 + div.setAttribute('role', 'region');
1390 + }
1391 + } else {
1392 + // Remove aria-label from divs without roles (not table containers)
1393 + if (!div.hasAttribute('role')) {
1394 + div.removeAttribute('aria-label');
1395 + }
1396 + }
1397 + });
1398 +
1399 + // Add role="img" to SVG elements with aria-label
1400 + var svgElements = chartContainer.querySelectorAll('svg[aria-label]');
1401 + svgElements.forEach(function(svg) {
1402 + if (!svg.hasAttribute('role')) {
1403 + svg.setAttribute('role', 'img');
1404 + }
1405 + });
1406 + }
1407 +
1243 1408 ChartBuilderGoogleCharts.prototype.drawChartFunction = function (source, options) {
1244 1409 var _this = this;
1245 1410
1246 1411 var view = new google.visualization.DataView(source);
1247 1412 _this.chartData = source;
1413 +
1414 + // Set role="img" on the chart container
1415 + var chartContainer = document.getElementById(_this.htmlClassPrefix + _this.chartType + _this.uniqueId);
1416 + if (chartContainer) {
1417 + chartContainer.setAttribute('role', 'img');
1418 + }
1419 +
1420 + // Fix ARIA attributes after chart is drawn
1421 + var drawCallback = function() {
1422 + _this.fixAriaAttributes();
1423 + };
1424 +
1425 + // Add callback to options if it doesn't exist
1426 + if (typeof options.chartArea === 'object') {
1427 + options.chartArea.chartReady = drawCallback;
1428 + } else {
1429 + options.chartReady = drawCallback;
1430 + }
1248 1431
1249 1432 if (_this.chartType == 'org_chart') {
1250 1433 view.setColumns([0, 1, 2]);
1251 1434 }