PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.11.15
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.11.15
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 / Render / Sidebar.php

Sidebar.php in Visualizer – Tables & Charts Manager with Built-in AI Generator 3.11.15, at classes/Visualizer/Render/Sidebar.php

843 lines 28.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 // +----------------------------------------------------------------------+
4 // | Copyright 2013 Madpixels (email : visualizer@madpixels.net) |
5 // +----------------------------------------------------------------------+
6 // | This program is free software; you can redistribute it and/or modify |
7 // | it under the terms of the GNU General Public License, version 2, as |
8 // | published by the Free Software Foundation. |
9 // | |
10 // | This program is distributed in the hope that it will be useful, |
11 // | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 // | GNU General Public License for more details. |
14 // | |
15 // | You should have received a copy of the GNU General Public License |
16 // | along with this program; if not, write to the Free Software |
17 // | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, |
18 // | MA 02110-1301 USA |
19 // +----------------------------------------------------------------------+
20 // | Author: Eugene Manuilov <eugene@manuilov.org> |
21 // +----------------------------------------------------------------------+
22 /**
23 * Base class for all chart sidebar groups.
24 *
25 * @category Visualizer
26 * @package Render
27 *
28 * @since 1.0.0
29 * @abstract
30 */
31 abstract class Visualizer_Render_Sidebar extends Visualizer_Render {
32
33 /**
34 * The array of font families accepted by visualization API.
35 *
36 * @since 1.0.0
37 *
38 * @static
39 * @access protected
40 * @var array
41 */
42 protected static $_fontFamilies = array(
43 'Arial' => 'Arial',
44 'Sans Serif' => 'Sans Serif',
45 'serif' => 'Serif',
46 'Arial black' => 'Wide',
47 'Arial Narrow' => 'Narrow',
48 'Comic Sans MS' => 'Comic Sans MS',
49 'Courier New' => 'Courier New',
50 'Garamond' => 'Garamond',
51 'Georgia' => 'Georgia',
52 'Tahoma' => 'Tahoma',
53 'Verdana' => 'Verdana',
54 );
55
56 /**
57 * The Yes/No array.
58 *
59 * @since 1.0.0
60 *
61 * @access protected
62 * @var array
63 */
64 protected $_yesno;
65
66 /**
67 * Whether this chart supports animation or not.
68 *
69 * @access protected
70 * @var bool
71 */
72 protected $_supportsAnimation = true;
73
74 /**
75 * Which library does this this chart implement?
76 *
77 * @access protected
78 * @var string
79 */
80 protected $_library = null;
81
82 /**
83 * Constructor.
84 *
85 * @since 1.0.0
86 *
87 * @access public
88 * @param array $data The data what has to be associated with this render.
89 */
90 public function __construct( $data = array() ) {
91 parent::__construct( $data );
92
93 $this->_yesno = array(
94 '' => '',
95 '1' => esc_html__( 'Yes', 'visualizer' ),
96 '0' => esc_html__( 'No', 'visualizer' ),
97 );
98
99 $this->hooks();
100 }
101
102 /**
103 * Renders chart title settings.
104 *
105 * @since 1.0.0
106 *
107 * @access protected
108 */
109 protected function _renderChartTitleSettings() {
110 self::_renderTextItem(
111 esc_html__( 'Chart Title', 'visualizer' ),
112 'title',
113 $this->title,
114 esc_html__( 'Text to display above the chart.', 'visualizer' )
115 );
116
117 self::_renderColorPickerItem(
118 esc_html__( 'Chart Title Color', 'visualizer' ),
119 'titleTextStyle[color]',
120 isset( $this->titleTextStyle['color'] ) ? $this->titleTextStyle['color'] : null,
121 '#000'
122 );
123
124 self::_renderTextAreaItem(
125 esc_html__( 'Chart Description', 'visualizer' ),
126 'description',
127 $this->description,
128 sprintf(
129 // translators: %1$s - HTML link tag, %2$s - HTML closing link tag.
130 esc_html__( 'Description to display in the structured data schema as explained %1$shere%2$s', 'visualizer' ),
131 '<a href="https://developers.google.com/search/docs/data-types/dataset#dataset" target="_blank">',
132 '</a>'
133 )
134 );
135 }
136
137 /**
138 * Add the correct description for the manual configuration box.
139 */
140 protected function _renderManualConfigDescription() {
141 self::_renderSectionStart();
142 self::_renderSectionDescription(
143 '<span class="viz-gvlink">' . sprintf(
144 // translators: %1$s - HTML link tag, %2$s - HTML closing link tag, %3$s - HTML link tag, %4$s - HTML closing link tag.
145 __( 'Configure the graph by providing configuration variables right from the %1$sGoogle Visualization API%2$s. You can refer to to some examples %3$shere%4$s.', 'visualizer' ), '<a href="https://developers.google.com/chart/interactive/docs/gallery/?#configuration-options" target="_blank">',
146 '</a>',
147 '<a href="https://docs.themeisle.com/article/728-manual-configuration" target="_blank">',
148 '</a>'
149 ) . '</span>'
150 );
151 }
152
153 /**
154 * Add the correct example for the manual configuration box.
155 */
156 protected function _renderManualConfigExample() {
157 return '{
158 "vAxis": {
159 "ticks": [5, 10, 15, 20],
160 "titleTextStyle": {
161 "color": "red"
162 },
163 "textPosition": "in"
164 }
165 }';
166 }
167
168 /**
169 * Renders chart advanced settings group.
170 *
171 * @access protected
172 */
173 protected function _renderAdvancedSettings() {
174 // Chart control settings.
175 $this->_renderChartControlsGroup();
176
177 if ( Visualizer_Module_Admin::proFeaturesLocked() ) {
178 self::_renderGroupStart( esc_html__( 'Frontend Actions', 'visualizer' ) );
179 } else {
180 self::_renderGroupStart( esc_html__( 'Frontend Actions', 'visualizer' ) . '<span class="dashicons dashicons-lock"></span>', '', apply_filters( 'visualizer_pro_upsell_class', 'only-pro-feature', 'chart-frontend-actions' ), 'vz-frontend-actions' );
181 echo '<div style="position: relative">';
182 }
183 self::_renderSectionStart();
184 self::_renderSectionDescription( esc_html__( 'Configure frontend actions that need to be shown.', 'visualizer' ) );
185 self::_renderSectionEnd();
186
187 $this->_renderActionSettings();
188 if ( ! Visualizer_Module_Admin::proFeaturesLocked() ) {
189 echo apply_filters( 'visualizer_pro_upsell', '', 'frontend-actions' );
190 echo '</div>';
191 }
192 self::_renderGroupEnd();
193
194 self::_renderGroupStart( esc_html__( 'Manual Configuration', 'visualizer' ) );
195 $this->_renderManualConfigDescription();
196 self::_renderTextAreaItem(
197 esc_html__( 'Configuration', 'visualizer' ),
198 'manual',
199 $this->manual,
200 sprintf(
201 // translators: %s - the format.
202 esc_html__( 'One per line in valid JSON (key:value) format e.g. %s', 'visualizer' ),
203 '<br><code>' . $this->_renderManualConfigExample() . '</code>'
204 ),
205 '',
206 array( 'rows' => 5 )
207 );
208
209 self::_renderSectionEnd();
210 self::_renderGroupEnd();
211
212 }
213
214 /**
215 * Renders chart action buttons group.
216 *
217 * @access protected
218 */
219 protected function _renderActionSettings() {
220 global $wp_version;
221 $disable_actions = version_compare( $wp_version, '4.7.0', '<' );
222 // default open this section when not testing through cypress because cypress expects to click and open each section
223 // and may not like finding a section is already open.
224 self::_renderSectionStart( esc_html__( 'Actions', 'visualizer' ), ! defined( 'TI_E2E_TESTING' ) );
225 self::_renderCheckboxItem(
226 esc_html__( 'Print', 'visualizer' ),
227 'actions[]',
228 isset( $this->actions ) && in_array( 'print', $this->actions, true ) ? true : false,
229 'print',
230 $disable_actions ? '<span class="viz-section-error">' . esc_html__( 'Upgrade to at least WordPress 4.7 to use this.', 'visualizer' ) . '</span>' : esc_html__( 'To enable printing the chart/data.', 'visualizer' ),
231 $disable_actions
232 );
233 self::_renderCheckboxItem(
234 esc_html__( 'CSV', 'visualizer' ),
235 'actions[]',
236 isset( $this->actions ) && in_array( 'csv;application/csv', $this->actions, true ) ? true : false,
237 'csv;application/csv',
238 $disable_actions ? '<span class="viz-section-error">' . esc_html__( 'Upgrade to at least WordPress 4.7 to use this.', 'visualizer' ) . '</span>' : esc_html__( 'To enable downloading the data as a CSV.', 'visualizer' ),
239 $disable_actions
240 );
241
242 $disabled = ! self::is_excel_enabled();
243 self::_renderCheckboxItem(
244 esc_html__( 'Excel', 'visualizer' ),
245 'actions[]',
246 isset( $this->actions ) && in_array( 'xls;application/vnd.ms-excel', $this->actions, true ) ? true : false,
247 'xls;application/vnd.ms-excel',
248 $disable_actions ? '<span class="viz-section-error">' . esc_html__( 'Upgrade to at least WordPress 4.7 to use this.', 'visualizer' ) . '</span>' : ( $disabled ? '<span class="viz-section-error">' . esc_html__( 'Enable the ZIP and XML extensions to use this setting.', 'visualizer' ) . '</span>' : esc_html__( 'To enable downloading the data as an Excel spreadsheet.', 'visualizer' ) ),
249 $disable_actions || $disabled
250 );
251 self::_renderCheckboxItem(
252 esc_html__( 'Copy', 'visualizer' ),
253 'actions[]',
254 isset( $this->actions ) && in_array( 'copy', $this->actions, true ) ? true : false,
255 'copy',
256 $disable_actions ? '<span class="viz-section-error">' . esc_html__( 'Upgrade to at least WordPress 4.7 to use this.', 'visualizer' ) . '</span>' : esc_html__( 'To enable copying the data to the clipboard.', 'visualizer' ),
257 $disable_actions
258 );
259
260 // not all charts support downloading as an image.
261 $disabled = ! $this->can_chart_have_action( 'image' );
262 self::_renderCheckboxItem(
263 esc_html__( 'Download Image', 'visualizer' ),
264 'actions[]',
265 isset( $this->actions ) && in_array( 'image', $this->actions, true ) ? true : false,
266 'image',
267 $disable_actions ? '<span class="viz-section-error">' . esc_html__( 'Upgrade to at least WordPress 4.7 to use this.', 'visualizer' ) . '</span>' : ( $disabled ? '<span class="viz-section-error">' . esc_html__( 'Not supported for this chart type.', 'visualizer' ) . '</span>' : esc_html__( 'To download the chart as an image.', 'visualizer' ) ),
268 $disable_actions || $disabled
269 );
270 self::_renderSectionEnd();
271 }
272
273 /**
274 * Checks if the Excel module can be enabled.
275 */
276 private static function is_excel_enabled() {
277 $vendor_file = VISUALIZER_ABSPATH . '/vendor/autoload.php';
278 if ( is_readable( $vendor_file ) ) {
279 include_once( $vendor_file );
280 }
281
282 if ( version_compare( phpversion(), '5.6.0', '<' ) ) {
283 do_action( 'themeisle_log_event', Visualizer_Plugin::NAME, sprintf( 'PHP version %s not supported', phpversion() ), 'error', __FILE__, __LINE__ );
284 return false;
285 }
286
287 return class_exists( 'OpenSpout\Writer\Common\Creator\WriterEntityFactory' ) && extension_loaded( 'zip' ) && extension_loaded( 'xml' ) && extension_loaded( 'fileinfo' );
288 }
289
290 /**
291 * Renders select item.
292 *
293 * @since 1.0.0
294 *
295 * @static
296 * @access public
297 * @param string $title The title of the select item.
298 * @param string $name The name of the select item.
299 * @param string $value The actual value of the select item.
300 * @param array $options The array of select options.
301 * @param string $desc The description of the select item.
302 * @param bool $multiple Is this a multiple select box.
303 * @param array $classes Any additional classes.
304 * @param array $attributes Custom attributes.
305 */
306 public static function _renderSelectItem( $title, $name, $value, array $options, $desc, $multiple = false, $classes = array(), $attributes = array() ) {
307 $atts = '';
308 if ( $attributes ) {
309 foreach ( $attributes as $k => $v ) {
310 $atts .= ' data-visualizer-' . $k . '=' . esc_attr( $v );
311 }
312 }
313 echo '<div class="viz-section-item">';
314 echo '<a class="more-info" href="javascript:;">[?]</a>';
315 echo '<b>', $title, '</b>';
316 echo '<select class="control-select ', implode( ' ', $classes ) , '" name="', $name, '" ', ( $multiple ? 'multiple' : '' ), ' ' , $atts, '>';
317 foreach ( $options as $key => $label ) {
318 // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
319 $extra = $multiple && is_array( $value ) ? ( in_array( $key, $value ) ? 'selected' : '' ) : selected( $key, $value, false );
320 echo '<option value="', $key, '"', $extra, '>';
321 echo $label;
322 echo '</option>';
323 }
324 echo '</select>';
325 echo '<p class="viz-section-description">', $desc, '</p>';
326 echo '</div>';
327 }
328
329 /**
330 * Renders color picker item.
331 *
332 * @since 1.0.0
333 *
334 * @static
335 * @access protected
336 * @param string $title The title of the select item.
337 * @param string $name The name of the select item.
338 * @param string $value The actual value of the select item.
339 * @param string $default The default value of the color picker.
340 */
341 protected static function _renderColorPickerItem( $title, $name, $value, $default ) {
342 echo '<div class="viz-section-item">';
343 echo '<b>', $title, '</b>';
344 echo '<div>';
345 echo '<input type="text" class="color-picker-hex color-picker" data-alpha-enabled="true" name="', $name, '" maxlength="7" placeholder="', esc_attr__( 'Hex Value', 'visualizer' ), '" value="', is_null( $value ) ? $default : esc_attr( $value ), '" data-default-color="', $default, '">';
346 echo '</div>';
347 echo '</div>';
348 }
349
350 /**
351 * Renders text item.
352 *
353 * @since 1.0.0
354 *
355 * @static
356 * @access protected
357 * @param string $title The title of the select item.
358 * @param string $name The name of the select item.
359 * @param string $value The actual value of the select item.
360 * @param string $desc The description of the select item.
361 * @param string $placeholder The placeholder for the input.
362 * @param string $type The type for the input (out of number, email, tel etc., default is text).
363 * @param array $custom_attributes The custom attributes.
364 */
365 protected static function _renderTextItem( $title, $name, $value, $desc, $placeholder = '', $type = 'text', $custom_attributes = array(), $extra_class = array() ) {
366 $attributes = '';
367 if ( $custom_attributes ) {
368 foreach ( $custom_attributes as $k => $v ) {
369 $attributes .= ' ' . $k . '="' . esc_attr( $v ) . '"';
370 }
371 }
372 $extra_class[] = 'viz-section-item';
373 echo '<div class="' . esc_attr( implode( ' ', $extra_class ) ) . '">';
374 echo '<a class="more-info" href="javascript:;">[?]</a>';
375 echo '<b>', $title, '</b>';
376 echo '<input type="', $type, '" class="control-text" ', $attributes, ' name="', $name, '" value="', esc_attr( $value ), '" placeholder="', $placeholder, '">';
377 echo '<p class="viz-section-description">', $desc, '</p>';
378 echo '</div>';
379 }
380
381 /**
382 * Renders the beginning of a group.
383 *
384 * @since 1.0.0
385 *
386 * @static
387 * @access public
388 * @param string $title The title of this group.
389 * @param string $html Any additional HTML.
390 * @param string $class Any additional classes.
391 */
392 public static function _renderGroupStart( $title, $html = '', $class = '', $id = '' ) {
393 echo '<li id="' . $id . '" class="viz-group ' . $class . '">';
394 echo '<h3 class="viz-group-title">', $title, '</h3>';
395 echo $html;
396 echo '<ul class="viz-group-content">';
397 }
398
399 /**
400 * Renders the ending of a group.
401 *
402 * @since 1.0.0
403 *
404 * @static
405 * @access public
406 */
407 public static function _renderGroupEnd() {
408 echo '</ul>';
409 echo '</li>';
410 }
411
412 /**
413 * Renders the beginning of a section.
414 *
415 * @since 1.0.0
416 *
417 * @static
418 * @access public
419 * @param string $title The title of this section. If the title is empty, no title will be displayed.
420 * @param boolean $open Determines whether the section items block has to be expanded or collapsed.
421 */
422 public static function _renderSectionStart( $title = false, $open = true ) {
423
424 if ( ! empty( $title ) ) {
425 echo '<li class="viz-subsection">';
426 echo '<span class="viz-section-title">', $title, '</span>';
427 } else {
428 echo '<li class=" ">';
429 }
430 echo '<div class="viz-section-items section-items', $open ? ' open' : '', '">';
431 }
432
433 /**
434 * Renders the ending of a section.
435 *
436 * @since 1.0.0
437 *
438 * @public
439 * @access protected
440 * @param string $html Any addition HTML to add.
441 */
442 public static function _renderSectionEnd( $html = '' ) {
443 echo '</div>';
444 echo $html;
445 echo '</li>';
446 }
447
448 /**
449 * Renders section description block.
450 *
451 * @since 1.0.0
452 *
453 * @static
454 * @access public
455 * @param string $description The description text.
456 */
457 public static function _renderSectionDescription( $description, $classes = '' ) {
458 echo '<div class="viz-section-item">';
459 echo '<div class="viz-section-description ' . $classes . '">', $description, '</div>';
460 echo '</div>';
461 }
462
463 /**
464 * Renders format field according to series type.
465 *
466 * @since 1.3.0
467 *
468 * @access protected
469 * @param int $index The index of the series.
470 */
471 protected function _renderFormatField( $index = 0 ) {
472 switch ( $this->__series[ $index + 1 ]['type'] ) {
473 case 'number':
474 self::_renderTextItem(
475 esc_html__( 'Number Format', 'visualizer' ),
476 'series[' . $index . '][format]',
477 isset( $this->series[ $index ]['format'] ) ? $this->series[ $index ]['format'] : '',
478 sprintf(
479 // translators: %1$s - HTML link tag, %2$s - HTML closing link tag.
480 esc_html__( 'Enter custom format pattern to apply to this series value, similar to the %1$sICU pattern set%2$s. Use something like #,### to get 1,234 as output, or $# to add dollar sign before digits. Pay attention that if you use &#37; percentage format then your values will be multiplied by 100.', 'visualizer' ),
481 '<a href="http://icu-project.org/apiref/icu4c/classDecimalFormat.html#_details" target="_blank">',
482 '</a>'
483 ),
484 '#,###.##'
485 );
486 break;
487 case 'date':
488 case 'datetime':
489 case 'timeofday':
490 self::_renderTextItem(
491 esc_html__( 'Date Format', 'visualizer' ),
492 'series[' . $index . '][format]',
493 isset( $this->series[ $index ]['format'] ) ? $this->series[ $index ]['format'] : '',
494 sprintf(
495 // translators: %1$s - HTML link tag, %2$s - HTML closing link tag.
496 esc_html__( 'Enter custom format pattern to apply to this series value, similar to the %1$sICU date and time format%2$s.', 'visualizer' ),
497 '<a href="https://unicode-org.github.io/icu/userguide/format_parse/datetime/#datetime-format-syntax" target="_blank">',
498 '</a>'
499 ),
500 'eeee, dd LLLL yyyy'
501 );
502 break;
503 }
504 }
505
506 /**
507 * Render a checkbox item
508 */
509 protected static function _renderCheckboxItem( $title, $name, $value, $default, $desc, $disabled = false ) {
510 echo '<div class="viz-section-item">';
511 echo '<a class="more-info" href="javascript:;">[?]</a>';
512 echo '<b>', $title, '</b>';
513 // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
514 echo '<input type="checkbox" class="control-check" value="', $default, '" name="', $name, '" ', ( $value == $default ? 'checked' : '' ), ' ', ( $disabled ? 'disabled=disabled' : '' ), '>';
515 echo '<p class="viz-section-description">', $desc, '</p>';
516 echo '</div>';
517 }
518
519 /**
520 * Render a textarea item.
521 */
522 protected static function _renderTextAreaItem( $title, $name, $value, $desc, $placeholder = '', $custom_attributes = array() ) {
523 $attributes = '';
524 if ( $custom_attributes ) {
525 foreach ( $custom_attributes as $k => $v ) {
526 $attributes .= ' ' . $k . '="' . esc_attr( $v ) . '"';
527 }
528 }
529 echo '<div class="viz-section-item">';
530 echo '<a class="more-info" href="javascript:;">[?]</a>';
531 echo '<b>', $title, '</b>';
532 echo '<textarea class="control-text" ', $attributes, ' name="', $name, '" placeholder="', $placeholder, '">', $value, '</textarea>';
533 echo '<p class="viz-section-description">', $desc, '</p>';
534 echo '</div>';
535 }
536
537 /**
538 * Returns the library this chart implements.
539 */
540 public function getLibrary() {
541 return $this->_library;
542 }
543
544 /**
545 * Loads generic libraries conditionally.
546 */
547 protected function load_dependent_assets( $libs ) {
548 if ( in_array( 'moment', $libs, true ) && ! wp_script_is( 'moment', 'registered' ) ) {
549 wp_register_script( 'moment' );
550 }
551
552 if ( in_array( 'numeral', $libs, true ) && ! wp_script_is( 'numeral', 'registered' ) ) {
553 wp_register_script( 'numeral', VISUALIZER_ABSURL . 'js/lib/numeral.min.js', array(), Visualizer_Plugin::VERSION );
554 }
555
556 }
557
558 /**
559 * Renders save chart as image setting group.
560 *
561 * @access protected
562 */
563 protected function _renderChartImageSettings() {
564 // Default enable if amp is active.
565 $is_amp = function_exists( 'amp_is_enabled' ) && amp_is_enabled();
566 $this->save_chart_image = null === $this->save_chart_image && $is_amp ? true : $this->save_chart_image;
567
568 $is_create_chart = true;
569 if ( filter_input( INPUT_GET, 'library', FILTER_VALIDATE_BOOLEAN ) ) {
570 if ( filter_input( INPUT_GET, 'action' ) === Visualizer_Plugin::ACTION_EDIT_CHART ) {
571 $is_create_chart = false;
572 }
573 }
574 $this->lazy_load_chart = null === $this->lazy_load_chart && $is_create_chart ? true : $this->lazy_load_chart;
575
576 self::_renderSectionStart( esc_html__( 'Save chart as an image inside Media Library', 'visualizer' ), false );
577 self::_renderCheckboxItem(
578 esc_html__( 'Save inside media library?', 'visualizer' ),
579 'save_chart_image',
580 $this->save_chart_image ? true : false,
581 'yes',
582 esc_html__( 'To enable save the image as an inside media library.', 'visualizer' ),
583 false
584 );
585 self::_renderSectionEnd();
586
587 self::_renderSectionStart( esc_html__( 'Lazy rendering of chart', 'visualizer' ), false );
588 self::_renderCheckboxItem(
589 esc_html__( 'Enable lazy rendering of chart?', 'visualizer' ),
590 'lazy_load_chart',
591 $this->lazy_load_chart ? true : false,
592 'yes',
593 esc_html__( 'To enable lazy chart rendering.', 'visualizer' ),
594 false
595 );
596 self::_renderSectionEnd();
597 }
598
599 /**
600 * Renders chart controls group.
601 *
602 * @access protected
603 */
604 protected function _renderChartControlsGroup() {
605 if ( 'google' !== $this->getLibrary() ) {
606 return;
607 }
608 if ( Visualizer_Module_Admin::proFeaturesLocked() ) {
609 self::_renderGroupStart( esc_html__( 'Chart Data Filter Configuration', 'visualizer' ) );
610 } else {
611 self::_renderGroupStart( esc_html__( 'Chart Data Filter Configuration', 'visualizer' ) . '<span class="dashicons dashicons-lock"></span>', '', apply_filters( 'visualizer_pro_upsell_class', 'only-pro-feature', 'chart-filter-controls' ), 'vz-data-controls' );
612 echo '<div style="position: relative">';
613 }
614 self::_renderSectionStart();
615 self::_renderSectionDescription(
616 '<span class="viz-gvlink">' . sprintf(
617 // translators: %1$s - HTML link tag, %2$s - HTML closing link tag.
618 __( 'Configure the data filter controls by providing configuration variables right from the %1$sChart Controls API%2$s. ', 'visualizer' ),
619 '<a href="https://developers.google.com/chart/interactive/docs/gallery/controls#controls-gallery" target="_blank">',
620 '</a>'
621 ) . '</span>'
622 );
623 self::_renderSectionEnd();
624 $this->_renderChartControlsSettings();
625 if ( ! Visualizer_Module_Admin::proFeaturesLocked() ) {
626 echo apply_filters( 'visualizer_pro_upsell', '', 'data-filter-configuration' );
627 echo '</div>';
628 }
629 self::_renderGroupEnd();
630 }
631
632 /**
633 * Renders chart controls setting.
634 *
635 * @access protected
636 */
637 protected function _renderChartControlsSettings() {
638
639 self::_renderSectionStart( esc_html__( 'Options', 'visualizer' ), false );
640 $control_type = ! empty( $this->controls['controlType'] ) ? $this->controls['controlType'] : '';
641
642 self::_renderSelectItem(
643 esc_html__( 'Filter Type', 'visualizer' ),
644 'controls[controlType]',
645 $control_type,
646 array(
647 '' => '',
648 'StringFilter' => esc_html__( 'String Filter', 'visualizer' ),
649 'NumberRangeFilter' => esc_html__( 'Number Range Filter', 'visualizer' ),
650 'CategoryFilter' => esc_html__( 'Category Filter', 'visualizer' ),
651 'ChartRangeFilter' => esc_html__( 'Chart Range Filter', 'visualizer' ),
652 'DateRangeFilter' => esc_html__( 'Date Range Filter', 'visualizer' ),
653 ),
654 '',
655 false,
656 array( 'vz-controls-opt' )
657 );
658
659 $column_index = [ 'false' => '' ];
660 $column_label = [ 'false' => '' ];
661 if ( ! empty( $this->__series ) ) {
662 foreach ( $this->__series as $key => $column ) {
663 $column_type = isset( $column['type'] ) ? $column['type'] : '';
664 $label = isset( $column['label'] ) ? $column['label'] : '';
665 $column_label[ $label ] = $label;
666 $column_index[ $key ] = sprintf(
667 // translators: %1$d - the column key, %2$s - the column type.
668 __( '%1$d — Column Type: %2$s ', 'visualizer' ),
669 $key,
670 ucfirst( $column_type )
671 );
672 }
673 }
674
675 self::_renderSelectItem(
676 esc_html__( 'Filter By Column Index', 'visualizer' ),
677 'controls[filterColumnIndex]',
678 isset( $this->controls['filterColumnIndex'] ) ? $this->controls['filterColumnIndex'] : '',
679 $column_index,
680 '',
681 false,
682 array( 'vz-controls-opt' )
683 );
684
685 self::_renderSelectItem(
686 esc_html__( 'Filter By Column Label', 'visualizer' ),
687 'controls[filterColumnLabel]',
688 ! empty( $this->controls['filterColumnLabel'] ) ? $this->controls['filterColumnLabel'] : '',
689 $column_label,
690 '',
691 false,
692 array( 'vz-controls-opt' )
693 );
694
695 self::_renderSelectItem(
696 esc_html__( 'Use Formatted Value', 'visualizer' ),
697 'controls[useFormattedValue]',
698 ! empty( $this->controls['useFormattedValue'] ) ? $this->controls['useFormattedValue'] : '',
699 array(
700 'false' => esc_html__( 'False', 'visualizer' ),
701 'true' => esc_html__( 'True', 'visualizer' ),
702 ),
703 '',
704 false
705 );
706
707 self::_renderTextItem(
708 esc_html__( 'Min Value', 'visualizer' ),
709 'controls[minValue]',
710 ! empty( $this->controls['minValue'] ) ? $this->controls['minValue'] : '',
711 esc_html__( 'Minimum allowed value for the range lower extent.', 'visualizer' ),
712 '',
713 'text'
714 );
715
716 self::_renderTextItem(
717 esc_html__( 'Max Value', 'visualizer' ),
718 'controls[maxValue]',
719 ! empty( $this->controls['maxValue'] ) ? $this->controls['maxValue'] : '',
720 esc_html__( 'Maximum allowed value for the range higher extent.', 'visualizer' ),
721 '',
722 'text'
723 );
724
725 self::_renderSelectItem(
726 esc_html__( 'Match Type', 'visualizer' ),
727 'controls[matchType]',
728 ! empty( $this->controls['matchType'] ) ? $this->controls['matchType'] : '',
729 array(
730 'prefix' => esc_html__( 'Prefix', 'visualizer' ),
731 'exact' => esc_html__( 'Exact', 'visualizer' ),
732 'any' => esc_html__( 'Any', 'visualizer' ),
733 ),
734 '',
735 false
736 );
737
738 self::_renderSelectItem(
739 esc_html__( 'Case Sensitive', 'visualizer' ),
740 'controls[caseSensitive]',
741 ! empty( $this->controls['caseSensitive'] ) ? $this->controls['caseSensitive'] : '',
742 array(
743 'false' => esc_html__( 'False', 'visualizer' ),
744 'true' => esc_html__( 'True', 'visualizer' ),
745 ),
746 '',
747 false
748 );
749
750 self::_renderSectionEnd();
751
752 self::_renderSectionStart( esc_html__( 'UI Options', 'visualizer' ), false );
753
754 self::_renderTextItem(
755 esc_html__( 'Label', 'visualizer' ),
756 'controls[ui][label]',
757 ! empty( $this->controls['ui']['label'] ) ? $this->controls['ui']['label'] : '',
758 '',
759 '',
760 'text'
761 );
762
763 self::_renderTextItem(
764 esc_html__( 'Label Separator', 'visualizer' ),
765 'controls[ui][labelSeparator]',
766 ! empty( $this->controls['ui']['labelSeparator'] ) ? $this->controls['ui']['labelSeparator'] : '',
767 '',
768 '',
769 'text'
770 );
771
772 self::_renderTextItem(
773 esc_html__( 'Caption', 'visualizer' ),
774 'controls[ui][caption]',
775 ! empty( $this->controls['ui']['caption'] ) ? $this->controls['ui']['caption'] : '',
776 '',
777 '',
778 'text'
779 );
780
781 self::_renderSelectItem(
782 esc_html__( 'Label Stacking', 'visualizer' ),
783 'controls[ui][labelStacking]',
784 ! empty( $this->controls['ui']['labelStacking'] ) ? $this->controls['ui']['labelStacking'] : '',
785 array(
786 'horizontal' => esc_html__( 'Horizontal', 'visualizer' ),
787 'vertical' => esc_html__( 'Vertical', 'visualizer' ),
788 ),
789 '',
790 false
791 );
792
793 self::_renderSelectItem(
794 esc_html__( 'Orientation', 'visualizer' ),
795 'controls[ui][orientation]',
796 ! empty( $this->controls['ui']['orientation'] ) ? $this->controls['ui']['orientation'] : '',
797 array(
798 'horizontal' => esc_html__( 'Horizontal', 'visualizer' ),
799 'vertical' => esc_html__( 'Vertical', 'visualizer' ),
800 ),
801 '',
802 false
803 );
804
805 self::_renderSelectItem(
806 esc_html__( 'Show Range Values', 'visualizer' ),
807 'controls[showRangeValues]',
808 ! empty( $this->controls['showRangeValues'] ) ? $this->controls['showRangeValues'] : '',
809 array(
810 'true' => esc_html__( 'True', 'visualizer' ),
811 'false' => esc_html__( 'False', 'visualizer' ),
812 ),
813 '',
814 false
815 );
816
817 self::_renderSelectItem(
818 esc_html__( 'Allow Multiple', 'visualizer' ),
819 'controls[allowMultiple]',
820 ! empty( $this->controls['allowMultiple'] ) ? $this->controls['allowMultiple'] : '',
821 array(
822 'true' => esc_html__( 'True', 'visualizer' ),
823 'false' => esc_html__( 'False', 'visualizer' ),
824 ),
825 '',
826 false
827 );
828
829 self::_renderSelectItem(
830 esc_html__( 'Allow Typing', 'visualizer' ),
831 'controls[allowTyping]',
832 ! empty( $this->controls['allowTyping'] ) ? $this->controls['allowTyping'] : '',
833 array(
834 'true' => esc_html__( 'True', 'visualizer' ),
835 'false' => esc_html__( 'False', 'visualizer' ),
836 ),
837 '',
838 false
839 );
840 self::_renderSectionEnd();
841 }
842 }
843