Published
Edited
Jul 14, 2019
2 forks
9 stars
Insert cell
md`# Adjacency Matrix`
Insert cell
{
const eachRow = Math.hypot(boxSize, boxSize);
const margin = {top: 20, left: 20, right: 20, bottom: 20};
const chartHeight = eachRow * items.length;
const chartWidth = width - margin.left - margin.right;
const height = chartHeight + margin.top + margin.bottom;
const svg = d3.create('svg').attr('width', width).attr('height', height);
const labelWidth = 120;
const group = svg.append('g').attr('transform', `translate(${margin.left}, ${margin.top})`);
const listing = group.selectAll('g.list-item')
.data(items)
.join('g')
.attr('class', 'list-item')
.attr('transform', (d, i) => `translate(0, ${i * eachRow})`)
listing.filter((d, i) => i == 0)
.append('line')
.attr('x1', 0)
.attr('x2', labelWidth)
.attr('y1', 0)
.attr('y2', 0)
.attr('stroke', '#000')
.attr('stroke-width', '1.5px');
const labels = listing.append('text')
.attr('text-anchor', 'end')
.attr('x', labelWidth - 5)
.attr('y', eachRow / 2 + 4)
.text(d => d)
const borders = listing.append('line')
.attr('x1', 0)
.attr('x2', labelWidth)
.attr('y1', eachRow)
.attr('y2', eachRow)
.attr('stroke', '#000')
.attr('stroke-width', '1.5px');
const circleGroup = group.append('g')
.attr('class', 'circleGroup')
.attr('transform', `translate(${labelWidth + 18}, ${eachRow / 2}) rotate(${45})`)
const circles = circleGroup.selectAll('g.dot').data(matrix)
.join('g')
.attr('class', 'dot')
.attr('transform', d => `translate(${d.x}, ${d.y})`)
circles.append('circle')
.attr('fill', d => d.color)
.attr('cx', boxSize / 2)
.attr('cy', boxSize / 2)
.attr('r', boxSize / 2 - 3)
circles.append('rect')
.attr('fill', 'transparent')
.attr('width', boxSize)
.attr('height', boxSize)
.attr('stroke', '#000')
.attr('stroke-width', '1.5px')
const twoLines = group.selectAll('scope-line')
.data([{
x1: labelWidth,
x2: labelWidth + boxSize,
y1: 0,
y2: 0,
rotate: `44.5 ${labelWidth} 0`
}, {
x1: labelWidth,
x2: labelWidth + boxSize,
y1: chartHeight,
y2: chartHeight,
rotate: `-44.5 ${labelWidth} ${chartHeight}`
}])
.join('line')
.attr('class', 'scope-line')
.attr('x1', d => d.x1)
.attr('x2', d => d.x2)
.attr('y1', d => d.y1)
.attr('y2', d => d.y2)
.attr('stroke', '#000')
.attr('stroke-width', '1.5px')
.attr('transform', d => `rotate(${d.rotate})`);
return svg.node();
}
Insert cell
colors = ({
'adjacent': '#40AF49',
'nearby': '#FBF405',
'not adjacent': '#232122',
'not related': '#D1D2D4'
})
Insert cell
items = ['parking', 'porch', 'living room', 'dining room', 'kitchen', 'back porch', 'master porch', 'bathroom 2', 'master bed', 'bedroom 2', 'bedroom 3', 'bedroom 4']
Insert cell
matrix.filter(d => d.source == "living room")
Insert cell
types = ['adjacent', 'nearby', 'not adjacent', 'not related']
Insert cell
matrix = {
const matrix = [];
const n = items.length;
for (let i = 0; i < n; i++) {
const xScale = scale(n - i - 1);
for (let j = i + 1; j < n; j++) {
const random = Math.floor(Math.random() * 4);
const type = types[random > 3 ? 3 : random];
matrix.push({
source: items[i],
target: items[j],
x: xScale(j - 1),
y: i * boxSize,
type: type,
color: colors[type]
});
}
}
return matrix;
}
Insert cell
scale = (n) => {
const width = n * boxSize;
return (i) => {
return i * boxSize;
}
}
Insert cell
boxSize = 25
Insert cell
d3 = require('d3@v5')
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