-
-
Save kingkool68/567527d28f82bd3a0107970b624fea0a to your computer and use it in GitHub Desktop.
<?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(); |
Aaah... I see!... because the action_wp_enqueue_scripts
is storing the results of get_the_csv_data()
to $csv_data
the data I'm trying to work with is in effect 'moved' from the variable $data
to $csv_data
I was closer than I thought, but I thought my problem was in the processing of the requested CSV when fetching the data! I've learned a little bit more once again! Thank you so much!
If it is possible to update the gist to include both charts (called by separate shortcodes) that would be amazing. I will then be able to compare and contrast the two separate plugin files and the consolidated one to try and understand the differences!
Your help has been and is very much appreciated.
I just updated the gist. There are now two shortcodes: [river-height-gauge]
and [river-level-chart]
. They can be used separately or together or however you see fit.
They should look like this:
This is what I threw into the Gutenberg editor:
<!-- wp:paragraph -->
<p>River Level Chart</p>
<!-- /wp:paragraph -->
<!-- wp:shortcode -->
[river-level-chart]
<!-- /wp:shortcode -->
<!-- wp:paragraph -->
<p>Guage Chart</p>
<!-- /wp:paragraph -->
<!-- wp:shortcode -->
[river-height-gauge]
<!-- /wp:shortcode -->
Hopefully that does what you want. Best of luck!
@kingkool68 Thank you... I'm so sorry, I have installed the updated code as a plugin and I'm not able to get any output on screen with the shortcodes either when only one is tried or when both are used?
I have also installed on a separate site and tried both with no other plugins activated and via the Gutenberg editor but neither display?
I am getting the div's outputted on the front end from the add_shortcode code sections but when I look in the WP database there doesn't seem to be any transient data being created / stored?
Hi Russell, I have finally managed to get this working!... however I have had to change the code on line 87 - 95 to be:
if ( !wp_script_is( 'river-gauge-chart', $list = 'enqueued' ) ) { $the_javascript_goodness = static::render_gauge_chart_javascript(); wp_add_inline_script( 'google-charts-library', $the_javascript_goodness, $position = 'after' ); }
if ( !wp_script_is( 'river-line-chart', $list = 'enqueued' ) ) { $the_javascript_goodness = static::render_line_chart_javascript(); wp_add_inline_script( 'google-charts-library', $the_javascript_goodness, $position = 'after' ); }
Which is obviously incorrect in terms of the logic that should be getting applied?!
@James--Taylor Ah yea that would do the opposite of what we want it to do. I copied the code of the gist and tested it locally as a plugin again. It worked as intended. In the action_wp_enqueue_scripts
method you can add debugigng statements like var_dump( 'BEEP' );
and see if that method is actually being called at all.
When you try and use the shortcodes what is the output? Is it just [river-height-gauge]
which would mean the shortcode isn't being registered. Or can you see the HTML <div id="river-gauge-chart" style="width: 400px; height: 200px;"></div>
in the source code of the page?
@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
??!
@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!
Let me see if I can update this gist to include both charts in one simple plugin.