TheGarrett
TheGarrett

Reputation: 311

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!

Upvotes: 0

Views: 1543

Answers (1)

kmandov
kmandov

Reputation: 3209

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();

Upvotes: 2

Related Questions