How to use D3 in your WordPress Plugins (without a plugin)


Hey guys it’s Oscar,

Recently, I’ve been obsessively interested in D3. It is a super COOL JavaScript library and it gave me a whole bunch of ideas of how could I implement it on my WordPress Plugins.

The difference of watching at a lively representation of visual data vs  looking at a bunch of dry numbers is HUGE, especially when it comes to taking quick decisions and, for me, one of the most important aspects commonly underestimated: the impact it creates in a person emotionally.

The impact visuals create into people’s minds is one of the things why i really liked D3.  Imagine how different you feel when you watch, say for example at some numerical data that tracks how many posts have you been writing each month. It is cool right? looking at data is always insightful.

Now imagine how awesome it would be when the data is represented into graphs, and those graphs move with transitions and other cool stuff, and instead of saying: 12 post last month vs 20 this one, cool … you just look at 2 bars and one is way BIGGER than the other.

The intensities the same data creates with different representations are different.

The BUY IN, the motivation and the emotions it creates visualizing data like that, is what made me fall in love with D3 capabilities.

So enough of telling you how awesome is D3. Let’s go to what you are probably here in:

How do you use D3 in your own WordPress Plugins?

Unfortunately, not many information is out there with regards of using D3 in Plugins, so i dived in and tried to create a simple chart to get me started with my D3 journey.

And I’m going to tell you how you do it today.

Some assumptions i’ve made about you:

  • I’m assuming you already know how to use D3 at a basic level.
  • I’m assuming you already know how to build WordPress Plugins.
  • I’m assuming you already know how to use OOP to build WordPress Plugins.

With that in mind, let’s get started.

For this example, i’ll add some new functionality to an already existing plugin i previously made: wp-dexter. You can find the source here: https://github.com/oscarssanchez/wp-dexter

I highly recommend you try it out with something you’ve already built or something you are already building and it’s in an advanced state. You want to focus as much as you can learning D3, not worrying about how to do a bunch of other things.

First step: Enqueuing the script files.

  • Create 1 new Js file (the one that will contain your scripts)
  • Get D3 CDN
  • Make a method that will enqueue both files

Mine Looks like this:

 

/**Enqueues our scripts **/
public function add_scripts() { 
wp_enqueue_script( 'd3-scripts', 'https://d3js.org/d3.v5.min.js');
wp_enqueue_script( 'dexter-scripts', plugins_url( '../js/dexter-scripts.js', __FILE__ ), array( 'jquery'), '', true ); 
} 

After that, you want to use an action to hook your files in the output HTML:


/** Constructor**/
public function __construct() {
   add_action( 'admin_menu', array( $this, 'admin_menus' ) );
   add_action( 'admin_head', array( $this, 'add_styles' ) );
   add_action( 'admin_enqueue_scripts', array( $this, 'add_scripts' ) );
}

Second Step: Send some data from WordPress to be available as a JavaScript variable

Ok, so after enqueuing our sript files, we will have to add something else to our add_scripts method, and that is the addition of wp_localize script(); which you can check out here: https://codex.wordpress.org/Function_Reference/wp_localize_script

For our purposes, we will use the parameters of this function in this manner:

wp_localize script( 'name_of_your_js_file', 'name_of_the_variable_t_obe_used', 'the_variable_data_in_php')

For this, i’ve  already created a  method called get_pokemon_json_data();


public static function get_pokemon_json_data() {
 $pokemon_data = json_encode( self::get_pokemon_data() );
 return $pokemon_data;
}

Since D3 works well with JavaScript objects, sending JSON data makes sense here.

So our add_scripts method would look like this:

/**
 * Enqueues JavaScript files
 */
public function add_scripts() {
 wp_enqueue_script( 'd3-scripts', 'https://d3js.org/d3.v5.min.js');
 wp_enqueue_script( 'dexter-scripts', plugins_url( '../js/dexter-scripts.js', __FILE__ ), array( 'jquery'), '', true );
 wp_localize_script( 'dexter-scripts', 'pokemon_stats', Dexter_api::get_pokemon_json_data() );
 }

Third Step: Access the data in your JavaScript file

Reload your plugin page and check out the browser’s console. You should be able to see your variable displaying.

Since the data is in JSON string format, we have to convert the data to a JavaScript object. We will have to use

var pokestats = JSON.parse(pokemon_stats);

to convert it to a Js Object.

Once we have that, we are good to go to start some hacking with D3!

Fourth Step: Use your data with D3

Since again, i’m not asumming you have some basic knowledge about D3, I will not cover step by step the code itself,  but we will explain it a little bit:

jQuery(document).ready( function() {
 var pokestats = JSON.parse(pokemon_stats);

 var width = 500;
 var barHeight = 20;

 var xScale = d3.scaleLinear()
 .domain([0, 255])
 .range([0, width]);

 var pokechart = d3.select(".pokestats")
 .attr("width", width)
 .attr("height", barHeight * pokestats.stats.length);

 var pokebar = pokechart.selectAll("g")
 .data(pokestats.stats)
 .enter()
 .append("g")
 .attr("transform", function(d, i) { return "translate(0," + i * barHeight + ")"; });

 pokebar.append("rect")
 .attr("width", function(d) { return xScale(d.base_stat) })
 .attr("height", barHeight - 4);

 pokebar.append("text")
 .attr("x", 3 )
 .attr("y", barHeight / 2)
 .attr("dy", ".35em")
 .text(function(d) { return d.stat.name + ": " + d.base_stat; });
});

So what we did here was first:

1.- Wrap everything inside an event listener.

2.- Set our dimensions

3.- Set our scale with d3.scaleLinear (in this case, the max base stat a pokemon can have is 255)

4.- Assign our dimensions to our chart class.

5.- Append some “g” elements and transform each of them to match our rect elements.

6.- Append our “rect” elements. In this case, i will be using the “stats” data from my variable to determine the width of each bar. Thanks to d3, we can access every element that is meaningful to us automatically. In this base, i want to know the number of the base stat, so i can access it inside a function with d.base_stat.

7.- Finally I want to append some text that says how much of each stat a pokemon has (and what stat it is). We can access that data with d.base_stat and d.stat.name inside a function.

The end result would be something like this: 

Cool isn’t it?

Conclusion.

Using D3 in conjunct with WordPress is not that hard. It is a fairly easy and straight thing to do. However, what i’ve been thinking lately is that the hard work you will have to put with D3 and WordPress will come when you want to access specific data or construct specific sets of data to use with D3. In this example we had a good source of data available to us. We didn’t have to build the data itself. That’s why this was easy.

However, if you want to build things with D3 with some custom that, well, that’s where you will have to put some neurons in.

Until next time 😉

Leave a Reply

Your email address will not be published. Required fields are marked *