JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://d3js.org/d3.v6.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
</head>
<body>
<h1>My Chart</h1>
<div id="my_chart"></div>
<div id="focus"></div>
</body>
</html>
CSS
.line {
fill: none;
stroke: #ffab00;
stroke-width: 1.5;
}
.overlay {
fill: none;
pointer-events: all;
}
/* Style the dots by assigning a fill and stroke */
.dot {
fill: #ffab00;
stroke: #fff;
}
.focus circle {
fill: none;
stroke: steelblue;
}
JavaScript
/* new data */
var x = d3.timeDays(new Date(2015, 06, 01), new Date(2020, 10, 30));
var y = Array.from({length: x.length}, Math.random).map(n => Math.floor(n * 10) + 5);
var data = x.map((v, i) => {
return {
"date": v,
"value": y[i]
}
});
var margin = {top: 20, right: 20, bottom: 30, left: 40}
var height = 440;
var width = 600;
var focusHeight = 100;
var focusedArea = d3.extent(x);
const svg = d3.select('#my_chart').append("svg")
.attr("viewBox", [0, 0, width, height])
.style("display", "block");
const clipId = {id: "clip"};
const clip = svg.append("clipPath")
.attr("id", clipId.id)
.append("rect")
.attr("x", margin.left)
.attr("y", 0)
.attr("height", height)
.attr("width", width - margin.left - margin.right);
const gx = svg.append("g");
const gy = svg.append("g");
const path = svg.append("path")
.datum(data)
.attr("clip-path", `url(#${clipId.id})`)
.attr("fill", "steelblue");
const updateChart = (focusX, focusY) => {
gx.call(xAxis, focusX, height);
gy.call(yAxis, focusY, data.y);
path.attr("d", area(focusX, focusY));
};
/* begin observable code */
var focus = () => {
const svg = d3.select("#focus").append("svg")
.attr("viewBox", [0, 0, width, focusHeight])
.style("display", "block");
const brush = d3.brushX()
.extent([[margin.left, 0.5], [width - margin.right, focusHeight - margin.bottom + 0.5]])
.on("brush", brushed)
.on("end", brushended);
const defaultSelection = [x(d3.utcYear.offset(x.domain()[1], -1)), x.range()[1]];
svg.append("g")
.call(xAxis, x, focusHeight);
svg.append("path")
.datum(data)
.attr("fill", "steelblue")
.attr("d", area(x, y.copy().range([focusHeight - margin.bottom, 4])));
const gb = svg.append("g")
.call(brush)
.call(brush.move, defaultSelection);
function brushed({selection}) {
if (selection) {
svg.property("value",...