viewof plotNachBezirken = {
const chartHeight = 450;
const hover = vl
.selectPoint("hover")
.encodings("x")
.on("mouseover")
.clear("mourseout")
.toggle(true)
.nearest(true);
const isHovered = hover.empty(false);
const line = vl
.markLine({
point: {
filled: false,
fill: "white",
size: 60
}
})
.encode(
vl.x().fieldT("date").timeUnit("year"),
vl
.y()
.fieldQ("Häufigkeitszahl")
.scale({
domain: [0, d3.max(dataByHaupttitel, (d) => d.Häufigkeitszahl)]
})
.title("Straftaten pro 1000 Einwohnende"),
vl
.color({
legend: { orient: "bottom", layout: { bottom: { anchor: "left" } } }
})
.fieldN("Haupttitel")
.title(null)
.scale({ domain: colorDomain, range: colorRange }),
// vl
// .strokeDash()
// .fieldN("Haupttitel")
// .legend({ orient: "bottom", layout: { bottom: { anchor: "left" } } })
// .title(null)
vl
.shape()
.fieldN("Haupttitel")
.scale({
domain: colorDomain,
range: ["circle", "triangle-up", "square", "diamond", "triangle-down"]
})
.legend({ orient: "bottom", layout: { bottom: { anchor: "left" } } })
.title(null)
);
// shared base for new layers, filtered to hover selection
const base = line.transform(vl.filter(isHovered));
// mark properties for text label layers
const label = { align: "left", dx: 5, dy: -5 };
const white = { stroke: "white", strokeWidth: 3 };
return vl
.data(dataByHaupttitel)
.layer(
line,
// add a rule mark to serve as a guide line
vl
.markRule({ color: "#333333", strokeWidth: 1.5 })
.transform(vl.filter(isHovered))
.encode(vl.x().fieldT("date").timeUnit("year")),
// add circle marks for selected time points, hide unselected points
line
.markCircle()
.params(hover) // use as anchor points for selection
.encode(vl.opacity().if(isHovered, vl.value(1)).value(0)),
// add white stroked text to provide a legible background for labels
base.markText(label, white).encode(vl.text().field("Häufigkeitszahl")),
// add text labels for stock prices
base.markText(label).encode(vl.text().field("Häufigkeitszahl"))
)
.width(plotWidth(2)) // chartWidth(2) specifying responsive width
.height(chartHeight)
.autosize({ type: "fit", resize: true })
.config({
locale: { number: locale },
view: { stroke: null },
background: "#ffffff",
padding: { top: 5, bottom: 5, left: 0, right: 25 },
axis: {
labelFontSize: 13,
labelColor: "black"
},
axisX: {
labelFont: ZHFonts.black,
labelFontSize: 12,
tickCount: { signal: Math.ceil(plotWidth(2) / 80) },
grid: true,
ticks: true,
title: null
},
axisY: {
titleAlign: "left",
titleAngle: 0,
titleX: -15,
titleY: -15,
labelFont: ZHFonts.regular,
labelFontSize: 12,
titleFont: ZHFonts.black,
titleFontSize: 12,
tickCount: { signal: Math.ceil(chartHeight / 80) },
grid: false
},
title: {
font: ZHFonts.black,
fontSize: 16,
offset: 15,
anchor: "start",
lineHeight: 1.5,
subtitleFont: ZHFonts.regular,
subtitleFontSize: 14
},
legend: {
labelFontSize: 14,
labelFont: ZHFonts.regular,
labelColor: "black",
labelLimit: labelLimit,
columns: 1,
rowPadding: 5,
title: null
},
text: { font: ZHFonts.regular, fontSize: 14, color: "black" }
})
.render();
}