简体   繁体   中英

How to add line arrow (marker) on D3 geo map?

I have looked around on stack overflow to see I could find an answer for my question but I cannot find the right answer. So for I have this map with lines and nodes on it, this can be found here: http://jsfiddle.net/GarrettUK/ppkf3vqb/ .

The Question

The question I have is how I would go about putting a marker-end on my lines. I know how to do this as seen on this example: http://bl.ocks.org/mbostock/1153292 . However I can't replicate that example as I generate my lines a different way as seen in the example below which is why I'm struggling to create the marker end attribute.

How I generate my lines and style them:

var arcs = [
  //red lines
  {
    origin: {
      latitude: 48.632909,
      longitude: 35.024414
    },
    destination: {
      latitude: 51.727028,
      longitude: -0.395508
    },
  },
  {
    origin: {
      latitude: 37.244200,
      longitude: -115.815167
    },
    destination: {
      latitude: 51.727028,
      longitude: -0.395508
    },
  },
  {
    origin: {
      latitude: 62.955223,
      longitude: 109.555664
    },
    destination: {
      latitude: 51.727028,
      longitude: -0.395508
    },
  },
  {
    origin: {
      latitude: 48.632909,
      longitude: 35.024414
    },
    destination: {
      latitude: 62.955223,
      longitude: 109.555664
    },
  },
  {
    origin: {
      latitude: 37.244200,
      longitude: -115.815167
    },
    destination: {
      latitude: -3.513421,
      longitude: 24.082031
    },
  },
  {
    origin: {
      latitude: -12.554564,
      longitude: -43.769531
    },
    destination: {
      latitude: 62.955223,
      longitude: 109.555664
    },
  },
  {
    origin: {
      latitude: 52.696361,
      longitude: -93.339844
    },
    destination: {
      latitude: 62.955223,
      longitude: 109.555664
    },
  },
  {
    origin: {
      latitude: 7.710992,
      longitude: -5.097656
    },
    destination: {
      latitude: 62.955223,
      longitude: 109.555664
    },
  },
  {
    origin: {
      latitude: 71.187754,
      longitude: -36.035156
    },
    destination: {
      latitude: -25.799891,
      longitude: 142.207031
    },
  },
  {
    origin: {
      latitude: 22.268764,
      longitude: 78.574219
    },
    destination: {
      latitude: -25.799891,
      longitude: 142.207031
    },
  },
  {
    origin: {
      latitude: 65.072130,
      longitude: 14.238281
    },
    destination: {
      latitude: 52.696361,
      longitude: -93.339844
    },
  },
];
map.arc(arcs,  {strokeWidth: 1, arcSharpness: 1.4});

Any questions, feel free to ask!

Apparently, datamaps.js does not provide an option to configure the markers of the paths. You may be better off using plain d3.js and do what datamaps.js does but add the arrows( example ):

Check out the handleArcs function in the source :

  arcs
      .enter()
        .append('svg:path')
        .attr('class', 'datamaps-arc')
        .style('stroke-linecap', 'round')
        .style('stroke', function(datum) {
          return val(datum.strokeColor, options.strokeColor, datum);
        })
        .style('fill', 'none')
        .style('stroke-width', function(datum) {
            return val(datum.strokeWidth, options.strokeWidth, datum);
        })
        .attr('d', function(datum) {
            var originXY = self.latLngToXY(val(datum.origin.latitude, datum), val(datum.origin.longitude, datum))
            var destXY = self.latLngToXY(val(datum.destination.latitude, datum), val(datum.destination.longitude, datum));
            var midXY = [ (originXY[0] + destXY[0]) / 2, (originXY[1] + destXY[1]) / 2];
            if (options.greatArc) {
                  // TODO: Move this to inside `if` clause when setting attr `d`
              var greatArc = d3.geo.greatArc()
                  .source(function(d) { return [val(d.origin.longitude, d), val(d.origin.latitude, d)]; })
                  .target(function(d) { return [val(d.destination.longitude, d), val(d.destination.latitude, d)]; });

              return path(greatArc(datum))
            }
            var sharpness = val(datum.arcSharpness, options.arcSharpness, datum);
            return "M" + originXY[0] + ',' + originXY[1] + "S" + (midXY[0] + (50 * sharpness)) + "," + (midXY[1] - (75 * sharpness)) + "," + destXY[0] + "," + destXY[1];
        })
        .transition()
          .delay(100)
          .style('fill', function(datum) {
            /*
              Thank you Jake Archibald, this is awesome.
              Source: http://jakearchibald.com/2013/animated-line-drawing-svg/
            */
            var length = this.getTotalLength();
            this.style.transition = this.style.WebkitTransition = 'none';
            this.style.strokeDasharray = length + ' ' + length;
            this.style.strokeDashoffset = length;
            this.getBoundingClientRect();
            this.style.transition = this.style.WebkitTransition = 'stroke-dashoffset ' + val(datum.animationSpeed, options.animationSpeed, datum) + 'ms ease-out';
            this.style.strokeDashoffset = '0';
            return 'none';
          })

    arcs.exit()
      .transition()
      .style('opacity', 0)
      .remove();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM