【问题标题】:radial gradients for multiple arcs in d3d3中多个弧的径向渐变
【发布时间】:2018-12-19 13:05:38
【问题描述】:

我有如下圆弧图:

我想为每个单独的弧添加一个渐变,该渐变从每个单独的弧的外半径流向内半径

我猜我需要为每条弧线创建一个单独的渐变?

let radius = 100;

for(let i = 0; i < 5; i ++) {

  let grad = defs.append('radialGradient')
       .attr('id', 'mygrad' + i)
    .attr('gradientUnits', 'userSpaceOnUse')
          .attr('cx', '0')
    .attr('cy', '0')
    .attr('r', radius)

  grad.append('stop')
       .attr('offset', '0%')
    .attr('stop-color', 'white');

  grad.append('stop')
       .attr('offset', '100%')
    .attr('stop-color', 'blue');

  let arc = d3.arc()
    .outerRadius( radius )
    .innerRadius( radius - 50)
    .startAngle( degToRad(-90) )
    .endAngle( degToRad(90) );

  g.append('path')
    .attr('d', arc)
    .attr('fill', `url(#${'mygrad' + i })`)
    .attr('stroke', 'lightgrey');

  radius += 50;
}


let grad = defs.append('radialGradient')
       .attr('id', 'mygrad' + i)
    .attr('r', '80%')

  grad.append('stop')
       .attr('offset', '0%')
    .attr('stop-color', 'white');

grad.append('stop')
   .attr('offset', '100%')
  .attr('stop-color', 'blue');

Codepen

【问题讨论】:

  • 您有 5 个渐变,但您只使用了 1 个。将 .attr('fill', url(#${'mygrad' + **1** })) 更改为 .attr('fill', url(#${'mygrad' + **i** })) 第 42 行
  • UPS。好的,修复它并更新图像。

标签: d3.js svg radial-gradients


【解决方案1】:

SVG 2 添加了一个fr 属性。这使得定义渐变的内部起始半径成为可能。结合在其他定义中引用渐变定义的可能性,您的代码可以重写为

let width = 800;
let height = 800;

let svg = d3.select('svg')
    .attr('width', width)
    .attr('height', height);

let defs = svg.append('defs');

let g = svg.append('g')
	  .attr('transform', `translate(${width/2}, ${height/2})`);

let radius = 100;
    
let gradcolors = defs.append('radialGradient')
    .attr('id', 'gradcolors')
    .attr('gradientUnits', 'userSpaceOnUse')
    .attr('cx', '0')
    .attr('cy', '0')

gradcolors.append('stop')
    .attr('offset', '0%')
    .attr('stop-color', 'white');

gradcolors.append('stop')
    .attr('offset', '100%')
    .attr('stop-color', 'blue');

for(let i = 0; i < 5; i++) {

    let grad = defs.append('radialGradient')
        .attr('id', 'mygrad' + i)
        .attr('href', '#gradcolors')
        .attr('fr', radius - 50)
        .attr('r', radius)

    let arc = d3.arc()
        .outerRadius( radius )
        .innerRadius( radius - 50)
        .startAngle( -90 * (Math.PI / 180) )
        .endAngle( 90 * (Math.PI / 180) );

    g.append('path')
        .attr('d', arc)
        .attr('fill', `url(#${'mygrad' + i })`)
        .attr('stroke', 'lightgrey');

    radius += 50;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg> </svg>

或者您使用spreadMethod="repeat" 属性仅定义一个具有无限重复颜色的渐变。

let width = 800;
let height = 800;

let svg = d3.select('svg')
    .attr('width', width)
    .attr('height', height);

let defs = svg.append('defs');

let g = svg.append('g')
	  .attr('transform', `translate(${width/2}, ${height/2})`);

let radius = 100;
let radiusWidth = 50;
    
let grad = defs.append('radialGradient')
    .attr('id', 'mygrad')
    .attr('gradientUnits', 'userSpaceOnUse')
    .attr('spreadMethod', 'repeat')
    .attr('cx', '0')
    .attr('cy', '0')
    .attr('r', radiusWidth)

grad.append('stop')
    .attr('offset', '0%')
    .attr('stop-color', 'white');

grad.append('stop')
    .attr('offset', '100%')
    .attr('stop-color', 'blue');

for(let i = 0; i < 5; i++) {

    let arc = d3.arc()
        .outerRadius( radius )
        .innerRadius( radius - 50)
        .startAngle( -90 * (Math.PI / 180) )
        .endAngle( 90 * (Math.PI / 180) );

    g.append('path')
        .attr('d', arc)
        .attr('fill', 'url(#mygrad')
        .attr('stroke', 'lightgrey');

    radius += radiusWidth;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg> </svg>

【讨论】:

    【解决方案2】:

    您需要在用户空间坐标中工作,因为对象边界框不是一个漂亮的正方形,您会得到一个扭曲的渐变。指定渐变的end-radius (r)。

    以相对于渐变的end-radius 的百分比指定白色停止(参数r

      grad.append('stop')
        .attr('offset', `${100*(radius-50)/radius}%`)
        .attr('stop-color', 'white');
    

    let width = 800;
    let height = 800;
    
    let svg = d3.select('svg')
      .attr('width', width)
      .attr('height', height);
    
    let defs = svg.append('defs');
    
    let g = svg.append('g')
       .attr('transform', `translate(${width/2}, ${height/2})`);
    
    let radius = 100;
    
    for(let i = 0; i < 5; i ++) {
    
      let grad = defs.append('radialGradient')
        .attr('id', 'mygrad' + i)
        .attr('gradientUnits', 'userSpaceOnUse')
        .attr('cx', 0)
        .attr('cy', 0)
        .attr('r', radius);
    
      grad.append('stop')
        .attr('offset', `${100*(radius-50)/radius}%`)
        .attr('stop-color', 'white');
    
      grad.append('stop')
        .attr('offset', '100%')
        .attr('stop-color', 'blue');
    
      let arc = d3.arc()
        .outerRadius( radius )
        .innerRadius( radius - 50)
        .startAngle( degToRad(-90) )
        .endAngle( degToRad(90) );
    
      g.append('path')
        .attr('d', arc)
        .attr('fill', `url(#${'mygrad' + i })`)
        .attr('stroke', 'lightgrey');
      radius += 50;
    }
    
    //helpers
    function degToRad( deg ) {
      return deg * (Math.PI / 180);
    }
    <svg></svg>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多