geom = ({
point: function(svg, data, layer_aesthetics={}) {
let base_aesthetics = svg.aesthetics.get(svg) ? svg.aesthetics.get(svg) : {}
let aesthetics = {...base_aesthetics, ...layer_aesthetics}
let x_accessor = aesthetics.x.accessor,
x_scale = aesthetics.x.scale(data),
y_accessor = aesthetics.y.accessor,
y_scale = aesthetics.y.scale(data)
svg.append('g')
.attr('transform', `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(x_scale));
svg.append('g')
.attr('transform', `translate(${margin.left},0)`)
.call(d3.axisLeft(y_scale));
const to_draw = ["x", "y", "color"]
if (!aesthetics["color"]) aesthetics.color = defaults.color(d => "d", defaults.joiner)
const drawers = to_draw.reduce((drawers, aesthetic) => {
let aesthetic_options = aesthetics[aesthetic]
let accessor = aesthetic_options.accessor
let scale = aesthetic_options.scale(data)
let attributes
switch(aesthetic) {
case "x":
case "y":
attributes = [`c${aesthetic}`]
break;
case "color":
attributes = ["stroke", "fill"]
break;
}
let drawer = g => attributes
.reduce((h, attr) => h.attr(attr, d => scale(accessor(d))), g)
return drawers.set(aesthetic, drawer)
}, new Map())
function draw(g, to_draw, update_status) {
to_draw.forEach(aesthetic => {
let joiner = aesthetics[aesthetic].joiner
let _draw = drawers.get(aesthetic);
g.call(joiner(_draw)[update_status])
})
}
svg.append("g")
.selectAll("g")
.data(data)
.join(
enter => enter.append("g")
.append("circle")
.attr("r", 2)
.call(draw, to_draw, "enter")
)
}
})