Search code examples
javascriptchartsgoogle-analyticse-commercechart.js

Chart.js: compare two periods like Google Analytics with a line chart


I'm using the chart.js 2.6.0 library.

I'm trying to made a comparation line chart like the Google Analytics compare functionality: Screenshot

I have to compare two revenue date periods of an ecommerce.

I would like to draw two x Axes with different labels, one x Axe for the first period, one for the second.

Now I can draw two lines, one for each period, and two xAxes, but I can use only one array of labels, giving me the following result: screeshot

Obviously wrongly, every period-two point on the line, is corresponding to the period 1 label (see the hover infowindow in the second screeshot)

This is my code

        var ctx = $("#ordersCompareChart");
        var chart = new Chart(ctx, {

            type: 'line',
            data: {

                labels: data.labels,
                datasets: [{

                    borderColor: "#E25F5F",
                    label: 'Period 1: From ' + $('#from_first').val() + ' to ' + $('#to_first').val(),
                    data: data.values_first,
                    borderWidth: 3,
                    xAxisID: "x-axis-1",
                },

                {

                    borderColor: "#2793DB",
                    label: 'Period 2: From ' + $('#from_second').val() + ' to ' + $('#to_second').val(),
                    data: data.values_second,
                    borderWidth: 3,
                    xAxisID: "x-axis-2",
                },


                ]

            },

            options: {
                scales: {
                    xAxes: [
                            {
                            display: true,
                            tipe: "time",
                            scaleLabel: {
                                display: true,
                                labelString: 'Period 1'
                            },
                            id: "x-axis-1"

                            },
                            {
                                display: true,
                                tipe: "time",
                                id: "x-axis-2",
                                labels: data.labels_second,
                                scaleLabel: {
                                    display: true,
                                    labelString: 'Period 2'

                                }, 
                                id: "x-axis-2"
                            }
                        ],
                    yAxes: [{
                    display: true,
                    scaleLabel: {
                        display: true,
                        labelString: 'Total'
                    },
                    ticks: {
                        callback: function(value, index, values) {

                            return value.toLocaleString("de-DE",{style:"currency", currency:"EUR"});

                        }
                    }
                    }]
                }
            }

        });

Thanks to whoever can answer


Solution

  • i'm sorry if I didn't answer before.

    Here a working fiddle https://jsfiddle.net/7L0fu4er/10/

    Let's explain my solution:

    With Charts.js you can use only one set of labels for both two x axes, the workaround is to populate the labels array with 2 dates every one value of the array, after that, you have to call a callback in the "ticks" method of every xAxe that will split dates with a delimiter ("#" in my case).

    In our case, we want to show two periods (like the ecommerce revenue of every day, this week and the last week), your labels array will be like:

    {labels: ["09/01/2018#02/01/2018","10/01/2018#03/01/2018"] ...}
    

    If you see the first value "09/01/2018#02/01/2018", the date before the "#" character is for the period 1, the second one is for the period 2.

    So

    • First. You have to build the labels array, the days for every period must be the same number for every period values

    • Give an unique Id for every xAxe

    • Call "ticks" callback for every xAxe that will elaborate every labels array value, so you can split and draw your correct date for every day

    I hope I have helped you