One y-axis, never two

Never two y-scales; use two charts, small multiples, or an index.

From dataviz (references/anti-patterns.md).

The right axis is a choice

Drag the Sessions axis bounds; the data never changes.

Dual axisBad
Sessions 1.51× on screencrossings 1
Indexed, Jan = 100Good
Users 3.45× · Sessions 1.51×
const index = (values, t0 = 0) => values.map((v) => (v / values[t0]) * 100);
const y = scaleLinear([0, max([...index(users), ...index(sessions)])], [height, 0]);

Three honest fixes

Switch fixes and hover; the crosshair is shared.

Indexed to 100Good
function setHover(i) {
  for (const chart of charts) chart.drawCrosshair(i);
}

Why it matters, pros and cons

Why it matters

With two scales, someone chose where each line sits. Crossings and slopes come from that choice, not the data.

Pros

  • Every cross, gap and slope is real.
  • An index answers which grew faster.
  • Small multiples scale past two measures.

Cons

  • An index hides absolute size; show raw values in tooltips.
  • A dip in the base period inflates every later value.
  • Two charts cost vertical space.