All examples By author By category About

timelyportfolio

structure of d3 flattree with datatables

assembled with blockbuilder.org


**for an array of objects, see timelyportfolio's block: structure 2 of d3 flattree with datatables**
Yesterday, I posted some code to convert a flat tree table structure into a `d3js` hierarchy. I discovered some bugs as I prepared a couple more examples, and I think they are now resolved.

Structure of flattable

A flat tree table contains a row for each node with columns for each of the levels of groupings and additional columns for attributes. It will look something like below and can be an array of object or an array of arrays.

grp    subgrp    attr1   attr2
A      null      50      'black'
A      A.1       20      'red'
B      null      5       'yellow'
B      B.1       2       'green'
B      B.2       3       'green'

In R this structure is well illuminated in the treemap package.

Example

This example tries to interactively demonstrate the table structure with datatables and a very simple d3 tree. Mouseover the table rows to see the equivalent node highlighted in the tree.

bl.ocks example

Code from R

I like to code even my JavaScript in R.

library(htmltools)
library(d3r)
library(treemap)

rhd <- random.hierarchical.data(children.root=2)
tm <- treemap(rhd, index=c('index1','index2','index3'), vSize='x')$tm

dt1 = htmlwidgets::onRender(
  DT::datatable(tm[,1:4], option = list(paging=FALSE), width="90%"),
'
function(el,x) {
  $("tbody tr", el).on("mouseover", function() {
    var api = $("table", el).DataTable();
    var dat = api.row(this).data();
    var key_to_find = dat.slice(1,4)
      .reverse()
      .filter(function(d) {
        return d !== null;
      })[0];
    d3.selectAll("svg g.node").each(function(d) {
      if(d.data.key && d.data.key === key_to_find) {
        d3.select(this).style("fill", "red");
      }
    });
  })

  $("tbody tr", el).on("mouseout", function() {
    d3.selectAll(".node").style("fill", "");
  })
}
'
)




browsable(
  tagList(
    tags$style("table {font-size: 0.75em;} td {line-height:.75em;}"),
    tags$div(
      style="width:50%; float:left;",
      dt1
    ),
    tags$div(
      style="width:50%; float:left;",
      tag("svg", list(id="tree"))
    ),
    tags$script(
      HTML(paste0(readLines("./build/d3-flattree.js"), collapse="\n"))
    ),
    tags$script(
      HTML(sprintf('var data=%s', jsonlite::toJSON(tm, dataframe="rows")))
    ),
    tags$script(HTML(
      '
      var d3h = d3.flattree(data, ["index1","index2","index3"]);
      d3h.sum(function(d) {return d.x});
      
      var d3t = d3.tree().size([500,350])(d3h);
      var svg = d3.select("svg#tree")
      .style("height", 600)
      .style("width", 400);
      
      var g = svg.append("g")
      .attr("transform", "translate(20,20)");
      
      
      var node = g.selectAll(".node")
      .data(d3t.descendants())
      .enter().append("g")
      .attr("class", function(d) { return "node" + (d.children ? " node--internal" : " node--leaf"); })
      .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });
      
      node.append("circle")
      .attr("r", 2.5);
      node.append("text")
      .style("text-anchor", "end")
      .style("font-size", "75%")
      .text(function(d) {
      return d.data.key; 
      })
      node.append("path")
      .attr("d", )
      
      '   
    )),
    d3_dep_v4()
  )
)