d3 = require("d3@5");

chart = {
	const svg = d3.create("svg")
		.attr("viewBox", [-width / 2, -height / 2, width, height])
		.attr("font-size", 10)
		.attr("font-family", "sans-serif")
		.style("width", "100%")
		.style("height", "auto");

	const chords = chord(data.matrix);

  const group = svg.append("g")
    .selectAll("g")
    .data(chords.groups)
    .join("g");

  group.append("path")
      .attr("fill", d => data.colorFills.get(d.index))
      .attr("stroke", d => data.colorStrokes.get(d.index))
      .attr("stroke-width", "3px")
      .attr("d", arc);

  group.append("text")
      .each(d => { d.angle = (d.startAngle + d.endAngle) / 2; })
      .attr("dy", ".35em")
      .attr("transform", d => `
        rotate(${(d.angle * 180 / Math.PI - 90)})
        translate(${innerRadius + 26})
        ${d.angle > Math.PI ? "rotate(180)" : ""}
      `)
      .attr("text-anchor", d => d.angle > Math.PI ? "end" : null)
      .text(d => data.nameByIndex.get(d.index));

  svg.append("g")
      .attr("fill-opacity", 0.67)
    .selectAll("path")
    .data(chords)
    .join("path")
      .attr("stroke", d => d3.rgb(data.colorStrokes.get(d.source.index)).darker())
      .attr("stroke-width", "1px")
      .attr("fill", d => data.colorFills.get(d.source.index))
      .attr("d", ribbon);

  return svg.node();
};

data = {
	const trades = await FileAttachment("tradePartnersData.php?league_id=100&year=2029").json();

	const indexByName =  new Map;
	const nameByIndex = new Map;
	const matrix = [];
	const colorFills = new Map;
	const colorStrokes = new Map;
	let n=0;
	
	// Compute a unique index for each package name.
	trades.forEach(d => {
		if (!indexByName.has(d.abbr)) {
			nameByIndex.set(n, d.abbr);
			indexByName.set(d.abbr, n);
			colorFills.set(n, d.background_color_id);
			colorStrokes.set(n, d.text_color_id);
			n++;
		}
	});

	// Construct a square matrix counting package trades.
	trades.forEach(d => {
		const source = indexByName.get(d.abbr);
		matrix[source] = d.trades;
	});
		
	return {
		matrix,
		indexByName;
		nameByIndex;
	};
};

chord = d3.chord()
    .padAngle(.04)
    .sortSubgroups(d3.descending)
    .sortChords(d3.descending);

// Set size of dark arc
arc = d3.arc()
    .innerRadius(innerRadius)
    .outerRadius(innerRadius + 20);
	
ribbon = d3.ribbon()
    .radius(innerRadius);
	
outerRadius = Math.min(width, height) * 0.5 - 30;
innerRadius = outerRadius - 20;

height = Math.min(640, width);

