Published
Edited
Jun 2, 2020
Fork of Hierarchies
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
data = d3.csvParse(await FileAttachment("pokemon.csv").text())
Insert cell
render_data_table(data.slice(0, 10))
Insert cell
md`This is a pokemon dataset, it has the name, type and secondary type if applicable, hp, attack, defense, special attack and defense, speed, and then the total. It also includes which generation of the pokemon game the pokemon was debuted in, as well as, if the pokemon is a legendary pokemon.`
Insert cell
Insert cell
key1 = "Type 1"
Insert cell
key2 = "Type 2"
Insert cell
nested = d3
.nest()
.key(d => d[key1])
.entries(data)
Insert cell
hierarchy = d3.hierarchy({ key: "type", values: nested }, d => d.values)
Insert cell
height = 450
Insert cell
make_treemap_layout = d3
.treemap()
.round(true)
.tile(d3.treemapResquarify)
.size([width, height])
Insert cell
color = d3
.scaleOrdinal()
.domain(nested.map(d => d.key))
.range(d3.schemePaired)
Insert cell
sunNested = d3
.nest()
.key(d => d[key1])
.key(d => d[key2])
.entries(data)
.map(d => {
d.name = d.key;
d.values = d.values.map(dd => {
dd.name = dd.key;
return dd;
});
return d;
})
Insert cell
sunHierarchy = d3.hierarchy({ values: sunNested }, d => d.values).sum(d => +1)
Insert cell
nestedData = d3
.nest()
.key(d => d[key1])
.entries(data)
.map(d => {
return {
name: d.key,
children: d.values
};
})
Insert cell
nestedData.forEach(
d =>
(d.children = d3
.nest()
.key(dd => dd[key2])
.key(dd => dd.Name)
.entries(d.children)
.map(dd => {
return {
name: dd.key,
children: dd.values.map(ddd => {
return {
name: ddd.key,
value: ddd.values.length
};
})
};
}))
)
Insert cell
formattedData = ({ name: 'Types', children: nestedData })
Insert cell
Insert cell
md`Chart 1: Sunburst`
Insert cell
sunPartition = data => d3.partition().size([2 * Math.PI, 500])(data)
Insert cell
import { chart as chart1 } with {
sunHierarchy as data,
sunPartition as partition
} from '@d3/sunburst'
Insert cell
chart1
Insert cell
md`This chart uses color to define the primary types of pokemon. The secondary type stays as the same color as the primary type. Angles/ size are used to show the quantity by comparison of each group of pokemon. The advantage of a sunburst chart, especially in perception is that it is easy to tell child andp arent relationships between data encodings. In this example that is Type 1 and Type 2. `
Insert cell
md`chart 2: TreeMap`
Insert cell
import { select } from "@jashkenas/inputs"
Insert cell
viewof metric = select({
title: "Metric for visualizatoin",
options: ["Attack", "Defense", "HP", "Speed", "Total"],
value: "Attack"
})
Insert cell
chart2 = {
const svg = d3
.create("svg")
.attr("width", width)
.attr("height", height);

svg.node().update = current_metric => {
make_treemap_layout(hierarchy.sum(d => d[current_metric]));
svg
.selectAll("g")
.data(hierarchy.leaves())
.join(enter => {
const gs = enter
.append("g")
.attr("transform", d => `translate(${width / 2}, ${height / 2})`);

gs.append("text")
.text(d => d.data[key1])
.style("font-size", "10px")
.attr("y", 10);

gs.append("rect")
.style("stroke", "white")
.style("fill", d => color(d.parent.data.key))
.style("fill-opacity", .5);
return gs;
})
.transition()
.ease(d3.easeBounceOut)
.duration(1500)
.delay((d, i) => i * 20)
.attr("transform", d => `translate(${d.x0}, ${d.y0})`)
.selectAll("rect")
.attr("width", d => d.x1 - d.x0)
.attr("height", d => d.y1 - d.y0);
};
return svg.node();
}
Insert cell
chart2.update(metric)
Insert cell
md`The relative advantages of a treemap in terms of perception are the fact that each major category is clear and that the user can easily see the distinction between groups. The disadvantages of a treemap in terms of perception are that it can be difficult to distinguish further subcategories or points about the data that are trying to be made. As a result, heavily nested and re nested data may not be shown in an aesthetic way.`
Insert cell
md`Chart 3: Circle Packing`
Insert cell
import { chart as chart3 } with {
formattedData as data
} from '@d3/circle-packing'
Insert cell
chart3
Insert cell
md`Chart 4: Tidy Tree`
Insert cell
import { chart as chart4 } with { formattedData as data } from '@d3/tidy-tree'
Insert cell
chart4
Insert cell
md`The charts central starting point is the key used, types. The chart then draws lines to each sub group and each child node of each subgroup. The Tidy tree makes it easy to see what the encoding key and layers are. It is clear what is the parent and what isnt, Sizing can be an issue with large variance in encodings. There is no distingusishing factor like color to separate the groups\. Only spacing/ lines are used. `
Insert cell
Insert cell
Insert cell
d3 = require("d3")
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more