Example #1
0
export const calcLayout = tree => {
    const root = d3.hierarchy(tree)
    const treeLayout = d3
        .tree()
        .nodeSize([20, 50])
        .separation(() => 1)

    treeLayout(root)
    const nodes = root
        .descendants()
        .filter(n => n.data.value != null)
        .map(n => ((n.id = n.data.path.join(',')), n))

    const links = root.links().filter(l => l.target.data.value != null)

    console.debug('nodes', nodes)
    return { nodes, links }
}
/**
 * sets global variables
 * creates and appends svg element to DOM
 * creates tree and hierarchy
 */
function treechartCreate(source13, source17) {
  const data = buildGraph(source17);
  data17 = source17;
  data13 = source13;

  svg = d3.select('body')
    .append('svg')
    .attr('width', width)
    .attr('height', height)
    .append('g')
    .attr('transform', 'translate(50,0)');

  tree = d3.tree().size([height, width - 100]);
  root = d3.hierarchy(data);

  // initially close all leafs
  root.children.forEach(collapse);

  treechartUpdate();
}
Example #3
0
  _generate = (data) => {
    const { width, height } = styles.svg
    const {
      offsetWidth: wrapperWidth,
      offsetHeight: wrapperHeight
    } = this.wrapper

    this.tree = d3.tree().size([wrapperHeight, wrapperWidth])
    this.zoom = d3.zoom().on('zoom', this._handleZoom)
    this.transition = d3.transition().duration(500)
    this.svg = d3.select(this.wrapper).append('svg')
      .attr('width', width)
      .attr('height', height)
      .call(this.zoom)
    this.container = this.svg.append('g')
    this.root = d3.hierarchy(data)
    this.root.x0 = wrapperHeight / 2
    this.root.y0 = 0

    this._update(this.root)
    this._center(this.root)
  }
Example #4
0
    westerosChart.tree = function Tree(_data) {
      const data = getMajorHouses(_data);

      const chart = this.container;

      const stratify = d3.stratify()
        .parentId(d => d.fatherLabel)
        .id(d => d.itemLabel);

      const root = stratify(data);

      const layout = d3.tree()
        .size([
          this.innerWidth,
          this.innerHeight,
        ]);

      fixateColors(houseNames(root), 'id');

      const line = d3.line().curve(d3.curveBasis);

      // Links
      const links = layout(root)
        .descendants()
        .slice(1);

      chart.selectAll('.link')
        .data(links)
          .enter()
          .append('path')
          .attr('fill', 'none')
          .attr('stroke', 'lightblue')
          .attr('d', d => line([
            [d.x, d.y],
            [d.x, (d.y + d.parent.y) / 2],
            [d.parent.x, (d.y + d.parent.y) / 2],
            // [(d.x + d.parent.x) / 2, d.y],
            // [(d.x + d.parent.y) / 2, d.parent.y],
            [d.parent.x, d.parent.y]],
          ));

      // Nodes
      const nodes = chart.selectAll('.node')
        .data(root.descendants())
        .enter()
          .append('circle')
          .attr('r', 4.5)
          .attr('fill', getHouseColor)
          .attr('class', 'node')
          .attr('cx', d => d.x)
          .attr('cy', d => d.y);

      const legendGenerator = legend.legendColor()
        .scale(colorScale);

      this.container
        .append('g')
        .attr('id', 'legend')
        .attr('transform', `translate(0, ${this.innerHeight / 2})`)
        .call(legendGenerator);

      nodes.call(tooltip(d => d.data.itemLabel, this.container));
    };
Example #5
0
export default (parentNode, data) => {
  const $svg = d3.select(parentNode).append('svg');
  const $drawBox = $svg.append('g').attr('class', 'playground-d3');
  const zoom = d3.zoom();

  zoom.on('zoom.drawBox', () => {
    $drawBox.attr('transform', d3.event.transform);
  });

  $svg.call(zoom).call(grid, zoom);
  zoom.translateBy($svg, window.innerWidth / 2, window.innerHeight / 2);

  const root = d3.hierarchy(data.node, (d) => d.childNodes);
  root.sum((d) => d.children ? d.children.length + 1 : 1);
  d3.tree().size([Math.PI * 2, 500])(root);
  root.descendants().forEach((d) => {
    const a = d.x;
    const r = d.y;
    d.x = Math.cos(a) * r;
    d.y = Math.sin(a) * r;
    d.f = d.parent
      ? (d.children ? d.children.length / d.parent.children.length : 0)
      : 1;
  });

  const nodes = root.descendants();
  const links = root.links();

  const sim = d3.forceSimulation(nodes)
    .stop()
    .velocityDecay(.1)
    .alphaMin(.03)
    // .stop()
    .force('link', d3.forceLink(root.links(links))
      .distance(10)
      .iterations(3)
    )
    .force('charge', d3.forceManyBody()
      .theta(.2)
        .strength((d) => d.children ? d.children.length * -.1 : -10)
        // .strength((d) => d.children ? d.f * -.1 + d.value * -.01 : -10)
        // .strength((d) => (d.children ? -1 : -10) * .1)
      // .strength(-.1)
      // .strength(-1)
    )
    .force('center', d3.forceCenter())
    ;
  // let steps = 100;
  // while(steps--) {
  //   sim.tick(10000);
  //   if(!(steps % 10)) {
  //     console.log(steps);
  //   }
  // }

  const $nodes = $drawBox.append('g').selectAll('.node')
    .data(nodes)
    .enter()
    .append('circle')
    .attr('class', 'node')
    .attr('cx', (d) => d.x)
    .attr('cy', (d) => d.y)
    .attr('r', .6);
  $nodes.filter((d) => !d.depth).attr('r', 50).classed('root', true);

  const $links = $drawBox.append('g').selectAll('.link')
    .data(links)
    .enter()
    .append('path')
    .attr('class', 'link')
    .attr('vector-effect', 'non-scaling-stroke')
    .attr('d', (d) => {
      return 'M' + d.source.x + ',' + d.source.y + ' ' + 'L' + d.target.x + ',' + d.target.y;
    });

  let ticks = 0;
  const update = () => {
    ticks++;
    $nodes
      .attr('cx', (d) => d.x)
      .attr('cy', (d) => d.y);
    $links
      .attr('d', (d) => {
        return 'M' + d.source.x + ',' + d.source.y + ' ' + 'L' + d.target.x + ',' + d.target.y;
      });
    if(!(ticks % 10)) {
      console.log('Ticks: %d | Alpha: %f | Min alpha: ', ticks, sim.alpha(), sim.alphaMin());
    }
  };
  sim.on('tick', update);
  sim.restart();
  // update();
}