Public
Edited
May 29, 2023
Importers
Insert cell
Insert cell
/**
* draw a general chart with given data and html selector
*/
class GeneralChart {
/**
* @param {Object} data - data to be drawn
* @param {String} selector - html selector
* @param {Object} config - configuration of the chart
*/
constructor(data, selector, config) {
this.data = data;
this.selector = selector;
this.config = config;
this.margin = this.config["margin"] || {
top: 5,
bottom: 5,
left: 5,
right: 5
};
this.width = this.config["width"];
this.height = this.config["height"];
this.xName = this.config["xName"];
this.yName = this.config["yName"];
this.rootSelector = this.selector.split(" ")[0];

this.tooltip = new Tooltip();
d3.select(this.selector).select("svg").remove();

this.svg = d3
.select(this.selector)
.append("svg")
.attr("width", this.width)
.attr("height", this.height)
.append("g");
}

paintBackground(sel, color) {
sel.call(this.paintBG.bind(this), color);
}

paintBG = (sel, color) => {
sel
.append("g")
.append("rect")
.attr("class", "bg")
.attr("x", this.margin.left)
.attr("y", this.margin.top)
.attr("width", this.width - this.margin.left - this.margin.right)
.attr("height", this.height - this.margin.top - this.margin.bottom)
.attr("fill", color);
};

draw() {}

mouseover(thisClass, event, d) {
d3.select(this).attr("stroke-width", 5);
thisClass.tooltip.show(event, d);
}
mousemove(thisClass, event, d) {
thisClass.tooltip.move(event, d);
}
mouseleave(thisClass, event, d) {
d3.select(this).attr("stroke-width", 1);
thisClass.tooltip.hide(event, d);
}
}
Insert cell
/** create a tooltip object */
class Tooltip {
constructor(
opacity = 0.8,
backgroundColor = "white",
border = "solid",
borderWidth = "1px",
borderRadius = "5px",
padding = "10px"
) {
this.opacity = opacity;
this.svg = d3
.select("body")
.append("div")
.attr("class", "tooltip")
.style("opacity", opacity)
.style("position", "absolute")
.style("background-color", backgroundColor)
.style("border", border)
.style("border-width", borderWidth)
.style("border-radius", borderRadius)
.style("padding", padding);
}

setStyle(name, value) {
this.svg.style(name, value);
}

setText(text) {
this.text = text;
}

show(event, d) {
this.svg.style("opacity", 0.8).style("display", "block");
}
move(event, d) {
this.svg
.html(this.text)
.style("left", event.pageX + 10 + "px")
.style("top", event.pageY - 10 + "px");
}
hide(event, d) {
this.svg.style("opacity", 0);
this.svg.style("display", "none");
}
}
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