在Highcharts饼图中旋转dataLabels [英] Rotating dataLabels in a Highcharts pie chart
问题描述
我试图在Highcharts饼图的每一段中旋转和定位dataLabels,只是觉得我正在让自己更深入,更深入,而没有更接近解决方案。会爱一些提示或建议。
一个图形来说明所需的目标:
我最好喜欢:
- 每个dataLabel都要旋转,基本上为每个段创建一条中心线(用洋红线表示);和
- 不管类型大小如何,dataLabel都将位于细分受众群中。
建议在哪里开始这个,或一个样本,让我关闭?
$(function)(){$('#container')。highcharts({chart:{type:'pie',backgroundColor:'transparent',spacing:[0,0,0,0],margin:[0, 0,0,0],事件:{load:function(){$ .each(this.series [0] .data,function(index,point){var degree =(point.angle * 180)/ Math.PI ; var rotation = 0;(degree <0)&&(degree + = 360); //如果切片位于左半部分,则旋转180 //所以文本不会颠倒如果度数= 90&度数< 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;旋转度= 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 total market share'}},plotOptions:{pie:{borderColor:'rgb(243,243,243)',borderWidth: 2,shadow:false,center:['50%','50%'],颜色:['rgb(77,196,215)','rgb(50,68,132)','rgb(85,系列:[{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 src =http://code.highcharts.com/highcharts.js>< / script>< div id =containerstyle =height:600px; width:100%; >< / div>
我发现旋转标签本身有问题,因为当使用 highcharts
旋转它们时,它似乎将它们围绕自己的轴旋转。要达到最佳效果,您需要旋转关于饼图来源的标签。为了达到这个目的,我直接在饼图上添加了绝对定位的div,并迭代了点来计算基于百分比的旋转。不利的一面是,外部div用于标签,而不是 highcharts
自己的标签功能。
下面是我添加的代码:
首先,包含标签的div的一些CSS样式,和饼图本身:
CSS
div#container {
position:relative;
}
div.outerContainer {
width:600px;
height:40px;
位置:绝对;
top:280px;
display:none;
颜色:白色;
font-family:Helvetica,Arial,Sans;
font-size:16px;
font-weight:bold;
text-transform:大写;
}
div.outerContainer> span {
float:left;
width:300px;
text-align:center;
height:40px;
line-height:40px;
}
然后,自定义加载
事件代码来计算标签
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 =角度+ 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的左侧还是右侧,具体取决于文本的方向。 - Each dataLabel to be rotated to basically create a center line for each segment (illustrated by the magenta lines); and
- The dataLabel to be centered in the segment, regardless of type size.
Flip the label div so that the text is not upside down (or leave it if less than 90 degrees)
Decide if the text should be on the left or right side of the div, depending on its orientation.
$ b b
90){角度=角度+ 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; $(#集装箱)追加($标签)。 }); $( div.outerContainer)显示()。 }}},title:{text:null},yAxis:{title:{text:'total total market share'}},plotOptions:{pie:{borderColor:'rgb(243,243,243)',borderWidth: 2,shadow:false,center:['50%','50%'],颜色:['rgb(77,196,215)','rgb(50,68,132)','rgb(85,系列:[{type:'pie',name:'Votes',data:[['Yes',9],['No',5 ],['Undecided',2]],size:'90%'}]});
div#container {position:relative; } div.outerContainer {width:600px;高度:40像素;位置:绝对的;顶:280像素;显示:无;白颜色; font-family:Helvetica,Arial,Sans;字体大小:16px的;字体重量:粗体;文本转换:大写; } div.outerContainer> span {float:left;宽度:300像素;文本对齐:中心;高度:40像素;行高:40像素; }
< div id =containerstyle = 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>
I'm trying to rotate and position the dataLabels in each segment of a Highcharts pie chart and just feel like Im getting myself deeper and deeper without getting closer to a solution. Would love some tips or suggestions.
A graphic to illustrate the desired goal:
There will be three segments in my pie chart. I would ideally like:
Suggestions on where to get started with this, or a sample that gets me close?
$(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>
I found rotating the labels themselves to be problematic, because when using highcharts
to rotate them, it seems to rotate them about their own axis. To achieve the best result, you want to rotate the label about the origin of the pie chart. To accomplish this, I appended absolutely positioned divs directly on top of the pie chart, and iterated over the points to calculate the rotation based on percentages. The downside, of course, is that external divs are being used for the labels, rather than highcharts
's own labeling functions.
Here is the code I added:
First, some CSS styles for the divs which hold the labels, and the pie chart itself:
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;
}
Then, custom load
event code to calculate the labels
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();
}
Also, I deleted the dataLabels
property.
Brief explanation:
cumulativePercent
keeps track of how much of the pie each section contributes, so that we can insert the label exactly in the middle of each section. We check if the angle is greater than 90 degrees so that we can
See it in action:
$('#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饼图中旋转dataLabels的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!