Public
Edited
Aug 9, 2023
Insert cell
Insert cell
Insert cell
Insert cell
html`<svg viewBox="0,0,100,100" width="100" height="100">
${data.map((d, i) => `
<g transform="translate(${[i * squareSize, i * squareSize]})">
<rect width="${squareSize}" height="${squareSize}" fill="lightblue"></rect>
<circle cx="${squareSize/2}" cy="${squareSize/2}" r="${squareSize/3}" fill="salmon"></circle>
<text x="${squareSize/2}" y="${squareSize/2}" text-anchor="middle" dy=".35em" fill="white" font-family="Arial">${d}</text>
</g>`)}
</svg>`
Insert cell
Insert cell
html`
<svg viewBox="0,0,30,30" width="100" height="100">
<!-- a nested <svg> can't have a transform -->
<svg width="100" height="100" transform="translate(10,10)">
<rect width="10" height="10" fill="hotpink">
</svg>

<!-- option a: replace it with a <g> -->
<g width="100" height="100" transform="translate(10,10)">
<rect width="10" height="10" fill="steelblue">
</g>

<!-- option b: wrap it with a <g> -->
<g width="100" height="100" transform="translate(20,10)">
<svg width="100" height="100" >
<rect width="10" height="10" fill="orange">
</svg>
</g>
</svg>
`
Insert cell
Insert cell
html`
<svg viewBox="0 0 500 100" width="500" height="100">
<rect fill="lightgrey" width="100%" height="100%"></rect>

<svg viewBox="0 0 750 750" preserveAspectRatio="xMinYMid meet">
<circle r="375" cx="50%" cy="50%" fill="steelblue">
</svg>

<!-- this is the default preserveAspectRatio -->
<svg viewBox="0 0 750 750" preserveAspectRatio="xMidYMid meet">
<circle r="375" cx="50%" cy="50%" fill="hotpink">
</svg>
<svg viewBox="0 0 750 750" preserveAspectRatio="xMaxYMid meet">
<circle r="375" cx="50%" cy="50%" fill="orange">
</svg>
</svg>
`
Insert cell
html`
<svg viewBox="0 0 500 100" width="500" height="100">
<rect fill="lightgrey" width="100%" height="100%"></rect>

<g width="50" height="50">
<svg viewBox="0 0 750 750" preserveAspectRatio="xMinYMid meet">
<circle r="375" cx="50%" cy="50%" fill="steelblue">
</svg>
</g>
</svg>
`
Insert cell
Insert cell
{
const svg = d3.select(DOM.svg(100, 100));

svg
.selectAll("rect")
.data(data)
.join("rect")
.attr(
"transform",
(d, i) => `translate(${[i * squareSize, i * squareSize]})`
)
// same as:
// .attr("x", (d, i) => i * squareSize)
// .attr("y", (d, i) => i * squareSize)
.attr("width", squareSize)
.attr("height", squareSize)
.attr("fill", "lightblue");

svg
.selectAll("circle")
.data(data)
.join("circle")
.attr(
"transform",
(d, i) =>
`translate(${[
i * squareSize + squareSize / 2,
i * squareSize + squareSize / 2
]})`
)
// same as:
// .attr("cx", (d, i) => i * squareSize + squareSize / 2)
// .attr("cy", (d, i) => i * squareSize + squareSize / 2)
.attr("r", squareSize / 3)
.attr("fill", "salmon");

svg
.selectAll("text")
.data(data)
.join("text")
.attr(
"transform",
(d, i) =>
`translate(${[
i * squareSize + squareSize / 2,
i * squareSize + squareSize / 2
]})`
)
// same as:
// .attr("x", (d, i) => i * squareSize + squareSize / 2)
// .attr("y", (d, i) => i * squareSize + squareSize / 2)
.attr("text-anchor", "middle")
.attr("dy", ".35em")
.attr("fill", "white")
.attr("font-family", "Arial")
.text((d) => d);

return svg.node();
}
Insert cell
Insert cell
{
const svg = d3.select(DOM.svg(100, 100));

const g = svg.selectAll("g").data(data).join("g");

g.append("rect")
.attr(
"transform",
(d, i) => `translate(${[i * squareSize, i * squareSize]})`
)
.attr("width", squareSize)
.attr("height", squareSize)
.attr("fill", "lightblue");

g.append("circle")
.attr(
"transform",
(d, i) =>
`translate(${[
i * squareSize + squareSize / 2,
i * squareSize + squareSize / 2
]})`
)
.attr("r", squareSize / 3)
.attr("fill", "salmon");

g.append("text")
.attr(
"transform",
(d, i) =>
`translate(${[
i * squareSize + squareSize / 2,
i * squareSize + squareSize / 2
]})`
)
.attr("text-anchor", "middle")
.attr("dy", ".35em")
.attr("fill", "white")
.attr("font-family", "Arial")
.text((d) => d);

return svg.node();
}
Insert cell
Insert cell
{
const svg = d3.select(DOM.svg(100, 100));

const g = svg
.selectAll("g")
.data(data)
.join("g")
.attr(
"transform",
(d, i) => `translate(${[i * squareSize, i * squareSize]})`
);

g.append("rect")
.attr("width", squareSize)
.attr("height", squareSize)
.attr("fill", "lightblue");

g.append("circle")
.attr("transform", `translate(${[squareSize / 2, squareSize / 2]})`)
.attr("r", squareSize / 3)
.attr("fill", "salmon");

g.append("text")
.attr("transform", `translate(${[squareSize / 2, squareSize / 2]})`)
.attr("text-anchor", "middle")
.attr("dy", ".35em")
.attr("fill", "white")
.attr("font-family", "Arial")
.text((d) => d);

return svg.node();
}
Insert cell
Insert cell
{
const svg = d3.select(DOM.svg(100, 100));

const padding = 3;

const g = svg
.selectAll("g")
.data(data)
.join("g")
.attr(
"transform",
(d, i) =>
`translate(${[i * (squareSize + padding), i * (squareSize + padding)]})`
);

g.append("rect")
.attr("width", squareSize)
.attr("height", squareSize)
.attr("fill", "lightblue");

g.append("circle")
.attr("transform", `translate(${[squareSize / 2, squareSize / 2]})`)
.attr("r", squareSize / 3)
.attr("fill", "salmon");

g.append("text")
.attr("transform", `translate(${[squareSize / 2, squareSize / 2]})`)
.attr("text-anchor", "middle")
.attr("dy", ".35em")
.attr("fill", "white")
.attr("font-family", "Arial")
.text((d) => d);

return svg.node();
}
Insert cell
Insert cell
{
const svg = d3.select(DOM.svg(100, 100));

const padding = 3;

const g = svg
.selectAll("g")
.data(data)
.join("g")
.attr(
"transform",
(d, i) => `translate(${[i * squareSize, i * squareSize]})`
);

g.append("rect")
.attr("width", squareSize - padding)
.attr("height", squareSize - padding)
.attr("fill", "lightblue");

g.append("circle")
.attr(
"transform",
`translate(${[(squareSize - padding) / 2, (squareSize - padding) / 2]})`
)
.attr("r", (squareSize - padding) / 3)
.attr("fill", "salmon");

g.append("text")
.attr(
"transform",
`translate(${[(squareSize - padding) / 2, (squareSize - padding) / 2]})`
)
.attr("text-anchor", "middle")
.attr("dy", ".35em")
.attr("fill", "white")
.attr("font-family", "Arial")
.text((d) => d);

return svg.node();
}
Insert cell
Insert cell
{
const svg = d3.select(DOM.svg(100, 100));

const padding = 5;
const strokeWidth = 5;

const g = svg
.selectAll("g")
.data(data)
.join("g")
.attr(
"transform",
(d, i) =>
`translate(${[
i * squareSize + strokeWidth / 2,
i * squareSize + strokeWidth / 2
]})`
);

g.append("rect")
.attr("width", squareSize - padding)
.attr("height", squareSize - padding)
.attr("stroke", "steelblue")
.attr("stroke-width", strokeWidth)
.attr("fill", "lightblue");

g.append("circle")
.attr(
"transform",
`translate(${[(squareSize - padding) / 2, (squareSize - padding) / 2]})`
)
.attr("r", (squareSize - padding) / 3)
.attr("fill", "salmon");

g.append("text")
.attr(
"transform",
`translate(${[(squareSize - padding) / 2, (squareSize - padding) / 2]})`
)
.attr("text-anchor", "middle")
.attr("dy", ".35em")
.attr("fill", "white")
.attr("font-family", "Arial")
.text((d) => d);

return svg.node();
}
Insert cell
Insert cell
{
const height = 150;
const svg = d3.select(DOM.svg(width, height));

const textData = [
["right-aligned", "And line 2", "And, finally: line 3"],
["middle-aligned", "another line"]
];
const g = svg
.selectAll("g")
.data(textData)
.join("g")
.attr("transform", (d, i) => `translate(${[0, 10 + i * 70]})`);

const text = g
.append("text")
.attr("x", (d, i) => (i === 0 ? 0 : 90))
// .attr('y', height/2)
.attr("dy", ".35em")
.attr("font-family", "Arial");

text
.selectAll("tspan")
.data((d) => d)
.attr("text-anchor", (d, i) => (i === 0 ? "left" : "middle"))
.join("tspan")
.attr("y", (d, i) => i*20)
.text((d) => d);

return svg.node();
}
Insert cell
Insert cell
squareSize = 30
Insert cell
data = ["a", "b", "c"]
Insert cell
import { toc } from "@mbostock/toc"
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