assembled with blockbuilder.org
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.
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.
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.
library(htmltools)
library(d3r)
library(treemap)
rhd <- random.hierarchical.data(children.root=2)
dt1 = htmlwidgets::onRender(
DT::datatable(rhd, 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="values")))
),
tags$script(HTML(
'
var d3h = d3.flattree(data, [0,1,2]);
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()
)
)