I want to achieve something like a growing arc which indicates 5 levels (see picture). My data has only an integer value which is between 1-5. You can ignore the icon in the middle for now. Is there any possibility to achieve something like that in d3? I couldn't find any example for this. Moreover I tried it with a cut off pie (donut) chart approach, but I couldn't make the growing arc... I would appreciate any help! Thanks for that.
我希望实现类似于增长的弧形,表示5个等级(见图)。我的数据只有一个介于1-5之间的整数值。您现在可以忽略中间的图标。是否有可能在d3中实现类似的目标?我找不到任何这方面的例子。此外,我尝试了一个切断的馅饼(甜甜圈)图表方法,但我不能成为越来越多的弧...我会感激任何帮助!感谢那。
3 个解决方案
#1
You can do this with d3 without dependency on external images, SVG sprites or anything in the DOM — just d3.js.
您可以使用d3执行此操作,而不依赖于外部图像,SVG精灵或DOM中的任何内容 - 只需d3.js.
Here's a working fiddle. The implementation is explained below. But also, here's a more advanced fiddle that animates a clip-path over the growing arc. Check out its predecessor to see how the mask looks without clipping.
这是一个工作小提琴。实现解释如下。而且,这里还有一个更先进的小提琴,可以在不断增长的弧线上设置剪辑路径。看看它的前身,看看面具如何看起来没有剪裁。
First, you need to represent the graphics as an array of data that you bind to with d3. Specifically, you need a color and a "line command" (the string you assign to d as in <path d="...">
. Something like this:
首先,您需要将图形表示为与d3绑定的数据数组。具体来说,你需要一个颜色和一个“行命令”(你在
var segmentData = [
{ color:"#ED6000", cmd:"M42.6,115.3c5.2,1.5,11,2.4,16.8,2.4c1.1,0,2.7,0,3.7-0.1v-2.2c-7,0-13.1-1.3-18.8-3.6L42.6,115.3z" },
{ color:"#EF7D00", cmd:"M25.7,99.3c4.3,4.7,9.5,8.6,15.3,11.3l-1.4,3.8c-6.9-2.4-13.2-6.1-18.6-10.8L25.7,99.3z" },
{ color:"#F4A300", cmd:"M23.7,97c-5.2-6.4-8.8-14-10.3-22.4L2.9,75.7c2.9,10,8.5,18.9,15.8,25.9L23.7,97z" },
{ color:"#F7BC00", cmd:"M13,71.5c-0.2-2-0.4-4-0.4-6c0-10.7,3.4-20.6,9.2-28.8L9.4,28.3c-5.6,9-8.9,19.6-8.9,30.9 c0,4.6,0.6,9.1,1.6,13.5L13,71.5z" },
{ color:"#FFCF36", cmd:"M63,15.7V0.8c-1-0.1-2.5-0.1-3.7-0.1c-19.9,0-37.5,9.9-48.1,25l12.7,8.6C33.1,23,46,15.7,63,15.7z" }
];
Then you need an empty <svg>
and probably a <g>
within it, into which to draw the graphics:
然后你需要一个空的
var svg = d3.select("body").append("svg")
.attr("width", 125)
.attr("height", 125);
var gauge = svg.append("g");
Then you use d3 binding to create the segments:
然后使用d3绑定创建段:
var segments = gauge.selectAll(".segment")
.data(segmentData);
segments.enter()
.append("path")
.attr("fill", function(d) { return d.color; })
.attr("d", function(d) { return d.cmd; });
This just creates the graphic, but doesn't color it based on an integer value. For that, you can define an update
function:
这只是创建图形,但不会根据整数值对其进行着色。为此,您可以定义更新功能:
function update(value) {
segments
.transition()
.attr("fill", function(d, i) {
return i < value ? d.color : "#ccc";
})
}
Calling update(4)
will color all but the last segment. Calling update(0)
color none (leaving all of them gray).
调用update(4)将为最后一段除外。调用update(0)color none(将所有这些都保持为灰色)。
In the fiddle, there's also a tick()
function that calls update
with a new value on a setTimeout basis, but that's just for demo.
在小提琴中,还有一个tick()函数,它在setTimeout的基础上使用新值调用update,但这仅适用于demo。
Finally, if you wish, you can wrap all that code up and create a reusable component by following the advice in [this article].(http://bost.ocks.org/mike/chart/)
最后,如果您愿意,可以按照[本文]中的建议包装所有代码并创建可重用的组件。(http://bost.ocks.org/mike/chart/)
#2
since it is relatively simple picture, I'd use a sprite, with 5 variations. That would be much easier than using d3 and gives the same result. (you could use some online tool like http://spritepad.wearekiss.com/ )
因为它是相对简单的图片,我会使用一个精灵,有5种变化。这比使用d3容易得多并给出相同的结果。 (你可以使用一些在线工具,如http://spritepad.wearekiss.com/)
#3
If you want to mimic duolingo progress images you can just simply copy their solution with own images. They are using sprites as this one: http://d7mj4aqfscim2.cloudfront.net/images/skill-strength-sprite2.svg not the d3.js approach. This will save you a lot of time and effort.
如果你想模仿duolingo进度图像,你可以简单地用自己的图像复制他们的解决方案。他们正在使用sprite:http://d7mj4aqfscim2.cloudfront.net/images/skill-strength-sprite2.svg而不是d3.js方法。这将为您节省大量的时间和精力。
#1
You can do this with d3 without dependency on external images, SVG sprites or anything in the DOM — just d3.js.
您可以使用d3执行此操作,而不依赖于外部图像,SVG精灵或DOM中的任何内容 - 只需d3.js.
Here's a working fiddle. The implementation is explained below. But also, here's a more advanced fiddle that animates a clip-path over the growing arc. Check out its predecessor to see how the mask looks without clipping.
这是一个工作小提琴。实现解释如下。而且,这里还有一个更先进的小提琴,可以在不断增长的弧线上设置剪辑路径。看看它的前身,看看面具如何看起来没有剪裁。
First, you need to represent the graphics as an array of data that you bind to with d3. Specifically, you need a color and a "line command" (the string you assign to d as in <path d="...">
. Something like this:
首先,您需要将图形表示为与d3绑定的数据数组。具体来说,你需要一个颜色和一个“行命令”(你在
var segmentData = [
{ color:"#ED6000", cmd:"M42.6,115.3c5.2,1.5,11,2.4,16.8,2.4c1.1,0,2.7,0,3.7-0.1v-2.2c-7,0-13.1-1.3-18.8-3.6L42.6,115.3z" },
{ color:"#EF7D00", cmd:"M25.7,99.3c4.3,4.7,9.5,8.6,15.3,11.3l-1.4,3.8c-6.9-2.4-13.2-6.1-18.6-10.8L25.7,99.3z" },
{ color:"#F4A300", cmd:"M23.7,97c-5.2-6.4-8.8-14-10.3-22.4L2.9,75.7c2.9,10,8.5,18.9,15.8,25.9L23.7,97z" },
{ color:"#F7BC00", cmd:"M13,71.5c-0.2-2-0.4-4-0.4-6c0-10.7,3.4-20.6,9.2-28.8L9.4,28.3c-5.6,9-8.9,19.6-8.9,30.9 c0,4.6,0.6,9.1,1.6,13.5L13,71.5z" },
{ color:"#FFCF36", cmd:"M63,15.7V0.8c-1-0.1-2.5-0.1-3.7-0.1c-19.9,0-37.5,9.9-48.1,25l12.7,8.6C33.1,23,46,15.7,63,15.7z" }
];
Then you need an empty <svg>
and probably a <g>
within it, into which to draw the graphics:
然后你需要一个空的
var svg = d3.select("body").append("svg")
.attr("width", 125)
.attr("height", 125);
var gauge = svg.append("g");
Then you use d3 binding to create the segments:
然后使用d3绑定创建段:
var segments = gauge.selectAll(".segment")
.data(segmentData);
segments.enter()
.append("path")
.attr("fill", function(d) { return d.color; })
.attr("d", function(d) { return d.cmd; });
This just creates the graphic, but doesn't color it based on an integer value. For that, you can define an update
function:
这只是创建图形,但不会根据整数值对其进行着色。为此,您可以定义更新功能:
function update(value) {
segments
.transition()
.attr("fill", function(d, i) {
return i < value ? d.color : "#ccc";
})
}
Calling update(4)
will color all but the last segment. Calling update(0)
color none (leaving all of them gray).
调用update(4)将为最后一段除外。调用update(0)color none(将所有这些都保持为灰色)。
In the fiddle, there's also a tick()
function that calls update
with a new value on a setTimeout basis, but that's just for demo.
在小提琴中,还有一个tick()函数,它在setTimeout的基础上使用新值调用update,但这仅适用于demo。
Finally, if you wish, you can wrap all that code up and create a reusable component by following the advice in [this article].(http://bost.ocks.org/mike/chart/)
最后,如果您愿意,可以按照[本文]中的建议包装所有代码并创建可重用的组件。(http://bost.ocks.org/mike/chart/)
#2
since it is relatively simple picture, I'd use a sprite, with 5 variations. That would be much easier than using d3 and gives the same result. (you could use some online tool like http://spritepad.wearekiss.com/ )
因为它是相对简单的图片,我会使用一个精灵,有5种变化。这比使用d3容易得多并给出相同的结果。 (你可以使用一些在线工具,如http://spritepad.wearekiss.com/)
#3
If you want to mimic duolingo progress images you can just simply copy their solution with own images. They are using sprites as this one: http://d7mj4aqfscim2.cloudfront.net/images/skill-strength-sprite2.svg not the d3.js approach. This will save you a lot of time and effort.
如果你想模仿duolingo进度图像,你可以简单地用自己的图像复制他们的解决方案。他们正在使用sprite:http://d7mj4aqfscim2.cloudfront.net/images/skill-strength-sprite2.svg而不是d3.js方法。这将为您节省大量的时间和精力。