Week selector in place
This commit is contained in:
parent
0d8298d2c7
commit
05ebd2e417
|
@ -240,31 +240,15 @@ var WeekIntervalSelector = React.createClass({
|
||||||
weeks.push(i);
|
weeks.push(i);
|
||||||
};
|
};
|
||||||
|
|
||||||
var from = (this.getQuery().f ? parseInt(this.getQuery().f, 10)*100 : lastWeek - 7*weekSeconds),
|
|
||||||
to = (this.getQuery().t ? parseInt(this.getQuery().t, 10)*100 : lastWeek);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
from: from,
|
weeks: weeks.sort()
|
||||||
to: to,
|
|
||||||
weeks: weeks
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
componentDidMount: function() {
|
|
||||||
this.updateLocation();
|
|
||||||
},
|
|
||||||
|
|
||||||
handleChange: function(thing, e) {
|
handleChange: function(thing, e) {
|
||||||
var patch = {};
|
var params = this.getQuery();
|
||||||
patch[thing] = e.target.value;
|
params[thing.slice(0, 1)] = e.target.value/100;
|
||||||
this.setState(patch, this.updateLocation);
|
this.transitionTo(document.location.pathname, null, params);
|
||||||
},
|
|
||||||
|
|
||||||
updateLocation: function() {
|
|
||||||
this.transitionTo(document.location.pathname, null, {
|
|
||||||
f: this.state.from/100,
|
|
||||||
t: this.state.to/100
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
formatDate: function(ts, showYear) {
|
formatDate: function(ts, showYear) {
|
||||||
|
@ -281,18 +265,23 @@ var WeekIntervalSelector = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
|
var daySeconds = 86400,
|
||||||
|
weekSeconds = daySeconds*7,
|
||||||
|
lastWeek = this.state.weeks[this.state.weeks.length-1],
|
||||||
|
from = (this.getQuery().f ? parseInt(this.getQuery().f, 10)*100 : lastWeek - 7*weekSeconds),
|
||||||
|
to = (this.getQuery().t ? parseInt(this.getQuery().t, 10)*100 : lastWeek);
|
||||||
|
|
||||||
var weeksBefore = _(this.state.weeks)
|
var weeksBefore = _(this.state.weeks)
|
||||||
.filter(function(week) {
|
.filter(function(week) {
|
||||||
return week <= this.state.to;
|
return week <= to;
|
||||||
}.bind(this))
|
})
|
||||||
.sort()
|
|
||||||
.reverse()
|
.reverse()
|
||||||
.value();
|
.value();
|
||||||
var weeksAfter = _(this.state.weeks)
|
var weeksAfter = _(this.state.weeks)
|
||||||
.filter(function(week) {
|
.filter(function(week) {
|
||||||
return week >= this.state.from;
|
return week >= from;
|
||||||
}.bind(this))
|
})
|
||||||
.sort()
|
.reverse()
|
||||||
.value();
|
.value();
|
||||||
|
|
||||||
var renderOption = function(ts) {
|
var renderOption = function(ts) {
|
||||||
|
@ -303,16 +292,17 @@ var WeekIntervalSelector = React.createClass({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="week-selector">
|
<div className="week-selector">
|
||||||
<div ref="from" className="week">
|
<span>from</span>
|
||||||
<span ref="label" className="label">{this.formatDate(this.state.from)}</span>
|
<div ref="from" className="selector">
|
||||||
<select ref="select" value={this.state.from} onChange={this.handleChange.bind(this, 'from')}>
|
<em ref="label">{this.formatDate(from)}</em>
|
||||||
|
<select ref="select" value={from} onChange={this.handleChange.bind(this, 'from')}>
|
||||||
{weeksBefore.map(renderOption)}
|
{weeksBefore.map(renderOption)}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
—
|
<span>to</span>
|
||||||
<div ref="to" className="week">
|
<div ref="to" className="selector">
|
||||||
<span ref="label" className="label">{this.formatDate(this.state.to)}</span>
|
<em ref="label">{this.formatDate(to)}</em>
|
||||||
<select ref="select" value={this.state.to} onChange={this.handleChange.bind(this, 'to')}>
|
<select ref="select" value={to} onChange={this.handleChange.bind(this, 'to')}>
|
||||||
{weeksAfter.map(renderOption)}
|
{weeksAfter.map(renderOption)}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -120,7 +120,7 @@ var BarChart = React.createClass({
|
||||||
return (
|
return (
|
||||||
<div className="barchart-container">
|
<div className="barchart-container">
|
||||||
<div className="whatsgoingon">
|
<div className="whatsgoingon">
|
||||||
This bar chart represents <em>{words.items[this.state.item]}</em> {words.actions[this.state.item]} <em>{who}</em> {words.item[subject]} from <em className="date">Mar 9</em> to <em className="date">Apr 27</em>
|
This bar chart represents <em>{words.items[this.state.item]}</em> {words.actions[this.state.item]} <em>{who}</em> {words.item[subject]} <WeekIntervalSelector />
|
||||||
</div>
|
</div>
|
||||||
<div className="filters">
|
<div className="filters">
|
||||||
<Selector thing="sort"
|
<Selector thing="sort"
|
||||||
|
|
|
@ -196,7 +196,7 @@ var StackedAreaChart = React.createClass({
|
||||||
return (
|
return (
|
||||||
<div className="sachart-container">
|
<div className="sachart-container">
|
||||||
<div className="whatsgoingon">
|
<div className="whatsgoingon">
|
||||||
This stacked area chart represents <em>{words.items[this.state.item]}</em> {words.actions[this.state.item]} <em>{who}</em> {words.item[subject]} from <em className="date">Mar 9</em> to <em className="date">Apr 27</em>
|
This stacked area chart represents <em>{words.items[this.state.item]}</em> {words.actions[this.state.item]} <em>{who}</em> {words.item[subject]} <WeekIntervalSelector />
|
||||||
</div>
|
</div>
|
||||||
<div className="filters">
|
<div className="filters">
|
||||||
<Selector thing="sort"
|
<Selector thing="sort"
|
||||||
|
|
|
@ -41,33 +41,3 @@
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
.week-selector {
|
|
||||||
position: absolute;
|
|
||||||
top: 20px;
|
|
||||||
right: 20px;
|
|
||||||
font-size: 30px;
|
|
||||||
line-height: 40px;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
.week-selector .week {
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
padding: 0 6px;
|
|
||||||
margin: 0 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.week-selector .week select {
|
|
||||||
position: absolute;
|
|
||||||
top: 30%;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.week-selector .week:hover .label {
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
.week-selector .week:hover select {
|
|
||||||
visibility: visible;
|
|
||||||
}
|
|
||||||
|
|
|
@ -103,10 +103,13 @@
|
||||||
background-color: #f0f0f0;
|
background-color: #f0f0f0;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
.whatsgoingon em.date {
|
|
||||||
|
|
||||||
|
|
||||||
|
.week-selector em {
|
||||||
background-color: #d0f0f0;
|
background-color: #d0f0f0;
|
||||||
}
|
}
|
||||||
.whatsgoingon em.date:before {
|
.week-selector em:before {
|
||||||
content: '';
|
content: '';
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin: 0 3px -1px 0;
|
margin: 0 3px -1px 0;
|
||||||
|
@ -116,3 +119,33 @@
|
||||||
/* Source: https://github.com/github/octicons/blob/master/svg/calendar.svg */
|
/* Source: https://github.com/github/octicons/blob/master/svg/calendar.svg */
|
||||||
background-image: url("data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEwMjQiIHdpZHRoPSIxMDI0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxwYXRoIGQ9Ik03MDQgNTEyaC02NHYxMjhoNjRWNTEyek01NzYgNTEyaC02NHYxMjhoNjRWNTEyek03MDQgMzIwaC02NHYxMjhoNjRWMzIwek04MzIgNTEyaC02NHYxMjhoNjRWNTEyek01NzYgNzA0aC02NHYxMjhoNjRWNzA0ek03NjggMGgtNjR2MTI4aDY0VjB6TTI1NiAwaC02NHYxMjhoNjRWMHpNODMyIDMyMGgtNjR2MTI4aDY0VjMyMHpNNTc2IDMyMGgtNjR2MTI4aDY0VjMyMHpNMzIwIDcwNGgtNjR2MTI4aDY0VjcwNHpNMTkyIDUxMmgtNjR2MTI4aDY0VjUxMnpNMzIwIDUxMmgtNjR2MTI4aDY0VjUxMnpNODMyIDY0djEyOEg2NDBWNjRIMzIwdjEyOEgxMjhWNjRIMHY4OTZoOTYwVjY0SDgzMnpNODk2IDg5Nkg2NFYyNTZoODMyVjg5NnpNMTkyIDcwNGgtNjR2MTI4aDY0VjcwNHpNNDQ4IDMyMGgtNjR2MTI4aDY0VjMyMHpNNDQ4IDcwNGgtNjR2MTI4aDY0VjcwNHpNMzIwIDMyMGgtNjR2MTI4aDY0VjMyMHpNNDQ4IDUxMmgtNjR2MTI4aDY0VjUxMnpNNzA0IDcwNGgtNjR2MTI4aDY0VjcwNHoiIC8+Cjwvc3ZnPg==");
|
background-image: url("data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEwMjQiIHdpZHRoPSIxMDI0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxwYXRoIGQ9Ik03MDQgNTEyaC02NHYxMjhoNjRWNTEyek01NzYgNTEyaC02NHYxMjhoNjRWNTEyek03MDQgMzIwaC02NHYxMjhoNjRWMzIwek04MzIgNTEyaC02NHYxMjhoNjRWNTEyek01NzYgNzA0aC02NHYxMjhoNjRWNzA0ek03NjggMGgtNjR2MTI4aDY0VjB6TTI1NiAwaC02NHYxMjhoNjRWMHpNODMyIDMyMGgtNjR2MTI4aDY0VjMyMHpNNTc2IDMyMGgtNjR2MTI4aDY0VjMyMHpNMzIwIDcwNGgtNjR2MTI4aDY0VjcwNHpNMTkyIDUxMmgtNjR2MTI4aDY0VjUxMnpNMzIwIDUxMmgtNjR2MTI4aDY0VjUxMnpNODMyIDY0djEyOEg2NDBWNjRIMzIwdjEyOEgxMjhWNjRIMHY4OTZoOTYwVjY0SDgzMnpNODk2IDg5Nkg2NFYyNTZoODMyVjg5NnpNMTkyIDcwNGgtNjR2MTI4aDY0VjcwNHpNNDQ4IDMyMGgtNjR2MTI4aDY0VjMyMHpNNDQ4IDcwNGgtNjR2MTI4aDY0VjcwNHpNMzIwIDMyMGgtNjR2MTI4aDY0VjMyMHpNNDQ4IDUxMmgtNjR2MTI4aDY0VjUxMnpNNzA0IDcwNGgtNjR2MTI4aDY0VjcwNHoiIC8+Cjwvc3ZnPg==");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.week-selector {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.week-selector .selector {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0 6px;
|
||||||
|
width: 110px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.week-selector .selector em {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.week-selector .selector select {
|
||||||
|
position: absolute;
|
||||||
|
top: 5px;
|
||||||
|
left: 5%;
|
||||||
|
width: 90%;
|
||||||
|
margin: 0;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.week-selector .selector:hover em {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
.week-selector .selector:hover select {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue