Siya
Siya

Reputation: 829

D3js External JavaScript file

I am working through a project for a company I plan on working for and I was given a code challenge to create a choropleth map of Kenya. I have been able to generate the map using GeoJSON and TopoJSON drawing the paths from JSON files in a folder. Currently this is how my HTML looks:

<!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
                <script type="text/javascript" src="js/d3.v3.js"></script>
                <script type="text/javascript" src="js/topojson.js"></script>
                <script type="text/javascript" src="js/jquery.js"></script>
                <script type="text/javascript" src="js/bootstrap.js"></script>



                <link rel="stylesheet" href="css/bootstrap.css" media="screen">
        </head>
        <body>
            <div class="row">
            <header class="span12">
                <h1>Aphellion Activity 1 - Kenya Maps</h1>
                <h3>The goal of this activity is generate two maps one drawn with D3.js using GeoJSON to generates the paths, the other drawn using TopoJSON to generate the paths.</h3>
            </header>
            </div>
            </br>
            <div class="row">
                <div  class="span4" id="Map1"></div>
                <div class="span2" id="paragraph">

                </div>
                <div class="span4" id="Map2"></div>
                <div class="span2">
                    <p>Mauris ornare mollis odio, non molestie arcu ullamcorper sit amet. Vivamus ultrices, est id ullamcorper blandit, risus ligula fringilla nibh, in convallis orci urna et sapien. Phasellus malesuada accumsan velit ut tristique. Duis vehicula pellentesque gravida. Curabitur at mollis turpis, in convallis risus. Sed faucibus non dui quis vehicula. Fusce mollis ullamcorper adipiscing. Vestibulum hendrerit luctus erat ac iaculis.</p>
                </div>
            </div>
        </body>
        <script type="text/javascript">
            d3.select("div#paragraph").text("Mauris ornare mollis odio, non molestie arcu ullamcorper sit amet. Vivamus ultrices, est id ullamcorper blandit, risus ligula fringilla nibh, in convallis orci urna et sapien. Phasellus malesuada accumsan velit ut tristique. Duis vehicula pellentesque gravida. Curabitur at mollis turpis, in convallis risus. Sed faucibus non dui quis vehicula. Fusce mollis ullamcorper adipiscing. Vestibulum hendrerit luctus erat ac iaculis");

            var width = 300;
            var height = 400;

    //TopoJSON Map
    //new projection
        var projection = d3.geo.mercator()
                                .center([36.8000, 1.2667])
                .scale([1000])
                                .translate([width/2, height/2]);


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


    var svg = d3.select("div#Map1")
                        .append("svg")
                        .attr("width", width)
                        .attr("height", height)
                        .style("fill", "steelblue");

            var g = svg.append("g")
                        .call(d3.behavior.zoom()
                              .scaleExtent([1, 10])
                              .on("zoom", zoom));

            d3.json("js/kenya-topo.json", function(error, topology) {
                g.selectAll("path")
                .data(topojson.feature(topology, topology.objects.Kenya).features)
                .enter()
                .append("path")
                .attr("d", path);
                });

            svg.append("rect").attr("width", width).attr("height", height).style("stroke", "black").style("fill", "none");

            function zoom() {
                g.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
            };

    //GeoJSON Map        
    var svg = d3.select("div#Map2")
                .append("svg")
                .attr("width", width)
                .attr("height", height);

    //Load in GeoJSON data
            d3.json("js/kenya.geojson", function(json) {

                //Create first guess for the projections
                var center = d3.geo.centroid(json)
                var scale = 2000;
                var offset = [width/2, height/2];
                var projection = d3.geo.mercator()
                            .scale(scale)
                            .center(center)
                            .translate(offset);

                //Define default path generator
                var path = d3.geo.path()
                    .projection(projection);

                //using the path determine the bounds of the current map and use
                //these to determine better values for the scale and translation
                var bounds = path.bounds(json);
                var hscale = scale*width / (bounds[1][0] - bounds[0][0]);
                var vscale = (hscale < vscale) ? hscale : vscale;
                var offset = [width - (bounds[0][0] + bounds[1][0])/2, height - (bounds[0][1] + bounds[1][1]/2)];

                //new projection
                projection = d3.geo.mercator().center(center)
                        .scale(scale).translate(offset);
                path = path.projection(projection);

                //add a rectangle to see the bound of the svg
                svg.append("rect").attr("width", width).attr("height", height).style("stroke", "black").style("fill", "none");



                //Bind data and create one path per GeoJSON feature
                svg.selectAll("path")
                   .data(json.features)
                   .enter()
                   .append("path")
                   .attr("d", path)
                   .style("fill", "steelblue");

            });            
        </script>

    </html>

As you can see my JavaScript is below the but what I wanted to do was to have it in two separate files that I would query in the . When I do this the data doesn't get bound to the DOM and no SVG's are generated. I don't see any errors in the console, so I figure that there is something I'm missing when write my D3 code in a separate JavaScript file. Can anyone help me in this regard? Much appreciated.

P.S. Please excuse the messy-ness of my code, I'm refactoring it as we speak. I took it from two different recipes I found in books and online.

Upvotes: 3

Views: 5262

Answers (2)

utkarsh
utkarsh

Reputation: 143

To analyse the problem you need to understand that semantically, the script tags can be replaced by the code they reference and the referenced code is executed before the next node is processed, so it's the same as having the code in your index file at the point where the script tags are.

Upvotes: 0

Scott
Scott

Reputation: 71

This answer may seem late, but I had this same problem and what fixed it was keeping in mind the script that contains your transfered code needs to be put at the very bottom of the page right before the ending of the body tag. Its always a good idea to put the script that links to the d3 library right above your written script. Reason being, is if you put your script in the head tags of the html page, the elements it searches for do not exist yet. Everything is synchronous when it come to the DOM unless specified.

Upvotes: 7

Related Questions