这是我的JSFdle: https://jsfiddle.net/msuatp90/3/

基本上,我希望将收入和过go 的收入叠加在一起,这样我就可以将一个时期与前一个时期进行比较.它将始终 for each 人提供相同的标记.

利润数据也是如此,我希望利润和过go 的利润重叠.

所有4个数据集每次都将具有完全相同的刻度数.但出于某种原因,它们并没有重叠,而是一个接一个地继续.

不过,工具提示似乎运行得很好.

以下是我现在拥有的完整代码:

let startGraph = function() {
  let canvas = document.getElementById('chart');
  let chart = new Chart(canvas.getContext('2d'), {
    type: 'line',
    data: {
      datasets: [{
          label: 'Revenue',
          data: {
            "2023-03-01": 250,
            "2023-03-02": 488,
            "2023-03-03": 358,
            "2023-03-04": 255,
            "2023-03-05": 895
          },
          borderColor: '#ff6384',
          xAxisID: 'x',
        },
        {
          label: 'Profit',
          data: {
            "2023-03-01": 125,
            "2023-03-02": 156,
            "2023-03-03": 195,
            "2023-03-04": 98,
            "2023-03-05": 466
          },
          borderColor: '#36a2eb',
          xAxisID: 'x',
        },
        {
          label: 'Past Revenue',
          data: {
            "2023-02-24": 280,
            "2023-02-25": 456,
            "2023-02-26": 665,
            "2023-02-27": 288,
            "2023-02-28": 499
          },
          borderColor: '#fa829b',
          xAxisID: 'x1',
        },
        {
          label: 'Past Profit',
          data: {
            "2023-02-24": 125,
            "2023-02-25": 198,
            "2023-02-26": 265,
            "2023-02-27": 101,
            "2023-02-28": 221
          },
          borderColor: '#76c1f5',
          xAxisID: 'x1',
        }
      ]
    },
    options: {
      elements: {
        point: {
          radius: 0,
          hoverRadius: 0,
          hitRadius: 3,
        },
        line: {
          borderWidth: 2,
        },
      },
      responsive: true,
      maintainAspectRatio: false,
      interaction: {
        intersect: false,
        mode: 'index',
      },
      stacked: false,
      scales: {
        y: {
          ticks: {
            display: true,
            beginAtZero: true,
          }
        },
        x: {
          position: 'bottom',
          ticks: {
            display: false,
          },
        },
        x1: {
          position: 'top',
          ticks: {
            display: false,
          },
          grid: {
            drawOnChartArea: false,
          },
        },
      },
      plugins: {
        legend: {
          display: true,
          position: 'bottom',
          labels: {
            boxWidth: 8,
            boxHeight: 8,
            useBorderRadius: true,
            borderRadius: 3,
            usePointStyle: false,
            pointStyleWidth: 0,
            padding: 7,
            font: {
              size: 11
            }
          }
        },
      },
    }
  });
}

推荐答案

如果启用xx1轴,您将看到问题所在:这两个x轴都是绝对的,而不是时间轴,这意味着日期字符串被视为简单的字符串,而不是日期.这可能对您有用,因为日期都是相同的间隔(1天),但它仍然是危险的,因为它们没有排序,并且不能保证它们将按顺序排列.

因此,为了解决这个问题并使图表显示更安全,我将解析日期并将它们转换为表单的按日期排序的数组

[{x:timestamp1, y: value1}, {x: timestamp2, y: value2},...]

这里有一个函数可以为您的date格式执行此操作:

function parseDateIndexed(data){
    return Object.entries(data).
        map(([s, f])=>({x: Date.parse(s), y: f, s})).
        sort(({x:t1},{x:t2})=>t1-t2);
}

我还将原始日期保存为低于s的字符串格式,因为它在格式化时非常有用,例如工具提示.

如果您不想显示日期,可以将轴设置为"linear",如下例所示,唯一棘手的部分是设置工具提示标题的格式.可以应用相同的技术来格式化轴标签,但您也可以 Select 将x轴的类型声明为"time"并使用adapter,如chartjs-adapter-date-fns.

function parseDateIndexed(data){
    return Object.entries(data).
    map(([s, f])=>({x: Date.parse(s), y: f, s})).
    sort(({x:t1},{x:t2})=>t1-t2);
}

let startGraph = function() {
    let canvas = document.getElementById('chart');
    let chart = new Chart(canvas.getContext('2d'), {
        type: 'line',
        data: {
            datasets: [{
                label: 'Revenue',
                data: parseDateIndexed({
                    "2023-03-01": 250,
                    "2023-03-02": 488,
                    "2023-03-03": 358,
                    "2023-03-04": 255,
                    "2023-03-05": 895
                }),
                borderColor: '#ff6384',
                xAxisID: 'x',
            },
                {
                    label: 'Profit',
                    data: parseDateIndexed({
                        "2023-03-01": 125,
                        "2023-03-02": 156,
                        "2023-03-03": 195,
                        "2023-03-04": 98,
                        "2023-03-05": 466
                    }),
                    borderColor: '#36a2eb',
                    xAxisID: 'x',
                },
                {
                    label: 'Past Revenue',
                    data: parseDateIndexed({
                        "2023-02-24": 280,
                        "2023-02-25": 456,
                        "2023-02-26": 665,
                        "2023-02-27": 288,
                        "2023-02-28": 499
                    }),
                    borderColor: '#fa829b',
                    xAxisID: 'x1',
                },
                {
                    label: 'Past Profit',
                    data: parseDateIndexed({
                        "2023-02-24": 125,
                        "2023-02-25": 198,
                        "2023-02-26": 265,
                        "2023-02-27": 101,
                        "2023-02-28": 221
                    }),
                    borderColor: '#76c1f5',
                    xAxisID: 'x1',
                }
            ]
        },
        options: {
            elements: {
                point: {
                    radius: 0,
                    hoverRadius: 0,
                    hitRadius: 3,
                },
                line: {
                    borderWidth: 2,
                },
            },
            responsive: true,
            maintainAspectRatio: false,
            interaction: {
                intersect: false,
                mode: 'index',
            },
            stacked: false,
            scales: {
                y: {
                    ticks: {
                        display: true,
                        beginAtZero: true,
                    }
                },
                x: {
                    type:"linear",
                    position: 'bottom',
                    ticks: {
                        display: false,
                    },
                },
                x1: {
                    type:"linear",
                    position: 'top',
                    ticks: {
                        display: false,
                    },
                    grid: {
                        drawOnChartArea: false,
                    },
                },
            },
            plugins: {
                tooltip:{
                    callbacks:{
                        title(items){
                            const dates = items.map(o=>o.raw.s);
                            const d1 = dates[0], d2 = dates[dates.length-1];
                            const ad = (d1 === d2) ? d1 : [d1, d2];
                            return ad.join(' / ')
                        }
                    }
                },
                legend: {
                    display: true,
                    position: 'bottom',
                    labels: {
                        boxWidth: 8,
                        boxHeight: 8,
                        useBorderRadius: true,
                        borderRadius: 3,
                        usePointStyle: false,
                        pointStyleWidth: 0,
                        padding: 7,
                        font: {
                            size: 11
                        }
                    }
                },
            },
        }
    });
}

document.addEventListener("DOMContentLoaded", function() {
    startGraph();
});
<canvas id="chart"></canvas>

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.1.2/chart.umd.js"
        integrity="sha512-t41WshQCxr9T3SWH3DBZoDnAT9gfVLtQS+NKO60fdAwScoB37rXtdxT/oKe986G0BFnP4mtGzXxuYpHrMoMJLA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

Javascript相关问答推荐

用户单击仅在JavaScript中传递一次以及其他行为

根据总价格对航班优惠数组进行排序并检索前五个结果- Angular HTTP请求

. NET中Unix时间转换为日期时间的奇怪行为

判断表格单元格中是否存在文本框

如何从隐藏/显示中删除其中一个点击?

获取Uint8ClampedArray中像素数组的宽度/高度

在运行时使用Next JS App Router在服务器组件中运行自定义函数

检索相加到点的子项

为什么JPG图像不能在VITE中导入以进行react ?

使用NextJS+MongoDB+Prisma ORM获取无效请求正文,无法发布错误

使用类型:assets资源 /资源&时,webpack的配置对象&无效

匹配一个或多个可选重复的特定模式

无法检索与Puppeteer的蒸汽游戏的Bundle 包价格

postman 预请求中的hmac/sha256内标识-从js示例转换

使用API调用的VUE 3键盘输入同步问题

select 2-删除js插入的项目将其保留为选项

如何使用Reaction路由导航测试挂钩?

在没有任何悬停或其他触发的情况下连续交换图像

如何在Highlihte.js代码区旁边添加行号?

在此div中添加一个类,并在一段时间后在Java脚本中将其删除