mirror of
https://github.com/status-im/fathom.git
synced 2025-03-01 03:20:27 +00:00
smart date formatting on chart x-axis
This commit is contained in:
parent
d4bd700513
commit
a00e72f81d
80
assets/js/components/Chart.js
vendored
80
assets/js/components/Chart.js
vendored
@ -12,7 +12,35 @@ function padZero(s) {
|
|||||||
return s < 10 ? "0" + s : s;
|
return s < 10 ? "0" + s : s;
|
||||||
}
|
}
|
||||||
|
|
||||||
function padData(startUnix, endUnix, data) {
|
const timeFormats = [
|
||||||
|
[() => '', function(d, n) {
|
||||||
|
return true;
|
||||||
|
}],
|
||||||
|
[d3.timeFormat("%Y"), function (d, i, n) {
|
||||||
|
return d.getUTCMonth() === 0 && d.getUTCDate() === 1;;
|
||||||
|
}],
|
||||||
|
[d3.timeFormat("%b"), function (d, i, n) {
|
||||||
|
return ( d.getUTCMonth() > 0 && d.getUTCDate() === 1 );
|
||||||
|
}],
|
||||||
|
[d3.timeFormat("%d"), function (d, i, n) {
|
||||||
|
return ( d.getUTCDate() > 1 ) && n < 32;
|
||||||
|
}],
|
||||||
|
[d3.timeFormat("%b %d"), function (d, i, n) {
|
||||||
|
return i === 0 && d.getUTCDate() > 1;
|
||||||
|
}]
|
||||||
|
]
|
||||||
|
|
||||||
|
var timeFormatPicker = function (formats, len) {
|
||||||
|
return function (date, pos) {
|
||||||
|
var i = formats.length - 1, f = formats[i];
|
||||||
|
while (!f[1](date, pos, len)) {
|
||||||
|
f = formats[--i];
|
||||||
|
}
|
||||||
|
return f[0](date);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
function prepareData(startUnix, endUnix, data) {
|
||||||
let startDate = new Date(startUnix * 1000);
|
let startDate = new Date(startUnix * 1000);
|
||||||
let endDate = new Date(endUnix * 1000);
|
let endDate = new Date(endUnix * 1000);
|
||||||
let datamap = [];
|
let datamap = [];
|
||||||
@ -25,16 +53,18 @@ function padData(startUnix, endUnix, data) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// make sure we have values for each date
|
// make sure we have values for each date
|
||||||
while(startDate < endDate) {
|
let currentDate = startDate;
|
||||||
let date = startDate.getFullYear() + "-" + padZero(startDate.getMonth() + 1) + "-" + padZero(startDate.getDate());
|
while(currentDate < endDate) {
|
||||||
let data = datamap[date] ? datamap[date] : {
|
let key = currentDate.getFullYear() + "-" + padZero(currentDate.getMonth() + 1) + "-" + padZero(currentDate.getDate());
|
||||||
"Date": date,
|
let data = datamap[key] ? datamap[key] : {
|
||||||
"Pageviews": 0,
|
"Pageviews": 0,
|
||||||
"Visitors": 0,
|
"Visitors": 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// replace Date property with actual date object
|
||||||
|
data.Date = new Date(currentDate);
|
||||||
newData.push(data);
|
newData.push(data);
|
||||||
startDate.setDate(startDate.getDate() + 1);
|
currentDate.setDate(currentDate.getDate() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return newData;
|
return newData;
|
||||||
@ -69,7 +99,7 @@ class Chart extends Component {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let padding = { top: 24, right: 12, bottom: 64, left: 40 };
|
let padding = { top: 12, right: 12, bottom: 24, left: 40 };
|
||||||
let height = Math.max( this.base.clientHeight, 240 );
|
let height = Math.max( this.base.clientHeight, 240 );
|
||||||
let width = this.base.clientWidth;
|
let width = this.base.clientWidth;
|
||||||
let innerWidth = width - padding.left - padding.right;
|
let innerWidth = width - padding.left - padding.right;
|
||||||
@ -89,33 +119,35 @@ class Chart extends Component {
|
|||||||
|
|
||||||
const t = d3.transition().duration(500).ease(d3.easeQuadOut);
|
const t = d3.transition().duration(500).ease(d3.easeQuadOut);
|
||||||
const max = d3.max(data, (d) => d.Pageviews);
|
const max = d3.max(data, (d) => d.Pageviews);
|
||||||
|
|
||||||
// axes
|
|
||||||
let x = d3.scaleBand().range([0, innerWidth]).padding(0.1).domain(data.map((d) => d.Date)),
|
|
||||||
y = d3.scaleLinear().range([innerHeight, 0]).domain([0, (max*1.1)]),
|
|
||||||
yAxis = d3.axisLeft().scale(y).ticks(3).tickSize(-innerWidth),
|
|
||||||
xAxis = d3.axisBottom().scale(x);
|
|
||||||
|
|
||||||
graph.append("g")
|
// axes
|
||||||
|
let x = d3.scaleBand().range([0, innerWidth]).padding(0.1).domain(data.map((d) => d.Date))
|
||||||
|
let y = d3.scaleLinear().range([innerHeight, 0]).domain([0, (max*1.1)])
|
||||||
|
let yAxis = d3.axisLeft().scale(y).ticks(3).tickSize(-innerWidth)
|
||||||
|
let xAxis = d3.axisBottom().scale(x).tickFormat(timeFormatPicker(timeFormats, data.length))
|
||||||
|
|
||||||
|
let yTicks = graph.append("g")
|
||||||
.attr("class", "y axis")
|
.attr("class", "y axis")
|
||||||
.call(yAxis);
|
.call(yAxis);
|
||||||
|
|
||||||
let nxTicks = Math.max(1, Math.round(data.length / 60));
|
|
||||||
let nxLabels = Math.max(1, Math.round(data.length / 15));
|
|
||||||
let xTicks = graph.append("g")
|
let xTicks = graph.append("g")
|
||||||
.attr("class", "x axis")
|
.attr("class", "x axis")
|
||||||
.attr('transform', 'translate(0,' + innerHeight + ')')
|
.attr('transform', 'translate(0,' + innerHeight + ')')
|
||||||
.call(xAxis)
|
.call(xAxis)
|
||||||
xTicks.selectAll('g text').style('display', (d, i) => {
|
|
||||||
return i % nxLabels != 0 ? 'none' : 'block'
|
|
||||||
}).attr("transform", "rotate(-60)").style("text-anchor", "end");
|
// hide all "day" ticks if we're watching more than 100 days of data
|
||||||
xTicks.selectAll('g').style('display', (d, i) => {
|
xTicks.selectAll('g').style('display', (d, i) => {
|
||||||
return i % nxTicks != 0 ? 'none' : 'block';
|
if(data.length > 100 && d.getUTCDate() > 1 ) {
|
||||||
});
|
return 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
})
|
||||||
|
|
||||||
// tooltip
|
// tooltip
|
||||||
const tip = d3.tip().attr('class', 'd3-tip').html((d) => (`
|
const tip = d3.tip().attr('class', 'd3-tip').html((d) => (`
|
||||||
<div class="tip-heading">${d.Date}</div>
|
<div class="tip-heading">${d.Date.toLocaleDateString()}</div>
|
||||||
<div class="tip-content">
|
<div class="tip-content">
|
||||||
<div class="tip-pageviews">
|
<div class="tip-pageviews">
|
||||||
<div class="tip-number">${d.Pageviews}</div>
|
<div class="tip-number">${d.Pageviews}</div>
|
||||||
@ -169,7 +201,7 @@ class Chart extends Component {
|
|||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
loading: false,
|
loading: false,
|
||||||
data: padData(after, before, d),
|
data: prepareData(after, before, d),
|
||||||
});
|
});
|
||||||
|
|
||||||
this.redrawChart();
|
this.redrawChart();
|
||||||
|
2304
package-lock.json
generated
2304
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user