Я создал свой собственный прототип https://jsfiddle.net/liilii_ii/9co8h4La/ из этого кода https://vizhub.com/ahlev/d77c2d3bd9a34d8c98791b89f47517fa
Моя проблема в том, что я не могу уменьшить внутренний радиус.Размер солнечных лучей должен оставаться неизменным, только белый корневой узел должен быть немного меньше.У кого-нибудь есть идея?Спасибо за вашу помощь!
<svg id="partitionSVG" width="932" height="480" viewBox="0 0 932 932"></svg>
const format = d3.format(',d');
const width = 932;
const radius = width / 6;
const arc = d3.arc()
.startAngle((d: any) => d.x0)
.endAngle((d: any) => d.x1)
.padAngle((d: any) => Math.min((d.x1 - d.x0) / 2, 0.005))
.padRadius(radius * 1.5)
.innerRadius((d: any) => (d.y0 * radius))
.outerRadius((d: any) => Math.max(d.y0 * radius, d.y1 * radius - 1));
const partition = data1 => {
const root3 = d3.hierarchy(data1)
.sum(d => d.value)
.sort((a, b) => b.value - a.value);
return d3.partition()
.size([2 * Math.PI, root3.height + 1])
(root3);
};
const data = getData();
const root = partition(data);
const color = d3.scaleOrdinal(d3.quantize(d3.interpolateRainbow, data.children.length + 1));
root.each((d: any) => d.current = d);
const svg = d3.select('#partitionSVG')
.style('width', '100%')
.style('height', 'auto')
.style('font', '15px sans-serif');
const g = svg.append('g')
.attr('transform', `translate(${width / 2},${width / 2})`);
const path = g.append('g')
.selectAll('path')
.data(root.descendants().slice(1))
.join('path')
.attr('fill-opacity', (d: any) => arcVisible(d.current) ? (d.children ? 0.6 : 0.4) : 0)
.attr('d', (d: any) => arc(d.current))
.style('fill', (d: any) => {
while (d.depth > 1) {
d = d.parent;
}
return color(d.data.name);
});
path
.style('cursor', 'pointer')
.on('click', clicked);
path.append('title')
.text(d => `${d.ancestors().map((d2: any) => d2.data.name).reverse().join('/')}\n${format(d.value)}`);
const label = g.append('g')
.attr('pointer-events', 'none')
.attr('text-anchor', 'middle')
.style('user-select', 'none')
.selectAll('text')
.data(root.descendants().slice(1))
.join('text')
.attr('dy', '0.35em')
.attr('fill-opacity', (d: any) => +labelVisible(d.current))
.attr('transform', (d: any) => labelTransform(d.current))
.text((d: any) => d.data.name);
let val;
label.each(getSize)
.style('font-size', (d: any) => {
if (d.scale > 0) {
val = true;
return 15 + 'px';
}
})
.text((d: any) => {
if (val) {
if (d.data.name.length >= 20) {
return d.data.name.substring(0, 16) + '...';
} else {
return d.data.name;
}
}
val = false;
});
const parent = g.append('circle')
.datum(root)
.attr('r', radius)
.attr('fill', 'none')
.attr('pointer-events', 'all')
.on('click', clicked);
function clicked(p) {
parent.datum(p.parent || root);
root.each((d: any) => d.target = {
x0: Math.max(0, Math.min(1, (d.x0 - p.x0) / (p.x1 - p.x0))) * 2 * Math.PI,
x1: Math.max(0, Math.min(1, (d.x1 - p.x0) / (p.x1 - p.x0))) * 2 * Math.PI,
y0: Math.max(0, d.y0 - p.depth),
y1: Math.max(0, d.y1 - p.depth)
});
const t = g.transition().duration(750);
// Transition the data on all arcs, even the ones that aren’t visible,
// so that if this transition is interrupted, entering arcs will start
// the next transition from the desired position.
path.transition(t)
.tween('data', (d: any) => {
const i = d3.interpolate(d.current, d.target);
return t2 => d.current = i(t2);
})
.filter((d: any, i: number, n: any) => {
return n[i].getAttribute('fill-opacity') || arcVisible(d.target);
})
.attr('fill-opacity', (d: any) => arcVisible(d.target) ? (d.children ? 0.6 : 0.4) : 0)
.attrTween('d', (d: any) => () => arc(d.current));
label
.filter((d: any, i: number, n: any) => {
return n[i].getAttribute('fill-opacity') || labelVisible(d.target);
})
.transition(t)
.attr('fill-opacity', (d: any) => +labelVisible(d.target))
.attrTween('transform', (d: any) => () => labelTransform(d.current));
}
function arcVisible(d) {
return d.y1 <= 3 && d.y0 >= 0 && d.x1 > d.x0;
}
function labelVisible(d) {
return d.y1 <= 3 && d.y0 >= 0 && (d.y1 - d.y0) * (d.x1 - d.x0) > 0.03;
}
function labelTransform(d) {
const x = (d.x0 + d.x1) / 2 * 180 / Math.PI;
const y = (d.y0 + d.y1) / 2 * radius;
return `rotate(${x - 90}) translate(${y},0) rotate(${x < 180 ? 0 : 180})`;
}
function getSize(d: any, i: number, n: any) {
const bbox = n[i].getBBox();
const cbbox = n[i].parentNode.getBBox();
const scale = Math.min(cbbox.width / bbox.width, cbbox.height / bbox.height);
d.scale = scale;
}
function getData(): any {
return {
name: 'TOPICS',
children: [
{
name: 'Smart Mobility',
children: [
{ name: 'Zugang zu internationlem Verkehr', value: 1 },
{ name: 'Bevorzugung von effizienten Transportmitteln', value: 1 },
{ name: 'Integration von IT im Verkehrsmittel und Infratsruktur', value: 1 }
]
},
{
name: 'Smart People',
children: [
{ name: 'Inklusive und partizipative Gesellscahft', value: 1 },
{ name: 'Moderene Bildungsangebote im Hochschulbereich', value: 1 },
{ name: 'Offenheit gegenüber Kreativität', value: 1 },
]
},
{
name: 'Smart Economy',
children: [
{ name: 'Unternehmerisches und innovatives Daenken und Handeln', value: 1 },
{ name: 'Produktivität', value: 1 },
{ name: 'Lokale und globale Vernetzung', value: 1 },
]
},
{
name: 'Smart Energy und Environment',
children: [
{ name: 'Nachhaltige Stadtplanung und - entwicklung', value: 1 },
{ name: 'Ressourcenschonung und erneurbare Energien', value: 1 },
{ name: 'Smarte und nachhaltige Gebäude', value: 1 },
]
},
{
name: 'Smart Government',
children: [
{ name: 'Open Government', value: 1 },
{ name: 'Bereitstellung technologischer Infrastruktur', value: 1 },
{ name: 'Anbieten von Online Services durch die Verwaltung', value: 1 },
]
},
{
name: 'Smart Living',
children: [
{ name: 'Gesundheit', value: 1, },
{ name: 'Sicherheit', value: 1, },
{ name: 'Lebensqualität und kultrelle Angebote', value: 1, }
]
}
]
};
}
}
Здесь вы можете увидеть, как выглядит моя диаграмма солнечных лучей