我需要绘制具有许多值(其中一部分是接近的)和长值标签的图表 . 值应显示在图表上(而不是图例) . 我正在使用以下插件来显示标签:
var drawItemsValuesPlugin = {
afterDraw: function(chartInstance) {
var ctx = chartInstance.chart.ctx;
// render the value of the chart above the bar
ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize, 'normal', Chart.defaults.global.defaultFontFamily);
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
ctx.strokeStyle = 'black';
ctx.font = "bold 11pt Arial";
ctx.lineWidth = 0.3;
chartInstance.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,
total = dataset._meta[Object.keys(dataset._meta)[0]].total,
mid_radius = model.innerRadius + (model.outerRadius - model.innerRadius)/2,
start_angle = model.startAngle,
end_angle = model.endAngle,
mid_angle = start_angle + (end_angle - start_angle)/2;
var fact = (chartInstance.config.type == 'pie'?
(i%2==0?1:1.6):
(i%2==0?0.9:1.1)
);
var x = mid_radius * fact * Math.cos(mid_angle);
var y = mid_radius * fact * Math.sin(mid_angle);
ctx.fillStyle = '#fff';
var label = chartInstance.config.data.labels[i];
var percent = String(Math.round(dataset.data[i]/total*100)) + "%";
ctx.fillText(label, model.x + x, model.y + y);
ctx.strokeText(label, model.x + x, model.y + y);
// Display percent in another line, line break doesn't work for fillText
ctx.fillText(dataset.data[i] + ' ('+percent+')', model.x + x, model.y + y + 15);
ctx.strokeText(dataset.data[i] + ' ('+percent+')', model.x + x, model.y + y + 15);
}
});
}
};
但我面临以下问题:
值标签挤在一起 . 一个简单的解决方案是将标签绕在轨道图上,如下图所示:
如何使用Chart JS 2.0获得此标签位置?
3 回答
注意:下面不是工作代码 . 只是一个布局 .
//这4个点=甜甜圈派的一部分 .
//仅查找外圈的上方坐标的中间位置
//你需要找到以像素为单位的文字高度 .
//这是文本的一半高度,因此可以将线条绘制到文本的中点 .
//制作一个更大的圆圈,然后添加一个小填充,使文字不在圆圈上 .
//好的坏代码弄清楚x,y坐标是什么 . 运用
在上面的所有事情上都有一个令人烦恼的环路 . 更改上面的最后一个代码 . 所以它每增加一点就会增加 . 所以没有标签会在彼此之上运行 .
你需要输入一个if / then / else函数来检查x是正数还是负数 . 并从my_next_height []向左或向右绘制线条 .
然后画出你的文字 .
还有一点是从外圆画出线,然后排到目前为止,然后放置标签 . 但是上面切断了代码的布局,应该给你足够的坐标来实现这一点 .
我试图避免使用x,y和z坐标 . 在没有打开旧的小学数学书的情况下,我永远不会记得找到点和角度的数学 . 并查看你的代码mid_radius,以及所有代码,我没有看到我在找到正确的x,y绘图点时记住的正常数学 .
尝试这个如果可以帮助你,作为charjs的简单解决方案
这是一个答案草案 . 它的主要目的是给你希望 . 没办法是最终的(它会在几天后最终确定),因为:
代码丑陋,黑客攻击,无证件 . 它基于您提供的插件 .
该代码需要Chart.js 2的下一个次要版本(可能是2.3.1) . 我已经构建了今天的Chart.js的主分支并将其上传到我的Dropbox中,因为最近合并的
layout.padding
选项是必需的,以便为围绕轨道标签的饼图提供空间(没有此选项标签将被切断) .绝对需要改进 .
这是demo .
一条小线将饼图的每个切片连接到轨道中的相应标签 . 连续标签(除了第一个和最后一个,如果数据集具有奇数个元素)将以不同的半径进行轨道运行,因此可以避免冲突 . 但我猜需要更多关心 . 主要问题是如何确保图表具有响应性 .
layout.padding
是指像素,而不是百分比 . 此外,标签字体目前在大小方面是固定的 . 我认为只是将标签的位置设置为距离画布边界一定的距离(因为填充也是固定的)可以解决这个问题(调整图表大小会给出一些想法,但稍后会有更多的想法) .该演示也可以在下面找到,但它无法从Dropbox加载JavaScript文件(而JSFiddle不应该失败 - 当更新Chart.js的CDN版本时,我将更新所有链接):