在 Highcharts 饼图中旋转数据标签
Rotating dataLabels in a Highcharts pie chart
我正在尝试在 Highcharts 饼图的每个部分中旋转和定位数据标签,但感觉自己越来越深入,却没有接近解决方案。希望得到一些提示或建议。
说明预期目标的图形:
我的饼图将分为三个部分。我理想情况下喜欢:
- 要旋转的每个数据标签基本上为每个段创建一条中心线(由洋红色线表示);和
- 要在段中居中的数据标签,无论类型大小如何。
关于从哪里开始的建议,或者让我接近的示例?
$(function () {
$('#container').highcharts({
chart: {
type: 'pie',
backgroundColor: 'transparent',
spacing: [0, 0, 0, 0],
margin: [0, 0, 0, 0],
events: {
load: function() {
$.each(this.series[0].data, function(index, point) {
var degree = (point.angle * 180) / Math.PI;
var rotation = 0;
(degree < 0) && (degree += 360);
// If the slice is in the left half, then rotate 180
// so the text won't look upside down
if (degree >= 90 && degree <= 270) {
rotation = degree - 180;
point.dataLabel.x = 0;
point.dataLabel.y = 0;
point.dataLabel.translateX = (point.labelPos[2] + point.labelPos[4]) / 2;
point.dataLabel.translateY = (point.labelPos[3] + point.labelPos[5]) / 2;
} else {
point.dataLabel.x = 0;
point.dataLabel.y = 0;
rotation = degree - 180;
point.dataLabel.translateX = (point.labelPos[2] + point.labelPos[4]) / 2;
point.dataLabel.translateY = (point.labelPos[3] + point.labelPos[5]) / 2;
}
point.dataLabel.rotation = Math.floor(rotation);
point.dataLabel.show();
point.dataLabel.updateTransform();
});
}
}
},
title: {
text: null
},
yAxis: {
title: {
text: 'Total percent market share'
}
},
plotOptions: {
pie: {
borderColor: 'rgb(243, 243, 243)',
borderWidth: 2,
shadow: false,
center: ['50%', '50%'],
colors: ['rgb(77, 196, 215)', 'rgb(50, 68, 132)', 'rgb(85, 119, 183)']
}
},
tooltip: {
enabled: false
},
series: [{
type: 'pie',
name: 'Votes',
data: [
['Yes', 9],
['No', 5],
['Undecided', 2]
],
size: '90%',
dataLabels: {
formatter: function () {
return this.point.name;
},
color: 'white',
connectorWidth: 0,
distance: -80
}
}]
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<div id="container" style="height: 600px; width: 100%;"></div>
我发现旋转标签本身是有问题的,因为当使用 highcharts
旋转它们时,它似乎绕着它们自己的轴旋转。为获得最佳结果,您需要围绕饼图的原点旋转标签。为此,我将绝对定位的 div 直接附加在饼图的顶部,并迭代这些点以根据百分比计算旋转。当然,缺点是外部 div 用于标签,而不是 highcharts
自己的标签函数。
这是我添加的代码:
首先,CSS 包含标签的 CSS 样式,以及饼图本身:
CSS
div#container{
position:relative;
}
div.outerContainer{
width:600px;
height:40px;
position:absolute;
top:280px;
display:none;
color:white;
font-family:Helvetica, Arial, Sans;
font-size:16px;
font-weight:bold;
text-transform:uppercase;
}
div.outerContainer > span{
float:left;
width:300px;
text-align:center;
height:40px;
line-height:40px;
}
然后,自定义load
事件代码来计算标签
load: function () {
var cumulativePercentage = 0;
var $labelTemplate = $("<div class=outerContainer><span class=left></span><span class=right></span></div>");
$.each(this.series[0].data, function (i, point) {
$label=$labelTemplate.clone();
$label.find('span').text(point.name);
var angle=-90+(cumulativePercentage+point.percentage/2)*360/100;
if (angle > 90) {
angle=angle+180;
$label.find('span.right').css({visibility:'hidden'});
}
else {
$label.find('span.left').css({visibility:'hidden'});
}
$label.css({transform:'rotate('+angle+'deg)'});
cumulativePercentage+=point.percentage;
$('#container').append($label);
});
$('div.outerContainer').show();
}
另外,我删除了dataLabels
属性。
简要说明:
cumulativePercent
跟踪每个部分贡献了多少馅饼,以便我们可以将标签恰好插入每个部分的中间。我们检查角度是否大于 90 度,这样我们就可以
翻转标签div使文字不上下颠倒(小于90度则保留)
根据其方向决定文本应该位于 div 的左侧还是右侧。
查看实际效果:
$('#container').highcharts({
chart: {
type: 'pie',
backgroundColor: 'transparent',
spacing: [0, 0, 0, 0],
margin: [0, 0, 0, 0],
events: {
load: function () {
var cumulativePercentage = 0;
var $labelTemplate = $("<div class=outerContainer><span class=left></span><span class=right></span></div>");
$.each(this.series[0].data, function (i, point) {
$label = $labelTemplate.clone();
$label.find('span').text(point.name);
var angle = -90 + (cumulativePercentage + point.percentage / 2) * 360 / 100;
if (angle > 90) {
angle = angle + 180;
$label.find('span.right').css({visibility: 'hidden'});
}
else {
$label.find('span.left').css({visibility: 'hidden'});
}
$label.css({transform: 'rotate(' + angle + 'deg)'});
cumulativePercentage += point.percentage;
$('#container').append($label);
});
$('div.outerContainer').show();
}
}
},
title: {
text: null
},
yAxis: {
title: {
text: 'Total percent market share'
}
},
plotOptions: {
pie: {
borderColor: 'rgb(243, 243, 243)',
borderWidth: 2,
shadow: false,
center: ['50%', '50%'],
colors: ['rgb(77, 196, 215)', 'rgb(50, 68, 132)', 'rgb(85, 119, 183)']
}
},
tooltip: {
enabled: false
},
series: [{
type: 'pie',
name: 'Votes',
data: [
['Yes', 9],
['No', 5],
['Undecided', 2]
],
size: '90%'
}]
});
div#container{
position:relative;
}
div.outerContainer{
width:600px;
height:40px;
position:absolute;
top:280px;
display:none;
color:white;
font-family:Helvetica, Arial, Sans;
font-size:16px;
font-weight:bold;
text-transform:uppercase;
}
div.outerContainer > span{
float:left;
width:300px;
text-align:center;
height:40px;
line-height:40px;
}
<div id="container" style="height: 600px; width: 600px;"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
Highcharts 未提供在饼图中自动旋转数据标签的选项。您可以为数据标签旋转编写自定义函数。
这是一个简单的例子,你可以怎么做:
var allY, angle1, angle2, angle3,
rotate = function () {
$.each(options.series, function (i, p) {
angle1 = 0;
angle2 = 0;
angle3 = 0;
allY = 0;
$.each(p.data, function (i, p) {
allY += p.y;
});
$.each(p.data, function (i, p) {
angle2 = angle1 + p.y * 360 / (allY);
angle3 = angle2 - p.y * 360 / (2 * allY);
p.dataLabels.rotation = -90 + angle3;
angle1 = angle2;
});
});
};
首先我计算所有 Y 值的总和。然后我计算所有饼图中间的角度。然后我将数据标签旋转相同的角度。
示例:
http://jsfiddle.net/izothep/j7as86gh/6/
类似主题:
我正在尝试在 Highcharts 饼图的每个部分中旋转和定位数据标签,但感觉自己越来越深入,却没有接近解决方案。希望得到一些提示或建议。
说明预期目标的图形:
我的饼图将分为三个部分。我理想情况下喜欢:
- 要旋转的每个数据标签基本上为每个段创建一条中心线(由洋红色线表示);和
- 要在段中居中的数据标签,无论类型大小如何。
关于从哪里开始的建议,或者让我接近的示例?
$(function () {
$('#container').highcharts({
chart: {
type: 'pie',
backgroundColor: 'transparent',
spacing: [0, 0, 0, 0],
margin: [0, 0, 0, 0],
events: {
load: function() {
$.each(this.series[0].data, function(index, point) {
var degree = (point.angle * 180) / Math.PI;
var rotation = 0;
(degree < 0) && (degree += 360);
// If the slice is in the left half, then rotate 180
// so the text won't look upside down
if (degree >= 90 && degree <= 270) {
rotation = degree - 180;
point.dataLabel.x = 0;
point.dataLabel.y = 0;
point.dataLabel.translateX = (point.labelPos[2] + point.labelPos[4]) / 2;
point.dataLabel.translateY = (point.labelPos[3] + point.labelPos[5]) / 2;
} else {
point.dataLabel.x = 0;
point.dataLabel.y = 0;
rotation = degree - 180;
point.dataLabel.translateX = (point.labelPos[2] + point.labelPos[4]) / 2;
point.dataLabel.translateY = (point.labelPos[3] + point.labelPos[5]) / 2;
}
point.dataLabel.rotation = Math.floor(rotation);
point.dataLabel.show();
point.dataLabel.updateTransform();
});
}
}
},
title: {
text: null
},
yAxis: {
title: {
text: 'Total percent market share'
}
},
plotOptions: {
pie: {
borderColor: 'rgb(243, 243, 243)',
borderWidth: 2,
shadow: false,
center: ['50%', '50%'],
colors: ['rgb(77, 196, 215)', 'rgb(50, 68, 132)', 'rgb(85, 119, 183)']
}
},
tooltip: {
enabled: false
},
series: [{
type: 'pie',
name: 'Votes',
data: [
['Yes', 9],
['No', 5],
['Undecided', 2]
],
size: '90%',
dataLabels: {
formatter: function () {
return this.point.name;
},
color: 'white',
connectorWidth: 0,
distance: -80
}
}]
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<div id="container" style="height: 600px; width: 100%;"></div>
我发现旋转标签本身是有问题的,因为当使用 highcharts
旋转它们时,它似乎绕着它们自己的轴旋转。为获得最佳结果,您需要围绕饼图的原点旋转标签。为此,我将绝对定位的 div 直接附加在饼图的顶部,并迭代这些点以根据百分比计算旋转。当然,缺点是外部 div 用于标签,而不是 highcharts
自己的标签函数。
这是我添加的代码:
首先,CSS 包含标签的 CSS 样式,以及饼图本身:
CSS
div#container{
position:relative;
}
div.outerContainer{
width:600px;
height:40px;
position:absolute;
top:280px;
display:none;
color:white;
font-family:Helvetica, Arial, Sans;
font-size:16px;
font-weight:bold;
text-transform:uppercase;
}
div.outerContainer > span{
float:left;
width:300px;
text-align:center;
height:40px;
line-height:40px;
}
然后,自定义load
事件代码来计算标签
load: function () {
var cumulativePercentage = 0;
var $labelTemplate = $("<div class=outerContainer><span class=left></span><span class=right></span></div>");
$.each(this.series[0].data, function (i, point) {
$label=$labelTemplate.clone();
$label.find('span').text(point.name);
var angle=-90+(cumulativePercentage+point.percentage/2)*360/100;
if (angle > 90) {
angle=angle+180;
$label.find('span.right').css({visibility:'hidden'});
}
else {
$label.find('span.left').css({visibility:'hidden'});
}
$label.css({transform:'rotate('+angle+'deg)'});
cumulativePercentage+=point.percentage;
$('#container').append($label);
});
$('div.outerContainer').show();
}
另外,我删除了dataLabels
属性。
简要说明:
cumulativePercent
跟踪每个部分贡献了多少馅饼,以便我们可以将标签恰好插入每个部分的中间。我们检查角度是否大于 90 度,这样我们就可以
翻转标签div使文字不上下颠倒(小于90度则保留)
根据其方向决定文本应该位于 div 的左侧还是右侧。
查看实际效果:
$('#container').highcharts({
chart: {
type: 'pie',
backgroundColor: 'transparent',
spacing: [0, 0, 0, 0],
margin: [0, 0, 0, 0],
events: {
load: function () {
var cumulativePercentage = 0;
var $labelTemplate = $("<div class=outerContainer><span class=left></span><span class=right></span></div>");
$.each(this.series[0].data, function (i, point) {
$label = $labelTemplate.clone();
$label.find('span').text(point.name);
var angle = -90 + (cumulativePercentage + point.percentage / 2) * 360 / 100;
if (angle > 90) {
angle = angle + 180;
$label.find('span.right').css({visibility: 'hidden'});
}
else {
$label.find('span.left').css({visibility: 'hidden'});
}
$label.css({transform: 'rotate(' + angle + 'deg)'});
cumulativePercentage += point.percentage;
$('#container').append($label);
});
$('div.outerContainer').show();
}
}
},
title: {
text: null
},
yAxis: {
title: {
text: 'Total percent market share'
}
},
plotOptions: {
pie: {
borderColor: 'rgb(243, 243, 243)',
borderWidth: 2,
shadow: false,
center: ['50%', '50%'],
colors: ['rgb(77, 196, 215)', 'rgb(50, 68, 132)', 'rgb(85, 119, 183)']
}
},
tooltip: {
enabled: false
},
series: [{
type: 'pie',
name: 'Votes',
data: [
['Yes', 9],
['No', 5],
['Undecided', 2]
],
size: '90%'
}]
});
div#container{
position:relative;
}
div.outerContainer{
width:600px;
height:40px;
position:absolute;
top:280px;
display:none;
color:white;
font-family:Helvetica, Arial, Sans;
font-size:16px;
font-weight:bold;
text-transform:uppercase;
}
div.outerContainer > span{
float:left;
width:300px;
text-align:center;
height:40px;
line-height:40px;
}
<div id="container" style="height: 600px; width: 600px;"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
Highcharts 未提供在饼图中自动旋转数据标签的选项。您可以为数据标签旋转编写自定义函数。
这是一个简单的例子,你可以怎么做:
var allY, angle1, angle2, angle3,
rotate = function () {
$.each(options.series, function (i, p) {
angle1 = 0;
angle2 = 0;
angle3 = 0;
allY = 0;
$.each(p.data, function (i, p) {
allY += p.y;
});
$.each(p.data, function (i, p) {
angle2 = angle1 + p.y * 360 / (allY);
angle3 = angle2 - p.y * 360 / (2 * allY);
p.dataLabels.rotation = -90 + angle3;
angle1 = angle2;
});
});
};
首先我计算所有 Y 值的总和。然后我计算所有饼图中间的角度。然后我将数据标签旋转相同的角度。
示例: http://jsfiddle.net/izothep/j7as86gh/6/
类似主题: