Time interval selector

This commit is contained in:
Gregory Eremin 2015-03-15 19:10:02 +07:00
parent 152940e7d8
commit 468b7e14ce
5 changed files with 102 additions and 42 deletions

View File

@ -90,17 +90,25 @@ var Menu = React.createClass({
var renderOrg = function(org) { var renderOrg = function(org) {
return ( return (
<li key={'org-'+ org.login} className="nav org"> <li key={'org-'+ org.login} className="nav org">
<Link to="org" params={{org: org.login}}>{org.login}</Link> <Link to="org"
params={{org: org.login}}
query={this.getQuery()}>
{org.login}
</Link>
</li> </li>
) )
}; }.bind(this);
var renderTeam = function(team) { var renderTeam = function(team) {
return ( return (
<li key={'team-'+ team.name} className="nav team"> <li key={'team-'+ team.name} className="nav team">
<Link to="team" params={{org: team.owner, team: team.name}}>{team.name}</Link> <Link to="team"
params={{org: team.owner, team: team.name}}
query={this.getQuery()}>
{team.name}
</Link>
</li> </li>
) )
}; }.bind(this);
return ( return (
<div className="menu"> <div className="menu">
<ul> <ul>
@ -210,6 +218,7 @@ var InfoBlock = React.createClass({
}); });
var WeekIntervalSelector = React.createClass({ var WeekIntervalSelector = React.createClass({
mixins: [ReactRouter.Navigation, ReactRouter.State],
monthNames: [ monthNames: [
'Jan', 'Feb', 'Mar', 'Jan', 'Feb', 'Mar',
'Apr', 'May', 'Jun', 'Apr', 'May', 'Jun',
@ -218,21 +227,6 @@ var WeekIntervalSelector = React.createClass({
], ],
getInitialState: function() { getInitialState: function() {
return {
from: 0,
to: 0
};
},
componentDidMount: function() {
// window.addEventListener('resize', this.resize);
},
showSelector: function() {
},
render: function() {
var ms = 1000, var ms = 1000,
daySeconds = 86400, daySeconds = 86400,
weekSeconds = daySeconds*7, weekSeconds = daySeconds*7,
@ -247,29 +241,81 @@ var WeekIntervalSelector = React.createClass({
weeks.push(i); weeks.push(i);
}; };
var renderWeek = function(week, i) { var from = (this.getQuery().f ? parseInt(this.getQuery().f, 10)*100 : lastWeek - 7*weekSeconds),
var d = new Date(week*ms), to = (this.getQuery().t ? parseInt(this.getQuery().t, 10)*100 : lastWeek);
month = this.monthNames[d.getMonth()],
season = this.seasons[d.getMonth()],
day = d.getDate();
return {
from: from,
to: to,
weeks: weeks
};
},
componentDidMount: function() {
this.updateLocation();
},
handleChange: function(thing, e) {
var patch = {};
patch[thing] = e.target.value;
this.setState(patch, this.updateLocation);
},
updateLocation: function() {
this.transitionTo(document.location.pathname, null, {
f: this.state.from/100,
t: this.state.to/100
});
},
formatDate: function(ts, showYear) {
var d = new Date(ts*1000),
day = d.getDate(),
month = this.monthNames[d.getMonth()],
year = (''+ d.getFullYear()).slice(2);
if (showYear) {
return month +' '+ day +" '"+ year;
} else {
return month +' '+ day;
}
},
render: function() {
var weeksBefore = _(this.state.weeks)
.filter(function(week) {
return week <= this.state.to;
}.bind(this))
.sort()
.reverse()
.value();
var weeksAfter = _(this.state.weeks)
.filter(function(week) {
return week >= this.state.from;
}.bind(this))
.sort()
.value();
var renderOption = function(ts) {
return ( return (
<div key={'week-'+ i} ref="blocks" className="week"> <option key={ts} value={ts}>{this.formatDate(ts, true)}</option>
<div key={''+ i +'-week'} className="square">{day}</div> );
<div key={''+ i +'-month'} className={'square '+ season}>{month}</div>
<div key={''+ i +'-day'} className="square">{day}</div>
</div>
)
}.bind(this); }.bind(this);
return ( return (
<div className="week-selector"> <div className="week-selector">
<div className="week"> <div ref="from" className="week">
Mar 9 <span ref="label" className="label">{this.formatDate(this.state.from)}</span>
<select ref="select" value={this.state.from} onChange={this.handleChange.bind(this, 'from')}>
{weeksBefore.map(renderOption)}
</select>
</div> </div>
&mdash; &mdash;
<div className="week"> <div ref="to" className="week">
Apr 27 <span ref="label" className="label">{this.formatDate(this.state.to)}</span>
<select ref="select" value={this.state.to} onChange={this.handleChange.bind(this, 'to')}>
{weeksAfter.map(renderOption)}
</select>
</div> </div>
</div> </div>
); );

View File

@ -57,7 +57,7 @@ var BarChart = React.createClass({
handleClick: function(point) { handleClick: function(point) {
var params = {org: this.getParams().org}; var params = {org: this.getParams().org};
params[this.state.item] = point.item; params[this.state.item] = point.item;
this.transitionTo(this.state.item, params); this.transitionTo(this.state.item, params, this.getQuery());
}, },
handleNewData: function() { handleNewData: function() {

View File

@ -2,6 +2,10 @@ var ChartDataMixin = {
apiParams: function() { apiParams: function() {
var params = _.clone(this.props.params); var params = _.clone(this.props.params);
params['item'] = this.state.item; params['item'] = this.state.item;
if (this.getQuery().f && this.getQuery().t) {
params['from'] = parseInt(this.getQuery().f, 10)*100;
params['to'] = parseInt(this.getQuery().t, 10)*100;
}
return params; return params;
}, },
@ -35,7 +39,7 @@ var ChartDataMixin = {
}, function() { }, function() {
$.get(this.props.api, this.apiParams(), function(res){ $.get(this.props.api, this.apiParams(), function(res){
this.setState({ this.setState({
rawData: res, rawData: res || [],
state: 'newData' state: 'newData'
}, this.handleNewData); }, this.handleNewData);
}.bind(this)); }.bind(this));

View File

@ -2,7 +2,7 @@ var StackedAreaChart = React.createClass({
mixins: [ReactRouter.Navigation, ReactRouter.State, SVGChartMixin, ChartDataMixin], mixins: [ReactRouter.Navigation, ReactRouter.State, SVGChartMixin, ChartDataMixin],
numElements: 10, numElements: 10,
maxWeeks: 20, maxWeeks: 30,
height: 350, height: 350,
getInitialState: function() { getInitialState: function() {

View File

@ -101,13 +101,23 @@
color: #666; color: #666;
} }
.week-selector .week { .week-selector .week {
position: relative;
display: inline-block; display: inline-block;
padding: 0 6px; padding: 0 6px;
margin: 0 3px; margin: 0 3px;
} }
.week-selector .week:hover {
background-color: #eaeaea; .week-selector .week select {
border-radius: 4px; position: absolute;
cursor: pointer; top: 30%;
color: #000; left: 0;
width: 100%;
visibility: hidden;
}
.week-selector .week:hover .label {
visibility: hidden;
}
.week-selector .week:hover select {
visibility: visible;
} }