Published
Edited
Feb 19, 2020
1 fork
2 stars
Insert cell
Insert cell
data = [
{name: "Jan", value: 3},
{name: "Feb", value: -5},
{name: "Mar", value: 10},
{name: "April", value: 2},
{name: "Mai", value: -15},
{name: "Iunie", value: 8},
{name: "Aug", value: 2},
{name: "Sep", value: 5},
{name: "Oct", value: 1},
{name: "Nov", value: 2},
]
Insert cell
height = 400
Insert cell
MAX = d3.max(data, d => Math.abs(d.value))
Insert cell
chart = {
const svg = d3.create("svg").attr("viewBox", [0, 0, width, height]);
let selected = -1

svg
.on("mouseover", function(d, i) {
svg
.select(".main")
.selectAll("rect")
.transition()
.duration(100)
.attr("opacity", (d, i) => i !== selected ? "0.5" : "1")
})
.on("mouseout", function(d) {
svg.select(".main").selectAll("rect").transition().duration(200).attr("opacity", "1")
})

// up bars
svg.append("g")
.selectAll("rect")
.data(data)
.join("rect")
.attr("x", (d, i) => x(i))
.attr("y", d => y(MAX) + margin.top)
.attr("fill", "#f8fbf4")
.attr("height", d => height/2 - margin.top)
.attr("width", x.bandwidth());
// down bars
svg.append("g")
.selectAll("rect")
.data(data)
.join("rect")
.attr("x", (d, i) => x(i))
.attr("y", d => y(0))
.attr("fill", "#fdf4f5")
.attr("height", d => height/2 - margin.bottom)
.attr("width", x.bandwidth());
svg.append("g")
.attr("class", "main")
.selectAll("rect")
.data(data)
.join("rect")
.attr("x", (d, i) => x(i))
.attr("y", d => {
if (d.value < 0) {
return y(0)
}

return y(d.value) + margin.top
})
.attr("height", d => {
if (d.value < 0) {
return y(d.value) - y(0) - margin.bottom
}
return y(0) - y(d.value) - margin.top
})
.attr("fill", d => d.value > 0 ? "#75b211" : "#e1191d")
.attr("width", x.bandwidth())
.on("mouseover", function(d, i) {
selected = i
})
.on("mouseout", () => selected = -1)
svg.append("g")
.call(xAxis);
// svg.append("g")
// .call(yAxis);
return svg.node()
}
Insert cell
d3 = require("d3");
Insert cell
x = d3.scaleBand()
.domain(d3.range(data.length))
.range([margin.left, width - margin.right])
.padding(0.05)
Insert cell
y = d3.scaleLinear()
.domain([0, MAX])
.range([height/2, 0])
Insert cell
margin = ({top: 20, right: 10, bottom: 20, left: 30})
Insert cell
xAxis = g => g
.attr("transform", `translate(0, ${height - margin.bottom})`)
.call(d3.axisBottom(x).tickFormat(i => data[i].name).tickSizeOuter(0))
Insert cell
yAxis = g => g
.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisLeft(y))
.call(g => g.select(".domain").remove())
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