{
const svg = d3.select(DOM.svg(width, height));
svg.append("rect")
.attr("width", width)
.attr("height", height)
.attr("fill", "white");
let g = svg.append("g")
.attr("class", "general")
.attr("transform", `translate(${margin.top}, ${margin.left})`);
let colorScale = d3.scaleOrdinal(d3.schemeCategory10);
let xAxis = d3.axisBottom(xScale)
.tickFormat(d3.timeFormat("%b-%d"));
let yAxis = d3.axisLeft(yScale)
.ticks(tasks.length);
let lineDash = "5, 10";
let lineColor = "#D0D0D0";
g.append("g")
.attr("class", "x-axis")
.attr("transform", `translate(0, ${chartHeight - margin.top})`)
.call(xAxis);
g.append("g")
.attr("class", ".date-dividers")
.selectAll(".divider")
.data(xScale.ticks().slice(1)).enter()
.append("line")
.attr("class", "divider")
.attr("x1", (d) => xScale(d))
.attr("x2", (d) => xScale(d))
.attr("y1", 1)
.attr("y2", chartHeight - margin.bottom)
.attr("stroke", lineColor)
.attr("stroke-dasharray", lineDash);
g.append("g")
.attr("class", "y-axis")
.attr("transform", `translate(${margin.left + 50}, 0)`)
.call(yAxis);
g.append("g")
.attr("class", "cell-dividers")
.selectAll(".divider")
.data(tasks).enter()
.append("line")
.attr("class", "divider")
.attr("x1", margin.left + 50)
.attr("x2", chartWidth)
.attr("y1", (d) => yScale(d.task))
.attr("y2", (d) => yScale(d.task))
.attr("stroke", lineColor)
.attr("stroke-dasharray", lineDash);
let eventsGroup = g.append("g")
.attr("class", "task-period-group")
.attr("transform", `translate(${margin.left + margin.right}, ${margin.top})`);
let cells = eventsGroup.selectAll(".task")
.data(tasks).enter()
.append("g")
.attr("class", "task")
.attr("transform", (d, i) => yScale(d.task) - 3)
svg.selectAll(".lanes")
.data(allPeriods)
.join("rect")
.attr("class", "lanes")
.attr("x", (d)=> d.startX)
.attr("width", (d) => d.endX - d.startX)
.attr("y", (d)=> yScale(d.task)+ (sizePerLane -2))
.attr("transform", (d)=>{
const lane = d.index +1 >= maxlanes ? sizePerLane * maxlanes : sizePerLane * d.index
return `translate(${0}, ${lane - d.index * (sizePerLane)})`
} )
.attr("height", sizePerLane -2)
.attr("fill", (d, i)=> colorScale(d.task) )
.attr("stroke", "black")
.attr("stroke-width", 1)
return svg.node();
}