图表JS填充两行之间 [英] Chart JS Fill Between two lines

查看:57
本文介绍了图表JS填充两行之间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种用Chart.js在两行之间填充的方法,使其看起来像这样。我已经看过了,似乎所有事情都在谈论填充零的两行之间。我还需要其他行来像往常一样填充所有内容。这是chart.js可以做的事情吗?



解决方案

这里是使用插件在两个数据集之间填充的解决方案。支持所有线型和多条线之间的填充阴影。要在一个数据集之间填充,请使用自定义参数fillBetweenSet告诉一个数据集填充另一个数据集之间的区域。



Fiddle-



代码:

 < html> 
< div>
< canvas id = demo>< / canvas>
< / div>
< / html>

< script>
var fillBetweenLinesPlugin = {
afterDatasetsDraw:function(chart){
var ctx = chart.chart.ctx;
var xaxis = chart.scales [’x-axis-0’];
var yaxis = chart.scales [’y-axis-0’];
var数据集= chart.data.datasets;
ctx.save();

for(var d = 0; d< datasets.length; d ++){
var datasets = datasets [d];
if(dataset.fillBetweenSet ==未定义){
继续;
}

//获取两个数据集的元数据
var meta1 = chart.getDatasetMeta(d);
var meta2 = chart.getDatasetMeta(dataset.fillBetweenSet);

//如果其中一个数据集被隐藏,则不绘制填充
如果(meta1.hidden || meta2.hidden)继续;

//创建成对的填充区域
for(var p = 0; p< meta1.data.length-1; p ++){
//如果为null跳过
如果(dataset.data [p] == null || dataset.data [p + 1] == null)继续;

ctx.beginPath();

//跟踪行1
var curr = meta1.data [p];
var next = meta1.data [p + 1];
ctx.moveTo(curr._view.x,curr._view.y);
ctx.lineTo(curr._view.x,curr._view.y);
if(curr._view.steppedLine === true){
ctx.lineTo(next._view.x,curr._view.y);
ctx.lineTo(next._view.x,next._view.y);
}
else if(next._view.tension === 0){
ctx.lineTo(next._view.x,next._view.y);
}
else {
ctx.bezierCurveTo(
curr._view.controlPointNextX,
curr._view.controlPointNextY,
next._view.controlPointPreviousX,
next._view.controlPointPreviousY,
next._view.x,
next._view.y
);
}

//将数据集1连接到数据集2
var curr = meta2.data [p + 1];
var next = meta2.data [p];
ctx.lineTo(curr._view.x,curr._view.y);

//如果(curr._view.steppedLine === true){
ctx.lineTo(curr._view.x),则跟踪BACKSETS set2以完成框
。 _view.y);
ctx.lineTo(next._view.x,next._view.y);
}
else if(next._view.tension === 0){
ctx.lineTo(next._view.x,next._view.y);
}
else {
//反向贝塞尔曲线
ctx.bezierCurveTo(
curr._view.controlPointPreviousX,
curr._view.controlPointPreviousY,
next._view.controlPointNextX,
next._view.controlPointNextY,
next._view.x,
next._view.y
);
}

//关闭循环并以阴影
填充ctx.closePath();
ctx.fillStyle = dataset.fillBetweenColor || rgba(0,0,0,0.1);
ctx.fill();
} //结束p循环
}
} //结束afterDatasetsDraw
}; //结束fillBetweenLinesPlugin

Chart.pluginService.register(fillBetweenLinesPlugin);

var chartData = {
标签:[1、2、3、4、5、6、7、8],
数据集:[
{
标签:设置1,
数据:[10,20,null,40,30,null,20,40],
borderColor:#F00,
填充: false,
steppedLine:false,
张力:0,
fillBetweenSet:1,
fillBetweenColor: rgba(255,0,0,0.2)
},
{
标签:设置2,
数据:[60、40、10、50、60,null,50、20],
borderColor:#00F ,
填充:false,
步进线:false,
张力:0.5
},
{
标签:设置2,
数据:[40,50,30,30,20,null,60,40],
borderColor:#0D0,
填充:false,
steppedLine:false,
张力:0,
fillBetweenSet:1,
fillBetweenColor: rgba(5,5,255,0.2)
}
]
};

var chartOptions = {
响应式:true,
标题:{
显示:true,
文本:'行间演示填充'
}
};

var chartDemo = new Chart($('#demo')。get(0),{
type:'line',
data:chartData,
选项:chartOptions
});
< / script>


I am looking for a way to fill between two lines with Chart.js so that it would look like this. I have looked and everything seems to talk about filling between two lines across zero. I also need other lines to fill all the way down like normal. Is this something chart.js can do?

解决方案

Here is a solution that uses a plugin to fill between two datasets. Supports all line styles and fill shading between multiple lines. To fill between a dataset, use the custom param fillBetweenSet to tell a dataset to fill the area between another dataset.

Fiddle - https://jsfiddle.net/ke5n5LnL/26/

Preview:

Code:

<html>
    <div>
        <canvas id="demo"></canvas>
    </div>
</html>

<script>
    var fillBetweenLinesPlugin = {
    afterDatasetsDraw: function (chart) {
        var ctx = chart.chart.ctx;
        var xaxis = chart.scales['x-axis-0'];
        var yaxis = chart.scales['y-axis-0'];
        var datasets = chart.data.datasets;
        ctx.save();

        for (var d = 0; d < datasets.length; d++) {
            var dataset = datasets[d];
            if (dataset.fillBetweenSet == undefined) {
                continue;
            }

            // get meta for both data sets
            var meta1 = chart.getDatasetMeta(d);
            var meta2 = chart.getDatasetMeta(dataset.fillBetweenSet);

            // do not draw fill if one of the datasets is hidden
            if (meta1.hidden || meta2.hidden) continue;

            // create fill areas in pairs
            for (var p = 0; p < meta1.data.length-1;p++) {
                // if null skip
              if (dataset.data[p] == null || dataset.data[p+1] == null) continue;

              ctx.beginPath();

              // trace line 1
              var curr = meta1.data[p];
              var next = meta1.data[p+1];
              ctx.moveTo(curr._view.x, curr._view.y);
              ctx.lineTo(curr._view.x, curr._view.y);
              if (curr._view.steppedLine === true) {
                ctx.lineTo(next._view.x, curr._view.y);
                ctx.lineTo(next._view.x, next._view.y);
              }
              else if (next._view.tension === 0) {
                ctx.lineTo(next._view.x, next._view.y);
              }
              else {
                  ctx.bezierCurveTo(
                    curr._view.controlPointNextX,
                    curr._view.controlPointNextY,
                    next._view.controlPointPreviousX,
                    next._view.controlPointPreviousY,
                    next._view.x,
                    next._view.y
                  );
                            }

              // connect dataset1 to dataset2
              var curr = meta2.data[p+1];
              var next = meta2.data[p];
              ctx.lineTo(curr._view.x, curr._view.y);

              // trace BACKWORDS set2 to complete the box
              if (curr._view.steppedLine === true) {
                ctx.lineTo(curr._view.x, next._view.y);
                ctx.lineTo(next._view.x, next._view.y);
              }
              else if (next._view.tension === 0) {
                ctx.lineTo(next._view.x, next._view.y);
              }
              else {
                // reverse bezier
                ctx.bezierCurveTo(
                  curr._view.controlPointPreviousX,
                  curr._view.controlPointPreviousY,
                  next._view.controlPointNextX,
                  next._view.controlPointNextY,
                  next._view.x,
                  next._view.y
                );
              }

                            // close the loop and fill with shading
              ctx.closePath();
              ctx.fillStyle = dataset.fillBetweenColor || "rgba(0,0,0,0.1)";
              ctx.fill();
            } // end for p loop
        }
    } // end afterDatasetsDraw
}; // end fillBetweenLinesPlugin

Chart.pluginService.register(fillBetweenLinesPlugin);

var chartData = {
    labels: [1, 2, 3, 4, 5,6,7,8],
    datasets: [
      {
          label: "Set 1",
          data: [10, 20, null, 40, 30,null,20,40],
          borderColor: "#F00",
          fill: false,
          steppedLine: false,
          tension: 0,
          fillBetweenSet: 1,
          fillBetweenColor: "rgba(255,0,0, 0.2)"
      },
      {
          label: "Set 2",
          data: [60, 40, 10, 50, 60,null,50,20],
          borderColor: "#00F",
          fill: false,
          steppedLine: false,
          tension: 0.5
      },
      {
          label: "Set 2",
          data: [40, 50, 30, 30, 20,null,60,40],
          borderColor: "#0D0",
          fill: false,
          steppedLine: false,
          tension: 0,
          fillBetweenSet: 1,
          fillBetweenColor: "rgba(5,5,255, 0.2)"
      }
    ]
};

var chartOptions = {
    responsive: true,
    title: {
        display: true,
        text: 'Demo Fill between lines'
    }
};

var chartDemo = new Chart($('#demo').get(0), {
    type: 'line',
    data: chartData,
    options: chartOptions
});
</script>

这篇关于图表JS填充两行之间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆