Тип графика
Радиальное Tidy Tree
Текущий вывод
Сначала я начинаю с ответа JSON с сервера и делаю рекурсия, чтобы сделать JSON плоской и использовать d3.tree
для построения рисунка, показанного ниже.
Я запрограммировал узел Legislation
таким образом, чтобы при двойном щелчке он отправил некоторую информацию в бэкэнд и получить новый JSON, который требует, чтобы график был повторно зарегистрирован.
При повторной передаче узел изменится на Manufacturer/Legislation
, как показано ниже:
Как и на картинке, я хочу сделать эту конкретную ссылку strokedashed
, чтобы указать, что конкретный узел был изменен.
code
Для краткости я обрезаю код здесь:
ngAfterViewInit(): void {
const self = this;
const svg = d3.select('svg'),
width = +svg.attr('width'),
height = +svg.attr('height'),
g = svg.append('g').attr('transform', 'translate(' + (width / 3 + 240) + ',' + (height / 3 + 140) + ')'); const tree = d3.tree()
.size([2 * Math.PI, 375])
.separation(function(a, b) { return (a.parent === b.parent ? 1 : 2) / a.depth; });
const root = tree(d3.hierarchy(this.parse_node(this.config['viewStructure'])));
this.root = root; // store this is private variable
const link = g.selectAll('.link')
.data(root.links())
.enter().append('path')
.attr('class', 'link')
.attr('d', <any>d3.linkRadial()
.angle(function(d) { return d['x']; })
.radius(function(d) { return d['y']; })); const node = g.selectAll('.node')
.data(root.descendants())
.enter().append('g')
.attr('class', function(d) { return 'node' + (d.children ? ' node--internal' : ' node--leaf'); })
.attr('transform', function(d) { return 'translate(' + radialPoint(d.x, d.y) + ')'; })
.on('click', click)
.on('dblclick', dblclick); node.append('circle')
.attr('r', 5)
.style('fill', (d) => {
if (d.data['color'] === 'green') {
return '#0f0';
} else {
if (d.depth === 0) {
return '#999';
}
return '#f00';
}
}); node.append('text')
.attr('dy', '0.31em')
.attr('x', function(d) { return d.x < Math.PI === !d.children ? 6 : -6; })
.attr('text-anchor', function(d) { return d.x < Math.PI === !d.children ? 'start' : 'end'; })
.attr('transform', function(d) {
return 'rotate(' + (d.x < Math.PI ? d.x - Math.PI / 2 : d.x + Math.PI / 2) * 180 / Math.PI + ')'; })
.text(function(d) { return d.data['name']; }); function radialPoint(x, y) {
return [(y = +y) * Math.cos(x -= Math.PI / 2), y * Math.sin(x)];
} // For brevity removed the click and double click logic..
}
Функция ретрансляции
getProperties() {
// .... Some logic
const self = this;
function askExtension() {
// call the backend, get the json response
// rerender with some latency here..
setTimeout(() => {
d3.selectAll('svg > *').remove();
self.ngAfterViewInit();
console.log(nodeInfo.parent.data.name + '/' + nodeInfo.data.name); // `Manufacturer/Legislation` // I can use self.root here to find the node
// how do I get the link information here and change }, 1000);
}
}
Я попытался использовать .forEach()
для циклического перехода через self.root.descendants()
, найти и используйте функцию Manufacturer/Legislation
, но это не соответствует моей цели.
Как я могу программно сделать конкретную ссылку пунктирной, пост-рендеринга?
Если я правильно понимаю вашу проблему, вы можете использовать функцию стиля, которую вы используете для цвета узла.
По существу, когда вы объединяете узлы, задайте класс или некоторый атрибут, который позволяет вам его дифференцировать , Затем вы можете установить стиль условно.
В этой статье далее описывается.
Кроме того, это сайт объясняет инсульт-дашарай. По существу, формат dasharray "# пикселей вкл., # Пикселей выключен".
link.style('stroke-dasharray', function(d) {if (d['target']['data']['name'] === 'Manufacturer/Legislation' {return ('10,3');} else {return undefined;}}
, и он отлично работает. Я ищу некоторый параметр, который мог бы сделать этот процесс автоматическим.