Skip to content

Instantly share code, notes, and snippets.

@kingkool68
Last active October 26, 2021 16:59
Show Gist options
  • Save kingkool68/567527d28f82bd3a0107970b624fea0a to your computer and use it in GitHub Desktop.
Save kingkool68/567527d28f82bd3a0107970b624fea0a to your computer and use it in GitHub Desktop.
James Taylor wanted to load CSV data and display it as a gauge data visualization in WordPress. See https://www.facebook.com/groups/advancedwp/posts/4673874846008026/
<?php
/**
* Plugin Name: River Height Levels
* Plugin URI: https://gist.github.com/kingkool68/567527d28f82bd3a0107970b624fea0a
* Description: Fetch the current river height values and display it as different data visualization.
* Version: 0.0.2
* Author: Russell Heimlich
* Author URI: https://twitter.com/kingkool68
* License: GPL v2 or later
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
*/
class River_Height_Levels {
/**
* Get an instance of this class
*/
public static function get_instance() {
static $instance = null;
if ( null === $instance ) {
$instance = new static();
$instance->setup_actions();
}
return $instance;
}
/**
* Hook into WordPress via actions
*/
public function setup_actions() {
add_action( 'init', array( $this, 'action_init' ) );
}
/**
* Register the Google Charts loader script
*/
public static function action_init() {
wp_register_script(
'google-charts-library',
'https://www.gstatic.com/charts/loader.js',
$deps = array(),
$ver = null,
$in_footer = true
);
// Register dummy script handlers so we can dynamically enqueue wp_add_inline_script()
// See https://wordpress.stackexchange.com/a/311279/2744
wp_register_script(
'river-gauge-chart',
'',
$deps = array( 'google-charts-library' ),
$ver = null,
$in_footer = true
);
wp_register_script(
'river-line-chart',
'',
$deps = array( 'google-charts-library' ),
$ver = null,
$in_footer = true
);
add_shortcode(
'river-height-gauge',
function() {
wp_enqueue_script( 'river-gauge-chart' );
$the_javascript_goodness = static::render_gauge_chart_javascript();
wp_add_inline_script( 'google-charts-library', $the_javascript_goodness, $position = 'after' );
return '<div id="river-gauge-chart" style="width: 400px; height: 200px;"></div>';
}
);
add_shortcode(
'river-level-chart',
function() {
wp_enqueue_script( 'river-line-chart' );
$the_javascript_goodness = static::render_line_chart_javascript();
wp_add_inline_script( 'google-charts-library', $the_javascript_goodness, $position = 'after' );
return '<div id="river-line-chart" style="width: 900px; height: 500px"></div>';
}
);
}
/**
* Load an external CSV file and store it as a transient
*/
public static function get_the_csv_data() {
$transient_key = 'river-height-csv-data';
$data = get_transient( $transient_key );
// If the data already exists then return it. We're done here!
if ( false !== $data ) {
return $data;
}
// Fetch the CSV data.
$request = wp_remote_get( 'https://check-for-flooding.service.gov.uk/station-csv/8056' );
// Retrieve the body contents from the request.
$raw_csv_string = wp_remote_retrieve_body( $request );
$rows = explode( "\n", $raw_csv_string );
// Remove the header rows from the beginning of the array.
array_shift( $rows );
$data = array();
foreach ( $rows as $row ) {
$data[] = str_getcsv( $row, ',' );
}
// Store the result for 15 minutes.
set_transient( $transient_key, $data, 15 * MINUTE_IN_SECONDS );
return $data;
}
/**
* Render the latest data point as a Google Visualization Gauge Chart
*
* @link https://developers.google.com/chart/interactive/docs/gallery/gauge
*/
public static function render_gauge_chart_javascript() {
$csv_data = static::get_the_csv_data();
$last_row = end( $csv_data );
ob_start();
?>
google.charts.load('current', {'packages':['gauge']});
google.charts.setOnLoadCallback(drawGaugeChart);
function drawGaugeChart() {
var data = google.visualization.arrayToDataTable([
['Label', 'Value'],
['Height', <?php echo floatVal( $last_row[1] ); ?>]
]);
var options = {
min: 0,
max: 2,
width: 400,
height: 200,
redFrom: 1.2,
redTo: 2,
greenFrom: 0.4,
greenTo: 1.2,
yellowFrom: 0,
yellowTo: 0.4,
minorTicks: 5
};
var chart = new google.visualization.Gauge(document.getElementById('river-gauge-chart'));
chart.draw(data, options);
}
<?php
return ob_get_clean();
}
/**
* Render the river height data point as a Google Visualization Line Chart
*
* @link https://developers.google.com/chart/interactive/docs/gallery/linechart
*/
public static function render_line_chart_javascript() {
$csv_data = static::get_the_csv_data();
ob_start();
?>
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawLineChart);
function drawLineChart() {
var data = google.visualization.arrayToDataTable([
['Date', 'Height'],
<?php
foreach ( $csv_data as $row ) {
$the_date = date( 'g:i a D, M j', strtotime( $row[0] ) );
echo ( "['" . $the_date . "', " . floatVal( $row[1] ) . '],' );
}
?>
]);
var options = {
title: 'River Level Over Last 5 Days',
curveType: 'function',
hAxis: {
showTextEvery: 96,
format: 'D M j'
},
vAxis: { minValue: 0, maxValue: 2 },
legend: { position: 'bottom' }
};
var chart = new google.visualization.LineChart(document.getElementById('river-line-chart'));
chart.draw(data, options);
}
<?php
return ob_get_clean();
}
}
River_Height_Levels::get_instance();
@James--Taylor
Copy link

@kingkool68 When I run your plugin code from the Gist I get the <div id="river-gauge-chart" style="width: 400px; height: 200px;"></div> being output to the HTML but no further population of content within it.

I also worked out that I was not getting any transient data written to the DB, and additional Javascript components of the Google Visualisation charts where not being loaded / shown in my HTML page source from the google.charts.load('current', {'packages':['corechart']}); google.charts.setOnLoadCallback(drawLineChart);

If I'm reading the plugin code and its data flow correctly, the 'guts' of the plugin ( get_the_csv_data() / render_gauge_chart_javascript() / render_line_chart_javascript() ) are never being called as the checks for wp_script_is()... aren't returning TRUE ??

When I add var_dump( 'BEEP' ); within the action_wp_enqueue_scripts I don't get any output of BEEP unless I change it to !wp_script_is ??!

@kingkool68
Copy link
Author

@James--Taylor Ahh I see the issue. I just updated the Gist again. got rid of the whole action_wp_enqueue_scripts() part and simplified it. Should work as expected now.

@James--Taylor
Copy link

@kingkool68 Thanks Russell, I have updated and it works!

Thank you once again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment