English
Step 2: axes and domains
An axis turns the values of your data into positions. Two things take part: its domain, the range of values it shows, and its scale, the function that maps that range to pixels. You write the domain; the axis builds the scale from it and from the size of the chart.
ts
import { D3PAxis, D3PAxisDomain, D3PChart, D3PLineRenderer, D3PSeries, getGlobalBus } from 'd3pict'
import {
D3PAutoDomain, D3PAxis, D3PAxisDomain, D3PChart, D3PLineRenderer, D3PSeries, getGlobalBus,
} from 'd3pict'
const bus = getGlobalBus()
const container = document.getElementById('app')! // any element with a size: the chart fills it
const temperature = new D3PSeries({ bus, name: 'temperature', data: [[0, 12], [4, 9], [8, 14], [12, 21], [16, 24], [20, 17], [24, 13]] })
const x = new D3PAxis({ bus, name: 'hour', domain: new D3PAxisDomain({ bus, domain: [0, 24] }) })
const y = new D3PAxis({ bus, name: 'temperature', domain: new D3PAxisDomain({ bus, domain: [0, 30] }), position: 'left' })
// the domain of an axis is the range of values it shows
const hours = new D3PAxisDomain({ bus, domain: [0, 24] })
const degrees = new D3PAxisDomain({ bus, domain: [0, 30] })
// an auto domain fits the domains to the data of the series it is linked to
const auto = new D3PAutoDomain({ bus })
auto.linkSeries(temperature, [hours, degrees])
const x = new D3PAxis({ bus, name: 'hour', domain: hours, props: { tickCount: 6, tickFormat: (v) => `${Math.round(v)} h`, grid: { enabled: true } } })
const y = new D3PAxis({ bus, name: 'temperature', domain: degrees, position: 'left', props: { tickFormat: (v) => `${Math.round(v * 10) / 10} °C`, grid: { enabled: true } } })
const line = new D3PLineRenderer({ bus, series: temperature })
const objects = [x, y, line]
const chart = new D3PChart({ container, bus })
objects.forEach((o) => o.addToChart(chart))What changed:
- The domains are variables.
hoursanddegreesareD3PAxisDomainobjects, given to the axes. A domain is a plain object that holds a range, nothing else: not a scale, not pixels. - An auto domain fits them to the data.
D3PAutoDomain.linkSeries(series, [xDomain, yDomain])sets the domains to the extent of the series, and keeps them up to date when the data changes. Leave it out to keep the ranges you wrote. - The axes are set with
props.tickCountis the number of ticks wanted,tickFormatwrites a value,griddraws the grid lines,displayNameis the name shown in the cursor labels and the titles.
Domains are shared and writable
The domain of an axis can be read and written: hours.domain = [6, 18] shows only the day, and the axis follows. This is all the zoom and the pan do (they write domains), and it is how charts stay in step: two axes built on the same D3PAxisDomain always show the same range, even on two different charts.
Kinds of scale
scaleType on the axis chooses the scale.
scaleType | For | Domain |
|---|---|---|
linear (default) | numbers | [min, max] |
time, utc | dates | [start, end] as Dates |
log | numbers over several orders of magnitude | [min, max], both above 0 |
symlog | the same, with negative values and zero | [min, max] |
pow, sqrt | areas and other power laws | [min, max] |
band | categories drawn as bands (bars) | the list of categories |
point | categories drawn as points (a line over categories) | the list of categories |
scaleOptions passes options to the scale: the base of a log scale, the exponent of a pow one.