Published unlisted
Edited
Feb 19, 2019
1 star
Insert cell
Insert cell
Insert cell
// you probably don't want to do this: an HTML document should only have one <body> tag
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/body
// html`<body></body>`
Insert cell
html`<div id="indonesia-map"></div>`
Insert cell
// indonesia_json = d3.json("https://gist.githubusercontent.com/tvalentius/10ef8cbefbacaecada45161b1f3810ce/raw/e5275d5a6ca90b4f0193d2ff151107cbfa0f89bc/indonesia.json")
Insert cell
{
var width = 700;
var height = 580;

// this selects the first div element in the HTML document, which is the title markdown cell:
// var svg = d3.select( "div" )
// this is probably what you wanted:
// var svg = d3.select( "#indonesia-map" )
// .append( "svg" )
// .attr( "width", width )
// .attr( "height", height );

// However, a cleaner approach is to have this cell return the SVG instead of appending it to another cell
var svg = d3.select(DOM.svg(width,height));

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

var projection = d3.geo.equirectangular()
// I changed the scale so that this will fit
.scale(600)
.rotate([-120, 0])
.translate([width / 2, height / 2]);

var path = d3.geo.path()
.projection(projection);

// It's easier to load the data in the same cell as the SVG because of the way d3 json works:
// It makes a request at a certain URL and then passes the result to a callback function.
// It is natural to make this callback function act directly on various d3 selections arising from
// the SVG, as you can see below.
const indonesia_json = d3.json("https://gist.githubusercontent.com/tvalentius/10ef8cbefbacaecada45161b1f3810ce/raw/e5275d5a6ca90b4f0193d2ff151107cbfa0f89bc/indonesia.json", function(error, response) {
if (error) throw error;

// This is a topoJSON map file, so we'll need to use features from the topojson library (and require it below!)
// each topoJSON file will have different objects containing different Geometries
// This particular one has 3: places, subunits, states_provinces
console.log(response);
// I'll just copy the same code 3 times, once for each of the objects
// Another approach would be to use a for loop
g.append("g")
.attr("id", "places")
.selectAll("path")
.data(topojson.feature(response, response.objects.places).features)
.enter().append("path")
.attr("d", path)
// Let's not worry about making this interactive for now
// .on("click", clicked);
.attr('fill', 'none')
.attr('stroke', 'red');

g.append("g")
.attr("id", "states_provinces")
.selectAll("path")
.data(topojson.feature(response, response.objects.states_provinces).features)
.enter().append("path")
.attr("d", path)
.attr('fill', 'none')
.attr('stroke', 'blue');
g.append("g")
.attr("id", "subunits")
.selectAll("path")
.data(topojson.feature(response, response.objects.subunits).features)
.enter().append("path")
.attr("d", path)
.attr('fill', 'none')
.attr('stroke', 'green');


// note that this function doesn't return anything but it has a lot of "side effects"!
// the logic to get this to work if this were in another cell would be rather more complicated

});

// The following gave an error because the indonesia_json cell was not returning a JSON object,
// but rather a HTTP request object
// g.selectAll( "path" )
// .data( indonesia_json.objects )
// .enter()
// .append( "path" )
// .attr( "fill", "#ccc" )
// .attr( "stroke", "#333")
// .attr( "d", path );

// generally you should only need to use "yield" if the cell is a generator
// yield svg
// in the previous version of this code, this line would have been unnecessary anyways
// since the above code was acting on another div cell

// "svg" is a D3 selection, so you have to return its underlying DOM node to display it
return svg.node();
}
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