d3 中多弧的径向梯度
radial gradients for multiple arcs in d3
我有如下弧线图:
我想为每个单独的圆弧添加渐变,从 外半径 流向 内半径 每个单独的弧。
我猜我需要为每个圆弧创建一个单独的渐变?
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');
您需要在用户空间坐标中工作,因为对象边界框不是一个漂亮的正方形,您会得到扭曲的渐变。指定渐变的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>
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>
我有如下弧线图:
我想为每个单独的圆弧添加渐变,从 外半径 流向 内半径 每个单独的弧。
我猜我需要为每个圆弧创建一个单独的渐变?
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');
您需要在用户空间坐标中工作,因为对象边界框不是一个漂亮的正方形,您会得到扭曲的渐变。指定渐变的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>
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>