Skip to content

Metric charts ​

<scope-chart> adds controls, a legend, raw data and persistent readings to metric charts. Use a headless factory when your application already supplies those surfaces.

Loading interactive chart…

Compare hourly query and ingestion activity.

Hover to read · Click to select

<scope-chart id="chart">
  <nav slot="toolbar" class="chart-controls" aria-label="Chart controls"></nav>
</scope-chart>

<script type="module">
  import '@scopedb/scopeview/register';
  import chartDocument from './chart.js';

  const chart = document.querySelector('#chart');
  const toolbar = chart.querySelector('[slot="toolbar"]');
  const labels = {
  "zoom-in": "+",
  "zoom-out": "−"
};

  function renderToolbar() {
    const controls = chart.controls;
    for (const button of toolbar.querySelectorAll('[data-action]')) {
      if (!controls.some((control) => control.action === button.dataset.action)) button.remove();
    }
    for (const control of controls) {
      let button = toolbar.querySelector('[data-action="' + control.action + '"]');
      if (!button) {
        button = document.createElement('button');
        button.type = 'button';
        button.dataset.action = control.action;
        button.addEventListener('click', () => chart.performAction(control.action));
        toolbar.append(button);
      }
      button.textContent = labels[control.action] || control.label;
      button.setAttribute('aria-label', control.label);
      button.disabled = control.disabled;
      if (control.expanded !== undefined) button.setAttribute('aria-expanded', String(control.expanded));
      else button.removeAttribute('aria-expanded');
    }
  }

  chart.addEventListener('scope-controls-change', renderToolbar);
  chart.configure({
  axes: "minimal",
  legend: true,
  dismissOnOutside: false
});
  chart.document = chartDocument;
  renderToolbar();
</script>

<style>
  #chart {
    color-scheme: light;
    --scope-chart-height: 232px;
    --color-text-primary: #202b38;
    --color-text-secondary: #657286;
    --color-text-tertiary: #7b8798;
    --color-surface: #ffffff;
    --color-border: #dce3eb;
    --color-border-light: #edf0f4;
  }
.chart-controls[slot="toolbar"] {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
  margin-top: 12px;
  padding: 8px 0;
  border-top: 1px solid var(--color-border-light);
  font-size: var(--scope-chart-tooltip-font-size, 12px);
  line-height: 1.4;
}
.chart-controls[slot="toolbar"] button {
  border: 0;
  border-radius: var(--radius-chart-control, 4px);
  padding: 5px 8px;
  font: inherit;
  color: var(--color-text-secondary);
  background: transparent;
  cursor: pointer;
}
.chart-controls[slot="toolbar"] button:hover:not(:disabled),
.chart-controls[slot="toolbar"] button[aria-expanded="true"] {
  color: var(--color-text-primary);
  background: var(--color-surface-hover);
}
.chart-controls[slot="toolbar"] button:disabled {
  opacity: 0.45;
  cursor: default;
}
.chart-controls[slot="toolbar"] button:focus-visible {
  outline: 2px solid var(--color-text-brand, #0876dd);
  outline-offset: 1px;
}

</style>

Copy the example ​

Follow Run an example for project setup and the development server. Save this example's three files beside each other. index.html mounts the component and toolbar, chart.js configures the chart, and data.json contains its rows.

Replace field definitions and rows together, keeping every row in field order. Update the encoding's field names to match. Values are strings or null; row count is rows.length. The data format lists all encodings and limits.

Configure display ​

Set plot options in the document. Set component UI with configure():

ts
import type { ScopeChartElement } from '@scopedb/scopeview/element';

export function configureChart(chart: ScopeChartElement) {
  const document = chart.document!;
  chart.updateDocument({ ...document, options: { ...document.options, labels: 'auto' } },
    { preserveViewState: true });
  chart.configure({
    legend: true
  });
}

Axis and distribution documents can also show numeric legend summaries. Use this only with line, area, bar, donut, treemap or top-list documents; scatter and aggregate values do not accept summary columns:

ts
import type { ScopeChartElement } from '@scopedb/scopeview/element';

export function configureSummary(chart: ScopeChartElement) {
  chart.configure({ legend: { columns: ['last', 'avg', 'max'] } });
}

Use legend: true for names, or false to hide it. stack controls bars/areas. Set orientation: 'horizontal' on a category bar with one measure and no breakdown to obtain horizontal rows. Source values and original field mappings remain available in the document. The metric options reference lists all accepted values and defaults.

Updates and selection ​

Set document to reset the view. Use updateDocument(input, { preserveViewState: true }) when refreshing the same source. scope-inspect and scope-select carry copied rows, rowIndices, the target key and pin state. Temporal targets may also expose time information.

Use the example's Options controls to try disclosure settings; its copyable source updates with the preview. See component API for custom toolbars and events, and styling for theme, height and fonts.