@flourish/chart-layout

Create axes and plotting regions for data

Usage no npm install needed!

<script type="module">
  import flourishChartLayout from 'https://cdn.skypack.dev/@flourish/chart-layout';
</script>

README

Flourish chart layout

Create axes and plotting regions for data

How to install

npm install -s @flourish/chart-layout

Add objects to your template state representing the x and/or y and/or y2 axes, and optionally also the background area. For example:

export var state = {
    x: {},
    y: {},
    y2: {},
    chart_bg: {},
    ...
}

Import the corresponding settings into your template.yml, e.g.:

- X axis
- property: x
  import: "@flourish/chart-layout/x"
- Y axis
- property: y
  import: "@flourish/chart-layout/y"
- Y2 axis
- property: y2
  import: "@flourish/chart-layout/y"
- Chart background
- property: chart_bg
  import: "@flourish/chart-layout/background"

How to use

Initialise a chart-layout object for every chart you want to create. You need a container SVG element (a node, a d3-selection or a CSS selector string) which you will add the chart to and an object containing the relevant state properties. For example

import createChartLayout from "@flourish/chart-layout";
var container = select(layout.getSection("primary")).select("svg"); // see @flourish/layout
var props = { x: state.x, y: state.y, y2: state.y2, background: state.chart_bg };
var chart_layout = createChartLayout(container, props);

This adds a number of SVG elements to the container and returns an object, chart_layout.

Properties of chart_layout

chart_layout.chart

A d3-selection of the route SVG element created by chart_element.

chart_layout.container

A d3-selection of the container specified at the time of creation.

chart_layout.data_background

A d3-selection of an area created within the chart_element that is suitable for adding data to. Data elements placed within this container will appear below any visible gridlines.

chart_layout.data_foreground

A d3-selection of an area created within the chart_element that is suitable for adding data to. Data elements placed within this container will appear above any visible gridlines.

The update method of chart_layout

chart_layout.update([options])

Call this method to recalculate and redraw (with animation) the chart layout components based on the current set of stored values and state properties. Returns the chart_layout instance.

Properties of optional options object can be used to modify the update method's functionality. If skip_rendering is true then distances, margins and ticks will be recalculated and any changes to the chart offset will be applied, but the chart components will not be re-rendered. If a margins object is supplied and any of its top, right, bottom or left properties are not undefined then the corresponding margin will be fixed to that value, rather than calculated.

The Data methods of chart_layout

These three methods expect values to be either an array or an instance of a Flourish enhanced array (see @flourish/enhanced-array). In the case of the former, an optional accessor method can be included in order to, for example, extract a specific property from each object in an array of objects. The stored data is used to determine both the type of axis (numeric or ordinal) and its domain. If values is an enhanced array then a numeric axis will be constructed for the relevant dimension if it is a numeric enhanced array and an ordinal scale will be constructed if it is a string enhanced array. If values is a regular array then the type of the first element (after application of the accessor function) will be used to determine whether the scale should be numeric or ordinal.

If values is undefined, an enhanced array will be returned that is either the original one passed in or one derived from the regular array passed in. When values is defined, the chart_layout instance is returned so that methods can be chained.

chart_layout.xData([values, [accessor]])

Gets or sets the data associated with the horizontal axis.

chart_layout.yData([values, [accessor]])

Gets or sets the data associated with the primary (left) vertical axis.

chart_layout.y2Data([values, [accessor]])

Gets or sets the data associated with the secondary (right) vertical axis.

The Scale methods of chart_layout

These three methods get d3-scales suitable for plotting data. Because this module uses SVG transforms then, in general by default, the scale will be useful for plotting data only within the chart_layout.chart container, and particularly the chart_layout.data_background or chart_layout.data_foreground containers. However, if the options object is present and has a global property that is truthy, the scale is suitable for use outside the chart_layout.chart object (and, generally, not inside it), anywhere that has the same calculated transform as chart_layout.container. The domain_only property of options specifies that a suitable range for the scale should not be calculated. This can be useful if you want to extract the domain for one axis before you specify the data for the other.

chart_layout.xScale([options])

Gets a scale function for calculating x-coordinates.

chart_layout.yScale([options])

Gets a scale function for calculating primary y-coordinates.

chart_layout.y2Scale([options])

Gets a scale function for calculating secondary y-coordinates.

In addition to the three *Scale methods and three *Data methods described above, the chart_layout instance also provides methods for returning the calculated minimum distances between data points on a given axis. This can be useful in the construction of bar charts, for example.

chart_layout.xMinStep()

Returns the minimum screen-coordinate distance between xData points.

chart_layout.yMinStep()

Returns the minimum screen-coordinate distance between yData points.

chart_layout.y2MinStep()

Returns the minimum screen-coordinate distance between y2Data points.

Dimensional and margin functions and properties of chart_layout

chart_layout.height([value])

If value is specified, sets the total height of the chart_layout area and returns the chart_layout instance. If value is null, the height of the bounding rectangle of chart_layout.svg is used (if the plotAspect hasn't been set). If value is undefined returns the calculated total height of the chart_layout area. Calling the plotAspect method with a value will lead to a recalculation of the height.

chart_layout.plotAspect([value])

If value is specified, sets the aspect ratio of the plot area and returns the chart_layout instance. If value is null, the plotAspect is unset and the aspect is determined implicitly from the width, height and margins. If value is undefined returns the calculated or previously set plot aspect ratio. Calling the height method with a value will lead to a recalculation of the plot aspect.

chart_layout.width([value])

If value is specified, sets the total width of the chart_layout area and returns the chart_layout instance. If value is any falsy value other than undefined, the width of the bounding rectangle of chart_layout.container is used. If value is undefined returns the calculated total width of the chart_layout area.

chart_layout.margins()

Returns an object containing the top, right, bottom and left margins as used the last time update was called. These can also be read individually as properties of the method, ie chart_layout.margins.top, chart_layout.margins.right, chart_layout.margins.bottom and chart_layout.margins.left.

chart_layout.plot_height

Read-only plot height of the chart_layout area.

chart_layout.plot_width

Read-only plot width of the chart_layout area.

chart_layout.x_left

Read-only on-screen x-coordinate for the left end of the x axis.

chart_layout.x_right

Read-only on-screen x-coordinate for the right end of the x axis.

chart_layout.y_bottom

Read-only on-screen y-coordinate for the bottom end of the y (and y2) axis.

chart_layout.y_top

Read-only on-screen y-coordinate for the top end of the y (and y2) axis.

The Ticks methods of chart_layout

chart_layout.xTicks()

Returns a frozen array of frozen objects, where each object includes properties of a single tick mark/label pair that was drawn on the x axis the last time update was called.

chart_layout.yTicks()

Returns a frozen array of frozen objects, where each object includes properties of a single tick mark/label pair that was drawn on the y axis the last time update was called.

chart_layout.y2Ticks()

Returns a frozen array of frozen objects, where each object includes properties of a single tick mark/label pair that was drawn on the y2 axis the last time update was called.

chart_layout.xTicks.autoLabelSpace([value, [unit]])
chart_layout.yTicks.autoLabelSpace([value, [unit]])
chart_layout.y2Ticks.autoLabelSpace([value, [unit]])

All three *Ticks methods outlined above have a sub-method that can be used to define how the maximum space for tick labels is calculated when the Flourish-user specifies the "auto" option for the relevant tick_label_space_mode property. These methods recognise up to two parameters. value specifies the magnitude of the margin in the given unit. Recognised units are "px", "rem" and "fraction". In the case of "fraction", this refers to the height (for the x method) or width of the chart-layout instance. If only a value is specified when calling one of these methods, the unit is assumed to be "px". The instance is returned in either case. If value is not specified when calling one of these functions then an object is returned that includes the current choice of unit and the calculated values for all three options based on the currently specified value and unit combination.

The space being defined is a height for the x axis and a width for the y and y2 axes. Labels that are too long for the defined space may be automatically shorted (with trailing characters replaced by a single "…" character). However, if the labels are oriented at right angles to the relevant spatial dimension, no shortening will occur.

The Title methods of chart_layout

chart_layout.xTitle()

Returns the computed title text for the x axis.

chart_layout.yTitle()

Returns the computed title text for the y axis.

chart_layout.y2Title()

Returns the computed title text for the y2 axis.

Other methods of chart_layout

All the methods below act like both getters and setters. When a value is specified the return value is always the chart_layout instance to allow for method chaining. When a value is not specified, the return value is the currently saved value(s) associated with that property.

chart_layout.animationDuration([value])

If value is specified, sets the duration of animations (in milliseconds) that take place when chart_layout.update is called.

chart_layout.clip([value])

If value is specified, sets whether (truthy) or not (falsy) the data is clipped to the bounds of the axes.

chart_layout.debug([value])

Sets whether (if value is truthy) or not to draw a bounding rectangle around the chart_layout container. This can be useful for debugging layout issues. The default is false.

chart_layout.debugColor([value])

Sets the color for the bounding rectangle discussed in chart_layout.debug. Defaults to red.

chart_layout.identifier([value])

If value is specified, sets the charts identifier to that value. This is used to make an id for clipping purposes so should not be used on more than one chart_layout instance on a page and should match the rules for HTML id attributes. If a value has never been passed to this method then a value that should be unique is used. It takes the form of the string "fl-chart-layout-" with a number appended.

chart_layout.offsetTop([value])

If value is specified, sets the vertical transform applied to the whole chart_layout instance (defaults to 0).

chart_layout.offsetLeft([value])

If value is specified, sets the horizontal transform applied to the whole chart_layout instance (defaults to 0).

chart_layout.xAutoTicks([value])

If value is specified, sets the array to be used or function to be called when the user sets the x-tick mode to “Auto”. null can also be passed, in which case the default function will be restored. This method has no effect when the x-axis is categorical.

chart_layout.xAutoTitle([value])

If value is specified, sets the title text to be used for the x axis to value when the Flourish user choses auto for the title_mode.

chart_layout.xDatetimeParse([func])

If func is specified, sets the parsing function to be applied when the Flourish user inputs dates in string format in the settings for the x axis. Currently this means the min and max for the date range and the values of custom ticks.

chart_layout.xFlipAxis([value])

If value is specified, sets whether the x axis should be flipped (after converting value to a Boolean) so it runs from right to left rather than left to right.

chart_layout.xFormat([func])

If func is specified, sets the formatting function to be applied to the tick formats on the x axis. The func function is called for every tick on the axis on update with the ticks own value as the only argument. The value returned is then used as the printed tick label. If chart_layout.xFormat is never called with a func or func is falsy (but not undefined) the default formatting function, function(value) { return "" + value; }, is used.

chart_layout.xHide([value])

If value is specified then sets whether or not the x axis should be hidden. By default this means the tick marks, labels, axis title and gridlines will not be drawn and no space will be left for them. The xScale and xTicks methods will still function as if the axis was visible (assuming it hasn't been switched off through settings). If value is an object with a keep_gridlines property that is truthy the tick marks, labels and axis title will not be drawn but gridlines will be (assuming they aren't switched off through settings).

chart_layout.xNumberParse([func])

If func is specified, sets the parsing function to be applied when the Flourish user inputs numbers in string format in the settings for the x axis. Currently this means the values of custom ticks.

chart_layout.xPadding([object])

If object is specified, sets the current left, right and unit properties for the x-axis padding. Any of these properties may be omitted from object, in which case their value remains unchanged. left and right should be numbers (default: 0). unit should be a string, either “px” or “steps” (default “px”). A value of “px” means the left and right values are specified in pixels, a value of “steps” means the left and right values are specified as a multiple of the minimum on-screen separation (AKA step-size) between the xData points. The padding setting is ignored for categorical scales and also for logarithmic numeric scales if the unit isn't “px”.

chart_layout.xZeroAxis([value])

Specifies the behaviour when the x axis zero_axis settings is set to auto. In this situation, if value is specified and is truthy then the x axis will include 0 if the data is numeric and the axis linear, regardless of the xData values. Can be overriden by user-set min and max values.

chart_layout.yAutoTicks([value])

If value is specified, sets the array to be used or function to be called when the user sets the y-tick mode to “Auto”. null can also be passed, in which case the default function will be restored. This method has no effect when the y-axis is categorical.

chart_layout.yAutoTitle([value])

If value is specified, sets the title text to be used for the y axis to value when the Flourish user choses auto for the title_mode.

chart_layout.yDatetimeParse([func])

If func is specified, sets the parsing function to be applied when the Flourish user inputs dates in string format in the settings for the y axis. Currently this means the min and max for the date range and the values of custom ticks.

chart_layout.yFlipAxis([value])

If value is specified, sets whether the y axis should be flipped (after converting value to a Boolean) so it runs from top to bottom rather than bottom to top.

chart_layout.yFormat([func])

If func is specified, sets the formatting function to be applied to the tick formats on the primary y axis. The func function is called for every tick on the axis on update with the ticks own value as the only argument. The value returned is then used as the printed tick label. If chart_layout.yFormat is never called with a func or func is falsy (but not undefined) the default formatting function, function(value) { return "" + value; }, is used.

chart_layout.yHide([value])

If value is specified then sets whether or not the y axis should be hidden. By default this means the tick marks, labels, axis title and gridlines will not be drawn and no space will be left for them. The yScale and yTicks methods will still function as if the axis was visible (assuming it hasn't been switched off through settings). If value is an object with a keep_gridlines property that is truthy the tick marks, labels and axis title will not be drawn but gridlines will be (assuming they aren't switched off through settings).

chart_layout.yNumberParse([func])

If func is specified, sets the parsing function to be applied when the Flourish user inputs numbers in string format in the settings for the y axis. Currently this means the values of custom ticks.

chart_layout.yPadding([object])

If object is specified, sets the current bottom, top and unit properties for the y-axis padding. Any of these properties may be omitted from object, in which case their value remains unchanged. bottom and top should be numbers (default: 0). unit should be a string, either “px” or “steps” (default “px”). A value of “px” means the bottom and top values are specified in pixels, a value of “steps” means the bottom and top values are specified as a multiple of the minimum on-screen separation (AKA step-size) between the yData points. The padding setting is ignored for categorical scales and also for logarithmic numeric scales if the unit isn't “px”.

chart_layout.yZeroAxis([value])

Specifies the behaviour when the y axis zero_axis settings is set to auto. In this situation, if value is specified and is truthy then the y axis will include 0 if the data is numeric and the axis linear, regardless of the yData values. Can be overriden by user-set min and max values.

chart_layout.y2AutoTicks([value])

If value is specified, sets the array to be used or function to be called when the user sets the y2-tick mode to “Auto”. null can also be passed, in which case the default function will be restored. This method has no effect when the y2-axis is categorical.

chart_layout.y2AutoTitle([value])

If value is specified, sets the title text to be used for the y2 axis to value when the Flourish user choses auto for the title_mode.

chart_layout.y2DatetimeParse([func])

If func is specified, sets the parsing function to be applied when the Flourish user inputs dates in string format in the settings for the y2 axis. Currently this means the min and max for the date range and the values of custom ticks.

chart_layout.yF2lipAxis([value])

If value is specified, sets whether the y2 axis should be flipped (after converting value to a Boolean) so it runs from top to bottom rather than bottom to top.

chart_layout.y2Format([func])

If func is specified, sets the formatting function to be applied to the tick formats on the secondary y axis. The func function is called for every tick on the axis on update with the ticks own value as the only argument. The value returned is then used as the printed tick label. If chart_layout.y2Format is never called with a func or func is falsy (but not undefined) the default formatting function, function(value) { return "" + value; }, is used.

chart_layout.y2Hide([value])

If value is specified then sets whether or not the y2 axis should be hidden. By default this means the tick marks, labels, axis title and gridlines will not be drawn and no space will be left for them. The y2Scale and y2Ticks methods will still function as if the axis was visible (assuming it hasn't been switched off through settings). If value is an object with a keep_gridlines property that is truthy the tick marks, labels and axis title will not be drawn but gridlines will be (assuming they aren't switched off through settings). Unlike for the xHide and yHide methods above, the default value for this method is true: you must explicitly turn the y2 axis on.

chart_layout.y2NumberParse([func])

If func is specified, sets the parsing function to be applied when the Flourish user inputs numbers in string format in the settings for the y2 axis. Currently this means the values of custom ticks.

chart_layout.yPadding([object])

If object is specified, sets the current bottom, top and unit properties for the y2-axis padding. Any of these properties may be omitted from object, in which case their value remains unchanged. bottom and top should be numbers (default: 0). unit should be a string, either “px” or “steps” (default “px”). A value of “px” means the bottom and top values are specified in pixels, a value of “steps” means the bottom and top values are specified as a multiple of the minimum on-screen separation (AKA step-size) between the y2Data points. The padding setting is ignored for categorical scales and also for logarithmic numeric scales if the unit isn't “px”.

chart_layout.y2ZeroAxis([value])

Specifies the behaviour when the y axis zero_axis settings is set to auto. In this situation, if value is specified and is truthy then the y2 axis will include 0 if the data is numeric and the axis linear, regardless of the y2Data values. Can be overriden by user-set min and max values.