【问题标题】:How to change line color based on data - chartist or chart.js如何根据数据更改线条颜色 - chartist 或 chart.js
【发布时间】:2020-02-17 00:27:08
【问题描述】:

一直在用chartist 或chart.js 寻找解决方案,但一直空着。我正在寻找一种方法来创建折线图并根据数据更改线的颜色。

示例数据集:

[
    {time: '3:00:00', speed: 20, direction: 345},
    {time: '3:01:00', speed: 0, direction: 0},
    {time: '3:02:00', speed: 25, direction: 90},
    {time: '3:03:00', speed: 10, direction: 180},
    {time: '3:04:00', speed: 5, direction: 0}
]

我正在寻找时间为x轴,速度为y轴,然后根据方向改变线段的颜色。似乎大多数图表库(除非我开始深入研究 d3)在创建折线图时会为整个系列创建一条大线,并且不允许您为线的各个部分设置样式。这里有一个很棒的 chartjs 示例,但是颜色不是基于数据(它只是一组任意颜色):

https://blog.vanila.io/chart-js-tutorial-how-to-make-gradient-line-chart-af145e5c92f9

【问题讨论】:

  • 提供一些代码
  • 看看这篇文章。它可能对你有用。看来您可能需要更改划线脚本中的编程,但是帖子中有一些有用的信息。 github.com/chartjs/Chart.js/issues/3071
  • 看到了一些类似的解决方案,但他们更关注“阈值”——比如上/下。如果结束了,假设为 0,则填充一种颜色;如果它在下面,则它充满了另一个。我需要做的是根据多个不同的值在那条线上有多种颜色。例如,在显示速度的行上显示“方向”(可能有大约 16 种不同的颜色值)。

标签: javascript chart.js chartist.js


【解决方案1】:

您可以创建一个scatter 图表并使用Plugin Core API 直接在画布上绘制线条。 API 提供了一系列可用于执行自定义代码的钩子。

在下面的代码 sn-p 中,我使用 afterDraw 钩子在数据点之间绘制连接线。它们的颜色取决于起始数据点的direction 属性。

const rawData = [
    {time: '3:00:00', speed: 20, direction: 345},
    {time: '3:01:00', speed: 0, direction: 0},
    {time: '3:02:00', speed: 25, direction: 290},
    {time: '3:03:00', speed: 10, direction: 180},
    {time: '3:04:00', speed: 5, direction: 0}
];
const data = rawData.map(o => ({ x: moment(o.time, 'H:mm:ss').toDate().getTime(), y: o.speed}));
const colorsPer100 = ['green', 'orange', 'blue', 'red']; 

new Chart(document.getElementById("myChart"), {
  type: "scatter",
  plugins: [{
    afterDraw: chart => {      
      var ctx = chart.chart.ctx; 
      var xAxis = chart.scales['x-axis-1'];
      var yAxis = chart.scales['y-axis-1'];      
      chart.config.data.datasets[0].data.forEach((value, index) => {
        if (index > 0) {        
           var valueFrom = data[index - 1];
           var xFrom = xAxis.getPixelForValue(valueFrom.x);     
           var yFrom = yAxis.getPixelForValue(valueFrom.y);     
           var direction = rawData[index -1].direction;
           var xTo = xAxis.getPixelForValue(value.x);         
           var yTo = yAxis.getPixelForValue(value.y); 
           ctx.save();           
           ctx.strokeStyle = colorsPer100[Math.floor(direction / 100)];           
           ctx.lineWidth = 2;
           ctx.beginPath();
           ctx.moveTo(xFrom, yFrom);             
           ctx.lineTo(xTo, yTo);
           ctx.stroke();
           ctx.restore();
        }
      });      
    }
  }],
  data: {
    datasets: [{
      label: "My Dataset",
      data: data,
      borderColor: "rgb(75, 192, 192)"
    }]
  },
  options: {
    legend: {
      display: false
    },
    scales: {
      xAxes: [{
        type: 'time',
        time: {
          unit: 'minute',
          displayFormats: {
            minute: 'H:mm:ss'
          }
        },
      }]
    }
  }  
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="myChart" height="90"></canvas>

【讨论】:

    【解决方案2】:

    uminder 有一个有趣的解决方案。在另一个线程中,有人发布了一个我使用的解决方案 - 他们只是创建了一个与数据集大小相同的颜色数组(并将其与数据一起输入)。效果很好,而且比我想的要简单得多。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-26
      • 1970-01-01
      • 2015-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多