Published
Edited
Jul 19, 2021
2 forks
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
chart = {
debugger;
var w = width;
var ourWidth = w - margin.left - margin.right;
var height = w - 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, ourWidth])
.paddingInner(0.1)
.align(0);
var svgDOM = d3.select(DOM.svg(w, w))
.attr('class','matrixdiagram');
var svg = svgDOM.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');

var graph = JSON.parse(JSON.stringify(data)); // inefficient, shrug

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 maxDim = x(graph.nodes.length - 1) + x.bandwidth();
svgDOM.attr("viewBox", `0,0,${maxDim + margin.left},${maxDim + margin.top}`);

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;
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;
});
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('font-size', x.bandwidth())
.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('font-size', x.bandwidth())
.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); })
.style('width', x.bandwidth())
.style('height', x.bandwidth())
.style('fill-opacity', function (d) { return opacity(d.val); })
.style('fill', function (d) {
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(d => {
if (d.i === d.j) {
return graph.nodes[d.i].id;
} else {
return `${graph.nodes[d.i].id} - ${graph.nodes[d.j].id}`;
}
});
}

return svgDOM.node();
}


Insert cell
Insert cell
Insert cell
Insert cell
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