当前位置: 首页 > 知识库问答 >
问题:

多色图例堆叠条形图Chartjs

栾越
2023-03-14

我一直在寻找一种使用Chartjs绘制此图的方法,但没有成功。这在Chartjs中可能吗?

我想画的图表

我尝试的图表

以下是我的设置:

const stacked_bar_data = {
    labels: ['Axi-cel', 'Tisa-cel'],
    datasets: [
    {
        label: 'Bridging therapy 2',
        data: [25, 25],
        backgroundColor: ['rgb(224, 178, 40)', 'rgb(78, 235, 255)']
    },
    {
        label: 'Bridging therapy 1',
        data: [25, 25],
        backgroundColor: ['rgb(204, 158, 20)', 'rgb(58, 215, 240)']
    }
    ]
}

const stacked_bar_config = {
    type: 'bar',
    data: stacked_bar_data,
    options: {
        responsive: true,
        scales: {
            x: {
                stacked: true,
                grid: {
                    display: false
                }
            },

            y: {
                stacked: true,
                grid: {
                    display: false
                },
                title: {
                    display: true,
                    text: 'Use, %'
                }
            }
        }
    }
}

var stacked_bar = new Chart(document.getElementById('stacked-bar').getContext('2d'), stacked_bar_config)

我知道如何设置堆叠条形图,只是不知道如何设置图像中的图例。任何帮助都很感激。提前感谢!

共有1个答案

袁宜
2023-03-14

自定义html图例是可能的,实现并不完美,但我认为您可以对其进行微调,使其能够正常工作

例子:

const getOrCreateLegendList = (chart, id) => {
  const legendContainer = document.getElementById(id);
  let listContainer = legendContainer.querySelector('ul');

  if (!listContainer) {
    listContainer = document.createElement('ul');
    listContainer.style.display = 'flex';
    listContainer.style.flexDirection = 'row';
    listContainer.style.margin = 0;
    listContainer.style.padding = 0;

    legendContainer.appendChild(listContainer);
  }

  return listContainer;
};

const htmlLegendPlugin = {
  id: 'htmlLegend',
  afterUpdate(chart, args, options) {
    const ul = getOrCreateLegendList(chart, options.containerID);

    // Remove old legend items
    while (ul.firstChild) {
      ul.firstChild.remove();
    }

    // Reuse the built-in legendItems generator
    const items = chart.options.plugins.legend.labels.generateLabels(chart);

    items.forEach((item, i) => {
      const li = document.createElement('li');
      li.style.alignItems = 'center';
      li.style.cursor = 'pointer';
      li.style.display = 'flex';
      li.style.flexDirection = 'row';
      li.style.marginLeft = '10px';

      li.onclick = () => {
        const {
          type
        } = chart.config;
        if (type === 'pie' || type === 'doughnut') {
          // Pie and doughnut charts only have a single dataset and visibility is per item
          chart.toggleDataVisibility(item.index);
        } else {
          chart.setDatasetVisibility(item.datasetIndex, !chart.isDatasetVisible(item.datasetIndex));
        }
        chart.update();
      };

      const datasets = chart.data.datasets;

      // Color box
      const boxSpan = document.createElement('span');
      boxSpan.style.background = datasets[item.datasetIndex].backgroundColor[i];
      boxSpan.style.borderColor = item.strokeStyle;
      boxSpan.style.borderWidth = item.lineWidth + 'px';
      boxSpan.style.display = 'inline-block';
      boxSpan.style.height = '20px';
      boxSpan.style.marginRight = '10px';
      boxSpan.style.width = '20px';

      const boxSpan2 = document.createElement('span');
      boxSpan2.style.background = datasets[item.datasetIndex].backgroundColor[i + 1] || datasets[item.datasetIndex].backgroundColor[i - 1];
      boxSpan2.style.borderColor = item.strokeStyle;
      boxSpan2.style.borderWidth = item.lineWidth + 'px';
      boxSpan2.style.borderColor = item.strokeStyle;
      boxSpan2.style.borderWidth = item.lineWidth + 'px';
      boxSpan2.style.display = 'inline-block';
      boxSpan2.style.height = '20px';
      boxSpan2.style.marginRight = '10px';
      boxSpan2.style.width = '20px';

      // Text
      const textContainer = document.createElement('p');
      textContainer.style.color = item.fontColor;
      textContainer.style.margin = 0;
      textContainer.style.padding = 0;
      textContainer.style.textDecoration = item.hidden ? 'line-through' : '';

      const text = document.createTextNode(item.text);
      textContainer.appendChild(text);

      li.appendChild(boxSpan);
      li.appendChild(boxSpan2);
      li.appendChild(textContainer);
      ul.appendChild(li);
    });
  }
};

var options = {
  type: 'bar',
  data: {
    labels: ["Red", "Blue"],
    datasets: [{
        label: '# of Votes',
        data: [12, 19],
        borderWidth: 1,
        backgroundColor: ['rgb(224, 178, 40)', 'rgb(78, 235, 255)']
      },
      {
        label: '# of Points',
        data: [7, 11],
        borderWidth: 1,
        backgroundColor: ['rgb(204, 158, 20)', 'rgb(58, 215, 240)']
      }
    ]
  },
  options: {
    responsive: true,
    scales: {
      x: {
        stacked: true,
        grid: {
          display: false
        }
      },

      y: {
        stacked: true,
        grid: {
          display: false
        },
        title: {
          display: true,
          text: 'Use, %'
        }
      }
    },
    plugins: {
      htmlLegend: {
        // ID of the container to put the legend in
        containerID: 'chartjs-legend',
      },
      legend: {
        display: false,
      }
    }
  },
  plugins: [htmlLegendPlugin],
}

var ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
  <div id="chartjs-legend">

  </div>
  <canvas id="chartJSContainer" width="600" height="400"></canvas>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.3.2/chart.js"></script>
</body>
 类似资料:
  • 我有以下不同月份的数据 一月:[1,5,3] Feb:[10,5] 三月:[4,8] 四月:[7] 可能:[3,1,5,0,7] 我想生成如下所示的条形图 现在,我有以下代码,我想知道如何生成如上图所示的条形图。 }); 非常感谢。

  • Highcharts 条形图 以下实例演示了堆叠条形图。 我们在前面的章节已经了解了 Highcharts 基本配置语法。接下来让我们来看下其他的配置。 配置 plotOptions 配置图表堆叠使用 plotOptions.series.stacking,并设置为 "normal"。如果禁用堆叠可设置为 null , "normal" 通过值设置堆叠, "percent" 堆叠则按百分比。 v

  • 我需要一张这样的图表: 我找到了这个示例,但它使用了旧版本的。我尝试使用v2.0,但我不明白。 有人能贴个例子吗?

  • 我需要一种在ChartJS中显示堆叠条形图中多个数据段的方法。在官方文档中,标签属于堆栈的每个部分,但我需要这些部分是独立的。 我已经模拟了我需要实现的输出类型。我们每天有三个堆叠的条,每个条显示一个单独的数据集。在每个数据集中,我们有一个段,它实际上是该条的子集。 不幸的是,中的属性似乎不接受数组。这个图表可以使用ChartJS吗?

  • 我有一只熊猫。DataFrame我想基于两列绘制一个图表:(int)、(int-或)。现在我有这样的东西: 这是我使用的代码: 这是两个子图。这很好,但是很难看出在特定的年龄范围内,在幸存的列中有和的记录量之间的差异。 所以我想要这样的东西: 在这个场景中,您可以看到这种差异。有什么方法可以在(因为在那里我可以轻松地操作)?如果可能的话,我不想使用香草

  • 我正在使用chartjs版本:2.1.4在MVC应用程序中创建图表。我正在使用控制条形图的宽度,以进行固定宽度设置。它在只有条形图的情况下工作正常,但在“堆叠条形图”的情况下,我无法确定条形图的宽度。我正在使用以下代码创建堆叠条形图,如下所示: 在这种情况下,"barper"属性不起作用。请在"chartjs版本: 2.1.4"中建议我解决方案。 提前谢谢