Skip to content

Commit

Permalink
feat: allow ticks to be configurable with total count, interval, and …
Browse files Browse the repository at this point in the history
…starting placement (#330)

* feat: allow ticks to be configurable with total count, interval, and starting placement

* chore: update README

* refactor: use existing span for text metrics, update README, rename test to it
  • Loading branch information
TCL735 authored Oct 22, 2020
1 parent c1c1fb9 commit 95ff730
Show file tree
Hide file tree
Showing 10 changed files with 655 additions and 57 deletions.
16 changes: 14 additions & 2 deletions giraffe/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,9 +258,21 @@ When using the comma separated values (CSV) from the Flux query as the `fluxResp

- **axisOpacity**: _number. Optional. Recommendation: do not include. Defaults to 1 when excluded._ A value between 0 and 1 inclusive for the [_CanvasRenderingContext2D globalAlpha_](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalAlpha) of the axes and the border around the graph. Excludes the inner horizontal and vertical rule lines.

- **xTicks**: _array[number, ...]. Optional._ An array of values representing tick marks on the x-axis. Actual data values and axis scaling may cause Plot to not render all of the given ticks, or Plot rendering may extend beyond all of the rendered ticks. When excluded, Giraffe attempts to use as many ticks as possible on the x-axis while keeping reasonable spacing between them.
- **xTicks**: _array[number, ...]. Optional._ An array of values representing tick marks on the x-axis. Actual data values and axis scaling may cause Plot to not render all of the given ticks, or Plot rendering may extend beyond all of the rendered ticks. When this option is included, **xTotalTicks**, **xTickStep**, **xTickStart** are ignored.

- **yTicks**: _array[number, ...]. Optional._ An array of values representing tick marks on the y-axis. Actual data values and axis scaling may cause Plot to not render all of the given ticks, or Plot rendering may extend beyond all of the rendered ticks. When excluded, Giraffe attempts to use as many ticks as possible on the y-axis while keeping reasonable spacing between them.
- **xTotalTicks**: _number. Optional. **Ignored when xTicks is specified**._ A number representing the maximum possible number of ticks to generate on the x-axis. Uses the **xTickStep** as the tick interval if also included. Otherwise the tick interval is taken from dividing the length of the rendered domain by this number. The actual number of rendered ticks may be less than this number due to the size of the tick interval.

- **xTickStep**: _number. Optional. **Ignored when xTicks is specified**._ A number representing the tick interval for the x-axis. May be negative.

- **xTickStart**: _number. Optional. **Ignored when xTicks is specified**._ A number representing a value less than or equal to the first tick on the x-axis. This number will determine the placement of all subsequent ticks. It and any subsequent ticks will be rendered only if they fall within the domain. This number _is_ the value of the first tick when it is in the domain, and at least one of **xTickStep** or **xTotalTicks** is included.

- **yTicks**: _array[number, ...]. Optional._ An array of values representing tick marks on the y-axis. Actual data values and axis scaling may cause Plot to not render all of the given ticks, or Plot rendering may extend beyond all of the rendered ticks. When this option is included, **yTotalTicks**, **yTickStep**, **yTickStart** are ignored.

- **yTotalTicks**: _number. Optional. **Ignored when yTicks is specified**._ A number representing the maximum possible number of ticks to generate on the y-axis. Uses the **yTickStep** as the tick interval if also included. Otherwise the tick interval is taken from dividing the length of the rendered domain by this number. The actual number of rendered ticks may be less than this number due to the size of the tick interval.

- **yTickStep**: _number. Optional. **Ignored when yTicks is specified**._ A number representing the tick interval for the y-axis. May be negative.

- **yTickStart**: _number. Optional. **Ignored when yTicks is specified**._ A number representing a value less than or equal to the first tick on the y-axis. This number will determine the placement of all subsequent ticks. It and any subsequent ticks will be rendered only if they fall within the domain. This number _is_ the value of the first tick when it is in the domain, and at least one of **yTickStep** or **yTotalTicks** is included.

- **tickFont**: _string. Optional._ The [_CSS font_](https://developer.mozilla.org/en-US/docs/Web/CSS/font) value for the styling of the tick labels and axis labels.

Expand Down
15 changes: 13 additions & 2 deletions giraffe/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,26 @@ export interface Config {
axisColor?: string
axisOpacity?: number

// Ticks on the axes can be specified, or else they are calculated,
// as well as the font, color, and the unit labels for each tick
// Tick placement on the axes can be specified otherwise they are calculated,
// - specified for an entire axis, or
// - specified by a step interval per tick and/or a total number of ticks
xTicks?: number[]
xTickStart?: number
xTickStep?: number
xTotalTicks?: number
yTicks?: Array<number | string>
yTickStart?: number
yTickStep?: number
yTotalTicks?: number

// Ticks can have font, color, and be formatted for precision and labeling
tickFont?: string
tickFontColor?: string
valueFormatters?: {
[colKey: string]: Formatter
}

// The labels on the axes
xAxisLabel?: string
yAxisLabel?: string

Expand Down
24 changes: 21 additions & 3 deletions giraffe/src/utils/PlotEnv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,23 @@ export class PlotEnv {
} = this
const getMarginsMemoized = this.fns.get('margins', getMargins)

const sampleYTicks = yTicks.length
? yTicks
: getVerticalTicks(
this.yDomain,
this.config.height,
this.config.tickFont,
this.yTickFormatter,
null,
null,
null
)

return getMarginsMemoized(
this.config.showAxes,
xAxisLabel,
yAxisLabel,
yTicks,
sampleYTicks,
this.yTickFormatter,
tickFont
)
Expand Down Expand Up @@ -100,7 +112,10 @@ export class PlotEnv {
this.xDomain,
this.config.width,
this.config.tickFont,
this.xTickFormatter
this.xTickFormatter,
this.config.xTotalTicks,
this.config.xTickStart,
this.config.xTickStep
)
}

Expand All @@ -122,7 +137,10 @@ export class PlotEnv {
this.yDomain,
this.config.height,
this.config.tickFont,
this.yTickFormatter
this.yTickFormatter,
this.config.yTotalTicks,
this.config.yTickStart,
this.config.yTickStep
)
}

Expand Down
7 changes: 6 additions & 1 deletion giraffe/src/utils/getTextMetrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ export const getTextMetrics = (font: string, text: string): TextMetrics => {

document.body.appendChild(div)

span.innerText = text
// Text with the same number of characters:
// when it includes a dash (negative number), it tends to be skinnier than
// a positive number because a dash is not as wide as a single digit (most of the time).
// Add padding when text has a dash by making dashes twice as wide.
span.innerText =
typeof text === 'string' && text.includes('-') ? `-${text}` : text

const metrics = {
width: span.offsetWidth,
Expand Down
Loading

0 comments on commit 95ff730

Please sign in to comment.