BruCh
BruCh

Reputation: 13

SVG path element created by d3 (d3.svg.arc) disappearing when mask is applied

I'm trying to put textures (e.g. stripes) on a svg path element created by d3 arc function. I found this example (https://bl.ocks.org/jfsiii/7772281), which it's exactly what I want (using css to apply the mask), but when I apply on a path element created by d3 arc function, the path disappears.

I did a jsfiddle to show the problem. I used the pie chart example from Mike Bostock (http:// bl.ocks.org/mbostock/3887235) and applied the mask from the other example. I'm trying to apply the mask to the pie chart (slice of 5-13 ages) and it's not showing. I even thought it was a problem with svg path element, but if I create a path explicit on the svg (blue rect on the jsfiddle) the mask works.

Anyone have any ideas why this is happening? Is it any configuration I'm missing in the d3 arc function? Any steps I should be doing and I'm not? I really would like to use mask by css.

Code part where I'm applying the mask:

// selecting slice with population (4499890)
d3.select('#id_4499890').classed('hbar',true);

The jsfiddle showing the problem.

Thanks!

Upvotes: 1

Views: 618

Answers (1)

Mark
Mark

Reputation: 108537

Your mask is a rect occupying space from 0 to 100% in the y direction, your arc path though is occupying space from -46 to -125 in the y direction, the two don't overlap at all.

So, simply start your rect more negative:

defs.append("mask")
    .attr("id","mask-stripe")
    .append("rect")
    .attr("x","-200")
    .attr("y","-200")
    .attr("width","100%")
    .attr("height","100%")
    .attr("fill",'url(#pattern-stripe)');

Update fiddle.


Full Code:

//adding the pattern
var defs = d3.select("#svgPattern").append("defs");
  defs.append("pattern")
    .attr("id","pattern-stripe")
    .attr("width","4")
    .attr("height","4")
    .attr("patternUnits","userSpaceOnUse")
    .attr("patternTransform","rotate(45)")
    .append("rect")
    .attr("width","2")
    .attr("height","4")
    .attr("transform","translate(0,0)")
    .attr("fill","white");

  defs.append("mask")
    .attr("id","mask-stripe")
    .append("rect")
    .attr("x","-200")
    .attr("y","-200")
    .attr("width","100%")
    .attr("height","100%")
    .attr("fill",'url(#pattern-stripe)');

function drawChart(){
  var width = 660,
      height = 300,
      radius = Math.min(width, height) / 2;

  var color = d3.scale.ordinal()
      .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);

  var arc = d3.svg.arc()
      .outerRadius(radius - 10)
      .innerRadius(0);

  var labelArc = d3.svg.arc()
      .outerRadius(radius - 40)
      .innerRadius(radius - 40);

  var pie = d3.layout.pie()
      .sort(null)
      .value(function(d) { return d.population; });

  function type(d) {
    d.population = +d.population;
    return d;
  }

  var svg = d3.select("#svgPattern")
      .attr("width", width)
      .attr("height", height)
    	.append("g")
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

    var g = svg.selectAll(".arc")
        .data(pie(data))
      	.enter().append("g")
        .attr("class", "arc");

    g.append("path")
        .attr("d", arc)
        .attr("id", function(d) { return 'id_'+d.data.population; })
        .style("fill", function(d) { return color(d.data.age); });

    g.append("text")
        .attr("transform", function(d) { return "translate(" + labelArc.centroid(d) + ")";})
        .attr("dy", ".35em")
        .text(function(d) { return d.data.age; });

      // selecting slice with population (4499890)
      d3.select('#id_4499890').classed('hbar',true);
}

var data = [
  {
    "age": "<5",
    "population": 2704659
  },
  {
    "age": "5-13",
    "population": 4499890
  },
  {
    "age": "14-17",
    "population": 2159981
  },
  {
    "age": "18-24",
    "population": 3853788
  },
  {
    "age": "25-44",
    "population": 14106543
  },
  {
    "age": "45-64",
    "population": 8819342
  },
  {
    "age": "≥65",
    "population": 612463
  }
];

drawChart();
.arc text {
  font: 10px sans-serif;
  text-anchor: middle;
}

.arc path {
  stroke: #fff;
}

.hbar {
  mask: url(#mask-stripe)
}
.thing-2{
  fill: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<!-- 
  Pie chart from: http://bl.ocks.org/mbostock/3887235 
  Mask example from: https://bl.ocks.org/jfsiii/7772281
  --> 
<svg id="svgPattern" >
  <!-- bar chart -->
  <rect class="hbar thing-2" x="0" y="0" width="50" height="100"></rect>
  <rect class="hbar thing-2" x="51" y="50" width="50" height="50"></rect>
  <rect class="hbar thing-2" x="102" y="25" width="50" height="75"></rect>
  <path d="M0,150 150,150 150,200 0,200" class="hbar" fill="blue" />
  
</svg>

Upvotes: 0

Related Questions