Last active
October 26, 2021 16:59
-
-
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/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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 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.
@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
@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 forwp_script_is()...
aren't returning TRUE ??When I add
var_dump( 'BEEP' );
within theaction_wp_enqueue_scripts
I don't get any output of BEEP unless I change it to!wp_script_is
??!