Chart.js - 多个 JSON 数据对象数组 [{x: Date, y: count}....] 表示图表的每个数据集

Chart.js - Multiple JSON data object array [{x: Date, y: count}....] representing each dataset of the chart

我一直在尝试实现一个 Stacked Area Line Chart using Chart.js,它又使用多个数据集作为每个折线图的输入。

虽然我能够查看带有关联数据集的最终堆叠图,但我可以清楚地注意到 y 轴数据被错误地表示(悬停在数据点上) w.r.t 每个数据集的x轴,这是一个主要问题。

主要问题是:

  1. 第二个数据集图表的 x 轴和 y 轴映射问题
  2. x 轴值(日期)重复且无序 - 导致图表突然显示

为了更清楚,我需要 dataset1[ {x: "2030*08-03", y: 8},{}...] 来精确映射键x 和 y 分别对应于 chart1 的 x 轴和 y 轴,类似地,dataset2[ {x: "2030*08-10", y: 8},{}...]分别映射到第二张图表,依此类推。

这是复制问题的示例 codepen 实施。

此外,我添加了完整的代码片段以便清楚地理解。

var ctx = document.getElementById("myChart").getContext("2d");

const colors = {
      green: {
        fill: 'rgb(0,128,0,0.2)',
        stroke: 'green',
      },
      grey: {
        fill: 'rgb(128,128,128, 0.2)',
          stroke: 'grey',
      },
      red: {
        fill: 'rgba(255, 0, 0, 0.2)',
        stroke: 'red',
      }
};

const data1 = [
        {x: "2030*08-03", y: 8},
        {x: "2030-08-04", y: 1},
        {x: "2030-08-08", y: 2},
        {x: "2030-08-09", y: 10},
        {x: "2030-08-10", y: 2},
        {x: "2030-08-12", y: 34} ];
const data2 = [
        {x: "2030-08-09", y: 1},
        {x: "2030-08-12", y: 12},
        {x: "2030-08-13", y: 3},
        {x: "2030-08-15", y: 3}
];
const data3 = [
        {x: "2030-08-06", y: 1},
        {x: "2030-08-09", y: 12},
        {x: "2030-08-10", y: 3},
        {x: "2030-08-12", y: 3} , ];


const myChart = new Chart(ctx, {
  type: 'line',
  data: {
    datasets: [
      {
        label: "Data1",
        fill: true,
        backgroundColor: colors.green.fill,
        pointBackgroundColor: colors.green.stroke,
        borderColor: colors.green.stroke,
        pointHighlightStroke: colors.green.stroke,
        borderCapStyle: 'butt',
        data: data1,
      },
      {
        label: "Data2",
        fill: true,
        backgroundColor: colors.grey.fill,
        pointBackgroundColor: colors.grey.stroke,
        borderColor: colors.grey.stroke,
        pointHighlightStroke: colors.grey.stroke,
        data: data2,
      },
      {
        label: "Data3",
        fill: true,
        backgroundColor: colors.red.fill,
        pointBackgroundColor: colors.red.stroke,
        borderColor: colors.red.stroke,
        pointHighlightStroke: colors.red.stroke,
        data: data3,
       }
    ]
  },
  options: {
    plugins: {
      responsive: true,
      legend: {
        display: true,
        position: 'bottom',
      },
      title: {
        display: true,
        text: 'Status',
        padding: {
          top: 20,
          bottom: 15
        },
        font: {
          weight: "bold",
          size: 25
        }
      }
    },
    layout: {
      padding: {
        left: 20,
        right: 0,
        top: 0,
        bottom: 25
      }
    },
    scales: {
      x: {
        ticks: {
          align: "center"
        }
      },
      y: {
        stacked: true,
        title: {
          display: true,
          text: "Count",
          font: {
            weight: "bold",
            size: 20
          }
        }
      },
    },
    parsing: {
      xAxisKey: 'x',
      yAxisKey: 'y'
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.0/chart.min.js"></script>
<canvas id="myChart" width="400" height="200"></canvas>

任何帮助将不胜感激。提前致谢。

发生此行为是因为 chart.js 自动添加标签(如果标签不存在且不关心顺序),您有两种修复方法,即提供一个标签数组,其中所有标签的顺序已经正确:

var ctx = document.getElementById("myChart").getContext("2d");

const colors = {
  green: {
    fill: 'rgb(0,128,0,0.2)',
    stroke: 'green',
  },
  grey: {
    fill: 'rgb(128,128,128, 0.2)',
    stroke: 'grey',
  },
  red: {
    fill: 'rgba(255, 0, 0, 0.2)',
    stroke: 'red',
  }
};

const data1 = [{
    x: "2030-08-03",
    y: 8
  },
  {
    x: "2030-08-04",
    y: 1
  },
  {
    x: "2030-08-08",
    y: 2
  },
  {
    x: "2030-08-09",
    y: 10
  },
  {
    x: "2030-08-10",
    y: 2
  },
  {
    x: "2030-08-12",
    y: 34
  }
];
const data2 = [{
    x: "2030-08-09",
    y: 1
  },
  {
    x: "2030-08-12",
    y: 12
  },
  {
    x: "2030-08-13",
    y: 3
  },
  {
    x: "2030-08-15",
    y: 3
  }
];
const data3 = [{
    x: "2030-08-06",
    y: 1
  },
  {
    x: "2030-08-09",
    y: 12
  },
  {
    x: "2030-08-10",
    y: 3
  },
  {
    x: "2030-08-12",
    y: 3
  },
];


const myChart = new Chart(ctx, {
  type: 'line',
  data: {
    labels: ["2030-08-03", "2030-08-04", "2030-08-06", "2030-08-08", "2030-08-09", "2030-08-10", "2030-08-12", "2030-08-13", "2030-08-15"],
    datasets: [{
        label: "Data1",
        fill: true,
        backgroundColor: colors.green.fill,
        pointBackgroundColor: colors.green.stroke,
        borderColor: colors.green.stroke,
        pointHighlightStroke: colors.green.stroke,
        borderCapStyle: 'butt',
        data: data1,
      },
      {
        label: "Data2",
        fill: true,
        backgroundColor: colors.grey.fill,
        pointBackgroundColor: colors.grey.stroke,
        borderColor: colors.grey.stroke,
        pointHighlightStroke: colors.grey.stroke,
        data: data2,
      },
      {
        label: "Data3",
        fill: true,
        backgroundColor: colors.red.fill,
        pointBackgroundColor: colors.red.stroke,
        borderColor: colors.red.stroke,
        pointHighlightStroke: colors.red.stroke,
        data: data3,
      }
    ]
  },
  options: {
    plugins: {
      responsive: true,
      legend: {
        display: true,
        position: 'bottom',
      },
      title: {
        display: true,
        text: 'Status',
        padding: {
          top: 20,
          bottom: 15
        },
        font: {
          weight: "bold",
          size: 25
        }
      }
    },
    layout: {
      padding: {
        left: 20,
        right: 0,
        top: 0,
        bottom: 25
      }
    },
    scales: {
      x: {
        ticks: {
          align: "center"
        }
      },
      y: {
        stacked: true,
        title: {
          display: true,
          text: "Count",
          font: {
            weight: "bold",
            size: 20
          }
        }
      },
    },
    parsing: {
      xAxisKey: 'x',
      yAxisKey: 'y'
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.0/chart.min.js"></script>
<canvas id="myChart" width="400" height="100"></canvas>

代码笔:https://codepen.io/leelenaleee/pen/gOWNXKm?editors=1010

或者你可以使用时间轴:

var ctx = document.getElementById("myChart").getContext("2d");

const colors = {
  green: {
    fill: 'rgb(0,128,0,0.2)',
    stroke: 'green',
  },
  grey: {
    fill: 'rgb(128,128,128, 0.2)',
    stroke: 'grey',
  },
  red: {
    fill: 'rgba(255, 0, 0, 0.2)',
    stroke: 'red',
  }
};

const data1 = [{
    x: "2030-08-03",
    y: 8
  },
  {
    x: "2030-08-04",
    y: 1
  },
  {
    x: "2030-08-08",
    y: 2
  },
  {
    x: "2030-08-09",
    y: 10
  },
  {
    x: "2030-08-10",
    y: 2
  },
  {
    x: "2030-08-12",
    y: 34
  }
];
const data2 = [{
    x: "2030-08-09",
    y: 1
  },
  {
    x: "2030-08-12",
    y: 12
  },
  {
    x: "2030-08-13",
    y: 3
  },
  {
    x: "2030-08-15",
    y: 3
  }
];
const data3 = [{
    x: "2030-08-06",
    y: 1
  },
  {
    x: "2030-08-09",
    y: 12
  },
  {
    x: "2030-08-10",
    y: 3
  },
  {
    x: "2030-08-12",
    y: 3
  },
];


const myChart = new Chart(ctx, {
  type: 'line',
  data: {
    datasets: [{
        label: "Data1",
        fill: true,
        backgroundColor: colors.green.fill,
        pointBackgroundColor: colors.green.stroke,
        borderColor: colors.green.stroke,
        pointHighlightStroke: colors.green.stroke,
        borderCapStyle: 'butt',
        data: data1,
      },
      {
        label: "Data2",
        fill: true,
        backgroundColor: colors.grey.fill,
        pointBackgroundColor: colors.grey.stroke,
        borderColor: colors.grey.stroke,
        pointHighlightStroke: colors.grey.stroke,
        data: data2,
      },
      {
        label: "Data3",
        fill: true,
        backgroundColor: colors.red.fill,
        pointBackgroundColor: colors.red.stroke,
        borderColor: colors.red.stroke,
        pointHighlightStroke: colors.red.stroke,
        data: data3,
      }
    ]
  },
  options: {
    plugins: {
      responsive: true,
      legend: {
        display: true,
        position: 'bottom',
      },
      title: {
        display: true,
        text: 'Status',
        padding: {
          top: 20,
          bottom: 15
        },
        font: {
          weight: "bold",
          size: 25
        }
      }
    },
    layout: {
      padding: {
        left: 20,
        right: 0,
        top: 0,
        bottom: 25
      }
    },
    scales: {
      x: {
        type: 'time',
        ticks: {
          align: "center"
        }
      },
      y: {
        stacked: true,
        title: {
          display: true,
          text: "Count",
          font: {
            weight: "bold",
            size: 20
          }
        }
      },
    },
    parsing: {
      xAxisKey: 'x',
      yAxisKey: 'y'
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.0/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.bundle.min.js"></script>
<canvas id="myChart" width="400" height="100"></canvas>

代码笔:https://codepen.io/leelenaleee/pen/GRmbOxN?editors=1010