Public
Edited
Oct 17, 2022
9 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
viewof chart = {
let container = html`<div class="container">`;
const x_axis = d3
.select(container)
.append("div")
.attr("class", "x_axis")
.append("svg")
.attr("width", width)
.attr("height", 28)
.append("g");

x_axis.append("g").call(xAxis);

const svg = d3
.select(container)
.append("svg")
.attr("viewBox", [0, 0, width, height])
.call((g) =>
g
.append("g")
.attr("class", "v_lines")
.selectAll("line")
.data(x.ticks(ticks))
.join("line")
.attr("x1", (d) => x(d))
.attr("x2", (d) => x(d))
.attr("y2", height)
);

// arrows
const refX = 3;
const refY = 3;
const markerWidth = 4;
const markerHeight = 4;
const arrowPoints = [[0, 0], [0, 5], [5, 2.5]];

svg
.append("defs")
.append("marker")
.attr("id", "arrow")
.attr("viewBox", [0, 0, 8, 8])
.attr("refX", refX)
.attr("refY", refY)
.attr("markerWidth", 5)
.attr("markerHeight", 5)
.attr("orient", "auto-start-reverse")
.append("path")
.attr("d", d3.line()(arrowPoints))
.attr("stroke", "black");

const uncertain_d = svg
.append("g")
.attr("stroke-width", size)
.selectAll("line")
.data(data.filter((d) => d.dress && d.dress.uncertainty && d.dress.uncertainty == "nach" ))
.join("line")
.attr("class", "lines")
.attr("stroke", colors.dress)
.attr("x1", (d) => x(new Date(d.dress.start)))
.attr("x2", (d) => d.dress.uncertainty ? x(new Date(d.dress.start)) + 20 : x(new Date(d.dress.end)))
.attr("y1", (d) => y(d.id))
.attr("y2", (d) => y(d.id))
.attr('marker-end', 'url(#arrow)')
const uncertain_p = svg
.append("g")
.attr("stroke-width", size)
.selectAll("line")
.data(data.filter((d) => d.painting && d.painting.uncertainty && d.painting.uncertainty == "nach" ))
.join("line")
.attr("class", "lines")
.attr("stroke", colors.painting)
.attr("x2", (d) => d.painting.uncertainty ? x(new Date(d.painting.start)) + 20 : x(new Date(d.painting.end)))
//.attr("y1", (d) => y(d.id))
//.attr("y2", (d) => y(d.id))
.attr("y1", (d) => d.dress ? y(d.id) + size*2 : y(d.id) )
.attr("y2", (d) => d.dress ? y(d.id) + size*2 : y(d.id) )

.attr('marker-end', 'url(#arrow)')

const uncertain_dp = svg
.append("g")
.attr("stroke-width", size)
.selectAll("line")
.data(data.filter((d) => d.depictedperson && d.depictedperson.uncertainty && d.depictedperson.uncertainty == "nach" ))
.join("line")
.attr("class", "lines")
.attr("stroke", colors.depictedperson)
.attr("x1", (d) => x(new Date(d.depictedperson.start)))
.attr("x2", (d) => d.depictedperson.uncertainty ? x(new Date(d.depictedperson.start)) + 20 : x(new Date(d.depictedperson.end)))
//.attr("y1", (d) => y(d.id))
//.attr("y2", (d) => y(d.id))
.attr("y1", (d) => d.painting || d.dress ? y(d.id) + size*2 : y(d.id) )
.attr("y2", (d) => d.painting || d.dress ? y(d.id) + size*2 : y(d.id) )
.attr('marker-end', 'url(#arrow)')
// lines
const line = svg
.append("g")
.attr("stroke-width", 1)
.selectAll("line")
.data(data)
.join("line")
.attr("stroke", "black")
.attr("opacity", ".2")
.attr("x1", margin.left)
.attr("x2", width - margin.right)
.attr("y1", (d) => y(d.id))
.attr("y2", (d) => y(d.id));

const d_line = svg
.append("g")
.attr("stroke-width", size)
.selectAll("line")
.data(data.filter((d) => d.dress && d.dress.uncertainty ? d.dress && d.dress.uncertainty != "nach" : d.dress ))
.join("line")
.attr("class", "lines")
.attr("stroke", colors.dress)
.attr("stroke-dasharray", (d) => d.dress.uncertainty ? "2 2" : 0 )
.attr("x1", (d) => d.dress.uncertainty ? x(new Date(d.dress.start)) - nachSpan: x(new Date(d.dress.start)))
.attr("x2", (d) => d.dress.uncertainty ? x(new Date(d.dress.start)) + nachSpan : x(new Date(d.dress.end)))
.attr("y1", (d) => y(d.id))
.attr("y2", (d) => y(d.id));

const p_line = svg
.append("g")
.attr("stroke-width", size)
.selectAll("line")
.attr("class", "lines")
.data(data.filter((d) => d.painting && d.painting.uncertainty ? d.painting && d.painting.uncertainty != "nach" : d.painting ))
.join("line")
.attr("stroke", colors.painting)
.attr("stroke-dasharray", (d) => d.painting.uncertainty ? "2 2" : 0 )
.attr("x1", (d) => d.painting.uncertainty ? x(new Date(d.painting.start)) - nachSpan : x(new Date(d.painting.start)))
.attr("x2", (d) => d.painting.uncertainty ? x(new Date(d.painting.start)) + nachSpan : x(new Date(d.painting.end)))
.attr("y1", (d) => d.dress ? y(d.id) + size*2 : y(d.id) )
.attr("y2", (d) => d.dress ? y(d.id) + size*2 : y(d.id) )

const dp_line = svg
.append("g")
.attr("stroke-width", size)
.selectAll("line")
.data(data.filter((d) => d.depictedperson && d.depictedperson.uncertainty ? d.depictedperson && d.depictedperson.uncertainty != "nach" : d.depictedperson ))
.join("line")
.attr("class", "lines")
.attr("stroke", colors.depictedperson)
.attr("stroke-dasharray", (d) => d.depictedperson.uncertainty ? "2 2" : 0 )
.attr("x1", (d) => d.depictedperson.uncertainty ? x(new Date(d.depictedperson.start)) - nachSpan : x(new Date(d.depictedperson.start)))
.attr("x2", (d) => d.depictedperson.uncertainty ? x(new Date(d.depictedperson.start)) + nachSpan : x(new Date(d.depictedperson.end)))
.attr("y1", (d) => d.painting || d.dress ? y(d.id) + size*2 : y(d.id) )
.attr("y2", (d) => d.painting || d.dress ? y(d.id) + size*2 : y(d.id) )

const label = svg
.append("g")
.attr("font-family", "sans-serif")
.attr("font-size", 10)
.attr("text-anchor", "end")
.selectAll("text")
.data(data)
.join("text")
.attr("x", margin.left - 5)
.attr("y", (d) => y(d.id))
.attr("dy", "0.35em")
.text((d) => d.id);

const d_dot1 = svg
.append("g")
.selectAll("circle")
.data(data.filter((d) => d.dress && !d.dress.uncertainty))
.join("circle")
.attr("cx", (d) => x(new Date(d.dress.start)))
.attr("cy", (d) => y(d.id) )
.attr("r", 2.5);
const d_dot2 = svg
.append("g")
.selectAll("circle")
.data(data.filter((d) => d.dress))
.join("circle")
.attr("cx", (d) => d.dress.uncertainty ? x(new Date(d.dress.start)) : x(new Date(d.dress.end)))
.attr("cy", (d) => y(d.id) )
.attr("r", 2.5);

const p_dot1 = svg
.append("g")
.selectAll("circle")
.data(data.filter((d) => d.painting && !d.painting.uncertainty))
.join("circle")
.attr("cx", (d) => x(new Date(d.painting.start)))
.attr("cy", (d) => d.dress ? y(d.id) + size*2 : y(d.id) )
.attr("r", 2.5);
const p_dot2 = svg
.append("g")
.selectAll("circle")
.data(data.filter((d) => d.painting))
.join("circle")
.attr("cx", (d) => d.painting.uncertainty ? x(new Date(d.painting.start)) : x(new Date(d.painting.end)))
.attr("cy", (d) => d.dress ? y(d.id) + size*2 : y(d.id) )
.attr("r", 2.5);

const dp_dot1 = svg
.append("g")
.selectAll("circle")
.data(data.filter((d) => d.depictedperson && !d.depictedperson.uncertainty))
.join("circle")
.attr("cx", (d) => x(new Date(d.depictedperson.start)))
.attr("cy", (d) => d.painting || d.dress ? y(d.id) + size*2 : y(d.id) )
.attr("r", 2.5);
const dp_dot2 = svg
.append("g")
.selectAll("circle")
.data(data.filter((d) => d.depictedperson))
.join("circle")
.attr("cx", (d) => d.depictedperson.uncertainty ? x(new Date(d.depictedperson.start)) : x(new Date(d.depictedperson.end)))
.attr("cy", (d) => d.painting || d.dress ? y(d.id) + size*2 : y(d.id) )
.attr("r", 2.5);

return container;
}
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
<style>
.container {
height:1640px;
overflow: scroll;
}
.x_axis {
background: white;
padding-top: 1rem;
position: sticky;
top: 0;
}
.v_lines {
fill: none;
stroke: black;
stroke-width: 1;
opacity: .2;
stroke-dasharray: 5 5;
}
.lines {
opacity: 1;
#mix-blend-mode: multiply;
}
</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