图表Js线定位

问题描述 投票:0回答:1

下面是图表代码。条已分组,但线条定位不正确。

new Chart(ctx, {
    grouped: true,
    data: {
      labels: this.shortenMonths,
      datasets: [
        {
          label: 'age',
          data: ageArray,
          backgroundColor: gradient,

          borderWidth: 2,
          pointRadius: 0,
          tension: 0,
          fill: true,
          type: "line",
          order: 2,
        },
        {
          label: 'users',
          data: arrayOfUsers,
          backgroundColor: "#fc9a00",
          order: 0,
          type: "bar",
        },
        {
          label: 'more users',
          data: moreUsers,
          backgroundColor: "#4fa1ee",
          order: 1,
          type: "bar",
        },
      ],
    },

图表选项

 options: {
    clip: false,
    responsive: true,
    interaction: {
      intersect: false,
      mode: "index",
    },
    maintainAspectRatio: false,
    scales: {
      x: {
        grid: {
          display: false,
          drawTicks: false,
        },
        border: {
          display: false,
          dash: [2, 4],
        },
        ticks: {
          padding: 1,
          beginAtZero: true,
          min: 0,
        },
        offset: true,
      },
      y: {
        offset: false,

        border: {
          display: false,
          dash: [2, 4],
        },
        grid: {
          drawTicks: false,
          color: "#eaecef",
          lineWidth: 2,
        },
        ticks: {
          padding: 1,
          stepSize: 250,
          beginAtZero: true,
          min: 0,
        },
      },
    },
    plugins: {
      legend: {
        position: "bottom",
        labels: {
          usePointStyle: true,
          padding: 24,
        },
      },
    },
  },

绿线没有向任何一侧延伸。 我希望绿线从橙色条之前和蓝色条之后开始。

我尝试添加一个可以定位 x 轴的插件,但没有成功。 任何帮助都会很棒!

javascript chart.js
1个回答
0
投票

这些点的位置与折线图中一样,因为折线图的points数量等于条形图的intervals数量,因此每个点应放置在间隔的中心,这意味着第一个和最后一个间隔为半间隔。

如果您想扩展折线图以覆盖整个x空间,有简单的技术解决方案。例如,为直线添加辅助 x 轴。

但是,仍然存在根本问题:如果有

N
个月的数据,则有
N
条形对 - 即
N
间隔,而数组包含
N
(这意味着
 N
-1 间隔)。因此,您必须从(至少)两个不完美的解决方案中进行选择来覆盖缺失的区间:

  1. 仅移动第一个和最后一个点,每个点移动一半间隔以覆盖缺失的间隔或
  2. 按比例移动所有点,这意味着没有点离其正确位置很远,但大多数点都稍微偏离中心。

在下面的实现中,有两种情况,突出显示的点以便人们可以看到每种情况下发生的情况。区别仅在于为该行生成

data
数组的行。

第一个变体:

const ageArray = Array.from({length: 12}, (_, i)=>20+(i+1)/100), // + (i+1)/100 to make sure which point gets in which month
    arrayOfUsers = Array.from({length: 12}, ()=>Math.ceil(7+8*Math.random())),
    moreUsers = Array.from({length: 12}, ()=>Math.ceil(5+10*Math.random()));

new Chart('chart1', {
    grouped: true,
    data: {
        labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
        datasets: [
            {
                label: 'age',
                data: ageArray.map((age, i) => ({x: i===0 ? i : i === ageArray.length-1 ? i+1 : i+0.5, y: age})),
                xAxisID: 'x1',
                backgroundColor: 'rgba(33, 221, 33, 0.3)',

                borderWidth: 2,
                pointRadius: 0,
                tension: 0,
                fill: true,
                pointRadius: 4,
                type: "line",
                order: 2,
            },
            {
                label: 'users',
                data: arrayOfUsers,
                backgroundColor: "#fc9a00",
                order: 0,
                type: "bar",
            },
            {
                label: 'more users',
                data: moreUsers,
                backgroundColor: "#4fa1ee",
                order: 1,
                type: "bar",
            },
        ],
    },

    options: {
        clip: false,
        responsive: true,
        interaction: {
            intersect: false,
            mode: "index",
        },
        maintainAspectRatio: false,
        scales: {
            x: {
                grid: {
                    display: false,
                    drawTicks: false,
                },
                border: {
                    display: false,
                    dash: [2, 4],
                },
                ticks: {
                    padding: 1,
                    beginAtZero: true,
                    min: 0,
                },
                offset: true,
            },
            x1: {
                type: 'linear',
                display: false
            },
            y: {
                offset: false,

                border: {
                    display: false,
                    dash: [2, 4],
                },
                grid: {
                    drawTicks: false,
                    color: "#eaecef",
                    lineWidth: 2,
                },
                ticks: {
                    padding: 1,
                    stepSize: 250,
                    beginAtZero: true,
                    min: 0,
                },
            },
        },
        plugins: {
            legend: {
                position: "bottom",
                labels: {
                    usePointStyle: true,
                    padding: 24,
                },
            },
        },
    },
});
<div style="height:500px">
    <canvas id="chart1"></canvas>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.3.0/chart.umd.js" integrity="sha512-CMF3tQtjOoOJoOKlsS7/2loJlkyctwzSoDK/S40iAB+MqWSaf50uObGQSk5Ny/gfRhRCjNLvoxuCvdnERU4WGg=="  crossOrigin="anonymous" referrerpolicy="no-referrer"></script>

第二个:

const ageArray = Array.from({length: 12}, (_, i)=>20+(i+1)/100), // + (i+1)/100 to make sure which point gets in which month
    arrayOfUsers = Array.from({length: 12}, ()=>Math.ceil(7+8*Math.random())),
    moreUsers = Array.from({length: 12}, ()=>Math.ceil(5+10*Math.random()));

new Chart('chart1', {
    grouped: true,
    data: {
        labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
        datasets: [
            {
                label: 'age',
                data: ageArray.map((age, i) => ({x: i * ageArray.length/(ageArray.length-1) , y: age})),
                xAxisID: 'x1',
                backgroundColor: 'rgba(33, 221, 33, 0.3)',

                borderWidth: 2,
                pointRadius: 0,
                tension: 0,
                fill: true,
                pointRadius: 4,
                type: "line",
                order: 2,
            },
            {
                label: 'users',
                data: arrayOfUsers,
                backgroundColor: "#fc9a00",
                order: 0,
                type: "bar",
            },
            {
                label: 'more users',
                data: moreUsers,
                backgroundColor: "#4fa1ee",
                order: 1,
                type: "bar",
            },
        ],
    },

    options: {
        clip: false,
        responsive: true,
        interaction: {
            intersect: false,
            mode: "index",
        },
        maintainAspectRatio: false,
        scales: {
            x: {
                grid: {
                    display: false,
                    drawTicks: false,
                },
                border: {
                    display: false,
                    dash: [2, 4],
                },
                ticks: {
                    padding: 1,
                    beginAtZero: true,
                    min: 0,
                },
                offset: true,
            },
            x1: {
                type: 'linear',
                display: false
            },
            y: {
                offset: false,

                border: {
                    display: false,
                    dash: [2, 4],
                },
                grid: {
                    drawTicks: false,
                    color: "#eaecef",
                    lineWidth: 2,
                },
                ticks: {
                    padding: 1,
                    stepSize: 250,
                    beginAtZero: true,
                    min: 0,
                },
            },
        },
        plugins: {
            legend: {
                position: "bottom",
                labels: {
                    usePointStyle: true,
                    padding: 24,
                },
            },
        },
    },
});
<div style="height:500px">
    <canvas id="chart1"></canvas>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.3.0/chart.umd.js"
        integrity="sha512-CMF3tQtjOoOJoOKlsS7/2loJlkyctwzSoDK/S40iAB+MqWSaf50uObGQSk5Ny/gfRhRCjNLvoxuCvdnERU4WGg=="
        crossOrigin="anonymous" referrerpolicy="no-referrer"></script>

© www.soinside.com 2019 - 2024. All rights reserved.