Public
Edited
Apr 22
1 fork
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
viewof driveTypeRadios = Inputs.radio(drive, { value: drive[0] })
Insert cell
viewof valueTypeRadios = Inputs.radio(werttyp, { value: werttyp[0] })
Insert cell
Insert cell
Insert cell
Insert cell
viewof mapView = {
const node = createMap({
colorScale,
getData: (d) => {
return data.find((r) => r.BFS === d.GEBIET_C).valuesByYear[defaultYear];
},
onClick: (d) => {
if (d.ART_C !== 1) return;
/* Region toggling */
toggleRegion(d.GEBIET_C);
},
onPointerEnter: (e, d) => {
if (d.ART_C === 1) {
setValue(d.GEBIET_C, viewof highlightedRegionId);
const position = getPointerPosition(e, e.target.ownerSVGElement);
setValue(
{
x: position[0],
y: position[1],
visible: true,
regionId: d.GEBIET_C
},
viewof mapTooltipState
);
}
},
onPointerLeave: (e, d) => {
setValue(null, viewof highlightedRegionId);
setValue(
{
...viewof mapTooltipState.value,
visible: false
},
viewof mapTooltipState
);
},
onPointerMove: (e, d) => {
const position = getPointerPosition(e, e.target.ownerSVGElement);
setValue(
{
...viewof mapTooltipState.value,
x: position[0],
y: position[1],
regionId: d.GEBIET_C,
visible: true
},
viewof mapTooltipState
);
}
});

return node;
}
Insert cell
Insert cell
viewof mapTooltip = {
const { x, y, visible, regionId } = mapTooltipState;

/*
* This array will always just contain one or none elements.
* It's just easier to use the array methods instead of using conditionals
*/
const regionDataPoints = data
.filter((r) => r.BFS === regionId)
.map((r) => ({
label: r.name,
value: isNaN(r.valuesByYear[defaultYear])
? "Keine Daten"
: valueFormat(r.valuesByYear[defaultYear])
}));

const xPosition = width / 2 > x ? `${x + 16}px` : `calc(-100% + ${x - 16}px)`;
const yPosition = `calc(-100% + ${y}px)`;

return createTooltip(
{
x: xPosition,
y: yPosition,
visible,
dataPoints: [
{
label: "Jahr",
value: defaultYear
},
...regionDataPoints
]
},
this
);
}
Insert cell
Insert cell
viewof regionList = {
const regionContent = (region, index) => {
return lit.html`<span>
${htmlRegionSymbol(region.BFS)}${region.name}</span>
`;
};

const shadowChips = new Array(
maxSelectedRegions - selectedRegionIds.length
).fill(null);

return render(
ChipList({
content: [...selectedRegionIds, ...shadowChips].map((id, index) => {
if (id === null) return ShadowChip();

const region = data.find((d) => d.BFS === id);
const args = {
content: regionContent(region, index),
onpointerenter: () =>
setValue(region.BFS, viewof highlightedRegionId),
onpointerleave: () => setValue(null, viewof highlightedRegionId)
};

return RemovableChip({
...args,
ondelete: () => removeRegion(region)
});
})
}),
this
);
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
selectedRegions = data.filter((d) => selectedRegionIds.includes(d.BFS))
Insert cell
maxValueOfYear = d3.max(
data.filter((d) => d.BFS != 0).map((r) => r.valuesByYear[defaultYear])
)
Insert cell
Insert cell
// toggleDrive = () => {
// let nextValue;
// if (selectedDrive === drive[0]) {
// nextValue = drive[1];
// } else {
// nextValue = drive[0];

// if (nextValue.length === 1) {
// nextValue.shift();
// }

// nextValue.push();
// }

// setValue(nextValue, viewof selectedDrive);
// }
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
setValue = (value, input) => {
if (input.value !== value) {
input.value = value;
input.dispatchEvent(new Event("input", { bubbles: true }));
}
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
valueArray = fetchedData
.filter(
(d) =>
d.Jahr.getFullYear() === defaultYear && // nur das aktuellste Jahr
d.BFS !== 0 && // Kanton Zürich für die Skala ausschliessen
d.Werttyp === valueTypeRadios && // Skala ist variabel nach Wert und...
d.Treibstoff === driveTypeRadios // ... nach Treibstoff
)
.map((r) => r.Wert)
Insert cell
d3.max(valueArray)
Insert cell
bin = d3.bin().thresholds(7)
Insert cell
buckets = bin(valueArray)
Insert cell
// Wenn der min. Wert vom dataDomainRange grösser ist als der kleinste Wert der lowerBounds, dann schliess den kleinsten Wert der lowerBounds aus
// Wenn der max. Wert vom dataDomainRange innerhalb vom grössten Bucket, dann nimm x1 als oberste Grenze, sonst x0

bucketsDomain = {
const valueArray = fetchedData
.filter(
(d) =>
d.Jahr.getFullYear() === defaultYear && // nur das aktuellste Jahr
d.BFS !== 0 && // Kanton Zürich für die Skala ausschliessen
d.Werttyp === valueTypeRadios && // Skala ist variabel nach Wert und...
d.Treibstoff === driveTypeRadios // ... nach Treibstoff
)
.map((r) => r.Wert);
const bin = d3.bin(); //.thresholds(8);
const buckets = bin(valueArray);
const dataDomainRange = bin.domain()(valueArray);
// let lowerBounds = buckets.map((d) => d.x0);
// let upperBounds = buckets.map((d) => d.x1);
let allBounds = [];

// Filter out
let lowerBounds =
dataDomainRange[0] * -1 >= buckets.map((d) => d.x0)[0] * -1
? buckets.map((d) => d.x1) //.filter((n) => n != buckets.map((d) => d.x0)[0])
: buckets.map((d) => d.x0);

let upperBounds =
dataDomainRange[1] >= d3.max(buckets.map((d) => d.x0)) &&
dataDomainRange[1] <= d3.max(buckets.map((d) => d.x1))
? buckets.map((d) => d.x1)
: buckets.map((d) => d.x0);
// .filter((n) => n != d3.max(buckets.map((d) => d.x1)));

// Adds all elements of lower bounds and upper bounds into all bounds. may contain duplicates
allBounds.push(...lowerBounds, ...upperBounds);

//Removes duplicates from allBounds
let bucketsDomain = allBounds.filter(
(val, index, self) => self.indexOf(val) === index
);

return bucketsDomain;
}
Insert cell
dataDomainRange = {
if (valueTypeRadios === "Anteil") {
const bin = d3.bin();
return bin.domain()(valueArray);
} else if (valueTypeRadios === "Gesamtzahl") {
const bin = d3.bin().thresholds(12);
return bin.domain()(valueArray);
}
}
Insert cell
// Wenn der min. Wert vom dataDomainRange grösser ist als der kleinste Wert der lowerBounds, dann schliess den kleinsten Wert der lowerBounds aus
// Wenn der max. Wert vom dataDomainRange innerhalb vom grössten Bucket, dann nimm x1 als oberste Grenze, sonst x0

{
let lowerBounds = buckets.map((d) => d.x0);
let upperBounds = buckets.map((d) => d.x1);
let allBounds = [];

// Adds all elements of lower bounds and upper bounds into all bounds. may contain duplicates
allBounds.push(...lowerBounds, ...upperBounds);

//Removes duplicates from allBounds
let bucketsDomain = allBounds.filter(
(val, index, self) => self.indexOf(val) === index
);
// return bucketsDomain;
if (
valueTypeRadios === "Gesamtzahl" &&
driveTypeRadios === "Steckerfahrzeuge"
) {
return [200, 400, 600, 800, 1000, 2000, 7000, 8000];
} else if (
valueTypeRadios === "Gesamtzahl" &&
driveTypeRadios === "Batterie-elektrische"
) {
return [200, 400, 600, 800, 1000, 2000, 5000];
} else {
return bucketsDomain;
}
}
Insert cell
colorScale = {
const stops = bucketsDomain;
return d3
.scaleThreshold()
.range(blPuScheme)
.domain(stops)
.unknown("lightgrey");
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
drive = [...new Set(fetchedData.map((d) => d.Treibstoff))]
Insert cell
werttyp = [...new Set(fetchedData.map((d) => d.Werttyp))]
Insert cell
referenceData = data.find((d) => d.name === "Zürich - ganzer Kanton")
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
import { fonts as ZHFonts } from "@statistikzh/common-styles"
Insert cell
lit = import(`https://esm.run/lit-html@3`) // import("lit-html@3.2.1")
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more