在chartjs中绘制混合的堆叠式水平条/线

时间:2019-11-07 23:56:48

标签: chart.js chartjs-2.6.0 vue-chartjs

我看过chartjs的文档/示例,但是有人知道执行以下操作的方法吗?

  • 创建宽度(x轴)可变但高度始终为满(也就是整个y轴)的钢筋吗?
  • 图表中这些条形可以有x个
  • 创建一条横跨x轴但可以更改其y轴的线(又不是一条直线,而是一条弯曲的线)。

我这里有一张粗图,黄色是条形图,黑色是线形

我有点用堆叠的条形和交换轴来放下第一部分,但是y轴(条形高度)仅设置为1。在尝试以混合模式绘制曲线时,这是一个问题,因为存在仅有一个y轴点(而不是许多y轴点):

这是另一个尝试,该尝试具有多个y轴点,但我无法控制钢筋宽度:

如果有人可以提供帮助(或者至少告诉我我是否朝着正确的方向前进),将不胜感激!

Please see code in the jsfiddle link

2 个答案:

答案 0 :(得分:1)

嗯,那很难。。。我唯一的解决方案是创建一个包含很多非常小的条形图的条形图。

I made a JSBin with my solution,但它远非完美,但在chart.js中是实现此目标的唯一方法。我不了解性能,因为我不知道您的数据,但这将非常重要,也是最大的问题。

现在只有一个矩形是可能的,但是将其改进为多个矩形并不困难。

这是我所有的代码,与JSBin相同:

var chartData = {
  datasets: [{
    type: 'line',
    label: 'Dataset 1',
    borderColor: 'blue',
    borderWidth: 2,
    fill: false,
    data: []
  }, {
    type: 'bar',
    label: 'Dataset 2',
    backgroundColor: 'red',
    data: [],
  }]
};

var newData0 = []
var newData1 = []
var labels = []
var counter = 50

// Rectangle between two random Integers
var rectangleBetween = [Math.round(Math.random()*counter), Math.round(Math.random()*counter)]
rectangleBetween.sort(function(a, b){return a - b})

for (var i = 0; i < counter; i++) {
  labels.push(i)

  // Data for Dataset 1 (line):
  var newObj0 = {}
  newObj0.x = i
  // 50/50 chance of data
  if (Math.random()<0.5) {
    newObj0.y = Math.round(Math.random()*100)
  } else {
    newObj0.y = null
  }
  newData0.push(newObj0)

  // Data for Dataset 2 (bar):
  var newObj1 = {}
  if (i >= rectangleBetween[0] && i <= rectangleBetween[1]) {
    newObj1.x = i
    newObj1.y = 100
  } else {
    newObj1.x = i
    newObj1.y = 0
  }  
  newData1.push(newObj1)
}

chartData.datasets[0].data = newData0
chartData.datasets[1].data = newData1
chartData.labels = labels


var ctx = document.getElementById('chart').getContext('2d');
myMixedChart = new Chart(ctx, {
  type: 'bar',
  data: chartData,
  options: {
    responsive: true,
    spanGaps: true,
    title: {
      display: true,
      text: 'Chart.js Combo Bar Line Chart'
    },
    tooltips: {
      mode: 'index',
      intersect: true
    },
    scales: {
      xAxes: [{
        //barThickness: 80, // number (pixels) or 'flex'
        //maxBarThickness: 100, // number (pixels)
        barPercentage: 1.0,
        categoryPercentage: 1.0,
        gridLines: {
          display: false
        }
      }]
    }
  }
});

答案 1 :(得分:1)

这似乎是最好的解决方案:

https://codepen.io/kurkle/pen/ExxdyXQ

var ctx = document.getElementById("chart").getContext("2d");
var chart = new Chart(ctx, {
  type: "horizontalBar",
  data: {
    labels: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    datasets: [
      {
        label: "Bar1",
        data: [[2.5, 5.7]],
      },
      {
        label: "Bar2",
        data: [[6, 8]],
      },
      {
        label: "Bar3",
        data: [[9,10]],
      },
      {
        label: "Line",
        type: "line",
        backgroundColor: "rgb(75, 192, 192, 0.5)",
        borderColor: "rgb(75, 192, 192)",
        fill: false,
        tension: 0,
        data: [11, 10, 9, 8, 7, 6, 5, 4, 3, 2],
        yAxisID: "line"
      }
    ]
  },
  options: {
    datasets: {
      horizontalBar: {
        backgroundColor: "rgb(255, 99, 132, 0.5)",
        borderColor: "rgb(255, 99, 132)",
        borderWidth: 1,
        barPercentage: 1,
        categoryPercentage: 1,
        yAxisID: "bar"
      }
    },
    scales: {
      yAxes: [
        {
          id: "bar",
          type: 'category',
          stacked: true,
          labels: ['bar'],
          offset: true
        },
        {
          id: "line",
          position: 'right',
          ticks: {
            min: 0,
            stepSize: 1
          }
        }
      ]
    }
  }
});

该代码的原始作者(Jukka Kurkela aka kurkle)。他在chart.js GitHub issues page上回答了这个问题。