Skip to content

Commit 9b7acf2

Browse files
improve chart ticks & tooltip content
1 parent be3b39e commit 9b7acf2

File tree

3 files changed

+44
-37
lines changed

3 files changed

+44
-37
lines changed

assets/src/js/components/Chart.js

Lines changed: 41 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -12,35 +12,49 @@ const formatMonth = d3.timeFormat("%b"),
1212
formatMonthDay = d3.timeFormat("%b %e");
1313

1414
const t = d3.transition().duration(600).ease(d3.easeQuadOut);
15-
const xTickFormat = (len) => {
16-
return {
17-
hour: (d, i) => {
18-
if(len <= 24 && d.getHours() == 0 || d.getHours() == 12) {
19-
return d.getHours() + ":00";
20-
}
2115

22-
if(i === 0 || i === len-1) {
16+
function xTickFormat(tickStep, n) {
17+
let formatters = {
18+
hour: (d, i) => {
19+
if(i === 0 || i === n-1) {
2320
return formatMonthDay(d);
2421
}
2522

23+
if(n <= 24 && d.getHours() === 0 || d.getHours() === 12) {
24+
return d.getHours() + ":00";
25+
}
26+
2627
return '';
2728
},
2829

29-
day: (d, i) => {
30-
if(i === 0 || i === len-1) {
31-
return formatMonthDay(d);
30+
day: (d, i, o) => {
31+
if( i === 0 || i === n-1) {
32+
return formatMonthDay(d);
3233
}
3334

3435
return '';
3536
},
3637
month: (d, i) => {
37-
if(len>24) {
38+
if(n>28) {
3839
return d.getFullYear();
3940
}
4041

4142
return d.getMonth() === 0 ? d.getFullYear() : formatMonth(d);
4243
}
4344
}
45+
46+
return formatters[tickStep];
47+
}
48+
49+
50+
const incrementers = {
51+
'hour': d => d.setHours(d.getHours() + 1),
52+
'day': d => d.setDate(d.getDate() + 1),
53+
'month': d => d.setMonth(d.getMonth() + 1)
54+
}
55+
56+
function incrementDate(date, incr) {
57+
return incrementers[incr](date);
4458
}
4559

4660
class Chart extends Component {
@@ -98,20 +112,7 @@ class Chart extends Component {
98112
};
99113

100114
nextDate = new Date(currentDate)
101-
102-
switch(this.state.tickStep) {
103-
case 'hour':
104-
nextDate.setHours(nextDate.getHours() + 1);
105-
break;
106-
107-
case 'day':
108-
nextDate.setDate(nextDate.getDate() + 1);
109-
break;
110-
111-
case 'month':
112-
nextDate.setMonth(nextDate.getMonth() + 1);
113-
break;
114-
}
115+
nextDate = incrementDate(nextDate, this.state.tickStep)
115116

116117
// grab data that falls between currentDate & nextDate
117118
for(let i=data.length-offset-1; i>=0; i--) {
@@ -163,21 +164,25 @@ class Chart extends Component {
163164

164165
// tooltip
165166
this.tip = d3.tip().attr('class', 'd3-tip').html((d) => {
166-
let title = d.Date.toLocaleDateString();
167+
let title;
167168

168169
if(this.state.tickStep === 'hour') {
169-
title += ` ${d.Date.getHours()}:00 - ${d.Date.getHours() + 1}:00`
170-
}
170+
title = `${d.Date.toLocaleDateString()} ${d.Date.getHours()}:00 - ${d.Date.getHours() + 1}:00`
171+
} else if(this.state.tickStep === 'day' ) {
172+
title = `${d.Date.toLocaleDateString()} (${d3.timeFormat("%a")(d.Date)})`
173+
} else {
174+
title = d3.timeFormat("%B %Y")(d.Date)
175+
}
171176

172177
return (`
173178
<div class="tip-heading">${title}</div>
174179
<div class="tip-content">
175180
<div class="tip-pageviews">
176-
<div class="tip-number">${d.Pageviews}</div>
181+
<div class="tip-number">${numbers.formatPretty(d.Pageviews)}</div>
177182
<div class="tip-metric">Pageviews</div>
178183
</div>
179184
<div class="tip-visitors">
180-
<div class="tip-number">${d.Visitors}</div>
185+
<div class="tip-number">${numbers.formatPretty(d.Visitors)}</div>
181186
<div class="tip-metric">Visitors</div>
182187
</div>
183188
</div>`
@@ -201,11 +206,13 @@ class Chart extends Component {
201206
let x = this.x.domain(data.map(d => d.Date))
202207
let y = this.y.domain([0, max*1.1])
203208
let yAxis = d3.axisLeft().scale(y).ticks(3).tickSize(-innerWidth).tickFormat(v => numbers.formatPretty(v))
204-
let xAxis = d3.axisBottom().scale(x).tickFormat(xTickFormat(data.length)[this.state.tickStep])
209+
let xAxis = d3.axisBottom().scale(x).tickFormat(xTickFormat(this.state.tickStep, data.length))
205210

206-
// only show first and last tick if we have more than 24 ticks to show
207-
if(data.length > 24) {
208-
xAxis.tickValues(data.map(d => d.Date).filter((d, i) => i === 0 || i === data.length-1))
211+
// only show first and last tick if we have more than 28 ticks to show
212+
if(data.length > 28) {
213+
let tickValues = data.map(d => d.Date).filter((d, i) => i === 0 || i === data.length-1);
214+
xAxis.tickValues(tickValues)
215+
xAxis.tickFormat(xTickFormat(this.state.tickStep, tickValues.length))
209216
}
210217

211218
// empty previous graph

assets/src/js/components/DatePicker.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,9 @@ class DatePicker extends Component {
220220
<li><Pikadayer value={this.dateValue(state.startDate)} onSelect={this.setStartDate} /> <span></span> <Pikadayer value={this.dateValue(state.endDate)} onSelect={this.setEndDate} /></li>
221221
</ul>
222222
<ul>
223-
{state.diff < 30 ? (<li class={classNames({ current: 'hour' === state.groupBy })}><a href="#" data-value="hour" onClick={this.setGroupBy}>Hourly</a></li>) : ''}
223+
{state.diff < 31 ? (<li class={classNames({ current: 'hour' === state.groupBy })}><a href="#" data-value="hour" onClick={this.setGroupBy}>Hourly</a></li>) : ''}
224224
<li class={classNames({ current: 'day' === state.groupBy })}><a href="#" data-value="day" onClick={this.setGroupBy}>Daily</a></li>
225-
{state.diff >= 30 ? (<li class={classNames({ current: 'month' === state.groupBy })}><a href="#" data-value="month" onClick={this.setGroupBy}>Monthly</a></li>) : ''}
225+
{state.diff >= 31 ? (<li class={classNames({ current: 'month' === state.groupBy })}><a href="#" data-value="month" onClick={this.setGroupBy}>Monthly</a></li>) : ''}
226226
</ul>
227227
</nav>
228228
)

assets/src/js/lib/numbers.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ function formatPretty(num) {
1111
if (num >= M) {
1212
num /= M
1313
decimals = 3 - ((Math.round(num) + "").length) || 0;
14-
return num.toFixed(decimals > -1 ? decimals : 0).replace(rx, '') + 'M';
14+
return (num.toFixed(decimals > -1 ? decimals : 0).replace(rx, '') + 'M').replace('.00', '');
1515
}
1616

1717
if (num >= (K * 10)) {

0 commit comments

Comments
 (0)