Published unlisted
Edited
Mar 17, 2020
Importers
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Chart = {
let _rootdiv = html`<div>`
let _name = "example"
let _draw = histConf.draw
return append_chart(_rootdiv, relts, _name, dim, _draw)
}
Insert cell
function append_chart(root, data_, name_, dim_, draw_={}, scale_=null){
// root: the root element to attache the graph
// data: a table to build the histogram
// name: the name of the chart, used in class and id
// dim: a dim objet to handle margins
// border: a object of boolean to toggle border and axis drawing
let _svg = hist(data_, name_, dim_, draw_, scale_);
let _style = mk_style(name_);
root.appendChild(_style)
root.appendChild(_svg.node());
return root;
}
Insert cell
Insert cell
function hist(data_, name_ = null, dim_ = null, draw_ = {}, scale_ = null) {
// data_ : the data to be binned in histogram. It's an array of values with
// d.theID attribute
// name_ : name used in id and class style attributes
// dim_: the dimension object for this chart (margin, width ect...)
// draw_: the draw object controling if to draw axis, borders ect..
// scale_ : scale function. If null initialize a scale base on chart's data and dim

let _histName = name_;
let _reltsInCir = data_.filter(d => d.inCir);

let _data = d3.histogram().value(d => d.theID)(data_);
let _dataInCir = d3.histogram().value(d => d.theID)(_reltsInCir);

let _scale = scale_ ? scale_ : scale(_data, dim_);
let _axis = axis(_scale, dim_);

let _baseOpacity = 0.6;

const [svg, g] = initChart(dim_, _histName, draw_.border);

//g.attr("viewBox", [dim.mid.nW, dim.mid.nH, dim.W, dim.H]); //centering coordinates in g
//g.attr("viewBox", [0, 0, dim.W, dim.H]);

/* main bars */
g.append("g")
.classed(`g-main-bar-${_histName} g-main-${_histName}`, true)
.selectAll("rect")
.data(_data)
.join("rect")
.attr("id", (_, i) => `g-main-bar-${_histName}-${i}`)
.attr("class", (_, i) => `g-main-${_histName}-${i} transparent`)

.attr("x", (d, i) => _scale.x(i))
.attr("y", d => _scale.y(d.length))
.attr("height", d => _scale.yHeight(d))
.attr("width", _scale.x.bandwidth())
.on("mouseover", mb_on_mover)
.on("click", mb_on_click)
.on("mouseout", mb_on_mout);

g.append("g")
.classed(`g-main-label-${_histName} g-main-${_histName}`, true)
.selectAll("text")
.data(_data)
.join("text")
.attr("id", (_, i) => `g-main-label-${_histName}-${i}`)
.attr("class", (_, i) => `g-main-${_histName}-${i} transparent`)
.attr("x", (d, i) => _scale.xLabelMainPos(d, i))
.attr("y", (d, i) => setYlabel(d, i, _scale).get("pos"))
.text(d => d.length)
.on("mouseover", mb_on_mover)
.on("mouseout", mb_on_mout);

/* bar for in Circuit */
g.append("g")
.classed(`g-inCir-bar-${_histName} g-inCir-${_histName}`, true)
.selectAll("rect")
.data(_dataInCir)
.join("rect")
.attr("id", (d, i) => `g-inCir-bar-${_histName}-${i}`)
.attr("class", (_, i) => `g-inCir-${_histName}-${i} transparent`)
.attr("x", (d, i) => _scale.xInCirPos(d, i))
.attr("y", d => _scale.y(d.length))
.attr("height", d => _scale.yHeight(d))
.attr("width", _scale.x.bandwidth() / 2)
.on("mouseover", mb_on_mover)
.on("click", mb_on_click)
.on("mouseout", mb_on_mout);

g.append("g")
.attr("class", `g-inCir-label-${_histName} g-inCir-${_histName}`)
.selectAll("text")
.data(_dataInCir)
.join("text")
.attr("id", (d, i) => `g-inCir-label-${_histName}-${i}`)
.attr("class", (_, i) => `g-inCir-${_histName}-${i} transparent`)
.attr("x", (d, i) => _scale.xInCirPos(d, i))
.attr("y", (d, i) => setYlabel(d, i, _scale).get("pos"))
.text(d => d.length)
.on("mouseover", mb_on_mover)
.on("mouseout", mb_on_mout);

draw_.xAxis ? g.append("g").call(_axis.x) : null;

draw_.yAxis ? g.append("g").call(_axis.y) : null;

return svg;
}
Insert cell
mb_on_mover = function(d,i){
// main bar on enter
let classList = this.attributes.class.value;

// l'ordre d'insertion des classes est important
let selector = classList.split(" ")[0]

d3.selectAll(`.${selector}`).classed("transparent", false)
}
Insert cell
mb_on_click = function(d,i) {
mutable selected_text = d
}
Insert cell
// Callback Function set green
mb_on_mout = function(){
let classList = this.attributes.class.value;
// l'ordre d'insertion des classes est important
let selector = classList.split(" ")[0]
d3.selectAll(`.${selector}`).classed("transparent", true)
}
Insert cell
setYlabel = (d, i, scale) => {
let params = new Map()
let p = scale.label(d.length) // return the catégorie 0, 1, 2 or 3 of d
params.set('color', 'black')
params.set('pos', scale.y(d.length) -10)
if (p == 0){
params.set('color', 'black')
params.set('pos', scale.y(d.length) )
}
//debugger
return params
}

Insert cell
function scale(data_, dim_) {

let y = d3.scaleLinear()
.domain([0, d3.max(data_, d => d.length)]).nice()
.range([dim_.gH, 0]);

let x = d3.scaleBand()
.domain(d3.range(data_.length))
.range([0, dim_.gW])
.padding(0.1)

let label = d3.scaleQuantile().range(d3.range(data_.length)) // scale for label placement

let yHeight = (d) => y(0) - y(d.length);
let xInCirPos = (d,i) => x(i) + x.bandwidth()/4 ;
let xLabelMainPos = (d,i) => x(i) + x.bandwidth()
return ({x, y, label, yHeight, xInCirPos, xLabelMainPos})
}
Insert cell
function axis(scale_, dim_) {
let x = g => g
.attr("transform", `translate(0,${dim_.gH})`)
.call(d3.axisBottom(scale_.x).tickFormat(i => `the${i}`).tickSizeOuter(0))

let y = g => g
// .attr("transform", `translate(${dim_.mgs.l},0)`)
.call(d3.axisLeft(scale_.y))
// .call(g => g.select(".domain").remove())
return {x, y}
}
Insert cell
drawing_borders = (svg, g, dim_, name_) => {
// toggle svg and g borders on and off

svg.append('rect').attr('id', `outter-border-${name_}`)
.attr('width', dim_.W).attr('height', dim_.H)
.attr('stroke', 'salmon')
.attr('stroke-width', 5)
.attr('fill', 'none');

g.append('rect')
.attr('id', `inner-border-${name_}`)
.attr('width', dim_.gW).attr('height', dim_.gH)
.attr('fill', 'none').attr('stroke', 'black').attr('stroke-dasharray', '10 10');
}
Insert cell
Insert cell
initChart = (dim_=dim, name_='test-chart', border_=false) => {
let svg = d3.select(DOM.svg(dim_.W, dim_.H))
.attr('id', `svg-${name_}`).attr('class', `${name_}-group`),
g = svg.append('g')
.attr('id', `g-${name_}`).attr('class', `${name_}-group`)
.attr('transform', `translate(${dim_.mgs.l}, ${dim_.mgs.t})`);

border_? drawing_borders(svg, g, dim_, name_) :null ;

return [svg, g]
}
Insert cell
import {checkbox} from "@jashkenas/inputs"
Insert cell
import {mk_dim} from "e52eb8c1ed8e0b33"
Insert cell
viewof drawch = checkbox({
description: "draw the borders",
options: [{ value: "toggle", label: "On" }],
value: null
})
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