我想创建一个显示完成百分比的半圆形圆环图。但要求是从右到左绘制百分比映射,而不是从左到右。以下是我的代码,
var percent = 30;
var ratio=percent/100;
var pie=d3.layout.pie()
.value(function(d){return d})
.sort(null);
var w=300,h=300;
var outerRadius=(w/2)-10;
var innerRadius=85;
var color = ['#ececec','#f06b3e','#888888'];
var colorOld='#F00';
var colorNew='#0F0';
var arc=d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius)
.startAngle(0)
.endAngle(Math.PI);
var arcLine=d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius)
.startAngle(0);
var svg=d3.select("#chart")
.append("svg")
.attr({
width:w,
height:h,
class:'shadow'
}).append('g')
.attr({
transform:'translate('+w/2+','+h/2+')'
});
var path=svg.append('path')
.attr({
d:arc,
transform:'rotate(-90)'
}).attr({
'stroke-width':"1",
stroke:"#666666"
})
.style({
fill:color[0]
});
var pathForeground=svg.append('path')
.datum({endAngle:0})
.attr({
d:arcLine,
transform:'rotate(-90)'
})
.style({
fill: function (d,i) {
return color[1];
}
});
var middleCount=svg.append('text')
.datum(0)
.text(function(d){
return d;
})
.attr({
class:'middleText',
'text-anchor':'middle',
dy:0,
dx:5
})
.style({
fill:d3.rgb('#000000'),
'font-size':'60px'
});
var oldValue=0;
var arcTween=function(transition, newValue,oldValue) {
transition.attrTween("d", function (d) {
var interpolate = d3.interpolate(d.endAngle, ((Math.PI))*(newValue/100));
var interpolateCount = d3.interpolate(oldValue, newValue);
return function (t) {
d.endAngle = interpolate(t);
middleCount.text(Math.floor(interpolateCount(t))+'%');
arcLine=d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius)
.startAngle(function(){
return (newValue * (Math.PI / 180));
});
return arcLine(d);
};
});
};
pathForeground.transition()
.duration(0)
.ease('cubic')
.call(arcTween,percent,oldValue);
在上面的代码中,我们使用svg:path绘制一个半圆形圆环图,然后再次绘制另一个svg:path,用于指示从左到右的完成百分比。
我们如何使用d3js从右到左而不是从左到右绘制百分比指标?
答案 0 :(得分:1)
首先,你的弧线上有一个rotate(90)
,这让我的大脑骨折了,所以我将它移除了。现在让我们开始思考角度的位置。从本质上讲,你想要从Math.PI/2
开始制作动画并向后移向0.然后数学看起来像这样:
这是一些正在运行的代码:
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.js"></script>
</head>
<body>
Click Chart to Re-Animate!
<div id="chart"></div>
<script>
var percent = Math.random() * 100;
var pie = d3.layout.pie()
.value(function(d) {
return d
})
.sort(null);
var w = 300,
h = 300;
var outerRadius = (w / 2) - 10;
var innerRadius = 85;
var color = ['#ececec', '#f06b3e', '#888888'];
var colorOld = '#F00';
var colorNew = '#0F0';
var arc = d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius)
.startAngle(0)
.endAngle(Math.PI);
var arcLine = d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius);
var svg = d3.select("#chart")
.append("svg")
.attr({
width: w,
height: h,
class: 'shadow'
}).append('g')
.attr({
transform: 'translate(' + w / 2 + ',' + h / 2 + ')'
})
.on('click', function(){
pathForeground.transition()
.duration(1000)
.ease('cubic')
.call(arcTween, Math.random() * 100, 0);
});
var path = svg.append('path')
.attr({
d: arc,
transform: 'rotate(-90)'
}).attr({
'stroke-width': "1",
stroke: "#666666"
})
.style({
fill: color[0]
});
var pathForeground = svg.append('path')
.datum({
endAngle: 0
})
.style({
fill: function(d, i) {
return color[1];
}
});
var middleCount = svg.append('text')
.datum(0)
.text(function(d) {
return d;
})
.attr({
class: 'middleText',
'text-anchor': 'middle',
dy: 0,
dx: 5
})
.style({
fill: d3.rgb('#000000'),
'font-size': '60px'
});
var oldValue = 0;
var arcTween = function(transition, newValue, oldValue) {
transition.attrTween("d", function(d) {
arcLine.startAngle(Math.PI / 2);
var interpolate = d3.interpolate(Math.PI / 2, (Math.PI / 2) - (Math.PI * (newValue / 100)));
var interpolateCount = d3.interpolate(oldValue, newValue);
return function(t) {
d.endAngle = interpolate(t);
middleCount.text(Math.floor(interpolateCount(t)) + '%');
return arcLine(d);
};
});
};
pathForeground.transition()
.duration(1000)
.ease('cubic')
.call(arcTween, percent, oldValue);
</script>
</body>
</html>