Shareable Views (Perspectives) in JavaScript

Using ApexCharts with JavaScript

This Shareable Views (Perspectives) example uses ApexCharts.js directly in JavaScript, with no wrapper component.

Install it with npm install apexcharts, then mount the chart with new ApexCharts(element, options).render().

JavaScript installation guide
// Perspectives (#10): capture the full VIEW state (zoom window, hidden series,
// selection, theme, annotations) as a token, apply it back, or encode it into
// a shareable URL. Passive: no config flag needed.
function bigSeries(seed, amp) {
  var d = []
  var v = seed
  for (var i = 0; i < 40; i++) {
    v += (Math.random() - 0.5) * amp
    d.push({ x: i + 1, y: Math.round(v) })
  }
  return d
}

var options = {
  series: [
    { name: 'North', data: bigSeries(50, 14) },
    { name: 'South', data: bigSeries(70, 10) },
  ],
  chart: {
    height: 380,
    type: 'line',
    id: 'perspectives-demo',
    animations: { enabled: true },
    toolbar: {
      show: true,
      tools: { zoom: true, pan: true, reset: true, download: false },
    },
    zoom: { enabled: true, type: 'x' },
    ink: { enabled: true },
    contextMenu: { enabled: true },
  },
  colors: ['#1971c2', '#e0447e'],
  stroke: { curve: 'smooth', width: 2 },
  dataLabels: { enabled: false },
  title: { text: 'Capture, apply, and share the exact view', align: 'left' },
  xaxis: { type: 'numeric', title: { text: 'Step' } },
  legend: { position: 'top' },
}

var chart = new ApexCharts(document.querySelector('#chart'), options)
chart.render()

var viewsSel = document.getElementById('views')
var linkEl = document.getElementById('link')
var saveCount = 0

function refreshList() {
  var list = chart.perspectives.list()
  viewsSel.innerHTML =
    '<option value="">' +
    (list.length ? 'Pick a saved view...' : '(none yet)') +
    '</option>'
  list.forEach(function (p) {
    var o = document.createElement('option')
    o.value = p.id
    o.textContent = p.name
    viewsSel.appendChild(o)
  })
}

document.getElementById('save').addEventListener('click', function () {
  saveCount++
  chart.perspectives.save('View ' + saveCount)
  refreshList()
})

viewsSel.addEventListener('change', function () {
  var id = viewsSel.value
  if (!id) return
  var entry = chart.perspectives.list().filter(function (p) {
    return p.id === id
  })[0]
  if (entry) chart.perspectives.apply(entry.token, { animate: true })
})

document.getElementById('copy').addEventListener('click', function () {
  var url = chart.perspectives.toURL()
  linkEl.textContent = url
  if (navigator.clipboard)
    navigator.clipboard.writeText(url).catch(function () {})
})

document.getElementById('resetZoom').addEventListener('click', function () {
  chart.resetSeries(true, true)
})

// Restore a shared view if the page was opened with a #apex= fragment.
try {
  var shared = ApexCharts.perspectives && ApexCharts.perspectives.fromURL()
  if (shared) chart.perspectives.apply(shared, { animate: false })
} catch (e) {}