How to Embed an Animated Chart in a WordPress Blog Post

Interactive charts are a beautiful way of visualizing pieces of data. In this blog post, I would like to share a way of adding an interactive chart to a WordPress blog post using the HTML code block. 

There are a few Javascript libraries to create interactive charts, like D3 (the most comprehensive yet complex one), Google Charts, Chart.js, and many more. 

Here I would use the Chart.js library, which I found intuitive with robust capabilities. 

If you skim through the examples the Chart.js share on their website, you’ll find easy to deploy examples. And while it sounds pretty straightforward to add a chart using Chart.js, there are still some things worth considering. Here are the things covered in this post: 

  1. Creating a basic chart
  2. Adding data labels using a plugin
  3. Coloring the bars with a gradient
  4. Setting the animation to start when the user can see it

In the end, we’ll end up with this kind of horizontal bar chart:

Let’s get started.

We’ll create the whole chart in one HTML doc. 

Before we start writing the actual code for the chart, we’ll need to import three libraries:

  • The chart.js library
  • The data labels plugin, that will help us create labels on top of the bars
  • JQuery – to track the user location on the page, so we can start the chart animation at the right time. 

We’ll use the CDN links to reference the three libraries above.

Here is the boilerplate code of our chart: 

<div class=horizonalBars>
    <canvas id="horizontal-bar-chart" width="600" height="450"></canvas>
</div>

<style>
    #canvas {
        position: absolute;
        width: 100%;
        height: 100%;
    }
</style>

<script src="https://cdn.jsdelivr.net/npm/chart.js@3.0.0/dist/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.0.0"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

<script>

    var data = {
        
    }

    const config = {
            type: 'bar',
            data,
            options: {

            }
        }

    const myChart = new Chart(
            document.getElementById("horizontal-bar-chart"),
            config
        );
</script>

Adding Data

Our data in this chart is hard-coded. I won’t go over the code line by line (the Chart.js docs are pretty straightforward with the basics). Though you can see that the code is structured in an easy way to understand:

  • Data labels
  • Datasets with their attributions: data, colors, design, labels
var data = {
            labels: ["Instagram", "Facebook", "TikTok", "YouTube"],
                    datasets: [
                        {
                            data: [94, 43, 13, 10],
                            backgroundColor: [                    
                                ig_gradient, 
                                "rgba(66,103,178)", 
                                tt_gradient,
                                "rgba(255, 0, 0)"
                            ],
                            borderRadius: 5,
                            datalabels: {
                                color: ['white', 'white','rgba(0, 0, 0, 0.8)','rgba(0, 0, 0, 0.8)'],
                                font: {
                                    weight: 'bold',
                                    size: 16
                                },
                                align: ['center','center','end','end'],
                                anchor: ['center','center','end','end'],
                                formatter: function(value, context) {
                                    return context.chart.data.labels[context.dataIndex] + ': ' + value + '%';
                                }
                            }
                        }
                    ]
            };

Chart Config with the Options Object

The chart configuration is handled with a global Options object. Here we can change the axis display (i.e. remove ticks), the bar chart orientation (indexAxis: ‘y’ will make the bars horizontal instead of vertical), and so on.

In our chart, the bars have labels. To add this layer, there’s a plugin to add called chartjs-plugin-datalabels. We have loaded it through a CDN in our boilerplate code (see in the first code section in this blog post).

Once it’s loaded, we can use the plugin to add data labels and design them as we wish. The datalabels configuration is listed here under “datalabels”. We will include an explicit registration of the plugin in the config const (see the last code part on this blog post), with the code: plugins: [ChartDataLabels].

Before we jump ahead, here’s how we configured the options:

var options = {
            indexAxis: 'y',
            responsive: true,
            legend: { display: false },
            scales: {
                y: {
                    beginAtZero: true,
                    grid: {
                        color: "rgba(238, 238, 238, 1)"
                    },
                    ticks: {
                        display: false
                    }
                },
                x: {
                    grid: {
                        display: false
                    }
                }
            },
            animation: {
                duration: 2500
            },
            plugins: {
                title: {
                    display: true,
                    text: 'Influencer Campaign Platform of Choice',
                },
                legend: {
                    display: false,
                },
                tooltip: {
                    enabled: false
                },
                datalabels: {
                    padding: {
                        left: 14
                    },
                    labels: {
                        title: {
                            font: {
                                weight: 'bold',
                            }
                        }
                    }
                }
            }
        };

Setting the Bars Gradient Colors

In the example bar chart, we use social media networks’ data. Some of these networks have multicolor logos. To reflect that in our chart, we can add a gradient color to each bar. Here are two gradients, one for Instagram and the other for TikTok:

let tt_gradient = bar_ctx.createLinearGradient(0, 0, 60, 0);
        tt_gradient.addColorStop(0, 'rgba(37,244,238)');
        tt_gradient.addColorStop(1, 'rgba(254,44,85)');

        let ig_gradient = bar_ctx.createLinearGradient(0, 0, 570, 0);
        ig_gradient.addColorStop(0, 'rgba(64,93,230)');
        ig_gradient.addColorStop(0.1, 'rgba(88,81,219)');
        ig_gradient.addColorStop(0.3, 'rgba(131,58,180)');
        ig_gradient.addColorStop(0.5, 'rgba(193,53,132)');
        ig_gradient.addColorStop(1, 'rgba(245,96,64)');

Trigger Animation When the Content Scrolls into View

By default, the animation starts when the page loads. If the chart is out of the visitors’ sight, the animation will most likely be over by the time they reach it.

What we would like to have is an animation that starts when the section comes to view. 

To accomplish that we will wrap our chart drawing in a function, and call it only when the chart div section is in view. To avoid chart redrawing attempts when the user scrolls out and into the chart’s div, we’ll use a boolean variable to draw it only once. We’ll use a JQuery function for the visitor location trigger:

var horizonal_bar_chart_drawn = false;
    $(window).scroll(function() {
        var top_of_element = $("#horizontal-bar-chart").offset().top;
        var bottom_of_element = $("#horizontal-bar-chart").offset().top + $("#horizontal-bar-chart").outerHeight();
        var bottom_of_screen = $(window).scrollTop() + $(window).innerHeight();
        var top_of_screen = $(window).scrollTop();

        if ((bottom_of_screen > top_of_element) && !horizonal_bar_chart_drawn){
            draw_horizontal_chart();
            horizonal_bar_chart_drawn = true;
        }
    });

Wrapping it all Together

Now that we configured each part of the code – data, options, adding plugins, animation, and adding a function to start the animation when object in view, we can consolidate all our parts in their places and add the full code into an HTML block:

<div class=horizonalBars>
    <canvas id="horizontal-bar-chart" width="600" height="450"></canvas>
</div>

<style>
    #canvas {
        position: absolute;
        width: 100%;
        height: 100%;
    }
</style>

<script src="https://cdn.jsdelivr.net/npm/chart.js@3.0.0/dist/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2.0.0"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

<script>
    
    // Function to start animation when content in view
    var horizonal_bar_chart_drawn = false;
    $(window).scroll(function() {
        var top_of_element = $("#horizontal-bar-chart").offset().top;
        var bottom_of_element = $("#horizontal-bar-chart").offset().top + $("#horizontal-bar-chart").outerHeight();
        var bottom_of_screen = $(window).scrollTop() + $(window).innerHeight();
        var top_of_screen = $(window).scrollTop();

        if ((bottom_of_screen > top_of_element) && !horizonal_bar_chart_drawn){
            draw_horizontal_chart();
            horizonal_bar_chart_drawn = true;
        }
    });

    function draw_horizontal_chart(){
        
        var bar_ctx = document.getElementById("horizontal-bar-chart").getContext('2d');

        // Gradients 
        let tt_gradient = bar_ctx.createLinearGradient(0, 0, 60, 0);
            tt_gradient.addColorStop(0, 'rgba(37,244,238)');
            tt_gradient.addColorStop(1, 'rgba(254,44,85)');

        let ig_gradient = bar_ctx.createLinearGradient(0, 0, 570, 0);
        ig_gradient.addColorStop(0, 'rgba(64,93,230)');
        ig_gradient.addColorStop(0.1, 'rgba(88,81,219)');
        ig_gradient.addColorStop(0.3, 'rgba(131,58,180)');
        ig_gradient.addColorStop(0.5, 'rgba(193,53,132)');
        ig_gradient.addColorStop(1, 'rgba(245,96,64)');

        var data = {
            labels: ["Instagram", "Facebook", "TikTok", "YouTube"],
                    datasets: [
                        {
                            data: [94, 43, 13, 10],
                            backgroundColor: [                    
                                ig_gradient, 
                                "rgba(66,103,178)", 
                                tt_gradient,
                                "rgba(255, 0, 0)"
                            ],
                            borderRadius: 5,
                            datalabels: {
                                color: ['white', 'white','rgba(0, 0, 0, 0.8)','rgba(0, 0, 0, 0.8)'],
                                font: {
                                    weight: 'bold',
                                    size: 16
                                },
                                align: ['center','center','end','end'],
                                anchor: ['center','center','end','end'],
                                formatter: function(value, context) {
                                    return context.chart.data.labels[context.dataIndex] + ': ' + value + '%';
                                }
                            }
                        }
                    ]
            };
        
        var options = {
            indexAxis: 'y',
            responsive: true,
            legend: { display: false },
            scales: {
                y: {
                    beginAtZero: true,
                    grid: {
                        color: "rgba(238, 238, 238, 1)"
                    },
                    ticks: {
                        display: false
                    }
                },
                x: {
                    grid: {
                        display: false
                    }
                }
            },
            animation: {
                duration: 2500
            },
            plugins: {
                title: {
                    display: true,
                    text: 'Influencer Campaign Platform of Choice',
                },
                legend: {
                    display: false,
                },
                tooltip: {
                    enabled: false
                },
                datalabels: {
                    padding: {
                        left: 14
                    },
                    labels: {
                        title: {
                            font: {
                                weight: 'bold',
                            }
                        }
                    }
                }
            }
        };

        const config = {
                type: 'bar',
                data,
                options,
                plugins: [ChartDataLabels]
            }
        
        
        const myChart = new Chart(
            document.getElementById("horizontal-bar-chart"),
            config
        );
    }
</script>

Hope you found this guide useful. Thanks for reading!

Leave a comment

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