generate clipPaths for multiple elements in d3.js

假如想象 提交于 2019-12-05 04:29:11

问题


I am trying to create partially filled circles like the ones in the final NYT political convention visualization: http://www.nytimes.com/interactive/2012/09/06/us/politics/convention-word-counts.html

The two clearest code examples I've found for clipPaths in d3 ( https://gist.github.com/1067636 and http://bl.ocks.org/3422480) create individual div elements with unique ids for each clip-path and then apply these paths to single elements.

I can not figure out how to go from these examples to a visualization with a unique circular clipPath for each element in a set of elements based on data values so that I can create my effect.

Here is what I have so far:

Given data with the following structure:

data = [        
    {value: 500, pctFull: 0.20, name: "20%"}, 
    {value: 250, pctFull: 0.75, name: "75%"},
    {value: 700, pctFull: 0.50, name: "50%"},        
]

1) Create a force diagram with a circle for each object in the dataset. The area of the circle is derived from the objects value.

2) Calculate k (and h) from a proportion (pctFull) for each datapoint using the algorithm from the mbostock example http://bl.ocks.org/3422480

3) Use k to generate a rect for each datapoint that covers the appropriate area of the circle.

I think the illustration would be done if I could limit the visibility of each rect to its respective circle but this is where I am stuck. I've tried a bunch of things, none of which have worked.

Here's the jsfilddle: http://jsfiddle.net/G8YxU/2/


回答1:


See a working fiddle here: http://jsfiddle.net/nrabinowitz/79yry/

// blue circle
node.append("circle")
    .attr("r", function(d, i) {return rVals[i];})
    .style("fill", "#80dabe")                
    .style("stroke", "#1a4876");   

// clip path for the brown circle
node.append("clipPath")
    // make an id unique to this node
    .attr('id', function(d) { return "clip" + d.index })
  // use the rectangle to specify the clip path itself 
  .append('rect')
    .attr("x", function(d, i){ return rVals[i] * (-1);})
    .attr("width", function(d, i){ return rVals[i] * 2;})
    .attr("y", function(d, i) {return rVals[i] - (2  * rVals[i] * kVals[i]);})
    .attr("height", function(d, i) {return 2  * rVals[i] * kVals[i];});

// brown circle
node.append("circle")
    // clip with the node-specific clip path
    .attr("clip-path", function(d) { return "url(#clip" + d.index + ")"})
    .attr("r", function(d, i) {return rVals[i];})
    .style("fill", "#dabe80")                
    .style("stroke", "#1a4876");   
  • It looks like the only way to specify a clip path for an element is to use the url(IRI) notation in the clip-path attribute, which means that you'll need a unique id for each clip path based on the node data. I've used the form clip<node index> for the id - so each node gets its own clip path, and other sub-elements of the node can refer to it.

  • It seemed easiest, following Mike's example, to make two circles of different colors and use the rectangle itself for the clip path, rather than making a circle-based clip path. But you could do it either way.



来源:https://stackoverflow.com/questions/12390158/generate-clippaths-for-multiple-elements-in-d3-js

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!