titleChart = {
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", [0, 0, width, height])
.attr("style", "max-width: 100%; height: auto; font: 10px sans-serif;")
.attr("text-anchor", "middle")
const g = svg.append("g")
.selectAll("g")
.data(bins)
.join("g")
const whisker = g.append("path")
.attr("stroke", "#00cc99")
.attr("d", d => `
M${x((d.x0 + d.x1) / 2)},${y(d.range[1])}
V${y(d.range[0])}
`)
const quantiles = g.append("path")
.attr("fill", "#ddd")
.attr("d", d => `
M${x(d.x0) + 1},${y(d.quartiles[2])}
H${x(d.x1)}
V${y(d.quartiles[0])}
H${x(d.x0) + 1}
Z
`)
const median = g.append("path")
.attr("stroke", "currentColor")
.attr("stroke-width", 2)
.attr("d", d => `
M${x(d.x0) + 1},${y(d.quartiles[1])}
H${x(d.x1)}
`)
const xAxis = svg.append("g")
.attr("transform", `translate(0,${height - margins.bottom})`)
.call(d3.axisBottom(x).ticks(n).tickSizeOuter(0))
const yAxis = svg.append("g")
.attr("transform", `translate(${margins.left},0)`)
.call(d3.axisLeft(y).ticks(null, "s"))
.call(g => g.select(".domain").remove())
const outliers = g.append("g")
.attr("fill", "currentColor")
.attr("fill-opacity", 0.2)
.attr("stroke", "none")
.attr("transform", d => `translate(${x((d.x0 + d.x1) / 2)},0)`)
.selectAll("circle")
.data(d => d.outliers)
.join("circle")
.attr("r", 2)
.attr("cx", () => (Math.random() - 0.5) * 4)
.attr("cy", d => y(d.price))
const title = svg.append("g")
.append("text")
.attr("x", width / 2)
.attr("y", (margins.top / 2))
.attr("text-anchor", "middle")
.attr("front-weight", "bold")
.attr("font-family", "Helvetica Neue, Arial")
.attr("font-size", "20px")
.text("Diamond price distribution")
return svg.node()
}