【问题标题】:ChartJS horizontal chart display legend on each barChartJS 水平图表在每个柱上显示图例
【发布时间】:2017-03-15 18:11:45
【问题描述】:

我是 ChartJS 的新手,我有一个水平条形图:

HTML

<canvas id="mybarChart"></canvas>

JavaScript:

var ctx = document.getElementById("mybarChart");

    ctx.height = 300;

    var mybarChart = new Chart(ctx, {
        type: 'horizontalBar',
        responsive: true,
        data: data,
        options: {
            legend: {
                display: false
            },
            scales: {
                yAxes: [{
                    display: false,
                    ticks: {
                        beginAtZero: true
                    },
                    gridLines: {
                        color: "rgba(0, 0, 0, 0)",
                    }
                }],
                xAxes: [{
                    display: false,
                    gridLines: {
                        color: "rgba(0, 0, 0, 0)",
                    },
                    barPercentage: 0.5,
                    categoryPercentage: 0.5
                }]
            }
        }
    });

我正在尝试在每个条上添加图例,例如 ,但现在它看起来像

我已经尝试添加

onAnimationComplete: function () {

            var ctx = this.chart.ctx;
            ctx.font = this.scale.font;
            ctx.fillStyle = this.scale.textColor
            ctx.textAlign = "center";
            ctx.textBaseline = "bottom";

            this.datasets.forEach(function (dataset) {
                dataset.points.forEach(function (points) {
                    ctx.fillText(points.value, points.x, points.y - 10);
                });
            })
        }

但仍然是相同的结果。我究竟做错了什么? 我发现了一些东西here,但每个条上显示的标签是 Y 轴的刻度。 是否可以在每个栏上添加图例并保留工具提示?

提前致谢!

【问题讨论】:

    标签: javascript jquery html css chart.js


    【解决方案1】:

    实际上有几种方法可以实现这一目标。为简单起见,我将仅修改您提供的示例。

    请记住,这会将标签放在栏内。您可以轻松修改它以将其放置在外部,但您必须添加逻辑以确保您不会溢出到图表顶部或其他条形(不是非常简单的逻辑)。

    此外,这种方法要求您为每个数据集配置一个标签(无论如何都需要它来驱动常规图例)。

    只需将其放在您的 animation.onComplete 属性中即可。

    function() {
      var ctx = this.chart.ctx;
      ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontFamily, 'normal', Chart.defaults.global.defaultFontFamily);
      ctx.textAlign = 'left';
      ctx.textBaseline = 'bottom';
    
      this.data.datasets.forEach(function(dataset) {
        for (var i = 0; i < dataset.data.length; i++) {
          var model = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._model,
              scale_max = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._yScale.maxHeight;
          left = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._xScale.left;
          offset = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._xScale.longestLabelWidth;
          ctx.fillStyle = '#444';
          var y_pos = model.y - 5;
          var label = model.label;
          // Make sure data value does not get overflown and hidden
          // when the bar's value is too close to max value of scale
          // Note: The y value is reverse, it counts from top down
          if ((scale_max - model.y) / scale_max >= 0.93)
            y_pos = model.y + 20;
          // ctx.fillText(dataset.data[i], model.x, y_pos);
    
          if (dataset.data[i] > 0) {
            ctx.fillText(dataset.label, left + 10, model.y + 8);
          }
        }
      });
    }
    

    这是一个jsfiddle example(来自您提供的示例)。

    【讨论】:

    • 我想保留工具提示,但是当您将鼠标悬停在一个条上时,它上面的标签会消失,它不应该。可以做到这一点或更好,只需在标签旁边添加值并禁用工具提示?
    • 我已编辑:ctx.fillText(dataset.label + ' ' + dataset.data[0], left + 10, model.y + 8);而且效果很好
    • 非常感谢您的帮助! :)
    • 只是几个 cmets:我会将 dataset._meta[Object.keys(dataset._meta)[0]].data[i] 存储在一个变量中以避免重复,并且不使用 offsety_poslabel,因此我最终删除了大部分代码,例如 scale_max 和第一个 if
    猜你喜欢
    • 2017-08-03
    • 1970-01-01
    • 1970-01-01
    • 2022-11-29
    • 1970-01-01
    • 2023-01-20
    • 1970-01-01
    • 2015-03-22
    • 1970-01-01
    相关资源
    最近更新 更多