Published
Edited
May 19, 2021
Insert cell
Insert cell
goodgraphics(
{
height: 800,
width: 800,
attributes: {
fill: "none",
style: "background: #fff",
stroke: "none",
"stroke-width": "1.5px"
}
},
(svg) => {
const grid = 7;
const colors = getRandomPalette();

const drawTile = (item) => {
const { posX, posY, cellWidth, cellHeight, colIndex, rowIndex } = item;
const clipId = `${colIndex}-${rowIndex}`;
const marginWidth = cellWidth * 0.1;
const marginHeight = cellHeight * 0.1;
const x = posX + marginWidth / 2;
const y = posY + marginHeight / 2;
const width = cellWidth - marginWidth;
const height = cellHeight - marginHeight;
const halfWidth = width / 2;
const halfHeight = height / 2;
const circleWidth = halfWidth * 0.8;
const circleHeight = halfHeight * 0.8;

svg.add(`
<defs>
<clipPath id="${clipId}">
<rect x="${x}" y="${y}" width="${width}" height="${height}" />
</clipPath>
</defs>
`);

svg.groupStart({
"clip-path": `url(#${clipId})`
});

svg.rect(x, y, width, height, { fill: colors[0] });
// big circle
svg.ellipse(
x - halfWidth / 2,
y + halfHeight,
halfWidth * 1.5,
halfHeight * 1.5,
{ fill: colors[1] }
);
// left circle
svg.ellipse(x, y + halfHeight, circleWidth, circleHeight, {
fill: colors[0]
});
// right circle
svg.ellipse(x + width, y + halfHeight, circleWidth, circleHeight, {
fill: colors[1]
});

svg.groupEnd();
};

svg.grid({ columns: grid, rows: grid }, (item) => {
drawTile(item);
});

svg.draw();
}
)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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