{
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();
}