Published
Edited
Apr 28, 2022
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: '全国各省份旅游景点热度',
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 || cases === 0 ?
'#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 || cases === 0 ?
'#636363' :
color(+cases);
});
}
return svg.node();
}
Insert cell
color = d3.scaleSequentialLog()
.domain([1, maxTotalCases])
.interpolator(d3.interpolateReds);
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

provinceID = [{ID: "11", count: 192520},
{ID: "12", count: 30289},
{ID: "13", count: 5002},
{ID: "14", count: 17325},
{ID: "15", count: 6406},
{ID: "21", count: 791},
{ID: "22", count: 9161},
{ID: "23", count: 41610},
{ID: "31", count: 251207},
{ID: "32", count:212394},
{ID: "33", count: 155226},
{ID: "34", count: 9594},
{ID: "35", count: 35816},
{ID: "36", count: 1589},
{ID: "37", count: 160239},
{ID: "41", count: 7013},
{ID: "42", count: 47710},
{ID: "43", count: 58110},
{ID: "44", count: 87114},
{ID: "45", count: 58820},
{ID: "46", count: 7033},
{ID: "50", count: 232364},
{ID: "51", count: 118669},
{ID: "52", count: 27558},
{ID: "53", count: 164532},
{ID: "54", count: 1642},
{ID: "61", count: 147346},
{ID: "62", count: 1000},
{ID: "63", count: 91382},
{ID: "64", count: 12932},
{ID: "65", count: 9232},
{ID: "71", count: 26435},
{ID: "81", count: 47560},
{ID: "82", count: 21382}]


Insert cell
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