Skip to content

Commit 5e7da28

Browse files
Download charts as images
1 parent 75ab385 commit 5e7da28

File tree

9 files changed

+413
-234
lines changed

9 files changed

+413
-234
lines changed

classes/Visualizer/Gutenberg/build/block.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

classes/Visualizer/Gutenberg/src/Components/Sidebar/FrontendActions.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class FrontendActions extends Component {
3131
render() {
3232

3333
const settings = this.props.chart['visualizer-settings'];
34+
const type = this.props.chart['visualizer-chart-type'];
3435

3536
return (
3637
<PanelBody
@@ -111,6 +112,25 @@ class FrontendActions extends Component {
111112
} }
112113
/>
113114

115+
{ ( -1 >= [ 'dataTable', 'tabular', 'gauge', 'table' ].indexOf( type ) ) && (
116+
<CheckboxControl
117+
label={ __( 'Download Image' ) }
118+
help={ __( 'To download the chart as an image.' ) }
119+
checked={ ( 0 <= settings.actions.indexOf( 'image' ) ) }
120+
onChange={ e => {
121+
if ( 0 <= settings.actions.indexOf( 'image' ) ) {
122+
const index = settings.actions.indexOf( 'image' );
123+
if ( -1 !== index ) {
124+
settings.actions.splice( index, 1 );
125+
}
126+
} else {
127+
settings.actions.push( 'image' );
128+
}
129+
this.props.edit( settings );
130+
} }
131+
/>
132+
) }
133+
114134
</Fragment>
115135

116136
) }

classes/Visualizer/Module/Frontend.php

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -120,15 +120,40 @@ function endpoint_register() {
120120
* @access private
121121
*/
122122
private function get_actions() {
123-
return apply_filters(
123+
$actions = apply_filters(
124124
'visualizer_action_buttons',
125125
array(
126-
'print' => __( 'Print', 'visualizer' ),
127-
'csv' => __( 'CSV', 'visualizer' ),
128-
'xls' => __( 'Excel', 'visualizer' ),
129-
'copy' => __( 'Copy', 'visualizer' ),
126+
'print' => array(
127+
'label' => esc_html__( 'Print', 'visualizer' ),
128+
'title' => esc_html__( 'Print Chart', 'visualizer' ),
129+
),
130+
'csv' => array(
131+
'label' => esc_html__( 'CSV', 'visualizer' ),
132+
'title' => esc_html__( 'Download as a CSV', 'visualizer' ),
133+
),
134+
'xls' => array(
135+
'label' => esc_html__( 'Excel', 'visualizer' ),
136+
'title' => esc_html__( 'Download as a spreadsheet', 'visualizer' ),
137+
),
138+
'copy' => array(
139+
'label' => esc_html__( 'Copy', 'visualizer' ),
140+
'title' => esc_html__( 'Copy data', 'visualizer' ),
141+
),
142+
'image' => array(
143+
'label' => esc_html__( 'Download', 'visualizer' ),
144+
'title' => esc_html__( 'Download as an image', 'visualizer' ),
145+
),
130146
)
131147
);
148+
149+
// backward compatibility before label and title attributes were introduced.
150+
if ( isset( $actions['edit'] ) && is_string( $actions['edit'] ) ) {
151+
$actions['edit'] = array(
152+
'label' => esc_html__( 'Edit', 'visualizer' ),
153+
'title' => esc_html__( 'Edit data', 'visualizer' ),
154+
);
155+
}
156+
return $actions;
132157
}
133158

134159
/**
@@ -161,6 +186,21 @@ public function perform_action( WP_REST_Request $params ) {
161186
case 'xls':
162187
$data = $this->_getDataAs( $chart_id, 'xls' );
163188
break;
189+
case 'image':
190+
$settings = get_post_meta( $chart_id, Visualizer_Plugin::CF_SETTINGS, true );
191+
$title = 'visualizer#' . $chart_id;
192+
if ( ! empty( $settings['title'] ) ) {
193+
$title = $settings['title'];
194+
}
195+
// for ChartJS, title is an array.
196+
if ( is_array( $title ) && isset( $title['text'] ) ) {
197+
$title = $title['text'];
198+
}
199+
if ( empty( $title ) ) {
200+
$title = 'visualizer#' . $chart_id;
201+
}
202+
$data = array( 'name' => $title );
203+
break;
164204
default:
165205
$data = apply_filters( 'visualizer_action_data', $data, $chart_id, $type, $params, $this );
166206
break;
@@ -296,8 +336,9 @@ public function renderChart( $atts ) {
296336
$key = $array[0];
297337
$mime = end( $array );
298338
}
299-
$label = $actions[ $key ];
300-
$actions_div .= '<a href="#" class="visualizer-action visualizer-action-' . $key . '" data-visualizer-type="' . $key . '" data-visualizer-chart-id="' . $atts['id'] . '" data-visualizer-container-id="' . $id . '" data-visualizer-mime="' . $mime . '" title="' . $label . '" ';
339+
$label = $actions[ $key ]['label'];
340+
$title = $actions[ $key ]['title'];
341+
$actions_div .= sprintf( '<a href="#" class="visualizer-action visualizer-action-%s" data-visualizer-type="%s" data-visualizer-chart-id="%s" data-visualizer-container-id="%s" data-visualizer-mime="%s" title="%s"', $key, $key, $atts['id'], $id, $mime, $title );
301342

302343
if ( 'copy' === $key ) {
303344
$copy = $this->_getDataAs( $atts['id'], 'csv' );

classes/Visualizer/Render.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,4 +171,23 @@ protected function is_request_from_gutenberg() {
171171
return false;
172172
}
173173

174+
/**
175+
* Gets the type of chart that is being rendered.
176+
*
177+
* This is useful if some type-specific functionality needs to be added.
178+
*
179+
* @since ?
180+
*
181+
* @access protected
182+
* @return string
183+
*/
184+
protected function get_chart_type( $with_library = false ) {
185+
$lib_type = str_replace( 'Visualizer_Render_Sidebar_Type_', '', get_class( $this ) );
186+
if ( $with_library ) {
187+
return $lib_type;
188+
}
189+
190+
$array = explode( '_', $lib_type );
191+
return end( $array );
192+
}
174193
}

classes/Visualizer/Render/Sidebar.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,18 @@ protected function _renderActionSettings() {
260260
$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' ),
261261
$disable_actions
262262
);
263+
264+
// not all charts support downloading as an image.
265+
$class = $this->get_chart_type( false );
266+
$disabled = in_array( $class, array( 'Gauge', 'Tabular', 'DataTable', 'Table' ), true );
267+
self::_renderCheckboxItem(
268+
esc_html__( 'Download Image', 'visualizer' ),
269+
'actions[]',
270+
isset( $this->actions ) && in_array( 'image', $this->actions, true ) ? true : false,
271+
'image',
272+
$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' ) ),
273+
$disable_actions || $disabled
274+
);
263275
self::_renderSectionEnd();
264276
}
265277

js/render-chartjs.js

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -407,18 +407,31 @@
407407

408408
// front end actions
409409
$('body').on('visualizer:action:specificchart', function(event, v){
410+
var id = v.id;
411+
if(typeof rendered_charts[id] === 'undefined'){
412+
return;
413+
}
414+
var canvas = $('#' + id + ' canvas');
410415
switch(v.action){
411416
case 'print':
412-
var id = v.id;
413-
if(typeof rendered_charts[id] === 'undefined'){
414-
return;
415-
}
416-
var canvas = $('#' + id + ' canvas');
417417
var win = window.open();
418418
win.document.write("<br><img src='" + canvas[0].toDataURL() + "'/>");
419419
win.document.close();
420420
win.onload = function () { win.print(); setTimeout(win.close, 500); };
421421
break;
422+
case 'image':
423+
var img = canvas[0].toDataURL();
424+
if(img !== ''){
425+
var $a = $("<a>"); // jshint ignore:line
426+
$a.attr("href", img);
427+
$("body").append($a);
428+
$a.attr("download", v.dataObj.name);
429+
$a[0].click();
430+
$a.remove();
431+
}else{
432+
console.warn("No image generated");
433+
}
434+
break;
422435
}
423436
});
424437

js/render-facade.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
var container = $(this).attr( 'data-visualizer-container-id' );
1818
var lock = $('.visualizer-front.visualizer-front-' + chart);
1919
var mime = $(this).attr( 'data-visualizer-mime' );
20-
console.log(mime);
2120
lock.lock();
2221
e.preventDefault();
2322
$.ajax({
@@ -56,7 +55,8 @@
5655
}
5756
break;
5857
case 'print':
59-
$('body').trigger('visualizer:action:specificchart', {action: 'print', id: container, data: data.data.csv});
58+
case 'image':
59+
$('body').trigger('visualizer:action:specificchart', {action: type, id: container, data: data.data.csv, dataObj: data.data});
6060
break;
6161
default:
6262
if(window.visualizer_perform_action) {

js/render-google.js

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -433,21 +433,33 @@ var __visualizer_chart_images = [];
433433

434434
// front end actions
435435
$('body').on('visualizer:action:specificchart', function(event, v){
436+
var id = v.id;
437+
if(typeof rendered_charts[id] === 'undefined'){
438+
return;
439+
}
440+
var arr = id.split('-');
441+
var img = __visualizer_chart_images[ arr[0] + '-' + arr[1] ];
436442
switch(v.action){
437443
case 'print':
438-
var id = v.id;
439-
if(typeof rendered_charts[id] === 'undefined'){
440-
return;
441-
}
442-
var arr = id.split('-');
443-
var img = __visualizer_chart_images[ arr[0] + '-' + arr[1] ];
444444
// for charts that have no rendered image defined, we print the data instead.
445445
var html = v.data;
446446
if(img !== ''){
447447
html = "<html><body><img src='" + img + "' /></body></html>";
448448
}
449449
$('body').trigger('visualizer:action:specificchart:defaultprint', {data: html});
450450
break;
451+
case 'image':
452+
if(img !== ''){
453+
var $a = $("<a>"); // jshint ignore:line
454+
$a.attr("href", img);
455+
$("body").append($a);
456+
$a.attr("download", v.dataObj.name);
457+
$a[0].click();
458+
$a.remove();
459+
}else{
460+
console.warn("No image generated");
461+
}
462+
break;
451463
}
452464
});
453465

0 commit comments

Comments
 (0)