Published
Edited
Dec 1, 2019
Insert cell
Insert cell
Insert cell
Insert cell
chart = chart_data.rootdiv
Insert cell
mutable mheight = 200
Insert cell
mutable mwidth = 800
Insert cell
chart_g = chart_data.g
Insert cell
chart_style = chart_data.style
Insert cell
mk_chart = function(data) {
const [rootdiv, svg, g] = initChart();

g.attr("transform", `translate(${dim.mgs.l}, ${dim.mgs.t})`);
//.attr("viewBox", [dim.mid.ngW, dim.mid.ngH, dim.mid.gW, dim.mid.gH]); //centering

// scales:
// x)
const domX = [0, Object.keys(data).length - 1],
ranX = [0, dim.gW];

const xScale = d3.scaleLinear(domX, ranX);

// y)
const Ymax = d3.max(data, d => d.y);

const domY = d3.extent(data, d => d.y),
ranY = [dim.gH, 0];

const linScale = d3.scaleLinear();

const yScale = linScale.domain(domY).range(ranY);

// Axis :
const abscissa = d3.axisBottom().scale(xScale),
ordinates = d3.axisLeft().scale(yScale);

// Adding axis and datapoint to the drawing zone: g
g.append("g")
.attr("class", "x axis")
.attr("transform", `translate(0, ${dim.gH})`)
.call(abscissa);

g.append("g")
.attr("class", "y axis")
.attr("transform", `translate(0,0)`)
.call(ordinates);

// line generator
const line = d3
.line()
.x(d => xScale(d.x))
.y(d => yScale(d.y));

const ligne = g
.append("path")
.datum(data).attr("class", "line")
.attr("d", line);

// data points (last to be on top)
const P = g
.selectAll("p")
.data(data)
.enter()
.append("circle") .attr("class", "point")
.attr("r", 4)
.attr("cx", d => xScale(d.x))
.attr("cy", d => yScale(d.y));
rootdiv.appendChild(svg.node());
rootdiv.append(style)
rootdiv;
return {rootdiv, g, style}
};
Insert cell
Insert cell
style = html`<style>
/* Edit to change graph's styles */
.line {
stroke: steelblue;
stroke-width: 3;
}

/* Style the dots by assigning a fill and stroke */
.point {
fill: red;
stroke: black;
}
</style>`
Insert cell
dim = mk_dim({W: mwidth, H: mheight})
Insert cell
Insert cell
mk_dim = ({W=400, H=300, mgs = {t:10, r:10, b:30, l:30}} = {}) => {
// make a dimension object
// inner graph margins
const gW = W - mgs.r - mgs.l,
gH = H - mgs.t - mgs.b;

// creating half width and hight, negative & positive respectively
// to use in viewBox, setting the 0 in the middle of the view
// can also handle two linked charts side by side
const tmpO = {W, H, gW, gH};
const mid = Object.keys(tmpO).reduce((o, k) => ({...o, [k]: Math.round(tmpO[k]/2),
[`n${k}`]: -Math.round(tmpO[k]/2)})
, {})

const radius = d3.min([gW, gH])/ 2;

return {mgs, mid, W, H, gW, gH, radius}
}
Insert cell
initChart = (d=dim) => {
let div = html`<div id='rootdiv'>`,
svg = d3.select(DOM.svg(dim.W, dim.H)),
g = svg.append('g').attr('transform', `translate(${d.mgs.r}, ${d.mgs.t})`);
return [div, svg, g]
}
Insert cell
function mk_data(n=5) {
const f = x => x;
let data = [...new Array(n)].map((d, x) => ({
x: x,
y: f(x)
}));
return data
}
Insert cell
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