{
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 node = group.append('g').attr('transform', `translate(${-Math.floor(items.length / 4) * eachRow})`)
const listing = node.selectAll('g.list-item')
.data(items)
.join('g')
.attr('class', 'list-item')
.attr('transform', (d, i) => `translate(${items.length * boxSize}, ${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', 'start')
.attr('x', 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 = node.append('g')
.attr('class', 'circleGroup')
.attr('transform', `rotate(-45 ${items.length * boxSize} ${0})`)
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 = node.selectAll('scope-line')
.data([{
x1: items.length * boxSize - Math.hypot(boxSize, boxSize) / 2,
x2: items.length * boxSize,
y1: eachRow / 2,
y2: 0
}, {
x1: items.length * boxSize - Math.hypot(boxSize, boxSize) / 2,
x2: items.length * boxSize,
y1: chartHeight - eachRow / 2,
y2: 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();
}