在 ChartJS 中截断画布标签,同时在工具提示中保留完整的标签值



我有一些条形图,它们的标签很长,它们会影响图表的大小。

示例:http://jsfiddle.net/norbiu/aqa8w19d/4/

我正在尝试截断图表下显示的标签,同时保留将鼠标悬停在条形图上时显示在工具提示中的标签。问题是工具提示和画布标签都从数据结构中的labels数组中获取其值。截断该值将在两个位置显示缩短的版本。

sales: ko.observable({
    labels: ['A really really long label', 'Another long labe', 'A third label that is long', 'Q4', 'Q5', 'Q6'],
    datasets: [{
        label: 'Helados',
        fillColor: '#152491',
        data: [70, 32, 6, 23, 63, 43]
    }]
}),

文档对此没有任何内容。有什么想法吗?

在图表 JS V2 中,您可以截断传递选项对象的标签。您还可以自定义工具提示。

options:{
    scales: {
        xAxes: [{
            ticks: {
                callback: function(value) {
                    return value.substr(0, 10);//truncate
                },
            }
        }],
        yAxes: [{}]
    },
    tooltips: {
        enabled: true,
        mode: 'label',
        callbacks: {
            title: function(tooltipItems, data) {
                var idx = tooltipItems[0].index;
                return 'Title:' + data.labels[idx];//do something with title
            },
            label: function(tooltipItems, data) {
                //var idx = tooltipItems.index;
                //return data.labels[idx] + ' €';
                return tooltipItems.xLabel + ' €';
            }
        }
    },
}

所以我这样做的方法是添加一个名为 labelLength 的新选项,如果传递一个大于 0 的数字,则会将 x 轴上的标签修剪到该长度。

它发生在图表的刻度类中,并且仅适用于轴标签,而不适用于工具提示。

如果需要,可以提取相关位,然后覆盖条形图中的缩放类和构建缩放函数以包含新选项。

在比例类中,这是添加的内容

 Chart.Scale = Chart.Element.extend({
        initialize: function() {
            //truncate the labels if option is grater than 0
            this.xLabels = this.labelLength > 0 ? this.xLabels.map(this.truncateLabel, this) : this.xLabels;
            this.fit();
        },
        truncateLabel: function(label) {
            return label.substring(0, this.labelLength);
        },
        addXLabel: function(label) {
            //also added here for when adding single items of data to a graph
            this.xLabels.push(this.labelLength > 0 ? this.truncateLabel(label) : label);
            this.valuesCount++;
            this.fit();
        },

}

然后在条形buildscale函数中,您需要将选项传递给秤。

或者我已经把它包含在我的图表 js (https://github.com/leighquince/Chart.js) 分支中,只需使用您想要的标签长度传递选项labelLength,下面的示例

var randomScalingFactor = function() {
  return Math.round(Math.random() * 100)
};
var barChartData = {
  labels: ["January a really long label", "February a really long label", "March a really long label", "April a really long label", "May a really long label", "June a really long label", "July a really long label"],
  datasets: [{
    fillColor: "rgba(220,220,220,0.5)",
    strokeColor: "rgba(220,220,220,0.8)",
    highlightFill: "rgba(220,220,220,0.75)",
    highlightStroke: "rgba(220,220,220,1)",
    data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
  }, {
    fillColor: "rgba(151,187,205,0.5)",
    strokeColor: "rgba(151,187,205,0.8)",
    highlightFill: "rgba(151,187,205,0.75)",
    highlightStroke: "rgba(151,187,205,1)",
    data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
  }, {
    fillColor: "rgba(15,18,20,0.5)",
    strokeColor: "rgba(15,18,20,0.8)",
    highlightFill: "rgba(15,18,20,0.75)",
    highlightStroke: "rgba(15,18,20,1)",
    data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
  }]
}
window.onload = function() {
  var ctx = document.getElementById("canvas").getContext("2d");
  window.myBar = new Chart(ctx).Bar(barChartData, {
    labelLength: 10,
  });
}
<script src="http://www.quincewebdesign.com/cdn/Chart.js"></script>
<div style="width: 50%">
  <canvas id="canvas" height="450" width="600"></canvas>
</div>

这可以在不修改插件代码的情况下实现customTooltips:function(tooltip)并带有此处记录的选项。
此处还提供了修改折线图工具提示的示例代码。使用该片段很容易实现所需的行为。
- 为自定义工具提示创建一个div。
- 截断 x 轴的标签,但保留与数组中原始文本的映射。
- 在自定义工具提示函数中,通过使用tooltip.text作为映射数组中的键,用原始文本填充工具提示div。

只是一些额外的信息(无法评论,但认为这会有所帮助)我在上面的答案中添加了一小段代码以获得"..."以显示标签是否被截断。

truncateLabel: function(label) {
    var xSubstring = label.substring(0, this.labelLength);
    if(xSubstring.length < this.labelLength) {
        return xSubstring;  
    } else {
        // Check if a word is cut off
        if ( ' ' != label.charAt( (this.labelLength-1) ) && ' ' != label.charAt( this.labelLength ) ) {
            // If so, cut the label off at the last space instead of mid-word
            var last_space_pos = label.lastIndexOf(" ", this.labelLength);
            last_space_pos = (0 > last_space_pos)? this.labelLength: last_space_pos;
            xSubstring = label.substring(0, last_space_pos);
        }
        return xSubstring+"...";
    }
},

最新更新