lucky1928
lucky1928

Reputation: 8841

d3.js - apply pattern with multiple lines to svg

I would like to apply multiple different size/color lines to pattern to the svg but only the first line show up.

console.clear()

demo()
function demo() {
  var width = 400
  var height = 400
  var svg = d3.select('body').append('svg')
  svg
    .append('defs')
    .append('pattern')
    .attr('id','grids')
    .attr('patternUnits', 'userSpaceOnUse')
    .attr('width', 200)
    .attr('height', 200)
    .append('path') // 200
    .attr('d','M 0,0 L 0,200 M 0,0 L 200,0')
    .attr('stroke','#b4b4f0')
    .attr('stroke-width',1)
    .attr('fill','none')
    .append('path') //100
    .attr('d','M 0,0 L 0,100 M 0,0 L 100,0')
    .attr('stroke','#b4b4b4')
    .attr('stroke-width',1)
    .attr('fill','none')
    .append('path') //10
    .attr('d','M 0,0 L 0,10 M 0,0 L 10,0')
    .attr('stroke','#d2d2d2')
    .attr('stroke-width',1)
    .attr('fill','none')

  svg
  //.attr('viewBox',`0 0 ${width} ${width}`)
  .attr('fill','url(#grids)')
  .attr('width',width)
  .attr('height',height)
  .style('border','1px solid red')
  
  var g = svg.append('g')
  .attr('fill','url(#grids)')
  
  svg.append('rect')
  .attr('x',0)
  .attr('y',0)
  .attr('width',width)
  .attr('height',height)
  .attr('stroke','green')
  .attr('stroke-width',1)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js"></script>

And if I ]remove the rectangle, the lines will disappear, not sure why!

Updated per comments from @ Michael Mullany

demo()
function demo() {
  var width = 600
  var height = 500
  var svg = d3.select('body').append('svg')
  .attr('width',width)
  .attr('height',height)
  .style('border','1px solid red')
  .attr('viewBox',`0 0 ${50} ${50}`)

  var group = svg
  .append('defs')
  .append('pattern')
  .attr('id','grids')
  .attr('patternUnits', 'userSpaceOnUse')
  .attr('width', 200)
  .attr('height', 200)
  .append('g')
  .attr('stroke-width',1)
  .attr('fill','none')

  group.selectAll(null)
    .data(Array(1).fill().map((element, index) => index*200) ).enter()
    .append('path') //200
    .attr('d',d => `M ${d} 0 L ${d} 200 M 0,${d} L 200,${d}`)
    .attr('stroke','#b4b4f0')

  group.selectAll(null)
    .data(Array(2).fill().map((element, index) => index*100) ).enter()
    .append('path') //100
    .attr('d',d => `M ${d} 0 L ${d} 200 M 0,${d} L 200,${d}`)
    .attr('stroke','#b4b4b4')

  group.selectAll(null)
    .data(Array(20).fill().map((element, index) => index*10) ).enter()
    .append('path') //10
    .attr('d',d => `M ${d} 0 L ${d} 200 M 0,${d} L 200,${d}`)
    .attr('stroke','#d2d2d2')

  svg
    .attr('fill','url(#grids)')

  svg.append('rect')
    .attr('x',0)
    .attr('y',0)
    .attr('width',width)
    .attr('height',height)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js"></script>

Yes, it works if append rects after g element. but if I change the viewBox to enlarge the view, the grids looks like has been applied some opacity (very hard to see).

Upvotes: 0

Views: 291

Answers (1)

user6018651
user6018651

Reputation:

Use pattern create grids not very efficient, remove the patterns and just draw it on svg should be better.

console.clear()


demo()
function demo() {
  var width = 600
  var height = 500
  var svg = d3.select('body').append('svg')
  .attr('width',width)
  .attr('height',height)
  .style('border','1px solid red')
  .attr('viewBox',`0 0 ${50} ${50}`)

  var group = svg
  .append('g')
  .attr('stroke-width',1)
  .attr('fill','none')

  group.selectAll(null)
    .data(Array(width/200).fill().map((element, index) => index*200) ).enter()
    .append('path') //200
    .attr('d',d => `M ${d} 0 L ${d},${height} M 0,${d} L ${width},${d}`)
    .attr('stroke','#b4b4f0')

  group.selectAll(null)
    .data(Array(width/100).fill().map((element, index) => index*100) ).enter()
    .append('path') //100
    .attr('d',d => `M ${d} 0 L ${d},${height} M 0,${d} L ${width},${d}`)
    .attr('stroke','#b4b4b4')

  group.selectAll(null)
    .data(Array(width/10).fill().map((element, index) => index*10) ).enter()
    .append('path') //10
    .attr('d',d => `M ${d} 0 L ${d},${height} M 0,${d} L ${width},${d}`)
    .attr('stroke','#d2d2d2')

  // svg.append('rect')
  //   .attr('x',0)
  //   .attr('y',0)
  //   .attr('width',width)
  //   .attr('height',height)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js"></script>

Upvotes: 0

Related Questions