I am new in d3.js.I downloaded two code generating graphs from site “observablehq”. Here are links to codes.
1-
zoomable-area-chart
2-
focus-context
I want to display both graphs in the same browser window. For this, I placed the files in the same directory. Here is html code of zoomable-area-chart
<!DOCTYPE html>
<meta charset="utf-8">
<title>Zoomable Area Chart</title>
<link rel="stylesheet" type="text/css" href="./inspector.css">
<body>
<script type="module">
import define from "./index.js";
import {Runtime, Library, Inspector} from "./runtime.js";
const runtime = new Runtime();
const main = runtime.module(define, Inspector.into(document.body));
</script>
Here is html code of focus-context
<!DOCTYPE html>
<meta charset="utf-8">
<title>Focus + Context</title>
<link rel="stylesheet" type="text/css" href="inspector1.css">
<body>
<script type="module">
import define from "./index1.js";
import {Runtime, Library, Inspector} from "./runtime1.js";
const runtime = new Runtime();
const main = runtime.module(define, Inspector.into(document.body));
</script>
I placed "Focus + Context" "script" in html file of "Zoomable Area Chart" like this
<!DOCTYPE html>
<meta charset="utf-8">
<title>Zoomable Area Chart</title>
<link rel="stylesheet" type="text/css" href="./inspector.css">
<body>
<script type="module">
import define from "./index.js";
import {Runtime, Library, Inspector} from "./runtime.js";
const runtime = new Runtime();
const main = runtime.module(define, Inspector.into(document.body));
</script>
<script type="module">
import define from "./index1.js";
import {Runtime, Library, Inspector} from "./runtime1.js";
const runtime = new Runtime();
const main = runtime.module(define, Inspector.into(document.body));
</script>
then I ran that html file using "webstorm" into browser. It is not displaying both graphs into the same browser window. It is displaying errors for the first graph and displaying the second graph
image url
Here are the error list of the first graph
RuntimeError: md could not be resolved
chart = RuntimeError: d3 could not be resolved
height = 500
margin = Object {top: 20, right: 20, bottom: 30, left: 30}
x = RuntimeError: d3 could not be resolved
y = RuntimeError: d3 could not be resolved
xAxis = RuntimeError: d3 could not be resolved
yAxis = RuntimeError: d3 could not be resolved
area = RuntimeError: d3 could not be resolved
data = RuntimeError: d3 could not be resolved
d3 = RequireError: invalid module
Here is js file for "Zoomable Area Chart"
export default function define(runtime, observer) {
const main = runtime.module();
const fileAttachments = new Map([["flights.csv",new URL("./files/1171cb24da0255c434c1ff554b4964c39c1253aa9349f2d356a25351acd3579367f92b24366ae5b6c208c9336811489c0a176cbc0cc62e31feff51e294a178fe",import.meta.url)]]);
main.builtin("FileAttachment", runtime.fileAttachments(name => fileAttachments.get(name)));
main.variable(observer()).define(["md"], function(md){return(
md`# Zoomable Area Chart
This zoomable time series area chart shows the number of flights per day. The effect of the September 11, 2001 attacks on air travel is evident.`
)});
main.variable(observer("chart")).define("chart", ["d3","margin","width","height","DOM","area","data","x","xAxis","yAxis","y"], function(d3,margin,width,height,DOM,area,data,x,xAxis,yAxis,y)
{
const zoom = d3.zoom()
.scaleExtent([1, 32])
.extent([[margin.left, 0], [width - margin.right, height]])
.translateExtent([[margin.left, -Infinity], [width - margin.right, Infinity]])
.on("zoom", zoomed);
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);
const clip = DOM.uid("clip");
svg.append("clipPath")
.attr("id", clip.id)
.append("rect")
.attr("x", margin.left)
.attr("y", margin.top)
.attr("width", width - margin.left - margin.right)
.attr("height", height - margin.top - margin.bottom);
const path = svg.append("path")
.attr("clip-path", clip)
.attr("fill", "steelblue")
.attr("d", area(data, x));
const gx = svg.append("g")
.call(xAxis, x);
svg.append("g")
.call(yAxis, y);
svg.call(zoom)
.transition()
.duration(750)
.call(zoom.scaleTo, 4, [x(Date.UTC(2001, 8, 1)), 0]);
function zoomed() {
const xz = d3.event.transform.rescaleX(x);
path.attr("d", area(data, xz));
gx.call(xAxis, xz);
}
return svg.node();
}
);
main.variable(observer("height")).define("height", function(){return(
500
)});
main.variable(observer("margin")).define("margin", function(){return(
{top: 20, right: 20, bottom: 30, left: 30}
)});
main.variable(observer("x")).define("x", ["d3","data","margin","width"], function(d3,data,margin,width){return(
d3.scaleUtc()
.domain(d3.extent(data, d => d.date))
.range([margin.left, width - margin.right])
)});
main.variable(observer("y")).define("y", ["d3","data","height","margin"], function(d3,data,height,margin){return(
d3.scaleLinear()
.domain([0, d3.max(data, d => d.value)]).nice()
.range([height - margin.bottom, margin.top])
)});
main.variable(observer("xAxis")).define("xAxis", ["height","margin","d3","width"], function(height,margin,d3,width){return(
(g, x) => g
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(x).ticks(width / 80).tickSizeOuter(0))
)});
main.variable(observer("yAxis")).define("yAxis", ["margin","d3","data"], function(margin,d3,data){return(
(g, y) => g
.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisLeft(y).ticks(null, "s"))
.call(g => g.select(".domain").remove())
.call(g => g.select(".tick:last-of-type text").clone()
.attr("x", 3)
.attr("text-anchor", "start")
.attr("font-weight", "bold")
.text(data.y))
)});
main.variable(observer("area")).define("area", ["d3","y"], function(d3,y){return(
(data, x) => d3.area()
.curve(d3.curveStepAfter)
.x(d => x(d.date))
.y0(y(0))
.y1(d => y(d.value))
(data)
)});
main.variable(observer("data")).define("data", ["d3","FileAttachment"], async function(d3,FileAttachment){return(
Object.assign(d3.csvParse(await FileAttachment("flights.csv").text(), d3.autoType), {y: "Flights"})
)});
main.variable(observer("d3")).define("d3", ["require"], function(require){return(
require("d3@5")
)});
return main;
}
Here is js file for "Focus + Context"
export default function define(runtime, observer) {
const main = runtime.module();
const fileAttachments = new Map([["aapl.csv",new URL("./files/de259092d525c13bd10926eaf7add45b15f2771a8b39bc541a5bba1e0206add4880eb1d876be8df469328a85243b7d813a91feb8cc4966de582dc02e5f8609b7",import.meta.url)]]);
main.builtin("FileAttachment", runtime.fileAttachments(name => fileAttachments.get(name)));
main.variable(observer()).define(["md"], function(md){return(
md`# Focus + Context
This [area chart](/@d3/area-chart) uses brushing to specify a focused area. Drag the gray region to pan, or brush to zoom. Compare to a [zoomable chart](/@d3/zoomable-area-chart). Data: [Yahoo Finance](https:
)});
main.variable(observer("chart")).define("chart", ["d3","width","height","DOM","margin","data","xAxis","yAxis","area"], function(d3,width,height,DOM,margin,data,xAxis,yAxis,area)
{
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height])
.style("display", "block");
const clipId = DOM.uid("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", clipId)
.attr("fill", "steelblue");
return Object.assign(svg.node(), {
update(focusX, focusY) {
gx.call(xAxis, focusX, height);
gy.call(yAxis, focusY, data.y);
path.attr("d", area(focusX, focusY));
}
});
}
);
main.variable(observer("viewof focus")).define("viewof focus", ["d3","width","focusHeight","margin","x","xAxis","data","area","y"], function(d3,width,focusHeight,margin,x,xAxis,data,area,y)
{
const svg = d3.create("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() {
if (d3.event.selection) {
svg.property("value", d3.event.selection.map(x.invert, x).map(d3.utcDay.round));
svg.dispatch("input");
}
}
function brushended() {
if (!d3.event.selection) {
gb.call(brush.move, defaultSelection);
}
}
return svg.node();
}
);
main.variable(observer("focus")).define("focus", ["Generators", "viewof focus"], (G, _) => G.input(_));
main.variable(observer()).define(["focus","d3","data","chart","x","y"], function(focus,d3,data,chart,x,y)
{
const [minX, maxX] = focus;
const maxY = d3.max(data, d => minX <= d.date && d.date <= maxX ? d.value : NaN);
chart.update(x.copy().domain(focus), y.copy().domain([0, maxY]));
}
);
main.variable(observer("data")).define("data", ["d3","FileAttachment"], async function(d3,FileAttachment){return(
Object.assign(d3.csvParse(await FileAttachment("aapl.csv").text(), d3.autoType).map(({date, close}) => ({date, value: close})), {y: "↑ Close $"})
)});
main.variable(observer("area")).define("area", ["d3"], function(d3){return(
(x, y) => d3.area()
.defined(d => !isNaN(d.value))
.x(d => x(d.date))
.y0(y(0))
.y1(d => y(d.value))
)});
main.variable(observer("x")).define("x", ["d3","data","margin","width"], function(d3,data,margin,width){return(
d3.scaleUtc()
.domain(d3.extent(data, d => d.date))
.range([margin.left, width - margin.right])
)});
main.variable(observer("y")).define("y", ["d3","data","height","margin"], function(d3,data,height,margin){return(
d3.scaleLinear()
.domain([0, d3.max(data, d => d.value)])
.range([height - margin.bottom, margin.top])
)});
main.variable(observer("xAxis")).define("xAxis", ["margin","d3","width"], function(margin,d3,width){return(
(g, x, height) => g
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(x).ticks(width / 80).tickSizeOuter(0))
)});
main.variable(observer("yAxis")).define("yAxis", ["margin","d3"], function(margin,d3){return(
(g, y, title) => g
.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisLeft(y))
.call(g => g.select(".domain").remove())
.call(g => g.selectAll(".title").data([title]).join("text")
.attr("class", "title")
.attr("x", -margin.left)
.attr("y", 10)
.attr("fill", "currentColor")
.attr("text-anchor", "start")
.text(title))
)});
main.variable(observer("margin")).define("margin", function(){return(
{top: 20, right: 20, bottom: 30, left: 40}
)});
main.variable(observer("height")).define("height", function(){return(
440
)});
main.variable(observer("focusHeight")).define("focusHeight", function(){return(
100
)});
main.variable(observer("d3")).define("d3", ["require"], function(require){return(
require("d3@5")
)});
return main;
}
How I can display both graphs in the same browser window correctly. You can download the complete project from this
google drive link
What I have tried:
I placed "Focus + Context" "script" in html file of "Zoomable Area Chart" like this
<!DOCTYPE html>
<meta charset="utf-8">
<title>Zoomable Area Chart</title>
<link rel="stylesheet" type="text/css" href="./inspector.css">
<body>
<script type="module">
import define from "./index.js";
import {Runtime, Library, Inspector} from "./runtime.js";
const runtime = new Runtime();
const main = runtime.module(define, Inspector.into(document.body));
</script>
<script type="module">
import define from "./index1.js";
import {Runtime, Library, Inspector} from "./runtime1.js";
const runtime = new Runtime();
const main = runtime.module(define, Inspector.into(document.body));
</script>