【问题标题】:d3.js - apply pattern with multiple lines to svgd3.js - 将多行模式应用于 svg
【发布时间】:2021-06-01 10:00:53
【问题描述】:

我想将多条不同尺寸/颜色的线条应用于 svg 的图案,但只显示第一行。

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>

如果我]删除矩形,线条会消失,不知道为什么!

@Michael Mullany 的每个 cmets 更新

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>

是的,如果在 g 元素之后追加 rects,它会起作用。但是如果我改变 viewBox 来放大视图,网格看起来像是被应用了一些不透明度(很难看到)。

【问题讨论】:

  • 您不能以您正在做的方式使用 append 将多个路径添加到模式中-它将每个路径嵌套在前一个路径中-这是无效的。请参阅此答案以了解如何添加多个对等元素:stackoverflow.com/questions/52821117/…
  • @Michael Mullay,谢谢,你是对的,但是在添加 g 元素并应用 viewBox 后,线条看起来不清晰!而且我必须附加矩形(最后一个)才能看到网格。上面更新了新版本!
  • 向 SVG 元素添加填充时,就像向 g 元素添加填充一样。它实际上并不为元素着色,它只是为您在其中渲染的元素设置填充。这就是为什么你必须画一个矩形才能让填充物真正出现。 (顺便说一句 - 你的路径生成代码很时髦 - 它在生成的 SVG 中渲染了大量的路径线)

标签: svg d3.js


【解决方案1】:

使用模式创建网格不是很有效,删除模式并在 svg 上绘制应该会更好。

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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-17
    • 2012-07-19
    • 2013-08-03
    • 1970-01-01
    相关资源
    最近更新 更多