Published
Edited
Jun 22, 2021
Insert cell
Insert cell
chart = {
const svg = d3.create("svg")
.attr("viewBox", [-width / 2, -height / 2, width, height]);

const chords = chord(data);

const group = svg.append("g")
.attr("font-size", 40)
.attr("font-family", "sans-serif")
.selectAll("g")
.data(chords.groups)
.join("g");

group.append("path")
.attr("fill", d => color(names[d.index]))
.attr("d", arc);

group.append("title")
.text(d => `${names[d.index]}
${formatValue(d.value)}`);

const groupTick = group.append("g")
.selectAll("g")
.data(ticks)
.join("g")
.attr("transform", d => `rotate(${d.angle * 180 / Math.PI - 90}) translate(${outerRadius},0)`);


group.append("text")
.each(d => (d.angle = (d.startAngle + d.endAngle) / 2))
.attr("dy", "0.35em")
.attr("transform", d => `
rotate(${(d.angle * 180 / Math.PI - 90)})
translate(${outerRadius + 5})
${d.angle > Math.PI ? "rotate(180)" : ""}
`)
.attr("text-anchor", d => d.angle > Math.PI ? "end" : null)
.text(d => names[d.index]);


svg.append("g")
.attr("fill-opacity", 1) //would use a function here for different transparency.
//Similar to colors: d => color(names[d.source.index])
.selectAll("path")
.data(chords)
.join("path")
.style("mix-blend-mode", "multiply")
//color function
.attr("fill", d => color(names[d.source.index]))
.attr("d", ribbon)
.append("title")
.text(d => `${formatValue(d.source.value)} ${names[d.target.index]} → ${names[d.source.index]}${d.source.index === d.target.index ? "" : `\n${formatValue(d.target.value)} ${names[d.source.index]} → ${names[d.target.index]}`}`);

return svg.node();
}
Insert cell
//Interac_Mean.csv using log(value+2) to nomalize data
data = Object.assign([
[0.6931471805599453, 0.6897482889140568, 0.6938503067096996, 0.6919916775600558, 0.6925962443344021],
[0.7893749043438424, 0.6931471805599453, 0.6931022043122079, 0.6931775186783133, 0.6919864660006892],
[0.6967870871578021, 0.709304670571946, 0.6931471805599453, 0.6910318829907118, 0.690689060176067],
[0.7295110326312894, 0.6916800523894259, 0.690462111498947, 0.6931471805599453, 0.6930967528505271],
[0.6952737830608349, 0.6875374181075806, 0.7012044246258312, 0.737389323848734, 0.6931471805599453]
], {
names: ["A", "B", "C", "D", "E"],
colors: ["#c4c4c4", "#69b40f", "#ec1d25", "#c8125c", "#008fc8"]
})
Insert cell
names = data.names === undefined ? d3.range(data.length) : data.names
Insert cell
colors = data.colors === undefined ? d3.quantize(d3.interpolateRainbow, names.length) : data.colors
Insert cell
function ticks({startAngle, endAngle, value}) {
const k = (endAngle - startAngle) / value;
return d3.range(0, value, tickStep).map(value => {
return {value, angle: value * k + startAngle};
});
}
Insert cell
tickStep = d3.tickStep(0, d3.sum(data.flat()), 1)
Insert cell
formatValue = d3.format(".4f")
Insert cell
chord = d3.chord()
.padAngle(10 / innerRadius)
.sortSubgroups(d3.descending)
.sortChords(d3.descending)
Insert cell
arc = d3.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius)
Insert cell
ribbon = d3.ribbon()
.radius(innerRadius - 1)
.padAngle(1 / innerRadius)
Insert cell
color = d3.scaleOrdinal(names, colors)
Insert cell
outerRadius = Math.min(width, height) * 0.5 - 60
Insert cell
innerRadius = outerRadius - 10
Insert cell
height = width
Insert cell
d3 = require("d3@6")
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