【问题标题】:How can I display fixed labels on X-axis while having data on that axis?如何在 X 轴上显示固定标签,同时在该轴上有数据?
【发布时间】:2018-10-18 12:06:57
【问题描述】:

我刚开始使用 Chart.js,但遇到了问题。

首先,我需要在我的简单折线图中显示的是这样的:

这是我目前的图表,在Y-axis 我有可能的成绩(学生考试),范围从1 to 6

X-axis 上,我有可能在给定考试中获得的分数。

现在变得更复杂了,此图表正在根据下拉菜单的输入和选择进行更新。

等级(Y 轴)可以有 5 种增量类型:Integer, Halves, Quarters, Decimal and Hundredths

这是通过下拉菜单选择的,默认值为Quarters,这意味着Quarters 选择了我的成绩数组,如下所示:

grades = [1, 1.25, 1.50, 1.75, 2....., 5.75, 6]

同时选择Hundredths,它看起来像:

grades = [1, 1.01, 1.02, 1.03, .... 5.97, 5.98, 5.99, 6]

并且对于每个等级,需要一定数量的点(X 轴)来实现它。 需要的点是用我放在函数中的公式计算的:

mySecretFormula(grades: Array<Number>) {
    grades.forEach(g => {
    const currentPoints = g * mySecretFormula;

    this.points.push(currentPoints);
}

所以基本上我在这个函数中传递了我的成绩,它返回另一个具有相同数量元素的数字数组(因为每个成绩对应一个分数)

例如,如果我选择了整数成绩,这意味着我的成绩数组如下所示:

grades = [1, 2, 3, 4, 5, 6]

我的分数得到的回报是:

scores = [0, 5, 10, 15, 25, 30] 

如果最大分数设置为 30(最大分数在输入中定义)

最后我使用chart.js 来显示我的数据,如下所示:

this.canvas.data.labels = this.points;
this.canvas.data.datasets[0].data = this.grades;
this.canvas.update();

所以每次我更改有关成绩增量的下拉菜单时,都会触发此函数并更新图表。

假设它正在工作,但远非最佳。

我想要实现的很简单。

应该是这样的:

这是我选择整数成绩时图表的样子,所以只有 6 个不同的成绩和 6 个不同的分数。

我希望图表始终看起来像这样,无论选择什么增量, 所以总是有 5 或 6 条网格线,并且 X 轴的刻度点总是相同。

如果当前选择的增量是整数,我将只有 6 个交点,但如果我要切换到小数或百分之一,所以有很多交点,图表看起来就像这样,但是当你将鼠标悬停在用鼠标划线,我会得到每个有效交叉点的工具提示。

现在,如果我换成小数增量,我的图表会更新为:

(忽略四舍五入,忘记四舍五入到小数点后两位) 因此,当您看到刻度点发生变化时,网格宽度会发生变化,整个图表的高度也会发生变化。

但是交叉点可以正常工作,如果我将鼠标悬停在线上,我会得到这些对的每个点的工具提示:

十进制增量等于:

等级 = [1, 1.1, 1.2, 1.3, 1.4, .... 5.9, 6] 点 = [0, 0.7, 1.4, 2.1, 2.8, .... 34.3, 35]

所以要达到同样的结果,但图表总是相同的,总是相同的刻度点和高度和宽度,因为等级和分数的范围总是相同的,但取决于增量选择时,可能有至少 6 个交叉点(整数)到 500 多个交叉点(百分之一)!

希望我说清楚了,非常感谢

编辑:在您的帮助下管理在 2 行上添加自定义工具提示:

afterBody: function([tooltipItem], data): any {
                            const multistringText = ["Points: " + tooltipItem.xLabel];
                            multistringText.push("Grade: " + tooltipItem.yLabel);

                            return multistringText;
                        }

完美运行,但我现在如何删除它上面的原始工具提示字符串?看图片,在我的 2 行自定义工具提示上方,我还有另一行要隐藏!

最后,一直看着这张图片,我怎样才能使 X 轴上的网格线宽度相同?如您所见,前 4 个比最后一个大!我希望它们始终保持相同的宽度!谢谢你

【问题讨论】:

  • 你不能为轴设置ticks options(比如最小值、最大值、精度/步长)吗?
  • 我试过这个:'scales: { xAxes: [ { ticks: { stepSize: 5 },' 但它不会做任何事情,tick 总是一样的!我希望刻度与范围始终相同(例如 0-30)
  • 因此,与其接受我对您推荐 chart.js 的 ng2-charts 问题的回答,不如删除该问题,开始使用 chart.js,然后再问一个关于 chart.js 的问题?
  • 嘿!我问了同样的问题,因为我看到 ng2-charts 不起作用,所以我删除了它,以免留下无用的问题!如果那是你的感受,我不是故意惹恼你的!对不起!
  • 不生气,只是澄清了您开始使用推荐技术的逻辑,但在不接受答案的情况下删除了问题。

标签: javascript angular charts chart.js angular6


【解决方案1】:

我建议将您的图表转换为 xy 图表,设置轴选项并自定义工具提示

var ctx = document.getElementById("myChart").getContext('2d');
var precision = 0;
var data = getData();

var myChart = new Chart(ctx, {
  type:"scatter",
    data: {
        datasets: [{
            label: 'grades',
            data: data,
            fill: false,
            pointRadius: 0,
            pointHitRadius: 3
        }]
    },
    options: {
        scales: {
            yAxes: [{
                ticks: {
                    beginAtZero:true,
                    max:6
                }
            }],
            xAxes: [{
                ticks: {
                    beginAtZero:true,
                    max:35,
                    stepSize: 1,
                    callback: function(value){
                      if (value < 5){
                        return value;
                      } else {
                        if (value% 5 === 0){
                          return value;
                        }
                      }
                    }
                }
            }]
        },
        tooltips: {
            callbacks: {
                label: function(tooltipItem, data) {
                    var label = [
                    'X: ' + tooltipItem.xLabel.toFixed(precision),
                    'Y: ' + tooltipItem.yLabel.toFixed(precision)
                    ];
                    return label;
                }
            }
        }
    }
});

function getData(){
  var step = 10**-precision;
  var arr = [];
  for (var i=0; i<=6; i+=step){
    arr.push({y: i, x: 35*i/6})
  }
  return arr;
}

setTimeout(function(){
    precision = 1;
    myChart.data.datasets[0].data = getData();
    myChart.update();

}, 2000)
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.js"></script>
<canvas id="myChart" width="100" height="100"></canvas>

【讨论】:

  • 非常感谢您的回答!我有一些疑问!首先,使用您的代码,当我将其粘贴到我的控制器中时,输出是图表,但线是不可见的!我可以用鼠标悬停并获取工具提示,但该行不显示!如果我将 pointRadius 更改为 1,我会得到一条虚线,否则什么也没有!那么,我怎样才能在两行上显示带有 x: value, y: value 的工具提示?我尝试附加 + "" 但不起作用!而且我还必须删除您的 toFixed() 部分,因为 yLabel 和 xLabel 对我来说是字符串!不允许我在下一条评论中使用 toFixed!2nd 部分
  • 所以现在要实现我的数据,我只需要将对象数组 {x: foo, y: bar} 传递给数据集,我猜它应该可以工作,要做一些测试,但我知道我必须能够将数据放在 X 轴上,只是不知道怎么做!最后一件事,将在输入上设置最大点数,我可以以某种方式为 X 轴上的刻度标签设置一个条件以根据最大点数显示不同的刻度吗?例如:
  • 如果最大点数 >50,每 5 个网格线(刻度线),然后 100 200,每 20 个网格线,对于每 40 条 200 多条和 >500 条网格线
  • 你用的是什么版本的chartjs?这是propertiesborderColor 和/或borderWidth 的列表应该让它可见
  • 对于自定义刻度,您可能需要this - 创建回调,如果刻度应隐藏返回nullundefined
猜你喜欢
  • 1970-01-01
  • 2021-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-20
  • 2019-07-28
相关资源
最近更新 更多