Public
Edited
Aug 9, 2023
Insert cell
Insert cell
Insert cell
Insert cell

chart = {
var margin = {
top: 70,
right: 0,
bottom: 0,
left: 70
};
var width = 800 - margin.left - margin.right;
var height = 800 - margin.top - margin.bottom;
const color = d3.scaleOrdinal(d3.schemeCategory10).domain(d3.range(10));
var opacity = d3.scaleLinear()
.domain([0, 4])
.range([0.25, 1])
.clamp(true);
var x = d3.scaleBand()
.rangeRound([0, width])
.paddingInner(0.1)
.align(0);
var svgDOM = d3.select(DOM.svg(800, 800))
.attr('class','matrixdiagram')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom);

var svg = svgDOM.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');

var graph = data;

var idToNode = {};
graph.nodes.forEach(function (n) {
n.degree = 0;
idToNode[n.id] = n;
});
graph.links.forEach(function (e) {
// if(idToNode[e.source]){
e.source = idToNode[e.source];
e.target = idToNode[e.target];
e.source.degree++;
e.target.degree++;
// }
});
graph.nodes.sort(function (a, b) {
return b.group - a.group;
});
x.domain(d3.range(graph.nodes.length));
opacity.domain([0, d3.max(graph.nodes, function (d) { return d.degree; })]);

const fillcolor = d3.scaleSequential(d3.interpolatePlasma).domain([0, d3.max(graph.links, function (d) { return d.value; })])

var matrix = graph.nodes.map(function (outer, i) {
outer.index = i;
return graph.nodes.map(function (inner, j) {
return {i: i, j: j, val: i === j ? inner.degree : 0};
});
});
graph.links.forEach(function (l) {
matrix[l.source.index][l.target.index].val += l.value/2;
// matrix[l.target.index][l.target.index].val += l.value;
// matrix[l.source.index][l.source.index].val += l.value;
matrix[l.target.index][l.source.index].val += l.value/2;
});
var row = svg.selectAll('g.row')
.data(matrix)
.enter().append('g')
.attr('class', 'row')
.attr('transform', function (d, i) { return 'translate(0,' + x(i) + ')'; })
.each(makeRow);
row.append('text')
.attr('class', 'label')
.attr('x', -4)
.attr('y', x.bandwidth() / 2)
.attr('dy', '0.32em')
.text(function (d, i) { return graph.nodes[i].id; });
var column = svg.selectAll('g.column')
.data(matrix)
.enter().append('g')
.attr('class', 'column')
.attr('transform', function(d, i) { return 'translate(' + x(i) + ', 0)rotate(-90)'; })
.append('text')
.attr('class', 'label')
.attr('x', 4)
.attr('y', x.bandwidth() / 2)
.attr('dy', '0.32em')
.text(function (d, i) { return graph.nodes[i].id; });
function makeRow(rowData) {
var cell = d3.select(this).selectAll('rect')
.data(rowData)
.enter().append('rect')
// .attr('class', 'cell')
.attr('x', function (d, i) { return x(i); })
.attr('width', x.bandwidth())
.attr('height', x.bandwidth())
// .style('fill-opacity', function (d) { return opacity(d.val); })
.style('fill-opacity', 0.9)
.style('fill', function (d) {
return fillcolor(d.val)
// if (d.val > 0 && graph.nodes[d.i].group === graph.nodes[d.j].group) {
// return color(graph.nodes[d.i].group);
// } else if (d.val > 0) {
// return '#555';
// } else {
// return null;
// }
})
.on('mouseover', function (d) {
row.filter(function (_, i) { return d.i === i; })
.selectAll('text')
.style('fill', '#d62333')
.style('font-weight', 'bold');
column.filter(function (_, j) { return d.j === j; })
.style('fill', '#d62333')
.style('font-weight', 'bold');
})
.on('mouseout', function () {
row.selectAll('text')
.style('fill', null)
.style('font-weight', null);
column
.style('fill', null)
.style('font-weight', null);
});
cell.append('title')
.text(function (d) {
return d.val;
// return graph.nodes[d.i].id;
});
}

return svgDOM.node();
}


Insert cell
data = {
var nodes = Object.keys(dist[0]).map(d => { return {id: d, group: 1} })
var links = []
dist.forEach( (row,i) => {
for (const [key, value] of Object.entries(row)) {
links.push({source: i.toString(), target: key, value: +value})
}
})
return {nodes, links}
}
Insert cell
dist = Object.assign(await FileAttachment("soft_dtw_dist@1.csv").csv())
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