ChartJS New Lines' \ n'在X轴标签或使用ChartJS V2显示图表或工具提示周围的更多信息

时间:2016-05-07 15:57:49

标签: javascript chart.js

我使用chart.js(V2)尝试构建一个条形图,向用户提供更多信息,而不必将鼠标悬停在任何地方或点击任何地方。我已经提供了两个我希望如何编辑图表的例子。

Two edited versions of what I hope to achieve

可以看出,我希望(在某处)放置标签之外的一些额外信息。我希望通过添加' \ n'我可能已经能够获得与选项A相似的标签。

提供了一些编辑过的代码:

var barChartData = {

        labels: playerNames,
        datasets: [{
            label: 'Actual Score/Hour',
            backgroundColor: "rgba(0, 128, 0,0.5)",
            data: playerScores
          }, {
            label: 'Expected Score/Hour',
            backgroundColor: "rgba(255,0,0,0.5)",
            data: playerExpected
        }]
    };
function open_win(linktosite) {
           window.open(linktosite)
      }
        canvas.onclick = function(evt){
            var activePoints = myBar.getElementsAtEvent(evt);
            console.log(activePoints);
            linktosite = 'https://www.mytestsite.com/' + activePoints[1]['_model']['label'];
            open_win(linktosite);
}; 
window.onload = function() {
        var ctx = document.getElementById("canvas").getContext("2d");
        window.myBar = new Chart(ctx, {
            type: 'bar',
            data: barChartData,
            options: {
                title:{
                    display:true,
                    text:"Player Expected and Actual Score per Hour"
                },
                tooltips: {
                    mode: 'label'
                },
                responsive: true,
                scales: {
                    xAxes: [{
                        stacked: false,
                    }],
                    yAxes: [{
                        stacked: false
                    }]
                },
                animation: {
                    onComplete: function () {
                        var ctx = this.chart.ctx;
                        ctx.textAlign = "center";
                        Chart.helpers.each(this.data.datasets.forEach(function (dataset) {

                            Chart.helpers.each(dataset.metaData.forEach(function (bar, index) {
                                // console.log("printing bar" + bar);
                                ctx.fillText(dataset.data[index], bar._model.x, bar._model.y - 10);
                                }),this)
                                }),this);
                    }
                }
            }
        });
        // Chart.helpers.each(myBar.getDatasetMeta(0).data, function(rectangle, index) {
        // rectangle.draw = function() {
        //     myBar.chart.ctx.setLineDash([5, 5]);
        //     Chart.elements.Rectangle.prototype.draw.apply(this, arguments);
        //     }
        // }, null);            
    };

此时我对在酒吧的任何地方放置extradata感到满意。任何帮助,将不胜感激。谢谢〜

4 个答案:

答案 0 :(得分:26)

Chart.js v2.1.5允许使用嵌套数组的多行标签(v2.5.0修复它用于雷达图):

...
data: {
    labels: [["Jake", "Active: 2 hrs", "Score: 1", "Expected: 127", "Attempts: 4"], 
             ["Matt", "Active: 2 hrs", "Score: 4", "Expected: 36", "Attempts: 4"]],
    ...

但是,这确实意味着您必须预先计算标签值。

答案 1 :(得分:6)

使用Chart.js v2.1,您可以编写图表插件来执行此操作

预览

enter image description here

<强>脚本

Chart.pluginService.register({
    beforeInit: function (chart) {
        var hasWrappedTicks = chart.config.data.labels.some(function (label) {
            return label.indexOf('\n') !== -1;
        });

        if (hasWrappedTicks) {
            // figure out how many lines we need - use fontsize as the height of one line
            var tickFontSize = Chart.helpers.getValueOrDefault(chart.options.scales.xAxes[0].ticks.fontSize, Chart.defaults.global.defaultFontSize);
            var maxLines = chart.config.data.labels.reduce(function (maxLines, label) {
                return Math.max(maxLines, label.split('\n').length);
            }, 0);
            var height = (tickFontSize + 2) * maxLines + (chart.options.scales.xAxes[0].ticks.padding || 0);

            // insert a dummy box at the bottom - to reserve space for the labels
            Chart.layoutService.addBox(chart, {
                draw: Chart.helpers.noop,
                isHorizontal: function () {
                    return true;
                },
                update: function () {
                    return {
                        height: this.height
                    };
                },
                height: height,
                options: {
                    position: 'bottom',
                    fullWidth: 1,
                }
            });

            // turn off x axis ticks since we are managing it ourselves
            chart.options = Chart.helpers.configMerge(chart.options, {
                scales: {
                    xAxes: [{
                        ticks: {
                            display: false,
                            // set the fontSize to 0 so that extra labels are not forced on the right side
                            fontSize: 0
                        }
                    }]
                }
            });

            chart.hasWrappedTicks = {
                tickFontSize: tickFontSize
            };
        }
    },
    afterDraw: function (chart) {
        if (chart.hasWrappedTicks) {
            // draw the labels and we are done!
            chart.chart.ctx.save();
            var tickFontSize = chart.hasWrappedTicks.tickFontSize;
            var tickFontStyle = Chart.helpers.getValueOrDefault(chart.options.scales.xAxes[0].ticks.fontStyle, Chart.defaults.global.defaultFontStyle);
            var tickFontFamily = Chart.helpers.getValueOrDefault(chart.options.scales.xAxes[0].ticks.fontFamily, Chart.defaults.global.defaultFontFamily);
            var tickLabelFont = Chart.helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);
            chart.chart.ctx.font = tickLabelFont;
            chart.chart.ctx.textAlign = 'center';
            var tickFontColor = Chart.helpers.getValueOrDefault(chart.options.scales.xAxes[0].fontColor, Chart.defaults.global.defaultFontColor);
            chart.chart.ctx.fillStyle = tickFontColor;

            var meta = chart.getDatasetMeta(0);
            var xScale = chart.scales[meta.xAxisID];
            var yScale = chart.scales[meta.yAxisID];

            chart.config.data.labels.forEach(function (label, i) {
                label.split('\n').forEach(function (line, j) {
                    chart.chart.ctx.fillText(line, xScale.getPixelForTick(i + 0.5), (chart.options.scales.xAxes[0].ticks.padding || 0) + yScale.getPixelForValue(yScale.min) +
                        // move j lines down
                        j * (chart.hasWrappedTicks.tickFontSize + 2));
                });
            });

            chart.chart.ctx.restore();
        }
    }
});

然后

...
data: {
    labels: ["January\nFirst Month\nJellyfish\n30 of them", "February\nSecond Month\nFoxes\n20 of them", "March\nThird Month\nMosquitoes\nNone of them", "April", "May", "June", "July"],
         ...

注意 - 我们假设一条线的最大内容将适合刻度线(即不需要旋转逻辑。我确信它也可以合并旋转逻辑,但它会是有点复杂)

您应该将工具提示格式化为不显示x轴标签,或将其格式化以显示标签的较短版本。

小提琴 - http://jsfiddle.net/m0q03wpy/

答案 2 :(得分:5)

如果您使用的是Chart.js v2.7.1,则上述解决方案可能无效。

实际适合我们的解决方案是在plugindata级别添加一个小options权限:

const config = {
  type: 'bar',
  data: {
    // ...
  },
  options: {
    // ...
  },
  plugins: [{
    beforeInit: function (chart) {
      chart.data.labels.forEach(function (e, i, a) {
        if (/\n/.test(e)) {
          a[i] = e.split(/\n/)
        }
      })
    }
  }]
};

有关如何解决此问题的完整说明,请访问here

答案 3 :(得分:4)

var config = {
  type: 'line',
  data: {
    labels: [["January","First Month","Jellyfish","30 of them"], ["February","Second Month","Foxes","20 of them"], ["March","Third Month","Mosquitoes","None of them"], "April", "May", "June", "July"],
    datasets: [{
      label: "My First dataset",
      data: [65, 40, 80, 81, 56, 85, 45],
      backgroundColor: "rgba(255,99,132,0.2)",
    }, {
      label: "My Second dataset",
      data: [40, 80, 21, 56, 85, 45, 65],
      backgroundColor: "rgba(99,255,132,0.2)",
    }]
  },
  scales : {
      xAxes : [{
          gridLines : {
              display : false,
              lineWidth: 1,
              zeroLineWidth: 1,
              zeroLineColor: '#666666',
              drawTicks: false
          },
          ticks: {
              display:true,
              stepSize: 0,
              min: 0,
              autoSkip: false,
              fontSize: 11,
              padding: 12
          }
      }],
      yAxes: [{
          ticks: {
              padding: 5
          },
          gridLines : {
              display : true,
              lineWidth: 1,
              zeroLineWidth: 2,
              zeroLineColor: '#666666'
          }
      }]
  },
                    spanGaps: true,
                    responsive: true,
                    maintainAspectRatio: true
};

var ctx = document.getElementById("myChart").getContext("2d");
new Chart(ctx, config);
<div class="myChart">
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.js"></script>

<canvas id="myChart"></canvas>
          </div>

如果标签是一个数组而不是一个字符串,即[[“June”,“2015”],“July”]那么每个元素都被视为一个单独的行。进行适当的计算以确定正确的高度和宽度,并且仍然支持旋转。

使用charJS版本2.7.2 这也适用于https://github.com/jtblin/angular-chart.js