Published
Edited
Jan 31, 2022
Insert cell
Insert cell
width = 960
Insert cell
chart = {
const chosen_years = calendarData;

const svg = d3
.create("svg")
.attr("viewBox", [0, 0, width, height * chosen_years.length])
.attr("font-family", "sans-serif")
.attr("font-size", 10);

const year = svg
.selectAll("g")
.data(chosen_years)
.join("g")
.attr(
"transform",
(d, i) => `translate(40.5,${height * i + cellSize * 1.5})`
);

year
.append("text")
.attr("x", -5)
.attr("y", -5)
.attr("font-weight", "bold")
.attr("text-anchor", "end")
.text(([key]) => key);

year
.append("g")
.attr("text-anchor", "end")
.selectAll("text")
.data(weekday === "weekday" ? d3.range(1, 6) : d3.range(7))
.join("text")
.attr("x", -5)
.attr("y", (i) => (countDay(i) + 0.5) * cellSize)
.attr("dy", "0.31em")
.text(formatDay);

year
.append("g")
.selectAll("rect")
.data(
weekday === "weekday"
? ([, values]) =>
values.filter((d) => ![0, 6].includes(d.date.getUTCDay()))
: ([, values]) => values
)
.join("rect")
.attr("width", cellSize - 1)
.attr("height", cellSize - 1)
.attr(
"x",
(d) => timeWeek.count(d3.utcYear(d.date), d.date) * cellSize + 0.5
)
.attr("y", (d) => countDay(d.date.getUTCDay()) * cellSize + 0.5)
.attr("fill", (d) =>
!d || d.value == 0 || !d.value ? "lightgrey" : color(d.value)
)
.append("title")
.text(
(d) => `${formatDate(d.date)}
${d.value} intervencija`
);

const month = year
.append("g")
.selectAll("g")
.data(([, values]) =>
d3.utcMonths(d3.utcMonth(values[0].date), values[values.length - 1].date)
)
.join("g");

month
.filter((d, i) => i)
.append("path")
.attr("fill", "none")
.attr("stroke", "#fff")
.attr("stroke-width", 3)
.attr("d", pathMonth);

month
.append("text")
.attr(
"x",
(d) => timeWeek.count(d3.utcYear(d), timeWeek.ceil(d)) * cellSize + 2
)
.attr("y", -5)
.text(formatMonth);

return svg.node();
}
Insert cell
import { SummaryTable } from "@observablehq/summary-table"
Insert cell
viewof summary_data = SummaryTable(data, { label: "Paukovanje" })
Insert cell
height = 153
Insert cell
cellSize = 17
Insert cell
weekday = "monday"
Insert cell
countDay = weekday === "sunday" ? i => i : i => (i + 6) % 7
Insert cell
formatDay = (i) => "NPUSČPS"[i]
Insert cell
timeWeek = weekday === "sunday" ? d3.utcSunday : d3.utcMonday
Insert cell
color = d3.scaleDiverging(
[
// d3.min(byDaySimplified, (d) => d.value),
d3.max(byDaySimplified, (d) => d.value),
d3.mean(byDaySimplified, (d) => d.value),
// d3.max(byDaySimplified, (d) => d.value)
//d3.min(byDaySimplified, (d) => d.value)
0
// d3.extent(byDaySimplified, (d) => d.value)
],
d3.interpolateSpectral
)
Insert cell
formatDate = d3.utcFormat("%x")
Insert cell
formatValue = x => `${Math.exp(x).toFixed(2)}×`
Insert cell
startDate = data[0].datum
Insert cell
endDate = d3.max(data, (d) => d.datum)
Insert cell
emptyDays = d3.timeDay.range(startDate, endDate)
Insert cell
function pathMonth(t) {
const n = weekday === "weekday" ? 5 : 7;
const d = Math.max(0, Math.min(n, countDay(t.getUTCDay())));
const w = timeWeek.count(d3.utcYear(t), t);
return `${d === 0 ? `M${w * cellSize},0`
: d === n ? `M${(w + 1) * cellSize},0`
: `M${(w + 1) * cellSize},0V${d * cellSize}H${w * cellSize}`}V${n * cellSize}`;
}
Insert cell
formatMonth = d3.utcFormat("%b")
Insert cell
calendarData = d3.groups(
byDaySimplified.filter((d) => d.date >= new Date(2014, 0, 1)),
(d) => d.date.getFullYear()
)
Insert cell
byDaySimplified = dataByDays.map((d) => {
return { date: d[0], value: d[1].length };
})
Insert cell
dayGrouped = d3.groups(data, (d) => d.datum)
Insert cell
dataByDays = {
//2538 before
//2742 after
let retval = [];

emptyDays.forEach((date) => {
let items = dayGrouped.filter((d) => d[0].getTime() == date.getTime());
if (items.length == 0) {
console.log("nemam ", date);
retval.push([date, new Array()]);
} else retval.push(items[0]);
});

return retval;
}
Insert cell
Insert cell
Plot.plot({
x: {
round: true
},
y: {
grid: true
},
marks: [
Plot.rectY(data, Plot.binX({ y: "count" }, { x: "datum", fill: "stanje" })),
Plot.ruleY([0])
]
})
Insert cell
Plot.plot({
grid: true,
facet: {
data: data,
y: "stanje"
},
marks: [
Plot.rectY(data, Plot.binX({ y: "count" }, { x: "datum", fill: "stanje" })),
Plot.ruleY([0])
]
})
Insert cell
Plot.plot({
x: {
round: true
},
y: {
grid: true,
label: "Mjesečno intervencija"
},
marks: [
Plot.rectY(data, Plot.binX({ y: "count" }, { x: "datum", inset: 0 })),
Plot.ruleY([0])
]
})
Insert cell
plotData = data.map((d) => {
return { x: d.datum, y: d.stanje };
})
Insert cell
data = {
//157408 prije

let raw = d3.csvParse(await FileAttachment("pauk@2.csv").text(), (d) => {
return {
broj: d.Broj,
datum: format(d["Datum i vrijeme"].split(" ")[0]),
pauk: d.Pauk,
nalogodavac: d.Nalogodavac,
tip: d["Tip zahtjeva"],
stanje: d["Stanje zahtjeva"]
};
});
return [...raw.sort((a, b) => a.datum - b.datum)];
}
Insert cell
//3/24/14 12:03
//format = d3.timeParse("%m/%d/%y %H:%M")
format = d3.timeParse("%m/%d/%y")
Insert cell
import { swatches as Swatches } from "@d3/color-legend"
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