Map – Interactions

What the map does once it is on the page: countries that answer to a click, a board that pans and zooms, a projection that can be exchanged while the map is running, and a centre that can be moved anywhere.

Example 1

Selecting countries

With selectMode: 'multiple' every country stays selected until it is clicked again, so several can be held at once. The look of a selected country comes from highlightStyle; the countries themselves have to be visible for there to be anything to hit.

JavaScript snippet

var map = board.create('geomap', [[0.2, 0.2], [11.6, 5.7]], {
  data: DATA,
  tabindex: null,
  ocean: {
    fillColor: '#aaccee',
    strokeColor: '#002244'
  },
  land: {
    visible: false
  },
  coast: {
    visible: true,
    strokeColor: '#002299',
    strokeWidth: 1.2
  },
  countries: {
    visible: true,
    strokeColor: '#336600',
    strokeWidth: .8,
    fillColor: '#99bbaa'
  },
  showSmallCountries: true,
  smallCountryRadius: .1,
  picking: true,
  selectMode: 'multiple',
  highlightStyle: {
    fillColor: '#ffee33',
    fillOpacity: 0.6,
    strokeColor: '#eeaa00',
    strokeWidth: 1
  }
});
Example 2

Selecting one country

With selectMode: 'single' a click clears whatever was selected before, so exactly one country is marked at a time. The same highlightStyle applies; only the bookkeeping differs.

JavaScript snippet

var map = board.create('geomap', [[0.2, 0.2], [11.6, 5.7]], {
  data: DATA,
  tabindex: null,
  countries: {
    visible: true,
    strokeColor: '#002244',
    strokeWidth: .4,
    fillColor: '#cceeff'
  },
  selectMode: 'single',
  highlightStyle: {
    fillColor: '#c0392b',
    fillOpacity: 0.6,
    strokeColor: '#7b241c',
    strokeWidth: 2
  }
});
Example 3

Picking turned off

A map that is only meant to be looked at should not react to the pointer at all. picking: false takes the countries out of the hit test, and selectMode: 'none' — the default — keeps them from being marked. Colour then comes from a layer of rings rather than from a click.

JavaScript snippet

var map = board.create('geomap', [[0.2, 0.2], [11.6, 5.7]], {
  data: DATA,
  tabindex: null,
  countries: {
    visible: true,
    strokeColor: '#a89a7d',
    strokeWidth: .55,
    fillColor: 'none'
  },
  picking: false,
  selectMode: 'none'
});

function countryColor(id, stil) {
  var c = DATA.countries.filter(function (x) {
    return x.id === id;
  })[0];
  return map.addGeoLayer('rings',
    function () {
      return JXG.Geography.countryRings(c, 1.15, true);
    }, stil);
}

var de = countryColor('DEU', { fillColor: '#cc4422', fillOpacity: 0.7, layer: 6 });
var fr = countryColor('FRA', { fillColor: '#33aa66', fillOpacity: 0.7, layer: 6 });
var us = countryColor('USA', { fillColor: '#99aa22', fillOpacity: 0.7, layer: 6 });
Example 4

Pan and zoom

Panning and zooming belong to the board, not to the map. Every other example on these pages switches them off; here they are left on, so the map can be dragged with the pointer and scaled with the wheel. The navigation buttons in the corner do the same thing without a wheel.

JavaScript snippet

var board = JXG.board(BOX, {
  boundingbox: [0, 6.1, 12, 0],
  keepaspectratio: true,
  axis: false,
  grid: false,
  showCopyright: true,
  showNavigation: true,
  showInfobox: false,
  pan: { enabled: true, needTwoFingers: false },
  zoom: { enabled: true, wheel: true, needShift: false, factorX: 1.25, factorY: 1.25 }
});

var map = board.create('geomap', [[0.2, 0.2], [11.6, 5.7]], {
  data: DATA,
  tabindex: null,
  graticule: {
    visible: true,
    step: [30, 30]
  },
  countries: {
    visible: true
  },
  capitals: {
    visible: true
  }
});
Example 5

Change projections

The projection can be exchanged while the map is running. setProjection(name, true) asks for the morph; with false the new projection appears at once. Every layer follows along — graticule, coastlines, borders, capitals, the feature lines and the coloured country rings.

JavaScript snippet

var map = board.create('geomap', [[0.2, 0.2], [11.6, 5.7]], {
  data: DATA,
  tabindex: null
});

map.setProjection('mercator', true);
Example 6

Moving the center

An oblique-capable projection can be centred on any point of the globe. setOblique(true) tilts the axis and setCenter(lon, lat) moves it; a projection that only takes a central meridian warns and stays upright.

JavaScript snippet

var map = board.create('geomap', [[0.2, 0.2], [11.6, 5.7]], {
  data: DATA,
  tabindex: null
});

map.setOblique(true);

map.setCenter(20, 30);

Example 7

Click to position

A point on a JSXGraph board can be turned back into a longitude and a latitude. Where the projection has a closed-form inverse — the azimuthal ones, Mercator and plate carrée among them — the answer is exact; for the others it is found numerically, to within a tiny tolerance. Click anywhere: on the board the position is reported, off it toGeo answers null.

JavaScript snippet

var map = board.create('geomap', [[0.2, 0.2], [11.6, 5.7]], {
  data: DATA,
  tabindex: null,
  graticule: { visible: true, step: [30, 30] },
  countries: { visible: true }
});

map.toGeo(10, 20);
Example 8

Azimuthal projections, and a circular cut

Four projections built around a point rather than a line. Everything is an angular distance from the centre and an azimuth, so the map edge is a circle rather than the antimeridian.

JavaScript snippet

var map = board.create('geomap', [[0.2, 0.2], [11.6, 5.7]], {
  data: DATA,
  tabindex: null,
  projection: 'azimuthalequalarea',
  graticule: { visible: true }
});

map.setCenter(10, 10);
Example 9

Moving the centre, and turning the axis

A map centred away from the equator needs an oblique-capable projection: the rotation is applied before projecting, so the projection has to be able to take a tilted axis. The centre can be moved with the sliders or by dragging on the map — both go through one function, so they cannot drift apart.

JavaScript snippet

var map = board.create('geomap', [[0.2, 0.2], [11.6, 5.7]], {
  data: DATA,
  tabindex: null
});

map.setCenter(10, 10);
Example 10

Showing a part of the world

A viewport decides what is fitted into the rectangle, not what is computed. The same points are clipped either way, so zooming costs nothing and a click still lands where it should.

JavaScript snippet

var map = board.create('geomap', [[0.2, 0.2], [11.6, 5.7]], {
  data: DATA,
  tabindex: null
});

map.zoomTo([10, 10], 2);
Example 11

Distortion, made visible

Small circles of equal angular radius on a lattice — a finite stand-in for Tissot's infinitely small indicatrix. Whatever the projection does to them, it does to everything there.

JavaScript snippet

var map = board.create('geomap', [[0.2, 0.2], [11.6, 5.7]], {
  data: DATA,
  tabindex: null
});

map.showDistortion('tissot');
Example 12

Day and night on the map (experimental)

The night cap, projected rather than masked. On an equal-area map the dark half really is half the map; on Mercator it is not, ... The terminator is the geometric one: refraction and the size of the sun's disc make the real day a few minutes longer, so the lit part is in fact slightly more than half.

JavaScript snippet

var map = board.create('geomap', [[0.2, 0.2], [11.6, 5.7]], {
  data: DATA,
  tabindex: null
});

var night = map.geoNight({
  blur: 1,
  blurWidth: 14,
  blurSteps: 6,
  fillColor: '#050b12',
  fillOpacity: 0.55
});