Published
Edited
Jun 21, 2021
Insert cell
Insert cell
chart = {
const chart = d3
.create('svg')
.attr('width', width)
.attr('height', height);

const color = d3
.scaleOrdinal()
.domain(["a", "b", "c"])
.range(['green', 'orange', 'red']);
const cells = circles.map((d, i) => [d, voronoi.cellPolygon(i)]);
// number of circles
const num = circles.length;

// get the area of the polgygon
// and divide it into the number of circles we want
// with some offset because ???
const area = (d3.polygonArea(polygon) / num) * 0.8;
// get the center of the polygon
// using this as a standin for our points just to plot something
const center = d3.polygonCentroid(polygon);
const diameter = Math.sqrt(-area);
// given the number of circles and the polygon shape
// return a vector of XYs to put inside our element object below for plotting
// (make a grid and get the centroids maybe?)
// (maybe we can use deulaney for this?)
// const XYs = getXYs(num, polygon)

// initially placed on the grid at the bottom
// const elements = circles.map((d, i) => ({
// x: center[0], //XY.x[i]
// y: center[1], //XY.y[i]
// r: d.count,
// food: d.food
// }));
const elements = circles.map((d, i) => ({
x: coor[i][0], //XY.x[i]
y: coor[i][1], //XY.y[i]
r: d.count,
food: d.food
}));


chart
.append('path')
.data([polygon])
.attr('stroke', 'black')
.attr('fill', 'none')
.attr('d', d => d3.line()(d));
// show the elements in their initial position
chart
.selectAll('g.element')
.data(elements, (d, i) => i)
.enter()
.append('g')
.attr('class', 'element')
.append('circle')
.attr('cx', d => d.x)
.attr('cy', d => d.y)
.attr('r', d => d.r)
.style('stroke', 'none')
.attr('fill', d => color(d.food))

// chart.append("g")
// .style("font", "10px sans-serif")
// .selectAll("text")
// .data(cells)
// .join("text")
// .each(function([[x, y], cell]) {
// console.log(cell)
// const [cx, cy] = d3.polygonCentroid(cell);
// const angle = (Math.round(Math.atan2(cy - y, cx - x) / Math.PI * 2) + 4) % 4;
// d3.select(this).call(angle === 0 ? orient.right
// : angle === 3 ? orient.top
// : angle === 1 ? orient.bottom
// : orient.left);
// })
// //.attr("transform", ([d]) => `translate(${d})`)
// .attr("display", ([, cell]) => -d3.polygonArea(cell) > 2000 ? null : "none")
// .text((d, i) => i);
return chart.node()

}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
/*

// RIGHT NOW THIS IS TOTALLY COPIED FROM THE SCRIPT FUNCTION
// WE DEF NEED TO ADAPT THIS A BIT AND UNPACK IT
// IDEALLY WE WANT TO SUPPLY N AND POLYGON
// AND RETURN N [X,Y]

getXY = (points) => {
// what IS points here?
const n = points.length
const c = new Float64Array(n * 2);
const s = new Float64Array(n);
const [cx, cy] = center;
const strength = 0.1

const delaunay = new d3.Delaunay(points);
const voronoi = delaunay.voronoi([0, 0, width, height]);

for (let k = 0; k < 80; ++k) {
// Compute the weighted centroid for each Voronoi cell.
c.fill(0);
s.fill(0);
for (let y = 0, i = 0; y < height; ++y) {
for (let x = 0; x < width; ++x) {
// what is data?!
const w = data[y * width + x];
i = delaunay.find(x + 0.5, y + 0.5, i);
s[i] += w;
c[i * 2] += w * (x + 0.5);
c[i * 2 + 1] += w * (y + 0.5);
}
}

// do we even need all of this part? probably not?
// Relax the diagram by moving points to the weighted centroid.
// Wiggle the points a little bit so they don’t get stuck.
const w = Math.pow(k + 1, -0.8) * 10;
for (let i = 0; i < n; ++i) {
const x0 = points[i * 2], y0 = points[i * 2 + 1];
const wp = data[Math.floor(y0) * width + Math.floor(x0)];
let x1, y1;
if (wp && s[i]) {
x1 = c[i * 2] / s[i];
y1 = c[i * 2 + 1] / s[i];
} else {
x1 = x0 + (cx - x0) * strength
y1 = y0 + (cy - y0) * strength;
}
points[i * 2] = x0 + (x1 - x0) * 1.8 + (Math.random() - 0.5) * w;
points[i * 2 + 1] = y0 + (y1 - y0) * 1.8 + (Math.random() - 0.5) * w;
}
// can we have this return a vector of [x, y] of length circles?
voronoi.update();
}
}
*/
Insert cell
//get our polygon from path
polygon = polygonSampledFromPath(maxspath, 1000)
Insert cell
Insert cell
polygonExt = d3.extent(polygon)
Insert cell
polygonExtX = {
return polygonExt.map(i => i[0])
}
Insert cell
polygonExtY = {
return polygonExt.map(i => i[1])
}
Insert cell
//make an array of random points
function getRandomPoints() {
let pts = [getRandomArbitrary(polygonExtX[0] ,polygonExtX[1]), getRandomArbitrary(polygonExtY[0] ,polygonExtY[1])]
return pts;
}

Insert cell
Insert cell
Insert cell
margin = 50
Insert cell
packed = {
let svgElement, svg;
[svgElement, svg] = getSVG();

const color = d3
.scaleOrdinal()
.domain(["a", "b", "c"])
.range(['green', 'orange', 'red']);
const cells = circles.map((d, i) => [d, voronoi.cellPolygon(i)]);
// number of circles
const num = circles.length;

// get the area of the polgygon
// and divide it into the number of circles we want
// with some offset because ???
const area = (d3.polygonArea(polygon) / num) * 0.8;
// get the center of the polygon
// using this as a standin for our points just to plot something
const center = d3.polygonCentroid(polygon);
const diameter = Math.sqrt(-area);

const elements = circles.map((d, i) => ({
x: coor[i][0], //XY.x[i]
y: coor[i][1], //XY.y[i]
r: d.count,
food: d.food
}));


svg
.append('path')
.data([polygon])
.attr('stroke', 'black')
.attr('fill', 'none')
.attr('d', d => d3.line()(d));

const root = pack(data);

const node = svg.selectAll("g")
.data(d3.group(root.descendants(), d => d.height))
.join("g")
.selectAll("g")
.data(d => d[1])
.join("g")
.attr("transform", d => `translate(${d.x + 1},${d.y + 1})`);

node.append("circle")
.attr("r", d => d.r)
.attr("fill", d => color(d.height));

const leaf = node.filter(d => !d.children);
leaf.select("circle")
.attr("id", d => (d.leafUid = DOM.uid("leaf")).id);
return svgElement
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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