Public
Edited
Jun 4
1 fork
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
viewof scatter = vl
.markPoint({
size: 250,
opacity: 1,
stroke: "white",
strokeWidth: 1
})
.data(locationData)
.encode(
vl
.x()
.fieldT("datum")
.scale({
domain: [
{ month: "Apr", year: minYear }, //, year: minYear
{ month: "Oct", year: currYear } //, year: currYear
]
})
.title(null),
vl
.y()
.fieldN("quality")
.axis({ grid: true })
.scale({
domain: ["Ausgezeichnet", "Gut", "Ausreichend", "Mangelhaft"]
})
.sort(["Ausgezeichnet", "Gut", "Ausreichend", "Mangelhaft"])
.title(null),
vl
.color()
.fieldN("quality")
.scale({
range: waterColors,
domain: ["Ausgezeichnet", "Gut", "Ausreichend", "Mangelhaft"],
opacity: 1
})
.sort(["Ausgezeichnet", "Gut", "Ausreichend", "Mangelhaft"])
.title(null)
.legend({ orient: "top", titleOrient: "top" }), //
vl
.fill()
.fieldN("quality")
.scale({
range: waterColors,
domain: ["Ausgezeichnet", "Gut", "Ausreichend", "Mangelhaft"]
})
.sort(["Ausgezeichnet", "Gut", "Ausreichend", "Mangelhaft"])
.legend({ orient: "top", titleOrient: "top" }), //{ orient: "left", titleOrient: "top", padding: 4 }
vl
.shape()
.fieldN("quality")
.scale({
range: ["cross", "square", "circle", "triangle"],
domain: ["Ausgezeichnet", "Gut", "Ausreichend", "Mangelhaft"]
})
.sort(["Ausgezeichnet", "Gut", "Ausreichend", "Mangelhaft"])
.legend({ orient: "top", titleOrient: "top" }), //{ orient: "left", titleOrient: "top", padding: 4 }
vl.tooltip([
{
field: "datum",
type: "temporal",
title: "Datum"
},
{ field: "quality", type: "nominal", title: "Qualität" }
])
//vl.column().fieldT("year") // show the date and quality fields in a tooltip
)
.width(width / 2.25) // specifying responsive width
.height(350)
.autosize({ resize: true, type: "fit" })
.config({
// locale: { number: localeNumber, time: localeTime },
view: { stroke: null },
// scale: { bandPaddingInner: 0.2, bandPaddingOuter: 0.2, stroke: 2 },
background: "#ffffff",
axis: {
labelFont: ZHFonts.regular,
labelFontSize: 14,
labelColor: "black",
titleFont: ZHFonts.regular,
titleFontSize: 14,
titleFontColor: "black",
tickColor: "lightgrey",
domainColor: "#949494",
gridColor: "lightgrey"
},
axisX: {
title: null,
labelAngle: 0,
zindex: 1,
labelAlign: "left",
tickCount: Math.ceil(widthNow / 80),
labelExpr:
"[timeFormat(datum.value, '%b'), timeFormat(datum.value, '%m') == '01' ? timeFormat(datum.value, '%Y') : '']",
labelOffset: 4,
labelPadding: -24,
tickSize: 30,
grid: true,
gridDash: {
condition: {
test: { field: "value", timeUnit: "month", equal: 1 },
value: []
},
value: [2, 2]
},
tickDash: {
condition: {
test: { field: "value", timeUnit: "month", equal: 1 },
value: []
},
value: [2, 2]
}
},
axisY: {
labelPadding: 10,
titleAlign: "left",
titleAngle: 0,
titleX: 0,
titleY: -20,
tickCount: Math.ceil(width / 2 / 3.5 / 120),
ticks: true,
tickSize: 10,
labelLimit: 300
},
title: {
font: ZHFonts.black,
fontSize: 16,
offset: 15,
anchor: "start",
lineHeight: 5,
padding: 40,
subtitleFont: ZHFonts.regular,
subtitleFontSize: 14
},
header: {
labelOrient: "top",
labelPadding: 5,
lineHeight: 3,
labelFontSize: 13,
labelFont: ZHFonts.black,
labelColor: "black"
},
legend: {
orient: "top",
symbolSize: 200,
titleFont: ZHFonts.black,
titleFontSize: 14,
labelFontSize: 14,
labelFont: ZHFonts.regular,
labelColor: "black",
labelLimit: 300,
padding: 10,
columns: nCol,
title: null
},
text: {
font: ZHFonts.regular,
align: "center",
fill: "black",
fontSize: 12,
dx: 0
}
})
.render()
Insert cell
width / 2.25
Insert cell
// badewasser = htl.html`
// <div class="flex-container">
// <p>${viewof table}</p>
// <p>${viewof map}
// <span>${viewof scatter}</span></p>
// </div>`
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
dataTG = d3
.csv(
"https://www.web.statistik.zh.ch/cms_vis/gesundheit_klzh/badewasserqualitaet/badewasserqualitaet_tg.csv"
)
.then(function (data) {
data.forEach(function (d) {
d.N = +d.lat;
d.E = +d.long;
d.location = d.location;
d.quality = d.quality;
d.source = d.source;
d.datum = parseDate(d.date);
d.remark = d.remark;
d.img = d.image;
d.year = formatYear(d.datum);
});
return data.sort(desc((d) => d.datum));
})
Insert cell
dataZH = // await FileAttachment("KTZH_00000729_00003341@1.csv") // data_update
// .csv()

d3
.csv(
"https://www.web.statistik.zh.ch/ogd/daten/ressourcen/KTZH_00000729_00003341.csv" // "https://raw.githubusercontent.com/openZH/bathing_water_quality_ZH/master/data/bathing_water_quality_ZH.csv"
)
.then(function (data) {
data.forEach(function (d) {
d.N = +d.lat;
d.E = +d.long;
d.location = d.location;
d.quality = d.quality;
d.source = d.source;
d.datum = parseDate(d.date);
d.remark = d.remark;
d.img = d.image;
d.year = formatYear(d.datum);
});
return data.sort(desc((d) => d.datum));
})
Insert cell
// data_update = FileAttachment("Bathing_water_quality_ZH.csv")
// .csv()
// .then(function (data) {
// data.forEach(function (d) {
// d.E = +d.lat;
// d.N = +d.long;
// d.location = d.location;
// d.quality = d.quality;
// d.source = d.source;
// d.datum = parseDate(d.date);
// d.remark = d.remark;
// d.img = d.image;
// d.year = formatYear(d.datum);
// });
// return data.sort(desc((d) => d.datum));
// })
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
data[0].quality
Insert cell
map.clickedPlace.image
Insert cell
Insert cell
Insert cell
Insert cell
formatDate = d3.timeFormat("%d.%m.%Y")
Insert cell
formatYear = d3.timeFormat("%Y")
Insert cell
Insert cell
years = [...Array.from(new Set(data.map((d) => d.year)))]
Insert cell
Insert cell
Insert cell
Insert cell
ZoomStart = d3.scaleLinear().domain([300, 1200]).range([9, 11])(width)
Insert cell
// plotWidth = {
// if (width >= 1100) {
// return width / 1.5;
// } else if (width < 1100 && width >= 750) {
// return width / 3;
// } else {
// return width / 1.5;
// }
// }
Insert cell
plotWidth = {
if (width >= 1100) {
return width / 2; //ursprünglich 5.8
} else if (width < 1100 && width >= 750) {
return width / 3;
} else {
return width / 1.5;
}
}
Insert cell
widthNow = {
if (width >= 1100) {
return width / 3.75; // 3.745;
} else if (width < 1100 && width >= 750) {
return width / 2;
} else {
return width / 0.75;
}
}
Insert cell
nCol = {
if (width >= 1100) {
return 4;
} else if (width < 1100 && width >= 750) {
return 2;
} else {
return 1;
}
}
Insert cell
Insert cell
Insert cell
Insert cell
import { fonts as ZHFonts } from "@statistikzh/common-styles"
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
style = html`<style>
/* required styles */
* { font-family: ${ZHFonts.regular};
margin: 0;
}

select {
font-size: calc(0vw + 16px);
}

p {
font-size: calc(0vw + 14px);
font-family: ${ZHFonts.regular};
overflow:hidden;
padding:10px 5px;
word-break:normal;
}

form {
font-size: 16px;
}

#input {
background-color: #ffffff;
padding-left: 10px;
padding-top: 10px;
margin-bottom: 15px;
}

.flex-container {
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
background-color: #ffffff;
}

.flex-child {
flex: 1;
border: 2px solid white;
}

.flex-child:first-child {
margin-right: 20px;
padding-left: 10px;
}

/*table with header, border and stripes*/
.tg {
border-collapse:collapse;
border-color:#ccc;
border-spacing:0;
margin-bottom:15px;
margin-top:10px;
}

.tg td{
background-color:#fff;
border-bottom-width:1px;
border-color:#ccc;
border-style:solid;
border-top-width:1px;
border-width:0px;
color:#333;
font-family: ${ZHFonts.regular};
font-size: calc(0vw + 14px);
overflow:hidden;
padding:10px 9px;
word-break:normal;
}
.tg th{
background-color:#f0f0f0;
border-bottom-width:1px;
border-color:#ccc;
border-style:solid;
border-top-width:1px;
border-width:0px;
color:#333;
font-family: ${ZHFonts.regular};
font-size: calc(0vw + 14px);
overflow:hidden;
padding:10px 5px;
word-break:normal;
}

.tg .tg-buh4{
background-color:#f9f9f9;
text-align:left;
vertical-align:top
}
.tg .tg-0lax{
text-align:left;
font-family: ${ZHFonts.black};
vertical-align:top
}
.tg .tg-1lax{
text-align:left;
vertical-align:top
}
.tg .tg-73oq{
border-color:#000000;
text-align:left;
vertical-align:top
}
.tg .tg-i817{
background-color:#f9f9f9;
border-color:#000000;
text-align:left;
vertical-align:top
}

@media screen and (max-width: 760px) {.tg {width: auto !important;}.tg col {width: auto !important;}.tg-wrap {overflow-x: auto;-webkit-overflow-scrolling: touch;}
}

/*table with header; no border or stripes*/

.tg2 {
border-collapse:collapse;
border-color:#ccc;
border-spacing:0;
margin-top:10px;
}
.tg2 td{
background-color:#fff;
border-bottom-width:1px;
border-color:#ccc;
border-style:solid;
border-top-width:1px;
border-width:0px;
color:#333;
font-family: ${ZHFonts.regular};
font-size: calc(0vw + 14px);
overflow:hidden;
padding:10px 9px;
word-break:normal;
}
.tg2 th{
background-color:#f0f0f0;
border-bottom-width:1px
;border-color:#ccc;
border-style:solid;
border-top-width:1px;
border-width:0px;
color:#333;
font-family: ${ZHFonts.regular};
font-size: calc(0vw + 14px);
overflow:hidden;
padding:10px 9px;
word-break:normal;
}
.tg2 .tg2-0lax{
text-align:left;
vertical-align:top;
font-family: ${ZHFonts.black};
}
.tg2 .tg2-73oq{
border-color:#000000;
text-align:left;
vertical-align:top
}
@media screen and (max-width: 760px) {.tg2 {width: auto !important;}.tg2 col {width: auto !important;}.tg2-wrap {overflow-x: auto;-webkit-overflow-scrolling: touch;}}

.info {
width: 50%;
padding: 6px 8px;
font-family: ${ZHFonts.regular};
font-size: calc(0vw + 14px);
word-break:normal;
hyphens: auto;
background: white;
box-shadow: 0 0 15px rgba(0,0,0,0.2);
border-radius: 5px; }

</style>`
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