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>