Public
Edited
Dec 19, 2022
Insert cell
Insert cell
{
const svg = d3.select(DOM.svg(width + margin.left + margin.right, height + margin.left + margin.right));

const voronoi = svg.append("g").attr('class', 'voronoiG').attr("transform", "translate(" + margin.left + "," + margin.top + ")");
const giantCircleG = svg.append("g").attr('class', 'giantG').attr("transform", "translate(" + margin.left + "," + margin.top + ")");
const labels = svg.append("g").attr('class', 'labelG').attr("transform", "translate(" + margin.left + "," + margin.top + ")");
const pop_labels = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
const reducer = (acc, cur) => acc + cur.market_cap;
const allMktCap = data.reduce(reducer, 0);
const mkt_radius = 20* Math.sqrt(allMktCap);
const weightScale = function(d){return d.market_cap}
const clippingPoly = computeClippingPolygon(mkt_radius)
const giantCircle = giantCircleG.selectAll('.circle')
.data([1]).enter().append('circle').attr('class', 'circle')
.attr('cx', mkt_radius+100)
.attr('cy', mkt_radius)
.attr('r', 20* Math.sqrt(46.16))
.attr('stroke', '#000')
.attr('stroke-dasharray', '3 3')
.attr('fill', 'none')
.attr('stroke-width', 2)
var simulation = d3.voronoiMapSimulation(data)
.weight(function(d){ return weightScale(d); } ) // set the weight accessor
.clip(clippingPoly) // set the clipping polygon
.on ("tick", ticked) // function 'ticked' is called after each iteration

function ticked() {
var state = simulation.state(), // retrieve the simulation's state
polygons = state.polygons, // retrieve polygons
drawnCells;
const area_scale = d3.scaleSqrt()
.domain([0, 100000])
.range([2, 30])

drawnCells = voronoi.selectAll('path').data(polygons); // d3's join
drawnCells = drawnCells
.enter().append('path') // create cells at first render
.merge(drawnCells) // assigns appropriate shapes and colors
.attr('id', d=>`${d.site.originalObject.data.originalData.ticker}`)
.attr('d', function(d) {
let area0 = d3.polygonArea(d)
return drawRoundedPolygon(d, area_scale(area0)) //rounded-corners.js
// return `M${d.join("L")}Z`
})
.attr('stroke', 'white')
.style('fill', function(d) {
return fillScale(d.site.originalObject);
});
let labelText = labels.selectAll('.label').data(polygons);
labelText = labelText.enter().append('text').attr('class', 'label')
.merge(labelText).text(d=> `${d.site.originalObject.data.originalData.ticker}` )
.attr('x',function(d){
return d.site.x
} )
.attr('y', d=> d.site.y )
.attr('fill', 'black')
.attr('stroke', 'none')
.attr('font-family', 'Retina')
}
function fillScale(d){
if(d.data.originalData.role =='giant'){
return '#0098db';
}
return '#e2e3e4'
}
return svg.node();
}
Insert cell
function getMyCentroid(element) {
var bbox = element.node().getBBox();
return [bbox.x + bbox.width/2, bbox.y + bbox.height/2];
}
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
data = origin_data.company.filter(t=>t.role!='giant' && ['YUM', 'QSR', 'CMG'].indexOf(t.ticker)==-1)
Insert cell
Insert cell
d3 = require("d3@5", "d3-weighted-voronoi", "d3-voronoi-map", "d3-voronoi-treemap")
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