View source
// CDN build: `ApexMaps` is a global (see index.html). With a bundler:
//   import ApexMaps from 'apexmaps'

// The camera is the lesson here: flyTo/easeTo/jumpTo move the same view, they
// just differ in how. flyTo derives its own duration from the distance and arcs
// out to a wider zoom on a long move; easeTo takes a fixed duration; jumpTo is
// instant. On a globe the same flyTo({ center }) turns the sphere instead of
// panning it. All of them honour prefers-reduced-motion by jumping.

const data = [
  { name: 'France', value: 77 },
  { name: 'Japan', value: 80 },
  { name: 'Argentina', value: 38 },
  { name: 'Germany', value: 69 },
  { name: 'Italy', value: 64 },
  { name: 'Switzerland', value: 88 },
  { name: 'Spain', value: 55 },
  { name: 'Brazil', value: 72 },
  { name: 'Canada', value: 41 },
  { name: 'Australia', value: 59 },
  { name: 'India', value: 66 },
  { name: 'Kenya', value: 33 },
]

const map = new ApexMaps(document.getElementById('map'), {
  chart: { height: 460 },
  geo: { map: 'world/countries@110m', sphere: { show: true } },
  legend: { show: false },
  series: [{ name: 'Index', joinBy: 'name', data, scale: { palette: 'blues' } }],
})

map.render()

// Van Wijk zoom-and-pan path, with a duration derived from the distance moved.
document.getElementById('fly-paris').addEventListener('click', () => {
  map.camera.flyTo({ center: [2.35, 48.86], zoom: 8 })
})
document.getElementById('fly-tokyo').addEventListener('click', () => {
  map.camera.flyTo({ center: [139.69, 35.69], zoom: 8 })
})
// A fixed-duration ease, and an instant jump, for comparison.
document.getElementById('ease').addEventListener('click', () => {
  map.camera.easeTo({ center: [2.35, 48.86], zoom: 6, duration: 400 })
})
document.getElementById('jump').addEventListener('click', () => {
  map.camera.jumpTo({ center: [2.35, 48.86], zoom: 6 })
})
// Frame a single feature, or reset back to the initial fit.
document.getElementById('frame').addEventListener('click', () => {
  map.frameFeature('France', { padding: 40 })
})
document.getElementById('reset').addEventListener('click', () => {
  map.resetView()
})

// The same call on an orthographic projection rotates the globe rather than
// panning it: it opens facing Brazil, so India is behind the planet until you
// fly to it. The rotation interpolates as a quaternion slerp.
const globe = new ApexMaps(document.getElementById('globe'), {
  chart: { height: 460 },
  geo: {
    map: 'world/countries@110m',
    projection: { name: 'orthographic', rotate: [53, 10], clipAngle: 90 },
    view: { fit: 'world' },
    sphere: { show: true },
    graticule: { show: true },
  },
  legend: { show: false },
  series: [{ name: 'Index', joinBy: 'name', data, scale: { palette: 'teal' } }],
})

globe.render()

document.getElementById('globe-india').addEventListener('click', () => {
  globe.camera.flyTo({ center: [79, 22] })
})
globe.on('rotateEnd', () => {
  const [lon, lat] = globe.viewport.subObserver()
  console.log(`facing ${lon.toFixed(1)}, ${lat.toFixed(1)}`)
})
Camera - ApexMaps Demo | ApexCharts.js