ChartJS 图表Js线定位

6yoyoihd  于 2023-10-18  发布在  Chart.js
关注(0)|答案(1)|浏览(196)

下面是一个图形的代码。条形图已成组,但线条条未正确定位。

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轴,但没有运气。任何帮助将是伟大的!

pvabu6sv

pvabu6sv1#

**编辑:**我想到了一个更简单的解决方案,它与下面的解决方案2具有相同的效果,但不需要重新Mapdata。它只是声明了第二个类别轴,并让chart.js重新分配空间。由于它的简单性,我把它作为最受欢迎的解决方案,但下面关于间隔重新分配的讨论不应被忽视。

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,
                xAxisID: 'x1',
                backgroundColor: 'rgba(33, 221, 33, 0.3)',

                borderWidth: 2,
                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: {
                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>

原文

这些点被很好地放置在线图中,因为线图的 * 点 * 的数量等于条形图的 * 间隔 * 的数量,所以每个点都应该放置在间隔的中心,这意味着第一个和最后一个是半间隔。
如果你想扩展线图以覆盖整个x空间,有一些简单的技术解决方案。例如,为直线添加辅助x轴。
然而,仍然存在根本问题:如果有N个月的数据,你有N条对-即N * 间隔 *,而数组包含N * 点 *(这意味着N-1间隔)。所以你必须从(至少)两个不完美的解中选择一个来覆盖缺失的区间:
1.仅移动第一个点和最后一个点,每个点移动半个间隔以覆盖缺失的间隔,或者
1.按比例移动所有点,这意味着没有点离其正确位置很远,但大多数点都稍微偏离中心。
在下面的实现中,有两种情况,突出显示了点,以便可以看到每种情况下发生的情况。区别仅在于为该行生成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,
                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,
                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>

相关问题