chart = {
const width = 950;
const height = 300;
const margin = {top: 20, right: 30, bottom: 30, left: 15};
let dateMinMax = d3.extent(data2, d => d.dt)
dateMinMax[0] = d3.utcMonth(dateMinMax[0])
const x = d3.scaleUtc()
.domain(dateMinMax)
.range([margin.left, width - margin.right]);
const reasons = d3.group(data2, d => d.ResolutionAction);
const reasonsSet = new Set(reasons.keys());
const y = d3.scalePoint()
.domain(d3.sort(reasons.keys()))
.rangeRound([margin.top, height - margin.bottom])
.padding(1);
const color = d3.scaleOrdinal()
.domain(reasonsSet)
.range(d3.schemeCategory10)
.unknown("#ccc");
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height);
svg.append("g")
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(x));
svg.append("g")
.selectAll("text")
.data(reasonsSet)
.join("text")
.attr("transform", reason => `translate(${margin.left},${y(reason) - 10})`)
.style("font", "12px sans-serif")
.text(reason=>reason)
const g = svg.append("g")
.attr("text-anchor", "end")
.style("font", "10px sans-serif")
.selectAll()
.data(reasons)
.join("g")
.attr("transform", ([reason]) => `translate(0,${y(reason)})`);
g.append("line")
.attr("stroke", "#bbb")
.attr("x1", x(dateMinMax[0]))
.attr("x2", x(dateMinMax[1]));
g.append("g")
.selectAll()
.data(([, values]) => values)
.join("circle")
.attr("cx", (d) => x(d.dt))
.attr("fill", (d) => color(d.ResolutionAction))
.attr("r", 4.5);
return svg.node();
}