Skip to content
Advertisement

d3js mask to show dots over bar chart

i saw this example here: https://jsfiddle.net/gruc1vod/4/

and i want to add these dots over my bar chart using mask.

Here is my JavaScript code:

var svg = d3.select("body").append("svg");
var dotsPatternDefs = svg.append('defs');
    
dotsPatternDefs.append('pattern')
        .attr('id', 'dotsPattern')
        .attr('patternUnits', 'userSpaceOnUse')
        .attr('width', 10)
        .attr('height', 10)
      .append('circle')
        .attr('cx', 5)
        .attr('cy', 5)
        .attr('r', 3)
        .style('fill', 'white');
    
dotsPatternDefs.append('mask')
        .attr('id', 'mask-dots')
      .append('rect')
        .attr('width', '100%')
        .attr('height', '100%')
        .attr('x', 0)
        .attr('y', 0)
        .style('fill', 'url(#dotsPattern)');
    
svg.append('rect')
        .attr('class', 'dotsPattern')
      .attr('width', '200')
      .attr('height', '200')
      .attr('x', 0)
      .attr('y', 0)
        .style('fill', '#F189b2');

Here is my CSS code:

rect.dotsPattern {
    mask: url(#mask-dots);
}

and here my live example: https://jsfiddle.net/uao5yfhm/6/

Where is the problem and i cannot see this outcome correct outcome but i see this one wrong outcome?

Advertisement

Answer

Solution: just change the circle color into black and add one more white rectangle in mask.

var svg = d3.select("body").append("svg");

var dotsPatternDefs = svg.append('defs');
    
dotsPatternDefs.append('pattern')
        .attr('id', 'dotsPattern')
        .attr('patternUnits', 'userSpaceOnUse')
        .attr('width', 10)
        .attr('height', 10)
      .append('circle')
        .attr('cx', 5)
        .attr('cy', 5)
        .attr('r', 3)
        .style('fill', 'black');
 
let mask = dotsPatternDefs.append('mask').attr('id', 'mask-dots')
mask.append('rect')
      .attr('width', '100%')
      .attr('height', '100%')
      .attr('x', 0)
      .attr('y', 0)
        .style('fill', 'white'); 
mask.append('rect')
      .attr('width', '100%')
      .attr('height', '100%')
      .attr('x', 0)
      .attr('y', 0)
        .style('fill', 'url(#dotsPattern)'); 

    
svg.append('rect')
    .attr('class', 'dotsPattern')
    .attr('width', '200')
    .attr('height', '200')
    .attr('x', 0)
    .attr('y', 0)
    .style('fill', '#F189b2');
rect.dotsPattern {
    mask: url(#mask-dots);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.12.1/d3.min.js"></script>

working example: https://jsfiddle.net/gspn7a3o/35/

I think you have misunderstood the usage of mask. If you fill the pattern circle into white, it means that “Everything under a white pixel will be visible”(See MDN). So the pink rectangle will be seen through these white circles.

So if you are trying to not see through circles, put them in black(“Everything under a black pixel will be invisible”) and also give a white rectangle mask to make sure the pink can be seen.

My first answer here, ask me if you have any more questions.

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement