PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.11.7
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.11.7
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
← All changes | classes/Visualizer/Gutenberg/src/utils.js +197 -0 3.1.23.11.7 View file →
@@ -1,8 +1,13 @@
1 1 import isPlainObject from 'is-plain-object';
2 2
3 3 import deepFilter from 'deep-filter';
4 4
5 +// Import WordPress dependencies
6 +const {
7 + apiFetch
8 +} = wp;
9 +
5 10 // Format Date of Chart Data
6 11 export const formatDate = ( data ) => {
7 12 Object.keys( data['visualizer-series']).map( i => {
8 13 if ( data['visualizer-series'][i].type !== undefined && 'date' === data['visualizer-series'][i].type ) {
@@ -14,8 +19,14 @@
14 19 return data;
15 20 };
16 21
17 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.
18 29 const notEmpty = value => {
19 30 let key;
20 31
21 32 if ( Array.isArray( value ) ) {
@@ -91,4 +102,190 @@
91 102 }
92 103
93 104 return ( arrData );
94 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 +}