d3.jsgeojsontopojson

Using D3.js for rendering map but the resulted map is too small


I'm using D3.js for drawing map of Vietnam. I fetch a GeoJSON data from an URL (in the code), I following a lot of instructions, from converting to TopoJSON (for compact size) then convert back to GeoJSON then generating path for SVG. But the map is too small.

const urlGEOJSON = 'https://data.opendevelopmentmekong.net/geoserver/ODMekong/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=ODMekong%3Aa4eb41a4-d806-4d20-b8aa-4835055a94c8&outputFormat=application%2Fjson';
const width = 800;
const height = 800;

d3.select('.container')
    .append('h1')
    .text('Viet Nam Map');

const svg = d3.select('.container')
                .append('svg')
                .attr('width', width)
                .attr('height', height)
                .attr('id', 'map')
                .attr('viewBox',[0, 0, width, width]);

fetch(urlGEOJSON)
    .then(res => res.json())
    .then(data => {
        
    // Convert GeoJSON data into TopoJSON
    const topo = topojson.topology({vietnam : data}, 1000);
    
    // Convert TopoJSON back to GeoJSON for using D3.geoPath()
    const provinces = topojson.feature(topo, topo.objects.vietnam);
    const country = topojson.mesh(topo, topo.objects.vietnam, (a,b)=> a === b);

    const projection = d3.geoMercator();
    
    const path = d3.geoPath().projection(projection);

    svg.append('g')
        .selectAll('path')
        .data(provinces.features)
        .enter()
        .append('path')
        .attr('d', path(provinces))
        .attr('fill', 'white');
            
    svg.append('path')
        .datum(country)
        .attr('fill', 'none')
        .attr('stroke', 'black')
        .attr('d', path(country))

    })
    .catch(err => console.log(err))

Solution

  • const urlGEOJSON = 'https://data.opendevelopmentmekong.net/geoserver/ODMekong/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=ODMekong%3Aa4eb41a4-d806-4d20-b8aa-4835055a94c8&outputFormat=application%2Fjson';
            const width = 800;
            const height = 800;
    
            d3.select('.container')
                .append('h1')
                .text('Vietnam Map');
    
            const svg = d3.select('.container')
                .append('svg')
                .attr('width', width)
                .attr('height', height)
                .attr('id', 'map')
                .attr('viewBox', [0, 0, width, height]);
    
            fetch(urlGEOJSON)
                .then(res => res.json())
                .then(data => {
                    // Convert GeoJSON data into TopoJSON
                    const topo = topojson.topology({ vietnam: data });
    
                    // Convert TopoJSON back to GeoJSON for using D3.geoPath()
                    const provinces = topojson.feature(topo, topo.objects.vietnam);
                    const country = topojson.mesh(topo, topo.objects.vietnam, (a, b) => a === b);
    
                    // Set up projection and path generator
                    const projection = d3.geoMercator()
                        .fitSize([width, height], provinces);
    
                    const path = d3.geoPath().projection(projection);
    
                    // Draw provinces
                    svg.append('g')
                        .selectAll('path')
                        .data(provinces.features)
                        .enter()
                        .append('path')
                        .attr('d', path)
                        .attr('fill', 'white')
                        .attr('stroke', '#666')
                        .attr('stroke-width', 0.5);
    
                    // Draw country border
                    svg.append('path')
                        .datum(country)
                        .attr('fill', 'none')
                        .attr('stroke', 'black')
                        .attr('stroke-width', 1)
                        .attr('d', path);
                })
                .catch(err => console.log(err));
            .container {
                text-align: center;
            }
            svg {
                border: 1px solid #ccc;
            }
    <head>
        <script src="https://d3js.org/d3.v6.min.js"></script>
        <script src="https://d3js.org/topojson.v3.min.js"></script>
    </head>
        <div class="container"></div>