ft-interactive/g-axis

Name: g-axis

Owner: FT Interactive News

Description: null

Created: 2017-06-29 10:34:31.0

Updated: 2017-11-27 17:13:53.0

Pushed: 2018-01-15 17:06:27.0

Homepage: null

Size: 549

Language: JavaScript

GitHub Committers

UserMost Recent Commit# Commits

Other Committers

UserEmailMost Recent Commit# Commits

README

gAxis codecov

Pre styled centralised repository of axis for use with the FT's g-chartframe architecture as part of the Visual Vocabulary. Creates ordinal, linear or date axis that can be appended to the .plot obejct in the g-chartframe hopefully eliminating the need to code another standard axis or set up the tick format for a date sequence.

The axis module also appends the correct script tags for use with the FT Pre-Flight script in Adobe Illustrator.

Will also work with other builds where the axis is called into an svg.

Prerequisites

The FT axis styles—add the folowwing link in your index file header

k rel="stylesheet" href="//rawgit.com/ft-interactive/visual-vocabulary-templates/master/styles.css">

The d3 library is already installed in the build

Manual installation

If you are working within the g-chartfram architecture add the following code to the top of your index.js

rt * as gAxis from 'g-axis
NPM install

Not yet deployed

Getting started

Notes All examples shown are from the web frame style. Always create and call a y-axis first, as it returms .labelWidth() that holds a value equal to the width of the widest tick label on the y-axis. This value is used to re-define the left or right margin of the chartframe before defining the .domain() of the x-axis e.g.

yOrdinal axis where the width of 'Switzerland' is returned in .labelWidth alt tag The tick 'Dem Republic of Congo'is much longer so will leave less space for the x-axis .domain() alt tag

For more detail on .labelWidth() and its use in positioning see:

The following axis types are currently defined in this repo (click to jump to section)

yLinear

Note All examples shown are from the web frame style. yLinear() creates a d3 linear axis with a couple of additional feature to help manage styling and day-to-day production of charts that use a linear y-axis

Getting started

Add the following code to your index.js to append a default y-axis to the current frame object (grey here but is not normally visible)

t yAxis = gAxis.yLinear()
t currentFrame = frame[frameName];

entFrame.plot()
.call(yAxis);

alt tag

Use the current frame dimensions to define your .range() and the .ticksize() and a .domian()

t yAxis = gAxis.yLinear()
t currentFrame = frame[frameName];

is
.domain([0,200])
.range([currentFrame.dimension().height,0])
.tickSize(currentFrame.dimension().width)

entFrame.plot()
.call(yAxis);

alt tag

Positioning

The rendered axis returns the width of the widest text label on the y- axis via .labelWidth(). this will vary depending on the text e.g. '100,000' will return a larger value than '10' alt tag)

.labelWidth() is used to amend the appropriate margin of the current frame so that tick text is positioned outside it. The following code when added to you index.js file after the y-axis has been called will resize the margin depending on the .align() setting which is 'right' by default.

align == 'right' ){
        let newMargin = yAxis.labelWidth()+currentFrame.margin().right
        //Use newMargin redefine the new margin and range of xAxis
        currentFrame.margin({right:newMargin});
        //yAxis.yLabel().attr('transform', `translate(${currentFrame.dimension().width},0)`);
    }
    if (align == 'left' ){
        let newMargin = yAxis.labelWidth()+currentFrame.margin().left
        //Use newMargin redefine the new margin and range of xAxis
        currentFrame.margin({left:newMargin});
        yAxis.yLabel().attr('transform', `translate(${(yAxis.tickSize()-yAxis.labelWidth())},0)`);
    }
    d3.select(currentFrame.plot().node().parentNode)
        .call(currentFrame);

alt tag

The current frame can then still be used to correctly define the .range() values of an x-axis.

yLinear API reference

myAxis.align([String]) “right” or “left”. Determines the alignment of the tick text set as “right” by default. example

myAxis.domain([Array]) defines the axis domain in the same way as you would when creating a normal d3.scaleLinear(). If no .domain() is defined the default is [0,10000]

myAxis.invert([boolean]) Inverts the scale so that the lowest figures are nearer the top and the highest figures are nearer the bottom example

myAxis.labelWidth([Number]) used to return the width of the text on the axis tick. Will vary depending on tick e.g. a label of '1,000,000' will be wider than a label of '10' and will return a higher value. See yLinear Postioning

myAxis.numTicks([Number]) as they name suggest defines how many ticks are on the axis. 0 to 100 with 3 tick would give a zero line, a fifty line and a hundred line.If not enough ticks have been specifiesd d3 will automatically increase the number. example

myAxis.range([Array]) defines the axis range in the same way as you would when creating a normal d3.scaleLinear(). If no .range() is defined the default is [120,0])

myAxis.yAxishighlight([Number])Changes the style of the tick specified from the normal dotted 'axis' style to the solid 'baseline'. Mostly used on index charts where the 100 line should be highlighted of the minimum tick value goes below zero example

yLinear Examples
Left hand axis
Axis
.domain([0,200])
.range([currentFrame.dimension().height,0])
.tickSize(currentFrame.dimension().width)
.align('left')

entFrame.plot()
.call(myYAxis);

alt tag

Number of ticks

Zero to 100 with 6 tick, making increments of every 20

xis
.range([currentFrame.dimension().height,0])
.domain([0,200])
.tickSize(currentFrame.dimension().width)
.numTicks(6)

entFrame.plot()
.call(myYAxis);

alt tag

yAxisHighlight

-50 to 200 with 150 highlighted as this is the base line. Zero automatically highlights

s
.domain([-50,200])
.range([currentFrame.dimension().height,0])
.align(align)
.tickSize(currentFrame.dimension().width)
.yAxisHighlight(-50);

entFrame.plot()
.call(myYAxis);

alt tag

Inverted scale

200 down to zero. 200 line highlighted

s
.domain([0,200])
.range([currentFrame.dimension().height,0])
.tickSize(currentFrame.dimension().width)
.yAxisHighlight(200)
.invert(true);

entFrame.plot()
.call(yAxis);

alt tag

xDate

Note Your y-axis of choice should be created and appended to the current frame before attaching an x-axis as the size of the y-axis tick text should be used to determine the .domain() of the new x-axis

Add the following code to your index.js to append a default xDate() axis to the current frame (grey here but is not normally visible). Note that .tickSize() is included although not vital to create the axis. No positioning has been applied. The minor axis is visible as the default setting for .minorAxis() is true.

t xAxis = gAxis.xDate();
t currentFrame = frame[frameName];

s
.tickSize(currentFrame.rem()*.75)
.minorTickSize(currentFrame.rem()*.3)

entFrame.plot()
.call(xAxis);

alt tag

Postioning

To position the axis in the frame add the following code after the axis has been called. This will place the axis correctly at eithr the top or bottom depending on the .align() setter, bottom by default. If full height ticks length are defined then this code will need to be re-calculated, see examples

align == 'bottom' ){
myXAxis.xLabel().attr('transform', `translate(0,${currentFrame.dimension().height})`);
if(minorAxis) {
    myXAxis.xLabelMinor().attr('transform', `translate(0,${currentFrame.dimension().height})`);
}

align == 'top' ){
myXAxis.xLabel().attr('transform', `translate(0,${myXAxis.tickSize()})`);

alt tag You can now use the .align() to position the axis at the top or the bottom of the fram, see API reference

xDate API reference

xAxis.domain([Array]) defines the axis domain in the same way as you would when creating a normal d3.scaleTime(). If no .domain() is defined the default is [Jan 01 1970,Jun 01 2017]

xAxis.range([Array]) defines the axis range in the same way as you would when creating a normal d3.scaleLinear(). If no .range() is defined the default is [0,220])

xAxis.fullYear([boolean]) used on charts where interval('year')is used and forces the notation into a full year i.e 1977 instead of 77

xAxis.interval([String]) Defines the tick interval on the axis (see examples). By default this is set to “lustrum” meaning every five years. It can be set to:

The interval of the ticks will also effect the tick formatting, which will default to the following: alt tag

xAxis.tickSize([Number]) Defines the size of the ticks. Usually set to .rem() *.75 for the major ticks. When full height ticks are required some adjustment will be needed to the positioning of the axis, see examples

xAxis.minorTickSize([String]) Defines the size of the minor ticks. Usually set to .rem()*.3. When full height ticks are required some adjustment will be needed to the positioning of the axis

Note When the height of the current frame is equal to the .minorTickSize() then the minor tick will change 'axis' and not 'baseline' resulting in the dotted tick lines

xAxis.minorTickSize([Boolean]) Set to true by default this determines if the minor axis is displayed or not

xAxis.xlabel() Returns an accessor to allow the axis ticks to have changes made to their style

xAxis.xabel() Returns an accessor to allow the axis ticks to have changes made to their style

xDate Examples
Yearly

From Jan 1 2005 to June 1 2017, with each year labeled and no minor axis. Full years are turned off by default

t xAxis = xaxisDate();//sets up yAxis
t currentFrame = frame[frameName];

mindate = new Date(2005,1,1);
maxdate = new Date(2017,6,1);

xis
.domain([mindate,maxdate])
.range([0,currentFrame.dimension().width])
.interval("years")
.minorAxis(false)

entFrame.plot()
.call(myXAxis);

alt tag

Every ten years

From Jan 1 1940 to June 1 2017, with every ten years labeled and a minor axis

t xAxis = xaxisDate();//sets up yAxis
t currentFrame = frame[frameName];

mindate = new Date(1940,1,1);
maxdate = new Date(2017,6,1);

xis
.domain([mindate,maxdate])
.range([0,currentFrame.dimension().width])
.interval("decade")
.minorAxis(true)
.tickSize(currentFrame.rem()*.75)
.minorTickSize(currentFrame.rem()*.3)

alt tag

Every five years

From Jan 1 1986 to June 1 2017, with every five years labeled and a minor axis

t xAxis = xaxisDate();//sets up yAxis
t currentFrame = frame[frameName];

mindate = new Date(1986,1,1);
maxdate = new Date(2017,6,1);

xis
.domain([mindate,maxdate])
.range([0,currentFrame.dimension().width])
.interval("lustrun")
.minorAxis(true)
.tickSize(currentFrame.rem()*.75)
.minorTickSize(currentFrame.rem()*.3)

alt tag

Every month

From Jun 1 1991 to Feb 1 2000, with month years labeled and no minor axis

t xAxis = xaxisDate();//sets up yAxis
t currentFrame = frame[frameName];

mindate = new Date(1999,6,1);
maxdate = new Date(2000,2,1);

xis
.domain([mindate,maxdate])
.range([0,currentFrame.dimension().width])
.interval("months")
.minorAxis(false)
.tickSize(currentFrame.rem()*.75)
.minorTickSize(currentFrame.rem()*.3)

alt tag

yLinear
xOrdinal
yLinear
yOrdinal

This work is supported by the National Institutes of Health's National Center for Advancing Translational Sciences, Grant Number U24TR002306. This work is solely the responsibility of the creators and does not necessarily represent the official views of the National Institutes of Health.