Published unlisted
Edited
Sep 29, 2021
Insert cell
Insert cell
dataviz = {
const svg = d3
.create("svg")
.style("display", "block")
.attr("viewBox", [0, 0, width, height]);

const g = svg.append("g");

const path = d3.geoPath(projection);

const radius = d3.scaleSqrt(
[0, d3.max(points.features.map((d) => d.properties.Papers))],
[0, 10]
);

g.append("g")
.selectAll("path")
.data(countries.features)
.join("path")
.attr("class", "country")
.attr("fill", "lightgrey")
.attr("d", path)
.attr("stroke", "white")
.attr("stroke-width", 0.2)
.attr("stroke-linejoin", "round");

g.append("g")
.attr("fill", "#F8BF1E")
.attr("fill-opacity", 0.5)
.selectAll("circle")
.data(points.features)
.join("circle")
.attr("cx", (d) => path_points.centroid(d)[0])
.attr("cy", (d) => path_points.centroid(d)[1])
.attr("r", (d) => radius(d.properties.Papers))
.attr("stroke-width", 0.5)
.attr("data-tippy-content", (d) => `${d.properties.School}<br /> Number of Blockchain-related Research Papers: ${d.properties.Papers}`)
//.text((d) => `${d.properties.School} : ${d.properties.Papers}`);
g.selectAll('circle').nodes().forEach(c => tippy(c, {
allowHTML: true,
theme: "light",
}))

// const tooltip = svg.append("g");

// svg
// .selectAll("circle")
// .on("touchmove mousemove", function (event, d) {
// tooltip.call(
// callout,
// `${d.properties.School}
// Number of Blockchain-related Research Papers: ${d.properties.Papers}`
// );

// tooltip.attr(
// "transform",
// `translate(${path_points.centroid(d)[0]}, ${
// path_points.centroid(d)[1] + 15
// })`
// );

// d3.select(this).attr("stroke", "red").raise();
// })
// .on("touchend mouseleave", function () {
// tooltip.call(callout, null);
// d3.select(this).attr("stroke", null).lower();
// });

let zoom = d3
.zoom()
.scaleExtent([1, 16])
.translateExtent([
[0, 0],
[width, height]
])
.on("zoom", function (event, d) {
radius.range([0 / event.transform.k, 10 / event.transform.k]);

g.selectAll("path").attr("transform", event.transform);

svg
.selectAll("circle")
.attr("transform", event.transform)
.attr("r", (d) => radius(d.properties.Papers))
.attr("stroke-width", 0.5 / event.transform.k);
// tooltip.attr(
// "transform",
// `translate(${path_points.centroid(d)[0]}, ${
// path_points.centroid(d)[1]
// })`
// );
// tooltip.attr("transform", `translate(${event.pageX}, ${event.pageY})`);
});

svg.call(zoom);

return svg.node();
}
Insert cell
projection = d3.geoMercator()
Insert cell
path_points = d3.geoPath().projection(projection)
Insert cell
height = {
const [[x0, y0], [x1, y1]] = d3.geoPath(projection.fitWidth(width, outline)).bounds(outline);
const dy = Math.ceil(y1 - y0), l = Math.min(Math.ceil(x1 - x0), dy);
projection.scale(projection.scale() * (l - 1) / l).precision(0.2);
return dy;
}
Insert cell
outline = ({ type: "Sphere" })
Insert cell
Insert cell
points = FileAttachment("CoinDesk_map.geojson").json()
Insert cell
countries = topojson.feature(world, world.objects.countries)
Insert cell
world = FileAttachment("countries-50m.json").json()
Insert cell
topojson = require("topojson-client@3")
Insert cell
d3 = require("d3@6")
Insert cell
tippy = require('tippy.js@6')
Insert cell
tippy_style = html`<link rel="stylesheet" href="${await require.resolve(
`tippy.js/themes/light.css`
)}">`
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