PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.11.9
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.11.9
4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 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.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 3.10.3 3.10.4 All 148 releases
visualizer / classes / Visualizer / Gutenberg / src / utils.js

utils.js in Visualizer – Tables & Charts Manager with Built-in AI Generator 3.11.9, at classes/Visualizer/Gutenberg/src/utils.js

292 lines 8.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import isPlainObject from 'is-plain-object';
2
3 import deepFilter from 'deep-filter';
4
5 // Import WordPress dependencies
6 const {
7 apiFetch
8 } = wp;
9
10 // Format Date of Chart Data
11 export const formatDate = ( data ) => {
12 Object.keys( data['visualizer-series']).map( i => {
13 if ( data['visualizer-series'][i].type !== undefined && 'date' === data['visualizer-series'][i].type ) {
14 Object.keys( data['visualizer-data']).map( o => {
15 return data['visualizer-data'][o][i] = new Date( data['visualizer-data'][o][i]);
16 });
17 }
18 });
19 return data;
20 };
21
22 // A fork of deep-compact package as it had some issues
23 // NOTE: This method is likely to create problems.
24 // Problem Scenario #1:
25 // - A table has 5 columns (series). Say the 1st column is Date and others are Numbers.
26 // - If the 1st columns format (series.format) is provided, DataTable.js gets 6 (0-5) series.
27 // - BUT if the 1st columns format (series.format) is empty, DataTable.js gets 5 (1-4) series.
28 // That is why when sending options to DataTable.js, filterChart method has not been used.
29 const notEmpty = value => {
30 let key;
31
32 if ( Array.isArray( value ) ) {
33 return 0 < value.length;
34 }
35
36 if ( isPlainObject( value ) ) {
37 for ( key in value ) {
38 return true;
39 }
40
41 return false;
42 }
43
44 if ( 'string' === typeof value ) {
45 return 0 < value.length;
46 }
47
48 return null != value;
49 };
50
51 export const compact = value => deepFilter( value, notEmpty );
52
53 // Remove chart size-related properies for Chart List
54 export const filterCharts = value => {
55 value.width = '';
56 value.height = '';
57 value.backgroundColor = {};
58 value.chartArea = {};
59
60 return compact( value, notEmpty );
61 };
62
63 // Check if JSON object is valid or not
64 export const isValidJSON = obj => {
65 try {
66 JSON.parse( obj );
67 } catch ( e ) {
68 return false;
69 }
70 return true;
71 };
72
73 // Convert CSV data to Array
74 // Source: https://www.bennadel.com/blog/1504-ask-ben-parsing-csv-strings-with-javascript-exec-regular-expression-command.htm
75 export const CSVToArray = ( strData, strDelimiter ) => {
76 strDelimiter = ( strDelimiter || ',' );
77
78 const objPattern = new RegExp(
79 ( '(\\' + strDelimiter + '|\\r?\\n|\\r|^)' + '(?:\'([^\']*(?:\'\'[^\']*)*)\'|' + '([^\'\\' + strDelimiter + '\\r\\n]*))' ), 'gi' );
80
81 const arrData = [ [] ];
82
83 let arrMatches = null;
84
85 while ( arrMatches = objPattern.exec( strData ) ) {
86
87 const strMatchedDelimiter = arrMatches[ 1 ];
88
89 if ( strMatchedDelimiter.length && strMatchedDelimiter !== strDelimiter ) {
90 arrData.push([]);
91 }
92
93 let strMatchedValue;
94
95 if ( arrMatches[ 2 ]) {
96 strMatchedValue = arrMatches[ 2 ].replace( new RegExp( '\'\'', 'g' ), '\'' );
97 } else {
98 strMatchedValue = arrMatches[ 3 ];
99 }
100
101 arrData[ arrData.length - 1 ].push( strMatchedValue );
102 }
103
104 return ( arrData );
105 };
106
107
108 export const isChecked = ( settings, param ) => {
109 return true === settings[param] || 'true' === settings[param] || '1' === settings[param] || 1 === settings[param];
110 };
111
112
113 export const formatData = ( chart ) => {
114 let library = chart['visualizer-chart-library'];
115
116 switch ( library ) {
117 case 'GoogleCharts':
118 return formatDataForGoogleCharts( chart );
119 }
120 };
121
122 export const formatDataForGoogleCharts = ( chart ) => {
123 let settings = chart['visualizer-settings'];
124 let type = chart['visualizer-chart-type'];
125 let series = chart['visualizer-series'];
126
127 let formatters = [];
128
129 if ( settings.series ) {
130 switch ( type ) {
131 case 'tabular':
132 for ( let i in settings.series ) {
133 i = parseInt( i );
134 if ( ! series[i + 1]) {
135 continue;
136 }
137 if ( settings.series[i].format && '' !== settings.series[i].format ) {
138 let col = i + 1;
139 let formatter = getFormatterForGoogle( series[i + 1].type );
140 if ( formatter ) {
141 formatters.push({ type: formatter, options: { pattern: settings.series[i].format }, column: col });
142 }
143 }
144 }
145 break;
146 default:
147 for ( let i = 0; i < settings.series.length; i++ ) {
148 if ( ! series[i + 1] || 'undefined' === typeof settings.series[i]) {
149 continue;
150 }
151 if ( settings.series[i].format && '' !== settings.series[i].format ) {
152 let col = i + 1;
153 let formatter = getFormatterForGoogle( series[i + 1].type );
154 if ( formatter ) {
155 formatters.push({ type: formatter, options: { pattern: settings.series[i].format }, column: col });
156 }
157 }
158 }
159 break;
160 }
161 } else if ( 'pie' === type && settings.format && '' !== settings.format ) {
162 formatters.push({ type: getFormatterForGoogle( 'number' ), options: { pattern: settings.format }, column: 1 });
163 }
164
165 if ( settings.hAxis && series[0]) {
166 let formatter = getFormatterForGoogle( series[0].type );
167 if ( formatter ) {
168 formatters.push({ type: formatter, options: { pattern: settings.hAxis.format }, column: 0 });
169 }
170 }
171
172 return formatters;
173 };
174
175 export const getFormatterForGoogle = ( dataType ) => {
176 switch ( dataType ) {
177 case 'number':
178 return 'NumberFormat';
179 case 'date':
180 case 'datetime':
181 case 'timeofday':
182 return 'DateFormat';
183 }
184 return null;
185 };
186
187 export const getColorCode = ( color ) => {
188 if ( -1 === color.indexOf( '#' ) ) {
189 let getCssVar = color.match( /\((.*)\)/ ).pop();
190 if ( getCssVar ) {
191 let style = getComputedStyle( document.body );
192 return style.getPropertyValue( getCssVar );
193 }
194 }
195 return color;
196 };
197
198 // Google Chart Packages
199 export const googleChartPackages = [ 'corechart', 'geochart', 'gauge', 'table', 'timeline', 'controls' ];
200
201 /**
202 * This function extends the wp.media.view.MediaFrame class to create a custom frame for Visualizer Charts creation/editing.
203 *
204 * @returns {wp.media.view.MediaFrame} The extended MediaFrame object.
205 *
206 * @example
207 *
208 * const popupBuilder = buildChartPopup;
209 * const popup = new popupBuilder();
210 * popup.open();
211 */
212 export const buildChartPopup = () => {
213 return wp.media.view.MediaFrame.extend(
214 {
215 initialize: function() {
216 const self = this;
217
218 _.defaults(
219 self.options, {
220 action: '',
221 id: 'visualizer',
222 state: 'iframe:visualizer',
223 title: 'Visualizer'
224 }
225 );
226
227 wp.media.view.MediaFrame.prototype.initialize.apply( self, arguments );
228
229 wp.media.view.settings.tab = 'Visualizer';
230 wp.media.view.settings.tabUrl = self.options.action;
231 self.createIframeStates();
232 },
233
234 createIframeStates: function( passedOptions ) {
235 const self = this;
236 wp.media.view.MediaFrame.prototype.createIframeStates.apply( self, arguments );
237
238 self.state( self.options.state ).set(
239 _.defaults(
240 {
241 tab: self.options.id,
242 src: self.options.action + '&tab=' + self.options.id,
243 title: self.options.title,
244 content: 'iframe',
245 menu: 'default'
246 }, passedOptions
247 )
248 );
249
250 },
251
252 open: function() {
253 try {
254 wp.media.view.MediaFrame.prototype.open.apply( this, arguments );
255 } catch ( error ) {
256 console.error( error );
257 }
258 }
259 }
260 );
261 };
262
263 /**
264 * Try to get the chart data from the server.
265 *
266 * If the status is not 'publish', it will retry.
267 *
268 * @param {number|string} chartId The chart ID.
269 * @returns {Promise<{result: Object, status: string}>} The chart data and status.
270 */
271 export async function tryGetPublishedChartData( chartId ) {
272 let result = await apiFetch({ path: `wp/v2/visualizer/${chartId}` });
273 const numRetries = 8;
274
275 let attempt = 0;
276 while (
277 result &&
278 undefined !== result.status &&
279 'publish' !== result.status &&
280 numRetries > attempt
281 ) {
282 await new Promise( resolve => setTimeout( resolve, 750 ) );
283 result = await apiFetch({ path: `wp/v2/visualizer/${chartId}` });
284 attempt++;
285 }
286
287 return {
288 result: result,
289 chartStatus: result.status ? result.status : 'auto-draft'
290 };
291 }
292