D3.js V4和Angular不会发生节点转换 [英] Node Transition does not occur with D3.js V4 and Angular

查看:91
本文介绍了D3.js V4和Angular不会发生节点转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 D3.js V.4.12 中使用 Angular Typescript ,尤其是在

I am using Angular Typescript with D3.js V.4.12 and I am particularly using the Tidy Radial Tree for representing a product.

ng-cli一起,我安装了npm install --save d3并创建了一个组件来显示信息.

along with ng-cli, I installed npm install --save d3 and created a component to display the information.

可视化如下所示:

各个组成部分如下:

treediag.component.ts

import { Component, OnInit, ViewEncapsulation} from '@angular/core';
import * as d3 from 'd3';
import { ont, ont_highchair } from '../fd-ontology/ontology';
import { recursionParse, ontNode } from './model/recursion';
export class leaf {
  name: string;
  url: string;
  color: string;
  children: leaf[] = [];
}

@Component({
  selector: 'app-treediag',
  templateUrl: './treediag.component.html',
  styleUrls: ['./treediag.component.css'],
  encapsulation: ViewEncapsulation.None
})

export class TreediagComponent implements OnInit {
  prop = {name: 'test'};
  constructor() {
  }

  ngOnInit() {
    var i = 0,
    duration = 750, root;
    var svg = d3.select("svg"),
    width = +svg.attr("width"),
    height = +svg.attr("height"),
    g = svg.append("g").attr("transform", "translate(" + (width / 2 + 40) + "," + (height / 2 + 90) + ")");

    var tree = d3.tree()
    .size([2 * Math.PI, 400])
    .separation(function(a, b) { return (a.parent == b.parent ? 1 : 10) / a.depth; });

    root = tree(d3.hierarchy(this.parse_node(ont_highchair.completeStructure)));
    // root.children.forEach(collapse);
    // update(root);
    var link = g.selectAll(".link")
    .data(root.links())
    .enter().append("path")
      .attr("class", "link")
      .attr("d", d3.linkRadial()
          .angle(function(d) { return d.x; })
          .radius(function(d) { return d.y; }));

    var 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", (d) => click(d))
            .on("dblclick", (d) => dblclick(d));

            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)];
    }

    /* PROBLEM HERE*/
    function click(d) {
        d3.select(this).select("circle").transition()
            .duration(750)
            .attr("r", 16);
    }
    /* PROBLEM HERE */
    function dblclick(d) {
      console.log(d.data);
      d3.select(this).select("circle").transition()
        .duration(750)
        .attr("r", 6);
    }
}

this.parse_node()只是一个从服务器接收 JSON 响应并展平层次结构的函数.

this.parse_node() is just a function that takes in a JSON Response from the server and flattens the heirarchical structure.

我在节点上使用.transistion(),这样,单击节点将增加节点半径,而双击将半径减小回标准大小.

I am using .transistion() to on the nodes such that a single click on the node will increase the node radius and a double click will reduce the radius back to standard size.

我没有在控制台中检索任何错误,也没有通过两个函数中的console.log()调用正确获取节点的信息.

I do not retrieve any errors in the console and obtain the information of the node correctly via the console.log() calls in both the functions.

但是我发现奇怪的是,浏览器检查器显示相同的g组件被生产两次.也许这可能是一个问题,但是我看不到点击发生任何过渡.

However what I find strange is that the Browser Inspector shows the same g components being produced twice. Maybe this might be a problem but I don't see any transitions happening upon clicks.

推荐答案

在设置点击处理程序时,如下所示:

When you set up your click handler like this:

.on("click", (d) => click(d))

粗箭头表示法保留了this的上下文,因此它引用的是类的实例.

The fat-arrow notation preserves the context of this, so it's referring to the instance of your class.

您的处理程序,但是:

function click(d) {
    d3.select(this).select("circle").transition()
        .duration(750)
        .attr("r", 16);
}

期望this是被点击的g.

因此,像这样设置您的处理程序:

So, set up your handler like:

.on("click", click)

这篇关于D3.js V4和Angular不会发生节点转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆