Published
Edited
Dec 30, 2021
3 forks
2 stars
Insert cell
Insert cell
Type JavaScript, then Shift-Enter. Ctrl-space for more options. Arrow ↑/↓ to switch modes.

Insert cell
chart = {
const svg = d3.create('svg')
.attr('viewBox', [0, 0, 960, 700]);
svg.append('g')
.attr('transform', 'translate(20, 10)')
.append(() => legend({color,
title: 'Starbucks',
ticks: 4,
tickFormat: '.0s'}));
const g = svg.append('g')
.selectAll('.provinces')
.data(provinceFeatures)
.join('path')
.attr('class', 'provinces')
.attr('d', pathGenerator)
.attr('fill', d => {
let cases = d.properties.count;
return cases === 'NA' || cases === undefined ?
'#636363' :
color(+cases);
})
.attr('stroke', 'white')
.attr('stroke-linejoin', 'round')
.attr('stroke-width', '0.7px')
// ********** new stuff starts here **********
.on('mouseenter', mouseEnter)
.on('mouseleave', mouseLeave)
.append("title")
.text(d => `省份:${d.properties.ProvCH}
星巴克门店数量:${d.properties.count === undefined ? 0 : d.properties.count}`);

// handle hovering over a circle
function mouseEnter(event, d) {
// make the circle larger
d3.select(this)
.attr('fill', "#D19F4A");
}
// handle leaving a circle
function mouseLeave(event, d) {
// reset the size of the circle
d3.select(this)
.attr('fill', d => {
let cases = d.properties.count;
return cases === 'NA' || cases === undefined ?
'#636363' :
color(+cases);
});
}
return svg.node();
}
Insert cell
color = d3.scaleSequentialLog()
.domain([1, maxTotalCases])
.interpolator(d3.interpolateGreens);
Insert cell
maxTotalCases = provinceFeatures.reduce((accumulator, d) => {
accumulator = (accumulator < +d.properties.count
&& d.properties.count !== 'NA') ?
+d.properties.count :
accumulator;
return accumulator;
}, 0)
Insert cell
projection = d3.geoMercator()
.center([105, 43])
.scale([820]);
Insert cell
pathGenerator = d3.geoPath().projection(projection);
Insert cell
provinceFeatures = provinces.features;
Insert cell
provinceFeatures[0].geometry.coordinates[0][0][0]
Insert cell
starMap = FileAttachment("starMap@3.csv").csv()
Insert cell
Insert cell
provinces = {
const provinces = topojson.feature(provinceJson, provinceJson.objects.china_province_basemap);
provinceID.forEach(d => {
d.count = starMap.filter(s => s.Province === d.ID).length
});
provinces.features.forEach(d => {
Object.assign(d.properties, provinceID.filter(a => a.ID === d.properties.GbProv)[0])
});
return provinces;
}
Insert cell
provinceJson = FileAttachment("china_province_basemap.json").json()
Insert cell
cityJson = FileAttachment('china_city_basemap@1.json').json()
Insert cell
topojson = require("topojson-client@3")
Insert cell
d3 = require("d3@5")
Insert cell
import {legend} from '@d3/color-legend'
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