D3旋转地球仪和文本

时间:2014-04-24 20:11:15

标签: map d3.js rotation

需要一些帮助...我能够找到旋转地球仪的一个例子,它很有效,我甚至找到了一种方法可以将红色圆圈放在一个点上。更好的是设置一个计时器,一切都与地球一起旋转。但是,如果我把地图上的文字放在与红色圆圈相同的点上,它会显示在我放置它的起始点,但随着世界的转动,红色圆圈随着地球一起移动,但是文本会冻结在它是写的。我试图让文本与世界和红色圆圈一起旋转。我认为在美国这个国家,我想提出一个数字,当全球轮换到中国时,巴西会有数字,价值仍然会出现在我所说的国家上,当美国和巴西轮流回到前线时,数字就在那里展示。这就是我在代码中所拥有的东西,在使用D3时,我仍然是一个菜鸟。谢谢你的任何意见......

// Initialize some variables:
var element = '#home1',
width = $("#home1").width(),
height = $("#home1").height();

var diameter = 460,
radius = diameter/2,
velocity = .001,
then = Date.now();

var features, circles;

var projection = d3.geo.orthographic()
.scale(radius - 2)
.translate([radius, radius])
.clipAngle(90);


// Save the path generator for the current projection:
var path = d3.geo.path()
.projection(projection)
.pointRadius( function(d,i) {
             return radius;
             });

// Define the longitude and latitude scales, which allow us to map lon/lat coordinates to pixel values:
var lambda = d3.scale.linear()
.domain([0, width])
.range([-180, 180]);

var phi = d3.scale.linear()
.domain([0, height])
.range([90, -90]);

// Create the drawing canvas:
var svg = d3.select("#home1").append("svg:svg")
.attr("width", diameter)
.attr("height", diameter);

//Create a base circle: (could use this to color oceans)
var backgroundCircle = svg.append("svg:circle")
.attr('cx', diameter / 2)
.attr('cy', diameter / 2)
.attr('r', 0)
.attr('class', 'geo-globe');

// Make a  tag to group all our countries, which is useful for zoom purposes. (child elements belong to a 'group', which we can zoom all-at-once)
var world = svg.append('svg:g');
var zoomScale = 1; // default

// Create the element group to mark individual locations:
var locations = svg.append('svg:g').attr('id', 'locations');

// Having defined the projection, update the backgroundCircle radius:
backgroundCircle.attr('r', projection.scale() );

// Construct our world map based on the projection:
d3.json('world-countries.json', function(collection) {

        features = world.selectAll('path')
        .data(collection.features)
        .enter()
        .append('svg:path')
        .attr('class', 'geo-path')
        .attr('d', path);

       // features.append('svg:title')
      //  .text( function(d) { return d.properties.name; });

    }); // end FUNCTION d3.json()


d3.json("data.geojson", function(collection) {
        console.log("2");



       cs = locations.selectAll('path')
        .data(collection.features)
        .enter().append('svg:path')
        .datum(function(d) {return {type: "Point", coordinates: [d.geometry.coordinates[0], d.geometry.coordinates[1]]}; })
        .attr('class', 'geo-node')
        .attr("d", path.pointRadius(5))
        .attr('d', path);



        cs1 = locations.selectAll('text')
        .data(collection.features)
        .enter().append('svg:text')
        .attr("transform", function(d) {return "translate(" + projection(d.geometry.coordinates) + ")"; })
        .attr("dy", ".35em")
        .attr('d', path)
        .text(function(d) { return d.properties.name; });

        }); // end FUNCTION d3.json()



d3.timer(function() {
         if(offpage === 0)
         {
            var angle = velocity * (Date.now() - then);

            projection.rotate([angle,0,0])

            svg.selectAll("path").attr("d", path.projection(projection));


         }
    });


d3.select(window)
.on("touchmove", mousemove)
.on("touchstart", mousedown);


function mousemove() {

    offpage = 0;
    }


function mousedown() {

    offpage=1
}

1 个答案:

答案 0 :(得分:3)

在您的代码中,功能(世界地图)是路径,而cs(城市点)是路径,但cs1(城市名称)是文本。在您的计时器中,您可以旋转路径,而不会旋转文本。

我的解决方案使用旋转度而不是角度,因此您必须调整公式。

d3.timer(function() {  
            tcounter++
            rotation++
            if (rotation>=360) rotation = 0
            projection.rotate([rotation,0,0]) 
            www.attr("d", path.projection(projection));
            citydot.attr("d", path.projection(projection)); 
            ctext.attr("transform", function(d) {
                    return "translate(" + projection(d.geometry.coordinates) + ")"; }) 
                .text(function(d) {
                if (((rotation + d.geometry.coordinates[0]  > -90) && (rotation + d.geometry.coordinates[0]  <90)) ||
                    ((rotation + d.geometry.coordinates[0]  > 270) && (rotation + d.geometry.coordinates[0]  <450))) 
                  return d.properties.city; 
                    else return "" });

            if (tcounter > 360) return true
                else return false
        })