I’m working on a small weather station project, and I was looking for a way to plot the weather data quickly on a chart.
My first idea was to use the big visualization libraries such as D3.js and Fabrics, but they were way too heavy to get started with for my needs. They can do everything, but I was just looking for a quick chart, not another new framework to learn.
I finally choose to use the Chart.js library (https://www.chartjs.org/). It’s not the smallest library ever at 117.7KB minified and gzipped, but it does pull moment.js as a dependency which account for half the size. Still, for a chart-heavy application such as this one, I’m willing to pay that resource cost. Besides, I’ll be the only one use this application on my own network.
Weather plotted on a Chart.js chart. Example data, it was not really that cold in June.
Since it’s a JavaScript library, but not React specific, I wanted to decouple the Chart.js code from the React code. Since Chart.js expects a canvas to render the content; I just added the tag to my React component, such as:
And imported the JavaScript file containing the Chart.js code so it would initialize the chart (tucked away neatly in a chart folder in my project):
import drawWeatherVisualization from "../../chart/WeatherVisualization.js";
The chart itself is a simple object to which you pass various options. For a line chart like this one, you’ll need to feed it a dataset for each line (using the currentWeatherModule variable from the functional React component pulling this). The dataset will be shown on the Y axis, in that case the minimum and maximum temperature reached for each day in the last 30 days.
You also need to set the axis for the data. In my case, I’m generating a list of dates as the X axis, using the moment.js data format.
The minimum and maximum are not necessary; the library can figure it out from the data. For my use case, I want to make sure the display still make sense even if I don’t have data for all 30 days yet and to have always the same axis in all charts.
On the other hand, I forgot to sort the data by date before sending it to Chart.js and I had really strange results. Don’t forget your sorts!
I’m also setting the minimum and maximum weather expected so it looks better and it’s not just an arbitrary number, but it’s not necessary either.
Here is the complete code for the line chart with a few more formatting options added in. It’s not perfect, but I’m pretty satisfied at the speed at which I was able to add this in my project. If you want to see the complete project, you can check it out on GitHub (https://github.com/CindyPotvin/temperature-logger).
I’ve started playing with the new Gutenberg editor in WordPress, and the experience is a lot more modern than the old TinyMCE editor that’s been around for a good 15 years (and I’ve had blogs for almost that long!).
Instead of editing all the content of the post at once, the Gutenberg editor works with blocks of content that can be reordered, with a clean look similar to the Medium editor.
WordPress comes with many blocks by default for standard elements such as list, button or image galleries (see https://gogutenberg.com/blocks/ for all the blocks that comes built-in). You can also save blocks you’ve used in a post to reuse them in other posts.
For a really effective blogging workflow, you’ll need to build new blocks to extent the functionalities of the editor. For another blog I own (https://robotsbench.com/), I wanted to use the HTML
It involved more code than I expected and there are many steps. A good surprise still, the majority of the code the plugin is in React (JavaScript) instead of the PHP scripts used for standard plugins. You’ll still need a tiny bit of PHP to package it as a WordPress plugin, but it’s mostly boilerplate that can be generated.
This tutorial will walk you through the creation of plugin to use the
Setting up the right tools to get started.
Create the boilerplate for the plugin.
Add a rich text field to add content to the block.
Add CSS styles to the block.
Setting up the Environment
Before we get started creating the plugin template, you’ll need to install the following on your computer to follow along.
You’ll already have all of this if you’re already developing in JavaScript and own a blog, but here is it for completeness’ sake:
A code editor to edit PHP, JavaScript and CSS files. Right now, my favorite is Visual Studio Code at https://code.visualstudio.com/.
npm version 5.3 or more to create the template, get the required dependencies and package the plugin at https://www.npmjs.com/get-npm.
A live or local installation of WordPress with the Gutenberg editor to test the plugin. The Gutenberg editor now comes enabled by default in WordPress. I used Local by Flywheel to do this.
Generate an Empty Plugin Template
We are going to use a tool called create-guten-block (https://github.com/ahmadawais/create-guten-block) to create a template for our new plugin and upload it to your blog to test the whole process first. It will only contain a single block in this tutorial, but you could add all your custom blocks in a single plugin.
In the command line, use the following command to generate a plugin named cp-aside-gutenberg-block.
npx create-guten-block cp-aside-gutenberg-block
Your newly created plugin will be in a cp-aside-gutenberg-block subfolder of the current folder. To prepare your plugin to upload on your WordPress installation, navigate to the plugin folder and build it.
cd cp-aside-gutenberg-block
npm run build
To deploy the plugin, add the following files in the cp-aside-gutenberg-block folder to a .zip file:
\dist
\src
plugin.php
You could include all the other files for the sake of having the complete source code of your plugin on your blog, but they won’t be used by WordPress. If you do include them, ignore the \node_modules folder: it’s a pretty big folder and you can always download the content again using the npm install command if you need to recreate it.
Deploy it like you would deploy any other plugin, using the Plugins/Add new menu in WordPress and clicking the Upload Plugin button to select the .zip file you just created. Activate it and it should now be shown as active in your list of plugins.
From there on, the new block will appear in the list of blocks when you edit a post.
The block can be rendered differently in the editor and in the final blog post. With the boilerplate, it will show up in the editor as the following:
And in the real post (or in the post preview):
What’s in the Boilerplate?
The template has generated many files for the plugin. Here is what’s included in the plugin we just tried out from the generated template:
Many things here will be familiar to you if you’ve worked on a React application before. Here are the most interesting parts:
/dist: The frontend files that we built with the npm run build command and that need to be deployed.
/src: Contains all the source code of the plugin (both the frontend in JavaScript and backend in PHP).
package.json: Describes the various dependencies required and commands that can be run. You’ll only need to edit it if you need additional JavaScript dependencies. By default, it only depends on the cgb-script library that pulls everything else.
plugin.php: The standard file needed for a WordPress plugin.
The most interesting part is the src/block/block.js file that contains the JavaScript for the plugin:
import './style.scss';
import './editor.scss';
const { __ } = wp.i18n;
const { registerBlockType } = wp.blocks;
registerBlockType('cgb/block-cp-aside-gutenberg-block', {
title: __('cp-aside-gutenberg-block'),
icon: 'shield', // Icon used for the block from Dashicons
category: 'common',
edit: function(props) {
return (
Hello from the backend.
);
},
save: function(props) {
return (
Hello from the frontend.
);
},
} );
The Gutenberg Block API used to extend the editor makes the registerBlockType method available to add your own blocks. The registerBlockType method describes the block and what happens when displaying for the editor or from a post.
It includes metadata about the block such as its title, icon and category in the editor. It also includes the following two functions where most of the logic of the block lives:
edit: The fields that are shown in the Gutenberg editor to modify the content of the block.
save: The components that describe how to render the block in the post. The rendered markup is serialized and saved with the rest of the post so React is not needed when displaying the post.
Adding a Rich Text Field
Now that a basic block is available, let’s modify it to display content as an
To add the editable field, the block must now store a value in the block since it needs to render it. In the Block API, values are registered as a list of attributes in the registerBlockType method.
Attributes behave similarly to the state in React, but they contain some extra information so they can be managed by the Block API. The definition of the attribute specifies how to map the rendered content saved into the block to the content.
This block will have only one attribute named content. This attribute will look for the children inside the element described by the .cp-aside-gutenberg-block-content selector. The type of the content is an array because the block will contain many paragraphs (
When editing the post in Gutenberg, the edit method will receive the current value of the attributes as a parameter so it can show the controls needed to edit them. It also receives a setAttributes to update the current value of the attributes when the control is edited.
Those values will be used to initialize the RichText control already available with Gutenberg (see the complete example at the bottom of the post to see how to import it in your block) .
Since it’s a React control, the name of the attribute for CSS class of the control is className instead of class in HTML. You can also specify which tag type is the parent of the control, so in that case we’ll use
When the content of the editor change, the method specified in the onChange attribute of the RichText control is called and the current value is updated.
Saving the Content of the Block
When the save method is called to render the control and save the result, it also receives the current value of the attributes as a parameter (but not the setAttributes method since it won’t change the current value).
save: (props) => {
return (
);
}
It then uses the RichText.Content control to render the value correctly as rich text so it can be displayed later, so the parameters are similar to the RichText editor control.
CSS for the Block
To complete the plugin, let’s add this little bit of CSS in src\block\style.scss to show a small border around the aside block. I’ve kept it simple since it will be most likely edited at the theme level.
This style is applied in the editor and in the post preview; there is also a src\block\editor.scss file already created for styles specific to the editor.
As soon as you start doing long-running operations such as network calls or anything else that can take more than a few seconds in your Android application, you’ll come across one of the following problems:
The [Application] not responding (ANR) popup is shown while you run your application, and the The application may be doing too much work on its main thread. warning is shown in your Logcat traces.
The NetworkOnMainThreadException exception is launched as soon as you call anything over the network like an API, regardless of the duration of the call.
Why does the Android SDK complains when one of those things happens? Why does code that seems to be correct doesn’t work? Well, if your application stays frozen, your users could think it crashed. A few seconds is an eternity when you don’t have any feedback about what’s going on, and users are probably going to keep pressing buttons as a response, or close your application and never return. So, to prevent this, the Android SDK enforces minimum standards for responsiveness and display errors if those standards are not respected.
To understand why the application freezes, we must take a look at the architecture of the application. By default, your Android application has only one thread, called the main thread. All you code execute on this single thread, and a thread can only do one thing at a time.
So, if you call the network and there is a delay, everything stops while the application waits for an answer, freezing your UI completely. You won’t even be able to display a progress bar because nothing else can run. The timeline looks like:
Fortunately, you can create new threads, which allow you to do more than one thing at once:
For one-time operations that only takes a few seconds, the easiest way to manage this is to use the AsyncTask class available in the Android SDK. It will create a new thread for you that will do a specific task, and then notify you when that task is over so you can update your UI.
Here is an example of an AsycTask that calls the GitHub API to calculate the number of repository that contains the “Android” string. While the query is running, a progress bar is shown in the UI.
private class GithubAndroidRepositoryQueryTask extends AsyncTask<String, Integer, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
// Prepare the UI in the main UI thread before executing the task.
mGitRepositoryProgressBar.setVisibility(View.VISIBLE);
}
@Override
protected String doInBackground(String... params) {
// Do the operation on a new thread and returns the result. It calls the GitHub API to
// calculate the number of repository that contains the Android string
return getAndroidRepositoryCountFromGitHub();
}
@Override
protected void onProgressUpdate(Integer... progress) {
// Could be used to update the main UI thread with the progress of the background
// operation.
}
@Override
protected void onPostExecute(String result) {
// Receive the result of the operation done in the new thread in the main UI thread and
// use it to update the UI.
super.onPostExecute(result);
mGitRepositoryProgressBar.setVisibility(View.INVISIBLE);
mGitRepositoryTextView.setText(result);
}
}
And here is how you execute that task. In that case, it’s launched onCreate event of the Activity so the response is visible immediately in the layout, but it could be launched from anywhere else:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGitRepositoryTextView = (TextView) this.findViewById(R.id.github_repositories_tv);
mGitRepositoryProgressBar = (ProgressBar) this.findViewById(R.id.github_repositories_pb);
// Fires off an AsyncTask to get the number of Android repositories on GitHub and displays
// it in the application.
new GithubAndroidRepositoryQueryTask().execute();
}
When you’re working with threads of any kinds, remember that updating the UI should only be done on the main thread. The Android SDK doesn’t support updating the UI from other threads, so you’ll likely have random crashes and weird behavior if you attempt it.
Also, as a caveat, Google doesn’t recommend relying on showing a progress bar exclusively for long-running operations. They believe that users should be able to keep working in the application and that you should manage what’s going on in the backend.
If you have a simple application that has only a few simple cases it may work, but if you have complex interactions between your data you can sink a lot of time trying to make everything work nicely together and handling what happens if an operation fails.
Still, you can start with a simple AsyncTask and optimize as you go along. In most cases, it’s going to be a good starting point, but as soon you need to execute many tasks at once it won’t be enough. When you’re ready to go further with this, you should take a look at libraries such as RxJava to help you manage your tasks.