Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
d0c8f10
Economist style ticks
henryjameslau Oct 15, 2025
aac5b92
Merge branch 'main' into economist-ticks
henryjameslau Nov 14, 2025
0123fcc
Add a flag in the config to switch method
henryjameslau Nov 14, 2025
9e17263
Merge branch 'economist-ticks' of https://github.com/ONSdigital/Chart…
henryjameslau Nov 14, 2025
f094b86
move getXaxisticks to the helpers
henryjameslau Nov 17, 2025
3441ce9
Merge branch 'main' into economist-ticks
henryjameslau Nov 21, 2025
960e967
Secondary level
henryjameslau Dec 31, 2025
42c5ab1
Add option to turn off secondary labels
henryjameslau Jan 2, 2026
3e4895c
Timespan labels for all charts
henryjameslau Jan 2, 2026
8f295b3
customBandAxis part1
henryjameslau Jan 14, 2026
bd93fe0
Working as two different versions
henryjameslau Jan 15, 2026
b2e7c4f
think column chart works
henryjameslau Jan 15, 2026
18a2415
WIP
henryjameslau Jan 15, 2026
efa2831
rename so .tickFormat works
henryjameslau Jan 15, 2026
4e0afc2
Move everything to utc time
henryjameslau Jan 16, 2026
fd00df7
Got it working well on columns
henryjameslau Jan 16, 2026
10a0899
prefix helper
henryjameslau Jan 16, 2026
1f05405
Example using offset years
henryjameslau Jan 16, 2026
6963ad9
Done major/minor for time. First + last for bands
henryjameslau Jan 16, 2026
26c3f06
Everything hooked up to the config I think
henryjameslau Jan 16, 2026
5d69244
Create customTemporalAxis.md
henryjameslau Jan 16, 2026
8daec98
Merge pull request #394 from ONSdigital/economist-ticks-unified
henryjameslau Jan 16, 2026
ff2ded6
Update customTemporalAxis.md
henryjameslau Jan 16, 2026
70bf94a
Merge branch 'economist-ticks' of https://github.com/ONSdigital/Chart…
henryjameslau Jan 16, 2026
b136113
move readme
henryjameslau Jan 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion area-stacked-sm/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ d3.csv(config.graphicDataURL)

// );
graphicData.forEach((d) => {
d.date = d3.timeParse(config.dateFormat)(d.date);
d.date = d3.utcParse(config.dateFormat)(d.date);
});

//use pym to create iframed chart dependent on specified variables
Expand Down
2 changes: 1 addition & 1 deletion area-stacked/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ function drawGraphic() {
d3.csv(config.graphicDataURL).then((rawData) => {
graphicData = rawData.map((d) => {
return {
date: d3.timeParse(config.dateFormat)(d.date),
date: d3.utcParse(config.dateFormat)(d.date),
...Object.entries(d)
.filter(([key]) => key !== 'date')
.map(([key, value]) => [key, +value])
Expand Down
5 changes: 5 additions & 0 deletions column-chart-ci-bands/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ config = {
"md": 4,
"lg": 2
},
"labelSpans": {
enabled: true,
timeUnit:"day",//set to "day","month",'quarter' or 'year'
secondaryTimeUnit:"auto",//can be 'auto', false to disable or override with "day","month",'quarter' or 'year'
},
"yAxisTicks": {
"sm": 4,
"md": 5,
Expand Down
32 changes: 19 additions & 13 deletions column-chart-ci-bands/script.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { initialise, wrap, addSvg, addAxisLabel, addSource } from "../lib/helpers.js";
import { initialise, wrap, addSvg, addAxisLabel, addSource, customTemporalAxis } from "../lib/helpers.js";

let graphic = d3.select('#graphic');
let pymChild = null;
Expand Down Expand Up @@ -73,16 +73,22 @@ function drawGraphic() {
let xTime = d3.timeFormat(config.xAxisTickFormat[size])

//set up xAxis generator
let xAxis = d3
.axisBottom(x)
.tickSize(10)
.tickPadding(10)
.tickValues(tickValues) //Labelling the first and/or last bar if needed
.tickFormat((d) => {
if (xDataType == 'date') return xTime(d);
if (xDataType == 'numeric') return d3.format(config.xAxisNumberFormat)(d);
return d; // categorical: just show the label
});
let xAxisGenerator;
if (config.labelSpans.enabled === true && xDataType=="date") {
xAxisGenerator = customTemporalAxis(x)
.timeUnit(config.labelSpans.timeUnit)
.tickSize(0)
.tickPadding(6)
.secondaryTimeUnit(config.labelSpans.secondaryTimeUnit);
} else {
xAxisGenerator = d3
.axisBottom(x)
.tickSize(10)
.tickPadding(10)
.tickValues(tickValues) //Labelling the first and/or last bar if needed
.tickFormat((d) => xDataType == 'date' ? xTime(d)
: d3.format(config.xAxisNumberFormat)(d));
}

//create svg for chart
svg = addSvg({
Expand Down Expand Up @@ -112,7 +118,7 @@ function drawGraphic() {
.append('g')
.attr('transform', 'translate(0,' + height + ')')
.attr('class', 'x axis')
.call(xAxis);
.call(xAxisGenerator);

svg
.append('g')
Expand Down Expand Up @@ -223,7 +229,7 @@ function drawGraphic() {

d3.csv(config.graphicDataURL)
.then((data) => {
let parseTime = d3.timeParse(config.dateFormat);
let parseTime = d3.utcParse(config.dateFormat);
//load chart data
graphicData = data;

Expand Down
7 changes: 7 additions & 0 deletions column-chart-stacked-optional-line-sm/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,15 @@ config = {
md: 4,
lg: 6,
},
addFirstDate: false,
addFinalDate: false,
legendColumns: 4,
dropYAxis: true,
labelSpans: {
enabled: true,
timeUnit:"month",//"day","month","year"
secondaryTimeUnit: "auto",//"auto" or define "day","month","year". false to disable
},
elements: { select: 0, nav: 0, legend: 0, titles: 0 },
chartBuild: {},
};
76 changes: 35 additions & 41 deletions column-chart-stacked-optional-line-sm/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
diamondShape,
addChartTitleLabel,
addAxisLabel,
customTemporalAxis
} from "../lib/helpers.js";

let graphic = d3.select("#graphic");
Expand Down Expand Up @@ -110,8 +111,8 @@ function drawGraphic() {
config.dropYAxis !== true
? d3.format(config.yAxisTickFormat)(d)
: chartPosition == 0
? d3.format(config.yAxisTickFormat)(d)
: ""
? d3.format(config.yAxisTickFormat)(d)
: ""
);

// Use stackColumns for the stack instead of filtering out lineSeries
Expand All @@ -126,44 +127,37 @@ function drawGraphic() {

let xTime = d3.timeFormat(config.xAxisTickFormat[size]);

//set up xAxis generator
const xAxis = d3
.axisBottom(x)
.tickSize(10)
.tickPadding(10)
.tickValues(
xDataType == "date"
? graphic_data
.map(function (d) {
return d.date.getTime();
}) //just get dates as seconds past unix epoch
.filter(function (d, i, arr) {
return arr.indexOf(d) == i;
}) //find unique
.map(function (d) {
return new Date(d);
}) //map back to dates
.sort(function (a, b) {
return a - b;
})
.filter(function (d, i) {
return (
(i % config.xAxisTicksEvery[size] === 0 &&
i <= graphic_data.length - config.xAxisTicksEvery[size]) ||
i == data.length - 1
); //Rob's fussy comment about labelling the last date
})
: x.domain().filter((d, i) => {
return (
(i % config.xAxisTicksEvery[size] === 0 &&
i <= graphic_data.length - config.xAxisTicksEvery[size]) ||
i == data.length - 1
);
})
)
.tickFormat((d) =>
xDataType == "date" ? xTime(d) : d3.format(config.xAxisNumberFormat)(d)
);
let xAxis;

let tickValues = x.domain().filter(function (d, i) {
return !(i % config.xAxisTicksEvery[size]);
});

//Labelling the first and/or last bar if needed
if (config.addFirstDate == true) {
tickValues.push(domain[0]);
}

if (config.addFinalDate == true) {
tickValues.push(domain[domain.length - 1]);
}

if (config.labelSpans.enabled === true && xDataType == "date") {
xAxis = customTemporalAxis(x)
.timeUnit(config.labelSpans.timeUnit)
.tickSize(0)
.tickPadding(6)
.secondaryTimeUnit(config.labelSpans.secondaryTimeUnit);
} else {
xAxis = d3
.axisBottom(x)
.tickSize(10)
.tickPadding(10)
.tickValues(tickValues)
.tickFormat((d) =>
xDataType == "date" ? xTime(d) : d3.format(config.xAxisNumberFormat)(d)
);
}

//create svg for chart
const svg = addSvg({
Expand Down Expand Up @@ -405,7 +399,7 @@ d3.csv(config.graphicDataUrl).then((data) => {
//load chart data
graphic_data = data;

let parseTime = d3.timeParse(config.dateFormat);
let parseTime = d3.utcParse(config.dateFormat);

data.forEach((d, i) => {
//If the date column is has date data store it as dates
Expand Down
6 changes: 6 additions & 0 deletions column-chart-stacked-optional-line/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ config = {
},
addFirstDate: false,
addFinalDate: false,
labelSpans: {
enabled: true,
timeUnit:"month",//set to "day","month",'quarter' or 'year'
secondaryTimeUnit: 'quarter',//can be 'auto', false to disable or override with "day","month",'quarter' or 'year'
yearStartMonth:0,//0 indexed so year starts in Jan
},
elements: { select: 0, nav: 0, legend: 0, titles: 0 },
chartBuild: {},
};
1 change: 0 additions & 1 deletion column-chart-stacked-optional-line/data.csv
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,3 @@ Dec-20,0.055,0.024,-0.004,0.052,0.09
Jan-21,0.088,0.083,-0.042,0.017,-0.061
Feb-21,0.056,0.043,-0.086,-0.083,0.098
Mar-21,0.041,0.057,-0.065,0.057,0.036
Apr-21,0.033,-0.057,0.004,0.02,0.022
30 changes: 21 additions & 9 deletions column-chart-stacked-optional-line/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import {
addSvg,
diamondShape,
addAxisLabel,
customTemporalAxis,
quarterYearFormatter
} from "../lib/helpers.js";

let graphic = d3.select("#graphic");
Expand Down Expand Up @@ -69,14 +71,24 @@ function drawGraphic() {
}

//set up xAxis generator
let xAxis = d3
.axisBottom(x)
.tickSize(10)
.tickPadding(10)
.tickValues(tickValues)
.tickFormat((d) =>
xDataType == "date" ? xTime(d) : d3.format(config.xAxisNumberFormat)(d)
);
let xAxis;
if (config.labelSpans.enabled === true && xDataType == "date") {
xAxis = customTemporalAxis(x)
.timeUnit(config.labelSpans.timeUnit)
.tickSize(0)
.tickPadding(6)
.secondaryTimeUnit(config.labelSpans.secondaryTimeUnit)
.secondaryTickFormat(d => quarterYearFormatter(d, config.labelSpans.yearStartMonth))
} else {
xAxis = d3
.axisBottom(x)
.tickSize(10)
.tickPadding(10)
.tickValues(tickValues)
.tickFormat((d) =>
xDataType == "date" ? xTime(d) : d3.format(config.xAxisNumberFormat)(d)
);
}

// Determine which columns to use for stacked bars based on line toggle
let stackColumns;
Expand Down Expand Up @@ -318,7 +330,7 @@ d3.csv(config.graphicDataUrl).then((data) => {
//load chart data
graphic_data = data;

let parseTime = d3.timeParse(config.dateFormat);
let parseTime = d3.utcParse(config.dateFormat);

data.forEach((d, i) => {
//If the date column is has date data store it as dates
Expand Down
7 changes: 7 additions & 0 deletions column-chart/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,12 @@ config = {
},
"addFirstDate": false,
"addFinalDate": false,
"labelSpans":{
"enabled":true,
timeUnit:"month",//set to "day","month",'quarter' or 'year'
secondaryTimeUnit:"auto",//can be 'auto', false to disable or override with "day","month",'quarter' or 'year'
yearStartMonth:3,//0 indexed so the year start in April
prefix:"FY ",//prefix for secondary label
},
"elements": { "select": 0, "nav": 0, "legend": 0, "titles": 0 }
};
2 changes: 2 additions & 0 deletions column-chart/data.csv
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@ Jan-21,0.241938997
Feb-21,0.582086196
Mar-21,0.732952731
Apr-21,0.916589365
May-21,0.81
Jun-21,0.71
35 changes: 24 additions & 11 deletions column-chart/script.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { initialise, wrap, addSvg, addAxisLabel, addSource } from "../lib/helpers.js";
import { initialise, wrap, addSvg, addAxisLabel, addSource, customTemporalAxis, prefixYearFormatter } from "../lib/helpers.js";

let graphic = d3.select('#graphic');
let pymChild = null;
Expand All @@ -22,7 +22,7 @@ function drawGraphic() {

const x = d3
.scaleBand()
.paddingOuter(0.0)
.paddingOuter(0.05)
.paddingInner(0.1)
.range([0, chartWidth])
.round(false);
Expand Down Expand Up @@ -60,14 +60,27 @@ function drawGraphic() {

let xTime = d3.timeFormat(config.xAxisTickFormat[size])


//set up xAxis generator
let xAxis = d3
.axisBottom(x)
.tickSize(10)
.tickPadding(10)
.tickValues(tickValues) //Labelling the first and/or last bar if needed
.tickFormat((d) => xDataType == 'date' ? xTime(d)
: d3.format(config.xAxisNumberFormat)(d));
let xAxisGenerator;
if (config.labelSpans.enabled === true && xDataType == "date") {
xAxisGenerator = customTemporalAxis(x)
.timeUnit(config.labelSpans.timeUnit)
.tickSize(0)
.tickPadding(6)
.secondaryTimeUnit(config.labelSpans.secondaryTimeUnit)
.yearStartMonth(config.labelSpans.yearStartMonth)
.secondaryTickFormat(d => prefixYearFormatter(d, config.labelSpans.yearStartMonth, config.labelSpans.prefix));

} else {
xAxisGenerator = d3
.axisBottom(x)
.tickSize(10)
.tickPadding(10)
.tickValues(tickValues) //Labelling the first and/or last bar if needed
.tickFormat((d) => xDataType == 'date' ? xTime(d)
: d3.format(config.xAxisNumberFormat)(d));
}

//create svg for chart
svg = addSvg({
Expand All @@ -93,7 +106,7 @@ function drawGraphic() {
.append('g')
.attr('transform', 'translate(0,' + height + ')')
.attr('class', 'x axis')
.call(xAxis);
.call(xAxisGenerator);

svg
.append('g')
Expand Down Expand Up @@ -142,7 +155,7 @@ d3.csv(config.graphicDataURL).then((data) => {
//load chart data
graphicData = data;

let parseTime = d3.timeParse(config.dateFormat);
let parseTime = d3.utcParse(config.dateFormat);

data.forEach((d, i) => {

Expand Down
Loading