Chart.js:用折线图比较两个时期,例如 Google 分析

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

我正在使用 chart.js 2.6.0 库。

我正在尝试制作类似 Google 分析比较功能的比较折线图:Screenshot

我必须比较电子商务的两个收入日期期间。

我想画两个不同标签的 x 轴,一个 x 轴用于第一个周期,一个 x 轴用于第二个周期。

现在我可以画两条线,每个周期一条,还有两个 xAxes,但我只能使用一组标签,得到以下结果: screeshot

显然是错误的,线上的每个周期 - 两个点对应于周期 1 标签(请参阅第二个屏幕截图中的悬停信息窗口)

这是我的代码

        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"});

                        }
                    }
                    }]
                }
            }

        });

感谢能回答的人

抱歉之前没有回答

这是一个有效的 fiddle https://jsfiddle.net/7L0fu4er/10/

让我们解释一下我的解决方案:

使用 Charts.js 你只能为两个 x 轴使用一组标签,解决方法是用数组的每个值的 2 个日期填充标签数组,之后,你必须调用每个 xAxe 的 "ticks" 方法中的回调将使用分隔符(在我的例子中为“#”)拆分日期。

在我们的例子中,我们想要显示两个时期(比如每天、本周和上周的电子商务收入),您的标签数组将如下所示:

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

如果您看到第一个值 "09/01/2018#02/01/2018",“#”字符之前的日期是第 1 个日期,第二个是第 2 个日期。

所以

  • 第一。您必须构建标签数组,每个周期的天数必须与每个周期值

  • 相同
  • 给每个xAxe一个唯一的Id

  • 为每个将详细说明每个标签数组值的 xAxe 调用 "ticks" 回调,这样您就可以拆分并绘制每天的正确日期

希望对你有所帮助

我知道这是一个老问题,但我找到了一个很好的解决方案,我使用 .net 框架。

1- 制作一个存储过程以从数据库中获取今年的所有数据 GroupBy 数据和月份的前 3 个字母:

 SELECT  sum(anything) AS something ,  MAX ( Convert(char(3), tb.date, 0)) AS ALL_MONTHS 
FROM table tb  WHERE  YEAR(tb.date) = YEAR(CURRENT_TIMESTAMP)    
GROUP BY YEAR(tb.date), MONTH(tb.date)
ORDER BY YEAR(tb.date), MONTH(tb.date)

2-做一个存储过程从数据库中获取去年的所有数据,类似于步骤 1 但 where 子句是这样的:

............. 年(tb.date)= 年(GETDATE())- 1 .........

表示减去当前年份。

3-controller发送数据到view后,在View页面使用JS操作数据

注意:有 12 个月,所以制作一个 12 个月的数组,这样只有一个标签,但数据将根据从 js 循环函数接收的索引计算出月份的位置.

/////-- 图表------------------------------------ --------------

   var salesChartCanvas = $('#salesChart').get(0).getContext('2d')

    var months = @Html.Raw(Json.Encode(Model.expChartMonths));
    var total = @Html.Raw(Json.Encode(Model.expChartTotal));
      var Lastmonths = @Html.Raw(Json.Encode(Model.expChartMonthsLast));
    var Lasttotal = @Html.Raw(Json.Encode(Model.expChartTotalLast));

    var arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
    var arr2 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];

    function getMonthFromString(mon) {
        return new Date(Date.parse(mon + " 1, 2021")).getMonth()
    }

    function getMonth(mon) {
        return new Date(Date.parse(mon + " 1, 2021")).getMonth()
    }
    //this year
    for (var x = 0; x < months.length; x++) { arr2[getMonth(months[x])] = total[x] }
    //last year
    for (var i = 0; i < Lastmonths.length; i++) { arr[getMonthFromString(Lastmonths[i])] = Lasttotal[i] }


    var salesChartData = {
        labels: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
            datasets: [
                {
                    label: 'This Year Expenses',
                    fill: false,
                    backgroundColor: 'rgba(60,141,188,0.9)',
                    borderColor: 'rgba(60,141,188,0.8)',
                    pointRadius: 5,
                    pointColor: '#3b8bba',
                    pointStrokeColor: 'rgba(60,141,188,1)',
                    pointHighlightFill: '#fff',
                    pointHighlightStroke: 'rgba(60,141,188,1)',
                    data: arr2
                }
            ,
            {
                label: 'Last Year Expenses',
                fill: false,
                backgroundColor: 'rgba(210, 214, 222, 1)',
                borderColor: 'rgba(210, 214, 222, 1)',
                pointRadius: 5,
                pointColor: 'rgba(210, 214, 222, 1)',
                pointStrokeColor: '#c1c7d1',
                pointHighlightFill: '#fff',
                pointHighlightStroke: 'rgba(220,220,220,1)',
                data: arr
            }
        ]
    }