componentDidMount() {
        const width = window.innerWidth * .8,
              height = window.innerHeight * .65,
              id = this.id,
              precinctClass = this.precinctClass,
              features = this.props.precinctJson.features;

        this.svg = d3.select("#" + id).append("svg")
            .attr("overflow", "visible");

        const projection = d3.geo.mercator()
            .center([-73.94, 40.70])
            .scale(50000)
            .translate([width/2, height/2]);

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

        this.svg
            .selectAll("." + precinctClass)
            .data(features)
            .enter().append("path")
            .attr("d", path)
            .classed(precinctClass, true);

        this.componentWillReceiveProps(this.props);
    }
示例#2
0
    function geo(json, id) {
        var height = 90,
            width = 110;

        console.log('reading ' + id);

        var center = d3.geo.centroid(json);

        var scale = height / 2;
        var offset = [width / 2, height / 2];
        var projection = d3.geo.mercator().scale(scale).center(center)
            .translate(offset);

        // create the path
        var svgPath = 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 = svgPath.bounds(json);
        var hscale = scale * width / (bounds[1][0] - bounds[0][0]);
        var vscale = scale * height / (bounds[1][1] - bounds[0][1]);
        scale = (hscale < vscale) ? hscale : vscale;
        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);
        svgPath = svgPath.projection(projection);
        var pathStr = svgPath(json, 0);

        var svg = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n<svg xmlns="http://www.w3.org/2000/svg" id="vis-country-' + id + '" width="' + width + '" height="' + height + '"><path d="' + pathStr + '" style="fill: rgb(59, 122, 181);"></path></svg>';
        fs.writeFileSync(path.join(__dirname, 'out', id + '.svg'), svg);
    }
  d3.json(url, function (error, mapData) {
    const features = mapData.features;
    const center = d3.geo.centroid(mapData);
    let scale = 150;
    let offset = [slice.width() / 2, slice.height() / 2];
    let projection = d3.geo.mercator().scale(scale).center(center)
      .translate(offset);

    path = path.projection(projection);

    const bounds = path.bounds(mapData);
    const hscale = scale * slice.width() / (bounds[1][0] - bounds[0][0]);
    const vscale = scale * slice.height() / (bounds[1][1] - bounds[0][1]);
    scale = (hscale < vscale) ? hscale : vscale;
    const offsetWidth = slice.width() - (bounds[0][0] + bounds[1][0]) / 2;
    const offsetHeigth = slice.height() - (bounds[0][1] + bounds[1][1]) / 2;
    offset = [offsetWidth, offsetHeigth];
    projection = d3.geo.mercator().center(center).scale(scale).translate(offset);
    path = path.projection(projection);

    // Draw each province as a path
    mapLayer.selectAll('path')
      .data(features)
      .enter().append('path')
      .attr('d', path)
      .attr('class', 'region')
      .attr('vector-effect', 'non-scaling-stroke')
      .style('fill', colorFn)
      .on('mouseenter', mouseenter)
      .on('mouseout', mouseout)
      .on('click', clicked);
  });
示例#4
0
var lineTween = _.curry(function lineTween(line, _datum, _index, _attr) {
    // Save start and end point.
    var a = line[0]
    var b = line[1]

    // Create interpolator between start & end of line.
    var i = d3.geo.interpolate(line[0], line[1])
    var i2 = d3.geo.interpolate(line[1], line[0])

    // Save the initial datum.
    var datum = _datum

    // Return new interpolator.
    return function(t) {
        datum.coordinates[1] = i(t) // set new *to* point, part-way to the end.
        return d(datum)
        /* does a tween which draws the line, then removes it
        if (t <= 0.5) {
            // First half, double the tween.
            datum.coordinates[1] = i(t*2)
        }
        else {
            // Second half, reverse the journey to bring the line to nothing.
            datum.coordinates[0] = i2((1-t)*2)
        }

        // Return new partial path.
        return d(datum)
        */
    }
})
示例#5
0
 smd.projection = function() {
   var projFunc = smd.options.projection;
 
   if (typeof projFunc == 'undefined' ||
     typeof d3.geo[projFunc] != 'function') {
     projFunc = 'albersUsa';
   }
   
   smd.centroid = d3.geo.centroid(smd.data);
   smd.projection = d3.geo[projFunc]()
     .scale(1000)
     .translate([smd.width / 2, smd.height / 2]);
   
   // Center if available
   if (typeof smd.projection.center === 'function') {
     smd.projection.center(smd.centroid);
   }
   
   // Rotate if needed
   if (typeof smd.options.rotation != 'undefined' &&
     smd.options.rotation.length > 0 &&
     typeof smd.projection.rotate === 'function') {
     smd.projection.rotate(smd.options.rotation);
   }
 
   smd.projPath = d3.geo.path()
     .projection(smd.projection);
     
   return smd;
 };
示例#6
0
function stateMap($elm, data, width, height, min, max, addLegend, addTooltips) {
  var svg = d3.select($elm[0])
    .append('svg')
      .attr('width', width)
      .attr('height', height);
  var projection = d3.geo.albersUsa()
    .scale(450)
    .translate([220, 150]);
  var path = d3.geo.path().projection(projection);

  var results = _.reduce(
    data.results,
    function(acc, val) {
      var row = fips.fipsByState[val.state] || {};
      var code = row.STATE ? parseInt(row.STATE) : null;
      acc[code] = val.total;
      return acc;
    },
    {}
  );
  var quantiles = 4;
  var totals = _.chain(data.results)
    .pluck('total')
    .filter(function(value) {
      return !!value;
    })
    .value();
  min = min || _.min(totals);
  max = max || _.max(totals);
  var scale = chroma.scale(colorScale).domain([min, max]);
  var quantize = d3.scale.linear().domain([min, max]);
  svg.append('g')
    .selectAll('path')
      .data(stateFeatures)
    .enter().append('path')
      .attr('fill', function(d) {
        return results[d.id] ? scale(results[d.id]) : colorZero;
      })
      .attr('data-state', function(d) {
        return fips.fipsByCode[d.id].STATE_NAME;
      })
      .attr('class', 'shape')
      .attr('d', path)
    .on('mouseover', function(d) {
      if (results[d.id]) {
        this.parentNode.appendChild(this);
        this.classList.add('state--hover');
      }
    });

  if (addLegend || typeof addLegend === 'undefined') {
    var legendSVG = d3.select('.legend-container svg');
    stateLegend(legendSVG, scale, quantize, quantiles);
  }

  if (addTooltips) {
    stateTooltips(svg, path, results);
  }
}
示例#7
0
	onLoaded: function(){
		this.bounds = d3.geo.bounds(this.data);
		this.path = d3.geo.path().projection(this._project);
		if(this.options.before){
			this.options.before.call(this, this.data);
		}
		this._feature = this._g.selectAll("path").data(this.options.topojson?this.data.geometries:this.data.features).enter().append("path").attr("class", this.options.pathClass);
		
		
		this._map.on('viewreset', this._reset, this);
		this._reset();
	},
 initProjection() {
     var elDimensions = this.elDimensions;
     var scale = elDimensions.width * 1.2
     this.svg.attr("width", "100%")
         .attr("height", elDimensions.height)
     this.projection = d3.geo.mercator()
         .scale(scale)
         .translate([elDimensions.width / 2, elDimensions.height/2])
         .center([133, -27])
         .precision(10.0);
     if (!this.path) this.path = d3.geo.path();
     this.path.projection(this.projection)
 }
示例#9
0
    function renderTilesProjected() {
	  if (d3MapTileLayer.length == 0) {
	    return;
	  }
//	  if (!rasterReprojecting) {
	  rasterReprojecting = true;
      for (var x in d3MapTileLayer) {
        if (d3MapTileLayer[x].object().visible) {

    mapDiv.select("#reprojectDiv").selectAll("div").remove();

    var layer = mapDiv.select("#reprojectDiv")
	.style("width", mapWidth + "px")
	.style("height", mapHeight + "px")
  .append("div")
    .style(prefix + "transform-origin", "0 0 0")
    .call(d3.geo.raster(d3MapProjection)
      .url("//{subdomain}.tiles.mapbox.com/v3/"+ d3MapTileLayer[x].object().path +"/{z}/{x}/{y}.png")
      .on("reprojectcomplete", function() {console.log("reprojectComplete");}));
	}
      }
    
//	  }

    }
示例#10
0
    _createProjection(topoJSONData, topContour, center) {

        // The map's scale out is based on the solution:
        // http://stackoverflow.com/questions/14492284/center-a-map-in-d3-given-a-geojson-object

        var width = this.W;
        var height = this.H;
        var guide = this.config.guide;

        var scale = 100;
        var offset = [width / 2, height / 2];

        var mapCenter = center || topoJSONData.center;
        var mapProjection = guide.projection || topoJSONData.projection || 'mercator';

        var d3Projection = this._createD3Projection(mapProjection, mapCenter, scale, offset);

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

        // 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(topojson.feature(topoJSONData, topoJSONData.objects[topContour]));

        var hscale = scale * width  / (bounds[1][0] - bounds[0][0]);
        var vscale = scale * height / (bounds[1][1] - bounds[0][1]);

        scale = (hscale < vscale) ? hscale : vscale;
        offset = [
            width - (bounds[0][0] + bounds[1][0]) / 2,
            height - (bounds[0][1] + bounds[1][1]) / 2
        ];

        // new projection
        return this._createD3Projection(mapProjection, mapCenter, scale, offset);
    }
示例#11
0
  smd.projection = function() {

    var xyratio = (maxX-minX)/(maxY-minY);
        var offsetW = 0.0;
        var offsetH = 0.0;
        if (w/h > xyratio) {
            // canvas is too wide
            offsetW = (w - h*xyratio)/2.0;
        } else if (w/h < xyratio) {
            // canvas is too tall
            offsetH = (h - w/xyratio)/2.0;
        }
         
    var scaleX = d3.scale.linear()
            .domain([minX,maxX])
            .range([0, w-offsetW*2]);
        scaleY = d3.scale.linear()
            .domain([minY, maxY])
            .range([h-offsetH*2,0]);

    function matrix(a, b, c, d, tx, ty) {
            return d3.geo.transform({
                point: function(x, y) { 
                    this.stream.point(scaleX(x)+offsetW, scaleY(y)+offsetH); 
                }});
    }
 
    smd.projPath = d3.geo.path()
      .projection(matrix(-1,0,0,1,0,0));
      
    return smd;
  };
示例#12
0
    function activate() {
        world     = canvas.append('g').attr('id', 'world');
        path      = d3.geo.path().projection(projection);
        iteration = 0;

        paint();
    }
countries.forEach(function(d){
  console.info('Generating ' + d.id + ' -> ' + d.name );
  var bounds = d3.geo.bounds(d),
      dx = bounds[1][0] - bounds[0][0],
      dy = bounds[1][1] - bounds[0][1],
      x = (bounds[0][0] + bounds[1][0]) / 2,
      y = (bounds[0][1] + bounds[1][1]) / 2,
      scale = 20 / Math.max(dx / width, dy / height);

  var projection = d3.geo.equirectangular()
    .center(d3.geo.centroid(d))
    .scale(scale);

  var Image = Canvas.Image
      , canvas = new Canvas(width, height)
      , context = canvas.getContext('2d');

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

        context.strokeStyle = '#f00';
        context.fillStyle = '#aca';

        context.beginPath();
        path.context(context)(land);
        context.fill();

        context.fillStyle = '#f22';

        context.beginPath();
        path.context(context)(d);
        context.fill();

        context.beginPath();
        path.context(context)(d);
        context.stroke();

    var out = fs.createWriteStream('/tmp/' + slug(d.name) + '.png');
    var stream = canvas.pngStream();
    stream.on('data', function(chunk){
      out.write(chunk);
    });

    stream.on('end', function(){
      console.log('saved png');
    });
});
示例#14
0
        d3.timer(function () {


            if (model.transition === false) {
                return;
            }


            // UNCOMMENT TO ROTATE TO CITY

            //var y = Math.abs(model.rotate[0] - model.oldrotate[0]);
            //var x = Math.abs(model.rotate[1] - model.oldrotate[1]);
            //if (x < (velocity * 2) - 0.1 && y < (velocity * 2) - 0.1) {
            //    model.transition = false;
            //    return;
            //}
            //if (x > (velocity * 2)) {
            //
            //    if (model.rotate[1] > model.oldrotate[1]) {
            //        model.oldrotate[1] += velocity;
            //    }
            //    else if (model.rotate[1] < model.oldrotate[1]) {
            //        model.oldrotate[1] -= velocity;
            //    }
            //}
            //if (y > (velocity * 2)) {
            //    if (model.rotate[0] > model.oldrotate[0]) {
            //        model.oldrotate[0] += velocity;
            //    }
            //    else if (model.rotate[0] < model.oldrotate[0]) {
            //        model.oldrotate[0] -= velocity;
            //    }
            //}

            // AUTO ROTATION
            model.oldrotate[0] += velocity;

            projection.rotate(model.oldrotate);
            path = d3.geo.path().projection(projection);
            var path3 = d3.geo.path().projection(projection).pointRadius(1.5);
            var path2 = d3.geo.path().projection(projection).pointRadius(4);
            model.land.selectAll("path").attr("d", path);
            model.points.selectAll("path").attr("d", path3);
            model.countryspot.selectAll("path").attr("d", path2);


        });
示例#15
0
function makeGraticule(lonaxisRange, lataxisRange, step) {
    return d3.geo.graticule()
        .extent([
            [lonaxisRange[0], lataxisRange[0]],
            [lonaxisRange[1], lataxisRange[1]]
        ])
        .step(step);
}
示例#16
0
  render: function() {

    // Dynamically calculate map dimensions
    $('.view-map').height(window.innerHeight);
    var height = window.innerHeight;
    var width  = $('.view-map').width();

    this.svg = d3.select('.view-map').append('svg')
                .attr('height', height - 20)
                .attr('width',  width - 20);

    this.projection = d3.geo.mercator()
                        .scale(width / 6.5)
                        .translate([width / 2, height / 1.8]);

    var path       = d3.geo.path().projection(this.projection);
    var g          = this.svg.append('g');

    // Filter effect for map circles
    var glowFilter = this.svg.append('defs')
                        .append('filter')
                        .attr('id', 'glow');

    glowFilter.append('feGaussianBlur')
              .attr('stdDeviation', 4.5)
              .attr('result', 'coloredBlur');

    var merge = glowFilter.append('feMerge');

    merge.append('feMergeNode')
         .attr('in', 'coloredBlur');
    merge.append('feMergeNode')
         .attr('in', 'SourceGraphic');


    // Retrieve topology from file and create map
    d3.json('data/world-110m2.json', function(error, topology) {
      g.selectAll('path')
        .data(topojson.feature(topology, topology.objects.countries).features)
        .enter()
        .append('path')
        .attr('d', path);
    });
    return this;
  },
示例#17
0
		segments.forEach(function(seg){
			var s1 = nparse(seg.properties.start.properties.stop_ids[0]);
			var s2 = nparse(seg.properties.end.properties.stop_ids[0]);
			if( (stopid === s1  && endid === s2) || (stopid === s2 && endid === s1) ){
				var len = d3.geo.length(seg);
				prod = len*RADIUSOFEARTH_METERS 
			}	

		});
示例#18
0
  renderCountries: function () {
    this.projection = d3.geo.mercator()
      .scale(150 * this.staticScale)
      .translate([Math.round(this.width / 2), Math.round(this.height / 2)])
      .center(this.center)
      .rotate(this.rotate);

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

    this.svg.append("g")
      .selectAll(".country")
      .data(this.countries)
      .enter()
      .insert("path", ".boundary")
      .attr("class", "country")
      .attr("d", this.path);
  },
示例#19
0
//Map part
function renderMap(isMercator) {
  d3.select(svgArea).selectAll('g')
    .remove()
  const projection = (isMercator ? d3.geo.mercator() : d3.geo.equirectangular())
    .scale(svgWidth / 6.28)
    .translate([svgWidth / 2, svgHeight / 2])
  const geoPath = d3.geo.path().projection(projection)
  d3.select(svgArea).append('g')
    .selectAll('path')
    .data(mapPolygonData.features)
    .enter()
    .append('path')
    .attr({
      class: 'countries',
      d: geoPath,
      fill: '#4A90E2'
    })
    .on('mouseout', function() { d3.select(this).attr('fill', '#4A90E2') })
    .on('mouseover', function() { d3.select(this).attr('fill', 'red') })
    //After bind the geo data, we can get the center position fromm geoPath.centroid
    //                                get the bind border points array from geoPath.bounds

  const citySelection = d3.select(svgArea).append('g')
    .selectAll('g')
    .data(cityData)
    .enter()
    .append('g')
    .attr('transform', d => `translate(${projection([d.x, d.y])[0]}, ${projection([d.x, d.y])[1]})`)

  citySelection.append('circle')
    .attr({
      r: 2,
      opacity: 0.5,
    })

  citySelection.append('text')
    .text(d => d.name)
    .attr({
      'font-size': 8,
      opacity: 0.8,
      dx: 2,
      dy: 2,
    })
}
示例#20
0
function _round(area) {
  return d3.geo.transform({
    point: function(x, y, z) {
      this.stream.point(Math.round(x), Math.round(y));
    },
    sphere: function() {
      this.stream.sphere();
    }
  });
}
    function initializeMap(data) {

        var tip = d3.tip()
            .attr('class', 'd3-tip')
            .offset([0,1])
            .html(function(d) {
                return "<div><strong>Zipcode:</strong> <span style='color:white'>" + d.id + "</span></div>" +
                    "<div><strong>Town:</strong> <span style='color:white'>" + d.properties.town + "</span></div>" +
                    "<div><strong>Time Read:</strong> <span style='color:white'>" + d.properties.timeRead + "</span></div>";
            });

        colorScale = d3.scale.linear()
            .range(['#003d4d', '#6ec9e0'])
            .domain(d3.extent(data, function(d){
                return d.minutesRead;
            }));

        mapContainer
            .attr("width", width)
            .attr("height", height);

        projection = d3.geo.albers()
            .center([0, 30.25000])
            .rotate([97.7500, 0])
            .parallels([50, 60])
            .scale(width * 30)
            .translate([width / 2, height / 2]);

        path = d3.geo.path()
            .projection(projection);
        mapContainer.call(tip);

        var mergedData = readingMapFactory.join(data, texas.features, "zipCode", "id", createReadingMapTopoEntry);

        mapContainer.selectAll(".subunit")
            .data(mergedData)
            .enter().append("path")
            .attr("class", function(d) { return "subunit zc" + d.id; })
            .attr("d", path)
            .attr("fill", function(d){ return d.properties.color ? d.properties.color : "white"; })
            .on('mouseover', tip.show)
            .on('mouseout', tip.hide);
    }
示例#22
0
  collection.features.forEach(function(c, ci) {
    var c = { type: 'FeatureCollection', features: [c] };
    var acres = c.features[0].properties.a;
    var id = c.features[0].properties.id;

    // Reproject
    var geojson = d3.geo.project(c, d3.geo.albersUsa());

    // Make into topology.
    var objects = { 'l': geojson };
    var topo = topojson.topology(objects, {
      id: function(d) { return id; },
      'property-transform': transformProperties
    });

    // Scale
    topo = topojson.scale(topo, {
      invert: false,
      width: lakeCanvasWidth,
      height: canvasHeight,
      margin: lakeCanvasWidth * lakeCanvasMargin
    });

    // Simplify based on acreage
    if (acres > acreMax) {
      //console.log(JSON.stringify(topo, null, 2));
      topo = topojson.simplify(topo, {
        //verbose: true,
        'coordinate-system': 'cartesian',
        'retain-proportion': Math.min(1, Math.max(0.2, 1 - (acres / 10000)))
      });
    }

    // Prune
    topo = topojson.prune(topo);

    // Remove bounding box
    delete topo.bbox

    // Push to final collection
    finalLakes[id] = topo;
  });
示例#23
0
function _getProj(projection) {
  /* albersUsa
   * azimuthalEquidistant
   * azimuthalEqualArea
   * conicEqulArea
   * conicConformal
   * conicEquidistant
   * equirectangularm
   * gnomonicm
   * orthographicm
   * stereographic
   * transverseMercator */

  if (d3.geo.hasOwnProperty(projection))
    return d3.geo[projection]();
  else if (projection === null)
    return null;
  else
    new Error(`Please check your projection setting. "${projection}" projection is invalid. `);
}
示例#24
0
MapModel.prototype.getCenterPointOfCountry = function(country) {
  if (!this._countryCentersCache[country]) {
    var feature = this.getFeatureForCountry(country);
    if (feature == null) {
      //console.log('could not find feature for ' + country);
      return [0, 0];
    }
    this._countryCentersCache[country] = d3.geo.centroid(feature);
  }
  return this._countryCentersCache[country];
};
示例#25
0
文件: geo.js 项目: n-riesco/plotly.js
proto.isLonLatOverEdges = function(lonlat) {
    var clipAngle = this.clipAngle;

    if(clipAngle === null) return false;

    var p = this.projection.rotate(),
        angle = d3.geo.distance(lonlat, [-p[0], -p[1]]),
        maxAngle = clipAngle * Math.PI / 180;

    return angle > maxAngle;
};
示例#26
0
    function renderCanvasFeatures(i,context) {

	var _data = d3MapRasterFeatureLayer[i].features();

	var canvasProjection = d3.geo.mercator().scale(d3MapProjection.scale() * d3MapZoom.scale()).translate(d3MapZoom.translate());
	var canvasPath = d3.geo.path().projection(canvasProjection);
    
	for (var x in _data) {
	    context.strokeStyle = _data[x]._d3Map.stroke;
	    context.fillStyle = _data[x]._d3Map.color;
	    context.lineWidth = _data[x]._d3Map.strokeWidth;
	    context.beginPath(), canvasPath.context(context)(_data[x]);
	    if (_data[x]._d3Map.stroke != "none") {
		context.stroke()
	    }
	    if (_data[x]._d3Map.color != "none") {
		context.fill();
	    }
	}
    }
示例#27
0
        .on("drag", function () {
            model.rotate[0] = d3.event.x;
            model.rotate[1] = -d3.event.y;

            // limit y axis to make it easier to navigate
            if (model.rotate[1] > 50) {
                model.rotate[1] = 50;
            }

            if (model.rotate[1] < -50) {
                model.rotate[1] = -50;
            }

            projection.rotate(model.rotate);
            path = d3.geo.path().projection(projection);
            var path2 = d3.geo.path().projection(projection).pointRadius(4);
            var path3 = d3.geo.path().projection(projection).pointRadius(1.5);
            model.land.selectAll("path").attr("d", path);
            model.points.selectAll("path").attr("d", path3);
            model.countryspot.selectAll("path").attr("d", path2);
        })
示例#28
0
    stateClick: function(d){

        var scope = this,
            newState = this.state;

        d3.select('.active_geo').classed('active_geo',false);
        if(d.properties.geoid){
            d3.select('.geo-'+d.properties.geoid).classed('active_geo',true);
        }else{
            d3.select('.geo-'+d.properties.DISTRICT).classed('active_geo',true);
        }
        
        newState.selectedState = d.properties.geoid;
        newState.stations.features = StationStore.getStateStations(d.properties.geoid);

        //stationLayer.externalUpdate(newState.stations);
        this.setState(newState);
        ClientActionsCreator.setSelectedState(newState.selectedState);
        map.fitBounds([d3.geo.bounds(d)[0].reverse(),d3.geo.bounds(d)[1].reverse()]);

    },
示例#29
0
文件: geo.js 项目: bwellington/dredge
let setGeo = config => {

	let {boundshape, mapContainer} = config;


	let w = mapContainer.node().getBoundingClientRect().width;
	let h = mapContainer.node().getBoundingClientRect().height;

	

	let projection = d3.geo.mercator().scale(1).translate([0,0]);
	let path = d3.geo.path().projection(projection);
    let b = path.bounds(boundshape);

    let s = ".9" / Math.max((b[1][0] - b[0][0]) / w, (b[1][1] - b[0][1]) / h);
    let t = [(w - s * (b[1][0] + b[0][0])) / 2, (h - s * (b[1][1] + b[0][1])) / 2];


    projection = projection.scale(s).translate(t);
	return {projection, path, s, t};
};
示例#30
0
 draw(svg, projection) {
     this.node = d3.select('#' + this.id);
     if(this.node.empty()) {
         this.node = svg.append('path').attr('id', this.id);
     }
     if(!this.data) {
         this._loadSource(() => { this.draw(svg, projection) });
         return;
     }
     this.node.datum(topojson.mesh(this.data, this.data.objects[this.objectName]))
         .attr('d', d3.geo.path().projection(projection))
         .attr(this.attrs);
 }