【问题标题】:Drawing a mixed stacked horizontal bar/line in chartjs在chartjs中绘制混合堆叠的水平条/线
【发布时间】:2020-03-04 14:43:48
【问题描述】:

我查看了 chartjs 的文档/示例,但有人知道以下方法吗?

  • 创建宽度(x 轴)可变但高度始终为满(也就是整个 y 轴)的条形?
  • 图表中可以有 x 个条形
  • 创建一条一直跨越 x 轴但可以更改它的 y 轴的线(也不是直线,而是曲线)。

我这里有一个粗略的绘图,黄色是条,黑色是线

我有点使用堆叠条并交换轴来降低第一部分,但 y 轴(条高度)仅设置为 1。尝试在混合模式下绘制曲线时出现问题,因为存在只有一个 y 轴点(而不是多个 y 轴点):

这是另一个尝试,它有多个 y 轴点,但我无法控制条形宽度:

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

Please see code in the jsfiddle link

【问题讨论】:

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


【解决方案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
        }
      }]
    }
  }
});

【讨论】:

  • FWIW 我的线实际上是一个散点图(showLines=true),大约有 2000 个点,我平均可以有 0 到 50 条之间的任何地方。
  • 我拿你的例子做了一个小的静态样本。酒吧之间似乎有差距。我不确定如何缩小这些差距。我还想在整个条形周围放置一个边框(而不是在条形的每个单独切片上放置一个边框)。我还希望对整体条形有一些不透明度(而不是在条的每个单独切片上)。这是我的编辑:jsbin.com/dubofajefo/1/edit?js,output 以您的示例为例,这可能吗?
  • 好吧,我想我放弃了。当在同一个索引上时,我找不到一种方法来显示彼此后面的条形,它总是将它们彼此相邻显示。 Here are information about that, but only for category and time scale, not for a linear scale。所以只有一个矩形是可能的。这也是酒吧之间的差距的原因。我不认为每个数据都有边界,only for the complete dataset。很抱歉我帮不了你,我不知道其他解决方案。
  • 我也是,但感谢您的调查!如果无法完成,我会发布一个功能请求
【解决方案2】:

看起来这是最好的解决方案:

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 上回答了这个问题。

【讨论】:

  • 比我的解决方案好多了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-07
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多