demo D238
Two metrics, two scales in Angular
A total and an average on independent left and right axes, each labelled so neither misleads
measures: [{ col, fn }, { col, fn, axis: 'right' }]
This plots a total and an average on independent left and right axes, each labelled, so two measures on very different scales sit side by side. It lets you compare, say, revenue against average order value without the small number vanishing under the large one.
This is the Angular version. A standalone component takes the whole configuration through one config input, surfaces grid events as outputs, and exposes the live grid on a getter for anything the inputs do not cover.
The configuration
import { Component, ViewChild, ElementRef } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { createGrid } from '@toclocoinc/lattice-grid';
import '@toclocoinc/lattice-grid/css';
import { createChart } from '@toclocoinc/lattice-grid/modules/charts';
import { LatticeGridComponent, provideLattice } from '@toclocoinc/lattice-grid/angular';
@Component({
selector: 'app-root',
standalone: true,
imports: [LatticeGridComponent],
template:
'<div #chart style="height:360px"></div>' +
'<lattice-grid [config]="grid" (grid-ready)="onGridReady()" style="display:block;height:340px;margin-top:14px"></lattice-grid>',
})
export class AppComponent {
@ViewChild('chart') chartEl!: ElementRef<HTMLElement>;
@ViewChild(LatticeGridComponent) gridRef!: LatticeGridComponent;
grid = {
rowKey: 'id',
columns: [
{ field: 'region', title: 'Region', filter: { type: 'set' } },
{ field: 'status', title: 'Status', filter: { type: 'set' } },
{ field: 'bandwidth', title: 'Bandwidth', type: 'number' },
{ field: 'utilisation', title: 'Utilisation', type: 'number', format: { decimals: 1, suffix: '%' } },
{ field: 'charge', title: 'Monthly charge', type: 'number',
format: { style: 'currency', currency: 'GBP' }, total: 'sum' },
],
rows: [/* circuit records */],
};
// The grid is created once the view has rendered, so the live instance
// arrives on grid-ready rather than in ngAfterViewInit.
onGridReady() {
// Two measures on independent scales: the second carries axis: 'right'.
createChart({
grid: this.gridRef.grid,
container: this.chartEl.nativeElement,
type: 'combo',
x: 'region',
measures: [
{ col: 'charge', fn: 'sum', type: 'bar', axis: 'left', label: 'Total charge' },
{ col: 'bandwidth', fn: 'mean', type: 'line', axis: 'right', label: 'Mean bandwidth' },
],
});
}
}
bootstrapApplication(AppComponent, {
providers: [provideLattice({ createGrid })],
});
Reading two metrics on one chart when their scales are nothing alike
Some comparisons only make sense side by side even though the two numbers live on wildly different scales: total revenue against average order value, spend against a rate, volume against a percentage. Plot them on one shared axis and the smaller of the two becomes a flat line along the floor, telling the reader nothing. A dual-axis chart in any JavaScript charting layer gives each metric its own axis, so both keep a scale that suits them. In Lattice Grid a chart is built from the grid’s own filtered rows, and a measure carrying axis: 'right' is bound to an independent right-hand scale while the first measure keeps the left, so a large total drawn as bars and a small average drawn as a line each read clearly on the same picture.
Both axes are labelled by default, because an unlabelled second axis is how a dual-axis chart misleads: a reader cannot tell which mark belongs to which scale. Each axis takes the label from its measure, and the right axis is drawn in its series’ own colour so the eye can follow it. Like every chart here it reads the grid’s filtered rows, so filtering or sorting the grid redraws both series and rescales both axes on the next frame, with nothing to keep in step by hand.
How do you put two Y axes on one chart?
Give the chart a measures array instead of a single y, and mark the second measure with axis: 'right'. That measure is bound to its own scale on the right while the first stays on the left, so two metrics with very different ranges each stay readable. Set a label on each measure and both axes are titled, so the chart says which mark belongs to which scale.
When should a chart use a second axis instead of one?
Use a second axis when the two metrics genuinely differ in scale or unit, such as a running total against an average or a count against a percentage, so that plotting them on one axis would flatten the smaller into a line at zero. When both metrics share a scale, a single axis is clearer and a second axis only adds a scale the reader has to keep straight.