我有以下弧形图:
我想为每个单独的圆弧添加一个渐变,该梯度从每个单独的圆弧的外半径到内半径。
我猜我需要为每个弧创建一个单独的渐变吗?
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');
答案 0 :(得分:4)
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>
答案 1 :(得分:3)
您需要在UserSpace坐标中工作,因为对象边界框不是一个不错的正方形,您将获得变形的渐变。指定渐变(end-radius
)的r
。
以相对于梯度end-radius
的{{1}}的百分比形式指定白色光阑
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);
}