Tutorial of using Chart.js in Soy Portlet

The purpose of this tutorial is to let you know how to involve a 3rd part js lib in metal soy portlet and how to use them in ES6 script. 
 
In Liferay DXP we provide abundant OOTB js lib to help the development. Jquery, AlloyUI, metal, lexicon component and etc.
 
They are all good, however, in real world project development nothing can satisfy the requirement once for all. In this changing world, the requirement is unpredictable. 
For this we can extend our ootb library by utilizing nodeJS to get 3rd part js lib works in Liferay.
 
In this journey, I will lead you to take a glimpse of the power of Liferay's integrability.
 
Knowledge:
    Google Closure Soy template.
    Liferay Soy Portlet.
    ECMA script 2015(ES6)
    Chart.js
 
In Tutorial of Creating Soy Portlet article, we have learned how to create a metal soy portlet by Liferay IDE. 
 
Based on that, we are going to do a further development -- to create a Chart. (In my professional life, many business requirement needs some sense of chart, this kind of requirement is very common.)
To build a chart js lib from scratch is not realistic. By utilizing Chart.js or other product on the market would help us to reduce develop effort and save project cost.
 
So let's start working on a portlet that display a chart.
 
Step 1, Create a soy portlet.
 
Create a Soy portlet as it shows in Tutorial of Creating Soy Portlet article with this file structure:
 
 
Step 2, ChartJS dependencies
 
To use ChartJS, we need to add NodeJS dependencies in package.json. Optionally you could manually copy a Chart.js bundle to your project path.
 
"chart.js": "^2.4.0"
 
Step 3, include it to your runtime environment.
 
Because Chart.js is a 3rd part js lib, it doesn't exist in the system(suppose it's not been used before). We have to involve it in our runtime -- in the jar.
So let's config our bnd.bnd to include the js to the right place. Add/Modify the following code to your bnd.bnd
 
Include-Resource: package.json,\
    META-INF/resources/js/Chart.js = node_modules/chart.js/dist/Chart.js
This means, I want a Chart.js in META-INF/resources/js of the jar, and the source is from node_modules/chart.js/dist/Chart.js
And add web context path in bnd.bnd
Web-ContextPath: /chartjs-soy
 
 
Step 4, Work with soy template
 
We are going to add a canvas for chart to use. So let's add the following code to ChartjsSoy.soy
{namespace ChartjsSoy}
/**
 * Display Chart canvas
 */
{template .render}
    <canvas id="chartjs-soy">
    </canvas>
{/template}
 
 
Step 5, import your Chart.js in your Component
 
I believe all audience of this blog know how to use ChartJS in a traditional way, in html and javascript like this:
<script src="Chart.js"></script>
<script>
    var myChart = new Chart({...})
</script>
But this is not going to be our approach. We are going to take advantage ES6 to use Chart, to extend our knowledge :)
So add the import in ChartjsSor.es.js in the head
 
import Chart from 'chartjs-soy/js/Chart';
 
You can see chartjs-soy is the web context path we define in bnd.bnd, and js/Chart is our web resource folder.
 
 
Step 6, create a chart with Chart.js
 
Add the following method to your Component
    /**
     * Create Chart
     *
     * @protected
     */
    createChart_() {
        let chartcanvas = document.getElementById("chartjs-soy");

        let data = {
            labels: ["January", "February", "March", "April", "May", "June", "July"],
            datasets: [
                {
                    label: "My First dataset",
                    backgroundColor: [
                        'rgba(255, 99, 132, 0.2)',
                        'rgba(54, 162, 235, 0.2)',
                        'rgba(255, 206, 86, 0.2)',
                        'rgba(75, 192, 192, 0.2)',
                        'rgba(153, 102, 255, 0.2)',
                        'rgba(255, 159, 64, 0.2)'
                    ],
                    borderColor: [
                        'rgba(255,99,132,1)',
                        'rgba(54, 162, 235, 1)',
                        'rgba(255, 206, 86, 1)',
                        'rgba(75, 192, 192, 1)',
                        'rgba(153, 102, 255, 1)',
                        'rgba(255, 159, 64, 1)'
                    ],
                    borderWidth: 1,
                    data: [65, 59, 80, 81, 56, 55, 40],
                }
            ]
        };

        let options = {
            scales: {
                xAxes: [{
                    stacked: true
                }],
                yAxes: [{
                    stacked: true
                }]
            }
        };

        let myBarChart = new Chart(chartcanvas, {
            type: 'bar',
            data: data,
            options: options
        });

    }
 
Step 7, constructor method to call
 
Let's add a constructor method in our component to call this createChart method
 
    constructor(opt_config) {
        super(opt_config);

        this.createChart_();

    }
 
 
Step 8, compile, deploy, test, debug and play around
 
If you have done it correctly, you would have a chart sheet like mine.
 
 
You can see how easy we can involve a 3rd part js lib in our project to improve our UX. Don't be limited with only 1 js lib, play around and test! The only limitation is your imagination. 
 
Hope you enjoy it.
Attachment is a compiled jar for you to deploy and test.
For full workable source code please visit sample.liferayee.com
 
Special Thanks to our Principal UI Engineer Chema Balsas, with his help I can get this tutorial done. Thanks Chema for many precious recommendations and help.

Write a blog post too!

Write a deep dive into how you use Liferay projects in your technology stack. Or let people know useful tips and tricks for a particular functionality. The Liferay community needs you!

Login or Create an account