Lattice Grid Buy a licence

demo D163

Line, area, bar and scatter in Angular

The cartesian types, one dataset

type: 'line' · 'step' · 'area' · 'bar' · 'combo' · 'pareto'

This shows the cartesian chart types, line, step, area, bar, combo and pareto, drawn from one dataset. It lets you compare how each shape reads the same numbers, so you can pick the one that tells your story clearest. The line chart also emphasises one series over the rest, by weight rather than only by colour.

Building…
Loading a live grid…

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 } 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';

const 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' },
];

const rows = [/* circuit records */];



@Component({
  selector: 'app-root',
  standalone: true,
  imports: [LatticeGridComponent],
  template:
    '<div style="display:grid;grid-template-columns:repeat(3, 1fr);gap:14px;height:210px">' +
    '<div id="line"></div>' +
    '<div id="step"></div>' +
    '<div id="area"></div>' +
    '<div id="rangeArea"></div>' +
    '<div id="bar"></div>' +
    '<div id="horizontalBar"></div>' +
    '<div id="scatter"></div>' +
    '<div id="bubble"></div>' +
    '<div id="combo"></div>' +
    '<div id="pareto"></div>' +
    '</div>' +
    '<lattice-grid [config]="grid" (grid-ready)="onGridReady()" style="display:block;height:340px;margin-top:14px"></lattice-grid>',
})
export class AppComponent {
  @ViewChild(LatticeGridComponent) gridRef!: LatticeGridComponent;

  grid = {
    rowKey: 'id',
    // A bar/horizontalBar with no series of its own takes its colour from
    // these budget rules, one legend entry per rule.
    formatting: {
      charge: [
        { id: 'under', label: 'Under budget', when: { op: 'lt', value: 200_000 }, style: { background: '#1a7f37', color: '#fff' } },
        { id: 'near', label: 'Near budget', when: { op: 'lt', value: 225_000 }, style: { background: '#b26a00', color: '#fff' } },
        { id: 'over', label: 'Over budget', when: { op: 'gte', value: 225_000 }, style: { background: '#c02c38', color: '#fff' } },
      ],
    },
    columns: columns,
    rows: rows,
  };

  // The grid is created once the view has rendered, so the live instance
  // arrives on grid-ready rather than in ngAfterViewInit.
  onGridReady() {
    const grid = this.gridRef.grid;
    createChart({ grid, container: '#line',          type: 'line',          x: 'region', y: 'charge' });
    createChart({ grid, container: '#step',          type: 'step',          x: 'region', y: 'charge' });
    createChart({ grid, container: '#area',          type: 'area',          x: 'region', y: 'charge' });
    // rangeArea draws the min-to-max band of y at each x.
    createChart({ grid, container: '#rangeArea',     type: 'rangeArea',     x: 'region', y: 'charge' });
    createChart({ grid, container: '#bar',           type: 'bar',           x: 'region', y: 'charge' });
    createChart({ grid, container: '#horizontalBar', type: 'horizontalBar', x: 'region', y: 'charge', labels: true });
    createChart({ grid, container: '#scatter',       type: 'scatter',       x: 'utilisation', y: 'charge' });
    createChart({ grid, container: '#bubble',        type: 'bubble',        x: 'utilisation', y: 'charge', size: 'charge' });
    // combo mixes marks and two axes, here bars of charge and a line of bandwidth.
    createChart({ grid, container: '#combo',         type: 'combo',         x: 'region',
      measures: [{ col: 'charge', fn: 'sum', type: 'bar', axis: 'left' },
                 { col: 'bandwidth', fn: 'mean', type: 'line', axis: 'right' }] });
    // pareto sorts the bars and draws the cumulative line.
    createChart({ grid, container: '#pareto',        type: 'pareto',        x: 'status', y: 'charge' });
  }
}

bootstrapApplication(AppComponent, {
  providers: [provideLattice({ createGrid })],
});