如何让折线图中连续的两个点属于同一类别?

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

我正在尝试创建一个折线图,在 Chartjs 的一个类别中最多可以有两个点。在“示例”中,标签和数据均作为数组传递,因此每个标签只能有一个点。我最多想要两点。 我尝试在数据中添加额外的条目,但额外的条目没有执行任何操作。

data: { datasets: [{ data: [10, 20, 30, 40, 50, 60, 70] // Only the first 6 entries are shown. }], labels: ['January', 'February', 'March', 'April', 'May', 'June'] },

	
chart.js react-chartjs-2
1个回答
0
投票
data

应该是一个数据点数组,而

labels
数组应该为这些数据点提供 x 轴值(如果 x 轴的类型为
category
), 这是
line
类型图表的默认设置。
假设我们的 

data

看起来像这样:

const data = {
    datasets: [{
        data: [10, 20, 30, 40, 50, 60, 70, 80]
    }],
    labels: ['January', 'February', 'February', 'March', 'April', 'May', 'June', 'June'],
};

通过它,我们定义了这样一个事实:两个类别,一个用于 
February

的一个类别和一个用于

June
的类别有两个点,而其他类别有一个点;如果想避免容易出现拼写错误的文本重复,则可以使用其他可能的约定。
为了更好地控制 x 轴的点位置和标签,您可以使用(可能隐藏的)线性轴,并在数据集中设置相关的 

x

data
有两种可能:

第一种

,如果希望类别大小相同,那么有两个点的类别中的点会靠得更近。 在这种情况下,可以使用辅助隐藏线性 x 轴来定位点,同时显示带有不重复标签的统一类别 x 轴:

const data = { datasets: [{ data: [10, 20, 30, 40, 50, 60, 70, 80] }], labels: ['January', 'February', 'February', 'March', 'April', 'May', 'June', 'June'], }; let xi = 0; data.datasets.forEach(dataset => { dataset.data = dataset.data.map((y, i) => { let x = xi + 0.5; if(data.labels[i] === data.labels[i-1]){ x += 1/6; } else if(data.labels[i] === data.labels[i+1]){ x -= 1/6; xi -= 1; } xi += 1; return ({x, y}); }) }); const options = { maintainAspectRatio: false, plugins: { tooltip:{ callbacks: { title: ([{dataIndex}]) => data.labels[dataIndex] } }, legend: { display: false, } }, scales: { x: { display: false, type: 'linear', }, x2:{ type: 'category', offset: true, labels: [... new Set(data.labels)], grid: { color: 'rgba(0,0,0,0.4)', offset: true } }, y: { beginAtZero: true, }, }, }; new Chart('myChart', {type: 'line', options, data});
<canvas style="height: 160px" id="myChart"></canvas>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

第二种情况

,如果你想保持点等距并具有可变宽度的类别,这样具有两个点的类别将是一个点的两倍大小。

在这种情况下,我们应该只保留线性 x 轴可见,但修改其标签以对应于原始 data.labels

。第二个类似的线性 x 轴可能是显示分隔类别的网格线的解决方案:

const data = { datasets: [{ data: [10, 20, 30, 40, 50, 60, 70, 80] }], labels: ['January', 'February', 'February', 'March', 'April', 'May', 'June', 'June'], }; data.datasets.forEach(dataset => { dataset.data = dataset.data.map((y, i) => ({x: i+0.5, y})); }); const options = { maintainAspectRatio: false, plugins: { tooltip:{ callbacks: { title: ([{dataIndex}]) => data.labels[dataIndex] } }, legend: { display: false, } }, scales: { x: { type: 'linear', min: 0, max: data.labels.length, ticks: { stepSize: 0.5, callback: (value) => { const idx = Math.floor(value), label = data.labels[idx]; if(Math.abs(Math.round(value) - value) < 1e-6){ if(label === data.labels[idx - 1]){ return label; } else{ return null; } } else{ if(label === data.labels[idx - 1] || label === data.labels[idx + 1]){ return null; } return label; } } } }, x2:{ type: "linear", min: 0, max: data.labels.length, ticks: { display: false, stepSize: 0.5, callback(value, ...args){ if(value === this.max || value === this.min){ return ''; } if(Math.abs(Math.round(value) - value) < 1e-6){ const idx = Math.floor(value), label = data.labels[idx]; if(label === data.labels[idx - 1]){ return null; } else{ return ''; } } else{ return null; } } }, grid: { color: 'rgba(0,0,0,0.4)', drawTicks: false //offset: true } }, y: { beginAtZero: true, //display: false, }, }, }; new Chart('myChart', {type: 'line', options, data});
<canvas style="height: 160px" id="myChart"></canvas> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.