Time interval selector
This commit is contained in:
parent
152940e7d8
commit
468b7e14ce
|
@ -90,17 +90,25 @@ var Menu = React.createClass({
|
|||
var renderOrg = function(org) {
|
||||
return (
|
||||
<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>
|
||||
)
|
||||
};
|
||||
}.bind(this);
|
||||
var renderTeam = function(team) {
|
||||
return (
|
||||
<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>
|
||||
)
|
||||
};
|
||||
}.bind(this);
|
||||
return (
|
||||
<div className="menu">
|
||||
<ul>
|
||||
|
@ -210,6 +218,7 @@ var InfoBlock = React.createClass({
|
|||
});
|
||||
|
||||
var WeekIntervalSelector = React.createClass({
|
||||
mixins: [ReactRouter.Navigation, ReactRouter.State],
|
||||
monthNames: [
|
||||
'Jan', 'Feb', 'Mar',
|
||||
'Apr', 'May', 'Jun',
|
||||
|
@ -218,21 +227,6 @@ var WeekIntervalSelector = React.createClass({
|
|||
],
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
from: 0,
|
||||
to: 0
|
||||
};
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
// window.addEventListener('resize', this.resize);
|
||||
},
|
||||
|
||||
showSelector: function() {
|
||||
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var ms = 1000,
|
||||
daySeconds = 86400,
|
||||
weekSeconds = daySeconds*7,
|
||||
|
@ -247,29 +241,81 @@ var WeekIntervalSelector = React.createClass({
|
|||
weeks.push(i);
|
||||
};
|
||||
|
||||
var renderWeek = function(week, i) {
|
||||
var d = new Date(week*ms),
|
||||
month = this.monthNames[d.getMonth()],
|
||||
season = this.seasons[d.getMonth()],
|
||||
day = d.getDate();
|
||||
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 {
|
||||
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 (
|
||||
<div key={'week-'+ i} ref="blocks" className="week">
|
||||
<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>
|
||||
)
|
||||
<option key={ts} value={ts}>{this.formatDate(ts, true)}</option>
|
||||
);
|
||||
}.bind(this);
|
||||
|
||||
return (
|
||||
<div className="week-selector">
|
||||
<div className="week">
|
||||
Mar 9
|
||||
<div ref="from" className="week">
|
||||
<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 className="week">
|
||||
Apr 27
|
||||
<div ref="to" className="week">
|
||||
<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>
|
||||
);
|
||||
|
|
|
@ -57,7 +57,7 @@ var BarChart = React.createClass({
|
|||
handleClick: function(point) {
|
||||
var params = {org: this.getParams().org};
|
||||
params[this.state.item] = point.item;
|
||||
this.transitionTo(this.state.item, params);
|
||||
this.transitionTo(this.state.item, params, this.getQuery());
|
||||
},
|
||||
|
||||
handleNewData: function() {
|
||||
|
|
|
@ -2,6 +2,10 @@ var ChartDataMixin = {
|
|||
apiParams: function() {
|
||||
var params = _.clone(this.props.params);
|
||||
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;
|
||||
},
|
||||
|
||||
|
@ -35,7 +39,7 @@ var ChartDataMixin = {
|
|||
}, function() {
|
||||
$.get(this.props.api, this.apiParams(), function(res){
|
||||
this.setState({
|
||||
rawData: res,
|
||||
rawData: res || [],
|
||||
state: 'newData'
|
||||
}, this.handleNewData);
|
||||
}.bind(this));
|
||||
|
|
|
@ -2,7 +2,7 @@ var StackedAreaChart = React.createClass({
|
|||
mixins: [ReactRouter.Navigation, ReactRouter.State, SVGChartMixin, ChartDataMixin],
|
||||
|
||||
numElements: 10,
|
||||
maxWeeks: 20,
|
||||
maxWeeks: 30,
|
||||
height: 350,
|
||||
|
||||
getInitialState: function() {
|
||||
|
|
|
@ -101,13 +101,23 @@
|
|||
color: #666;
|
||||
}
|
||||
.week-selector .week {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
padding: 0 6px;
|
||||
margin: 0 3px;
|
||||
}
|
||||
.week-selector .week:hover {
|
||||
background-color: #eaeaea;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
color: #000;
|
||||
|
||||
.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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue