d3地球在进入特定国家时切断了部分地球

时间:2014-03-28 16:41:39

标签: jquery svg d3.js

我在这里有一个测试网站: http://newsinteractive.post-gazette.com/test/

当我点击"国家"选项卡,然后单击其中一个国家/地区,如果该国家/地区位于欧洲,则一旦地球轮换到该国家/地区,地球的一部分就会被切断。

知道我做错了什么,拜托?

相关代码:

function handleGlobe() {

    //handle globe
    var width = 800,
    height = 800,
    centered;

        var feature;

        var projection = d3.geo.azimuthal()
            .scale(380)
            .origin([-71.03,42.37])
            .mode("orthographic")
            .translate([340, 450]);

        var circle = d3.geo.greatCircle()
            .origin(projection.origin());

        var scale = {
          orthographic: 380,
          stereographic: 380,
          gnomonic: 380,
          equidistant: 380 / Math.PI * 2,
          equalarea: 380 / Math.SQRT2
        };

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


        var svg = d3.select("div#globe").append("svg:svg")
            .attr("width", 800)
            .attr("height", 800)
            .on("dblclick", dblclick)
            .on("mousedown", mousedown);

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

        d3.json("simplified.geojson", function(collection) {

            g.append("g")
              .attr("id", "countries")
            g.append("g")
            .selectAll("path")
              .data(collection.features)
            .enter().append("svg:path")
              .attr("d", clip)
              .attr("id", function(d) { return d.properties.ISO3; })
              .attr("fill", function(d) { return d.properties.FILL; }) //change color and make clickable if data on this country exists
              .on("mouseover", pathOver)
              .on("mouseout", pathOut)
              .on( "dblclick", dblclick)
              .on("mousewheel.zoom", null)
              .on("click", click);

            feature = svg.selectAll("path");

            feature.append("svg:title")
              .text(function(d) { return d.properties.NAME; });


            $('#loader').hide();

        });

        //if a country in the countries tab has been clicked, show info about that country's person
        $('.represented').click(function(){
                var countryabbrev = $(this).attr('id'); 
                if ($(window).width() >= 600){ //rotate globe only if there is a globe to show
                    getCentroid(d3.select("#" + countryabbrev));
                    //projection.origin(projection.invert(#path.centroid(#CAN)));
                    projection.origin(getCentroid(d3.select("#" + countryabbrev)));
                    refresh(1500);
                }
                //showPerson(countryabbrev);
            });

        function getCentroid(selection) {
            // get the DOM element from a D3 selection
            // you could also use "this" inside .each()
            var element = selection.node(),
                // use the native SVG interface to get the bounding box
                bbox = element.getBBox();
                //console.log(projection.invert([bbox.x + bbox.width/2,  bbox.y + bbox.height/2]));
            // return the center of the bounding box
            return projection.invert([bbox.x + bbox.width/2, bbox.y + bbox.height/2]);
        }   

        d3.select(window)
            .on("mousemove", mousemove)
            .on("mouseup", mouseup)
            ;



        var m0,
            o0;

        function mousedown() {
          m0 = [d3.event.pageX, d3.event.pageY];
          o0 = projection.origin();
          d3.event.preventDefault();
        }

        function mousemove() {
          if (m0) {
            var m1 = [d3.event.pageX, d3.event.pageY],
                o1 = [o0[0] + (m0[0] - m1[0]) / 8, o0[1] + (m1[1] - m0[1]) / 8];
            projection.origin(o1);
            circle.origin(o1)
            refresh(1);
          }
        }

        function mouseup() {
          if (m0) {
            mousemove();
            m0 = null;
          }
        }

        function refresh(duration) {
          (duration ? feature.transition().duration(duration) : feature).attr("d", clip);
        }

        function clip(d) {
          return path(circle.clip(d));
        }

        function dblclick(d) {
            zoom = zoom*2;
            projection.origin(projection.invert(d3.mouse(this)));
            projection.scale(zoom);
            refresh(1500);
        }

        function mousewheel(d) {
            zoom = zoom/2;
            projection.origin(projection.invert(d3.mouse(this)));
            projection.scale(zoom);
            refresh(1500);
        }



        function click() {
            thisColor = d3.select(this).style("fill");
            thisCountry = $(this).attr('id');
            //only do popups for countries we have people for
            //|| ()
            if ((thisCountry  == 'GRL') || (thisCountry  == 'ATA') || (thisColor == '#ededed') ) {
                //do nothing
            } else {

                showPerson(thisCountry);
            }//end only for represented countries
        }

        //what to do if a country is selected
        function showPerson(thisCountry) {

            for (var i=0; i<countryAbbrev.length; i++) {
                if (thisCountry == countryAbbrev[i]) {

                    location.hash = countryAbbrev[i];

                    $('#aboutcountry h4').text(countryName[i]);

                    $('#population').text(pop[i] + " million");

                    if (gdp[i].length > 3) {
                        str = gdp[i];
                        /*str1 = str.substring(0, 1);
                        str2 = str.substring(2, str.length);
                        str = str1 + "." + str2;*/
                        num = parseInt(str);
                        num = (num/1000).toFixed(3);
                        $('#gdp').text("$" + num + " trillion");
                    } else {
                        $('#gdp').text("$" + gdp[i] + " billion");
                    }

                    $('#income').text(income[i]);

                    break;
                }
            }

            $('#grayout').fadeIn( function () {
                var screenTop = $(document).scrollTop();
                var personTop = screenTop + 10;
                $('#person_wrapper').css('top', personTop + 'px');


                $('#person_wrapper').fadeIn();
                //center person-wrapper
                w = $('#person_wrapper').width();
                winW = $(window).width();
                mL = (winW - w)/2;
                if ($(window).width() > 600) {
                    $('#person_wrapper').css('margin-left', mL + "px");
                    var wrapHeight = $('#person_wrapper').height();
                    var notesHeight = wrapHeight - $('#nameSpace').height() - $('#vidspace').height() - $('#personInfo').height() - 90; //90 = vertical whitespaces
                    $('#Notes').css('height', notesHeight + 'px');
                    var imageColHeight = .95 * wrapHeight;
                    $('#personImages').css('height', imageColHeight + 'px');
                }




            });
        }

        function pathOver() {
            thisID = $(this).attr('id');
            thisColor = d3.select(this).style("fill");
            if (thisColor == '#ededed') {
                $(this).css('cursor', 'auto');
                $(this).css('opacity', '1');
            }   
            if (thisColor == '#aaaaaa')
            {
                $(this).css('cursor', 'pointer');
                $(this).css('opacity', '.7');
            }   
            if ((thisID  == 'GRL') || (thisID  == 'ATA')){
                $(this).css('cursor', 'auto');
                $(this).css('opacity', '1');
            } 
        }

        function pathOut() {
            $(this).css('opacity', '1');
        }

        $('.searchsurround1').click(function(){
            zoom = zoom*2;
            projection.scale(zoom);
            refresh(1500);
        });

        $('.searchsurround2').click(function(){
            zoom = zoom/2;
            projection.scale(zoom);
            refresh(1500);
        });
        //end globe


    //adjust globe's position so it's centered
    mL = $('svg').css('margin-left');
    mL = mL.substring(0, mL.length-2);
    mL -= 400;
    $('svg').css('margin-left', mL + "px");



    }//end handling globe variables

1 个答案:

答案 0 :(得分:0)

单击某个国家/地区时,click函数会调用showPerson函数,该函数会显示信息模式。在此功能中,窗口会滚动,隐藏在图表的顶部。

    //what to do if a country is selected
    function showPerson(thisCountry) {

        for (var i=0; i<countryAbbrev.length; i++) {
           // ... mode code here ...
        }

        $('#grayout').fadeIn( function () {

            // -- HERE -- 
            var screenTop = $(document).scrollTop();
            var personTop = screenTop + 10;
            $('#person_wrapper').css('top', personTop + 'px');

       })
       // more code ...

该项目看起来很棒,您可能希望使用TopoJSON而不是GeoJSON。 TopoJSON文件比具有相同信息的等效GeoJSON文件小约80%。的问候,

巴勃罗。