Published
Edited
Apr 19, 2021
1 star
Insert cell
md`# D3 Quick Overview`
Insert cell
md `#### CSS Style`
Insert cell
html`<style>
body {
background-color: lightgray;
color: black;
}
</style>
`
Insert cell
md `#### SVG I`
Insert cell
html`<svg width="300" height="200">
<rect width="100%" height="100%" fill="red" />
<circle cx="150" cy="100" r="80" fill="green" />
<text x="150" y="125" font-size="60" text-anchor="middle" fill="white">SVG</text>
</svg>
`
Insert cell
md`#### SVG II`
Insert cell
html`<svg width="300" height="200">
<rect x="10" y="10" width="30" height="30"/>
<rect x="60" y="10" rx="10" ry="10" width="30" height="30"/>
<rect x="10" y="80" width="30" height="30" style="fill:none;stroke-width:3;stroke:rgb(0,0,0)"/>
<rect x="60" y="80" rx="10" ry="10" width="30" height="30" style="fill:none;stroke-width:3;stroke:rgb(0,0,0)"/>
<circle cx= "30" cy= "160" r= "25"/>
<ellipse cx= "90" cy= "160" rx= "25" ry = "15" style="fill:none;stroke-width:3;stroke:rgb(0,0,0)"/>
<line x1="150" x2="150" y1="10" y2="185" style="stroke-width:3;stroke:steelblue"/>
</svg>
`
Insert cell
md `#### SVG Path`
Insert cell
html`<svg width="300" height="200">
<path d="M150, 3 L75, 197 L225, 197 Z" fill="red" stroke="blue" stroke-width="5"/>
</svg>`
Insert cell
md `#### SVG Shape Elements: Summary`
Insert cell
html`<svg width="300" height="250">
<rect x="10" y="10" width="30" height="30" stroke="black" fill="transparent" stroke-width="5"/>
<rect x="60" y="10" rx="10" ry="10" width="30" height="30" stroke="black" fill="transparent" stroke-width="5"/>
<circle cx="25" cy="75" r="20" stroke="red" fill="transparent" stroke-width="5"/>
<ellipse cx="75" cy="75" rx="20" ry="5" stroke="red" fill="transparent" stroke-width="5"/>
<line x1="10" x2="50" y1="110" y2="150" stroke="orange" stroke-width="5"/>
<polyline points="60 110 65 120 70 115 75 130 80 125 85 140 90 135 95 150 100 145"
stroke="orange" fill="transparent" stroke-width="5"/>
<polygon points="50 160 55 180 70 180 60 190 65 205 50 195 35 205 40 190 30 180 45 180"
stroke="green" fill="transparent" stroke-width="5"/>
<path d="M20,230 Q40,205 50,230 T90,230" fill="none" stroke="blue" stroke-width="5"/>
</svg>
`
Insert cell
md`#### SVG Text`
Insert cell
html`<svg width="300" height="50">
<text x="20" y="40" style="font-family: Arial; font-size : 34; stroke : #000000; fill : #00ff00; ">
Styled SVG text
</text>
</svg>
`
Insert cell
md `#### SVG using D3`
Insert cell
{
let width = 400;
let height = 100;
let svgElement = html`<svg width=${width} height=${height}>`// or DOM.svg(width,height)
let svg = d3.select(svgElement);
svg.append("rect")
.attr("height", 100)
.attr("width",100)
.attr("rx", 10)
.style("fill","green")
return svgElement;
}

Insert cell
md `#### Drawing using D3`
Insert cell
{
let width = 700;
let height = 550;
let svgElement = DOM.svg(width,height)
let svg = d3.select(svgElement);
let data = [50, 100, 150, 200, 250, 300, 350,
400, 450, 500];
for (let i=0; i<10; i++)
svg.append("rect")
.attr("x", i*60)
.attr("height", data[i])
.attr("width",50)
.attr("rx", 10)
.style("fill","green")
return svgElement;
}
Insert cell
md `#### Interaction in D3`
Insert cell
{
let width = 700;
let height = 550;
let svgElement = DOM.svg(width,height)
let svg = d3.select(svgElement);
let data = [50, 100, 150, 200, 250, 300, 350,
400, 450, 500];
for (let i=0; i<10; i++)
svg.append("rect")
.attr("x", i*60)
.attr("height", data[i])
.attr("width",50)
.attr("rx", 10)
.style("fill","green")
.on("mouseover", function(){
d3.select(this).style("fill", "red");
})
.on("mouseout", function(d){
d3.select(this).style("fill", "green");
});
return svgElement;
}
Insert cell
md `#### D3: selectAll, data, join`
Insert cell
{
let width = 700;
let height = 550;
let svgElement = DOM.svg(width,height)
let svg = d3.select(svgElement);
svg.append("g")
.selectAll("rect")
.data([50, 100, 150, 200, 250, 300, 350, 400, 450, 500])
.join("rect")
.attr("x",(d,i)=> i*60)
.attr("height", d=>d)
.attr("width",50)
.attr("rx", 10)
.style("fill","green")
.on("mouseover", function(){
d3.select(this).style("fill", "red");
})
.on("mouseout", function(d){
d3.select(this).style("fill", "green");
});
return svgElement;
}
Insert cell
md`#### D3 Scales: scaleBand, scaleLinear`
Insert cell
{
let width = 700;
let height = 300;
let svgElement = DOM.svg(width, height);
let svg = d3.select(svgElement);

let margin = {
top: 20,
right: 20,
bottom: 50,
left: 50
};
let W = width - margin.left - margin.right,
H = height - margin.top - margin.bottom;

let chartContainer = svg
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

let dataArray = [50, 100, 150, 200, 250, 300, 350, 400, 450, 500];

let xScale = d3
.scaleBand()
.domain(d3.range(dataArray.length))
.range([0, W])
.padding(0.2);

let yScale = d3
.scaleLinear()
.domain([0, d3.max(dataArray)])
.range([H, 0]);

chartContainer
.selectAll("rect")
.data(dataArray)
.join("rect")
.attr("x", (d, i) => xScale(i))
.attr("y", (d, i) => yScale(d))
.attr("height", (d, i) => H - yScale(d))
.attr("width", xScale.bandwidth())
.attr("rx", 10)
.style("fill", "green")
.on("mouseover", function() {
d3.select(this).style("fill", "red");
})
.on("mouseout", function(d) {
d3.select(this).style("fill", "green");
});

return svgElement;
}
Insert cell
md`#### D3 scale: scaleOrdinal`
Insert cell
{
let width = 700;
let height = 300;
let svgElement = DOM.svg(width, height);
let svg = d3.select(svgElement);

let margin = {
top: 20,
right: 20,
bottom: 50,
left: 50
};
let W = width - margin.left - margin.right,
H = height - margin.top - margin.bottom;

let chartContainer = svg
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

let dataArray = [50, 100, 150, 200, 250, 300, 350, 400, 450, 500];

let colorScale = d3
.scaleOrdinal()
.domain(d3.range(dataArray.length))
.range(d3.schemeCategory10);

let xScale = d3
.scaleBand()
.domain(d3.range(dataArray.length))
.range([0, W])
.padding(0.2);

let yScale = d3
.scaleLinear()
.domain([0, d3.max(dataArray)])
.range([H, 0]);

chartContainer
.selectAll("rect")
.data(dataArray)
.join("rect")
.attr("x", (d, i) => xScale(i))
.attr("y", (d, i) => yScale(d))
.attr("height", (d, i) => H - yScale(d))
.attr("width", xScale.bandwidth())
.attr("rx", 10)
.style("fill", (d, i) => colorScale(i))
.on("mouseover", function() {
d3.select(this).style("stroke", "black");
})
.on("mouseout", function(d) {
d3.select(this).style("stroke", "none");
});

return svgElement;
}
Insert cell
md`#### D3 Axes`
Insert cell
{
let width = 700;
let height = 300;
let svgElement = DOM.svg(width, height);
let svg = d3.select(svgElement);

let margin = {
top: 20,
right: 20,
bottom: 50,
left: 50
};
let W = width - margin.left - margin.right,
H = height - margin.top - margin.bottom;

let chartContainer = svg
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

let dataArray = [50, 100, 150, 200, 250, 300, 350, 400, 450, 500];

let colorScale = d3
.scaleOrdinal()
.domain(d3.range(dataArray.length))
.range(d3.schemeCategory10);

let xScale = d3
.scaleBand()
.domain(d3.range(dataArray.length))
.range([0, W])
.padding(0.2);

let yScale = d3
.scaleLinear()
.domain([0, d3.max(dataArray)])
.range([H, 0]);

chartContainer
.selectAll("rect")
.data(dataArray)
.join("rect")
.attr("x", (d, i) => xScale(i))
.attr("y", (d, i) => yScale(d))
.attr("height", (d, i) => H - yScale(d))
.attr("width", xScale.bandwidth())
//.attr("rx", 10)
.style("fill", (d, i) => colorScale(i))
.on("mouseover", function() {
d3.select(this).style("stroke", "black");
})
.on("mouseout", function(d) {
d3.select(this).style("stroke", "none");
});

let xAxis = d3.axisBottom(xScale); // or d3.axisBottom().scale(xScale);
let yAxis = d3.axisLeft(yScale);
chartContainer
.append('g')
.attr('transform', 'translate(0,' + H + ')')
.call(xAxis);
chartContainer.append('g').call(yAxis);

return svgElement;
}
Insert cell
md`#### D3 line draing using line path generator I`
Insert cell
{
let width = 700;
let height = 300;
let svgElement = DOM.svg(width, height);
let svg = d3.select(svgElement);

let margin = {
top: 20,
right: 20,
bottom: 50,
left: 50
};
let W = width - margin.left - margin.right,
H = height - margin.top - margin.bottom;

let chartContainer = svg
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

let datum = [
{ date: new Date("2007-04-23"), close: 93.24 },
{ date: new Date("2008-01-02"), close: 194.84 },
{ date: new Date("2009-01-01"), close: 85.35 },
{ date: new Date("2010-01-01"), close: 210.73 },
{ date: new Date("2011-01-03"), close: 329.57 },
{ date: new Date("2012-01-03"), close: 411.23 }
];

let xScale = d3
.scaleTime()
.domain(d3.extent(datum, d => d.date))
.range([0, W]);

let yScale = d3
.scaleLinear()
.domain(d3.extent(datum, d => d.close))
.range([H, 0]);

let pathGenerator = d3
.line()
.x(d => xScale(d.date)) // set the x values for the line generator
.y(d => yScale(d.close)); // set the y values for the line generator

chartContainer
.selectAll("path")
.data([datum])
.join("path")
.attr("d", d => pathGenerator(d))
.style("fill", "none")
.style("stroke", "black");

let xAxis = d3.axisBottom(xScale); // or d3.axisBottom().scale(xScale);
let yAxis = d3.axisLeft(yScale);
chartContainer
.append('g')
.attr('transform', 'translate(0,' + H + ')')
.call(xAxis);
chartContainer.append('g').call(yAxis);

return svgElement;
}
Insert cell
md`#### D3 line draing using line path generator II`
Insert cell
Insert cell
{
let width = 700;
let height = 300;
let svgElement = DOM.svg(width, height);
let svg = d3.select(svgElement);

let margin = {
top: 20,
right: 20,
bottom: 50,
left: 50
};
let W = width - margin.left - margin.right,
H = height - margin.top - margin.bottom;

let chartContainer = svg
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

let datum = [
{ date: new Date("2007-04-23"), close: 93.24 },
{ date: new Date("2008-01-02"), close: 194.84 },
{ date: new Date("2009-01-01"), close: 85.35 },
{ date: new Date("2010-01-01"), close: 210.73 },
{ date: new Date("2011-01-03"), close: 329.57 },
{ date: new Date("2012-01-03"), close: 411.23 }
];

let xScale = d3
.scaleTime()
.domain(d3.extent(datum, d => d.date))
.range([0, W]);

let yScale = d3
.scaleLinear()
.domain(d3.extent(datum, d => d.close))
.range([H, 0]);

let pathGenerator = d3
.line()
.x(d => xScale(d.date))
.y(d => yScale(d.close))
.curve(d3[curveType]);

chartContainer
.selectAll("path")
.data([datum])
.join("path")
.attr("d", d => pathGenerator(d))
.style("fill", "none")
.style("stroke", "black");

chartContainer
.selectAll("circle")
.data(datum)
.join("circle")
.attr("transform", d => `translate(${xScale(d.date)},${yScale(d.close)})`)
.attr("r", 5)
.style("fill", "black");

let xAxis = d3.axisBottom(xScale); // or d3.axisBottom().scale(xScale);
let yAxis = d3.axisLeft(yScale);
chartContainer
.append('g')
.attr('transform', 'translate(0,' + H + ')')
.call(xAxis);
chartContainer.append('g').call(yAxis);

return svgElement;
}
Insert cell
md `#### D3 Symbol`
Insert cell
Insert cell
{
let width = 700;
let height = 300;
let svgElement = DOM.svg(width, height);
let svg = d3.select(svgElement);

let margin = {
top: 20,
right: 20,
bottom: 50,
left: 50
};
let W = width - margin.left - margin.right,
H = height - margin.top - margin.bottom;

let chartContainer = svg
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

let datum = [
{ date: new Date("2007-04-23"), close: 93.24 },
{ date: new Date("2008-01-02"), close: 194.84 },
{ date: new Date("2009-01-01"), close: 85.35 },
{ date: new Date("2010-01-01"), close: 210.73 },
{ date: new Date("2011-01-03"), close: 329.57 },
{ date: new Date("2012-01-03"), close: 411.23 }
];

let xScale = d3
.scaleTime()
.domain(d3.extent(datum, d => d.date))
.range([0, W]);

let yScale = d3
.scaleLinear()
.domain(d3.extent(datum, d => d.close))
.range([H, 0]);

let pathGenerator = d3
.line()
.x(d => xScale(d.date))
.y(d => yScale(d.close))
.curve(d3[curveType]);

chartContainer
.selectAll("path")
.data([datum])
.join("path")
.attr("d", d => pathGenerator(d))
.style("fill", "none")
.style("stroke", "black");

let symbolGenerator = d3
.symbol()
.size(100)
.type(d3[symbolType]);

chartContainer
.append("g")
.selectAll("path")
.data(datum)
.join("path")
.attr("transform", d => `translate(${xScale(d.date)},${yScale(d.close)})`)
.attr("d", symbolGenerator)
.style("fill", "steelblue");

let xAxis = d3.axisBottom(xScale); // or d3.axisBottom().scale(xScale);
let yAxis = d3.axisLeft(yScale);
chartContainer
.append('g')
.attr('transform', 'translate(0,' + H + ')')
.call(xAxis);
chartContainer.append('g').call(yAxis);

return svgElement;
}
Insert cell
md `#### D3 Area Chart I`
Insert cell
{
let width = 700;
let height = 300;
let svgElement = DOM.svg(width, height);
let svg = d3.select(svgElement);

let margin = {
top: 20,
right: 20,
bottom: 50,
left: 50
};
let W = width - margin.left - margin.right,
H = height - margin.top - margin.bottom;

let chartContainer = svg
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

let points = [
[0, 80],
[100, 100],
[200, 30],
[300, 50],
[400, 40],
[500, 80]
];
let xScale = d3
.scaleLinear()
.domain(d3.extent(points, d => d[0]))
.range([0, W]);

let yScale = d3
.scaleLinear()
.domain([0, d3.max(points, d => d[1])])
.range([H, 0]);

let areaGenerator = d3.area();

chartContainer
.append("path")
.datum(points)
.attr('d', areaGenerator)
.style("fill", "steelblue");

return svgElement;
}
Insert cell
md `D3 Area Chart II`
Insert cell
{
let width = 700;
let height = 300;
let svgElement = DOM.svg(width, height);
let svg = d3.select(svgElement);

let margin = {
top: 20,
right: 20,
bottom: 50,
left: 50
};
let W = width - margin.left - margin.right,
H = height - margin.top - margin.bottom;

let chartContainer = svg
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

let points = [
[0, 80],
[100, 100],
[200, 30],
[300, 50],
[400, 40],
[500, 80]
];
let xScale = d3
.scaleLinear()
.domain(d3.extent(points, d => d[0]))
.range([0, W]);

let yScale = d3
.scaleLinear()
.domain([0, d3.max(points, d => d[1])])
.range([H, 0]);

let areaGenerator = d3
.area()
.x(d => xScale(d[0]))
.y1(d => yScale(d[1]))
.y0(H);

chartContainer
.append("path")
.datum(points)
.attr('d', areaGenerator)
.style("fill", "steelblue");

let xAxis = d3.axisBottom(xScale);
let yAxis = d3.axisLeft(yScale);
chartContainer
.append('g')
.attr('transform', 'translate(0,' + H + ')')
.call(xAxis);
chartContainer.append('g').call(yAxis);
return svgElement;
}
Insert cell
md`#### D3 Area chart III`
Insert cell
{
let width = 700;
let height = 300;
let svgElement = DOM.svg(width, height);
let svg = d3.select(svgElement);

let margin = {
top: 20,
right: 20,
bottom: 50,
left: 50
};
let W = width - margin.left - margin.right,
H = height - margin.top - margin.bottom;

let chartContainer = svg
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

let points = [
{ low: 30, high: 80 },
{ low: 80, high: 100 },
{ low: 20, high: 30 },
{ low: 20, high: 50 },
{ low: 10, high: 40 },
{ low: 50, high: 80 }
];

let xScale = d3
.scaleLinear()
.domain([0, points.length - 1])
.range([0, W]);

let yScale = d3
.scaleLinear()
.domain([0, d3.max(points, d => d.high)])
.range([H, 0]);

let areaGenerator = d3
.area()
.x((d, i) => xScale(i))
.y0(d => yScale(d.low))
.y1(d => yScale(d.high));

chartContainer
.append('path')
.datum(points)
.attr('d', areaGenerator)
.style("fill", "steelblue");

let xAxis = d3.axisBottom(xScale);
let yAxis = d3.axisLeft(yScale);
chartContainer
.append('g')
.attr('transform', 'translate(0,' + H + ')')
.call(xAxis);

chartContainer.append('g').call(yAxis);
return svgElement;
}
Insert cell
md`#### D3 area chart: Stacked Area Chart`
Insert cell
{
let width = 700;
let height = 300;
let svgElement = DOM.svg(width, height);
let svg = d3.select(svgElement);

let margin = {
top: 20,
right: 20,
bottom: 50,
left: 50
};
let W = width - margin.left - margin.right,
H = height - margin.top - margin.bottom;

let chartContainer = svg
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

let data = [
{ apricots: 120, blueberries: 180, cherries: 100 },
{ apricots: 60, blueberries: 185, cherries: 105 },
{ apricots: 100, blueberries: 215, cherries: 110 },
{ apricots: 80, blueberries: 230, cherries: 105 },
{ apricots: 120, blueberries: 240, cherries: 105 }
];
let stack = d3.stack().keys(['apricots', 'blueberries', 'cherries']);
let stackData = stack(data);

let xScale = d3
.scaleLinear()
.domain([0, data.length - 1])
.range([0, W]);

let yScale = d3
.scaleLinear()
.domain([0, d3.max(stackData, d => d3.max(d, d => d[1]))])
.range([H, 0])
.nice();

let areaGenerator = d3
.area()
.x((d, i) => xScale(i))
.y0(d => yScale(d[0]))
.y1(d => yScale(d[1]));

chartContainer
.selectAll('path')
.data(stackData)
.join('path')
.attr('d', areaGenerator)
.style('fill', (d, i) => d3.schemeCategory10[i]);

let xAxis = d3.axisBottom(xScale);
let yAxis = d3.axisLeft(yScale);

chartContainer
.append('g')
.attr('transform', 'translate(0,' + H + ')')
.call(xAxis);

chartContainer.append('g').call(yAxis);
return svgElement;
}
Insert cell
md`#### D3 arc`
Insert cell
{
let width = 700;
let height = 300;
let svgElement = DOM.svg(width, height);
let svg = d3.select(svgElement);

let margin = {
top: 5,
right: 5,
bottom: 5,
left: 5
};

let W = width - margin.left - margin.right,
H = height - margin.top - margin.bottom;

let chartContainer = svg
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

let arcGenerator = d3
.arc()
.innerRadius(H / 6)
.outerRadius(H / 2)
.startAngle(0)
.endAngle(Math.PI / 4);

chartContainer
.append("path")
.attr("transform", `translate(${W / 2},${H / 2})`)
.attr("d", arcGenerator)
.style("fill", "steelblue")
.style("stroke", "black");

return svgElement;
}
Insert cell
md`#### D3 Pie/Donut Chart`
Insert cell
{
let width = 700;
let height = 300;
let svgElement = DOM.svg(width, height);
let svg = d3.select(svgElement);

let margin = {
top: 5,
right: 5,
bottom: 5,
left: 5
};

let W = width - margin.left - margin.right,
H = height - margin.top - margin.bottom;

let chartContainer = svg
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

let arcGenerator = d3
.arc()
.innerRadius(H / 6)
.outerRadius(H / 2);

let data = [10, 40, 30, 20, 60, 80];
let arcData = d3.pie().padAngle(2 / 180)(data);

chartContainer
.selectAll("path")
.data(arcData)
.join("path")
.attr("transform", `translate(${W / 2},${H / 2})`)
.attr("d", arcGenerator)
.style("fill", (d, i) => d3.schemeCategory10[i]);

return svgElement;
}
Insert cell
md`### External libraries and imports`
Insert cell
import {Button, Checkbox, Toggle, Radio, Range, Select, Text, Textarea, Search, Table} from "@observablehq/inputs"
Insert cell
d3 = require("d3@6")
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more