mirror of
https://github.com/apache/superset.git
synced 2026-05-12 11:25:56 +00:00
* Initial working prototype * Small fixes * Refactoring dekgl * Show all data when no time grain is selected * Refactor layers * Standardize function name * Fix exports * Fix require * Initial working prototype * Small fixes * Show all data when no time grain is selected * Moving play bar to correct location * Split component * Working on CSS * Remove control * Positioning the play slider * Fix refresh of slider state * Fix lint * Small fixes * Smoother animation for scans * Fix versions * Play/pause with spacebar. * Small fixes * Clean stuff that went to other PRs * Address issues * Refactor scatter animation
137 lines
3.8 KiB
JavaScript
137 lines
3.8 KiB
JavaScript
import React from 'react';
|
|
import PropTypes from 'prop-types';
|
|
import { Row, Col } from 'react-bootstrap';
|
|
|
|
import Mousetrap from 'mousetrap';
|
|
|
|
import 'bootstrap-slider/dist/css/bootstrap-slider.min.css';
|
|
import ReactBootstrapSlider from 'react-bootstrap-slider';
|
|
import './PlaySlider.css';
|
|
|
|
import { t } from '../javascripts/locales';
|
|
|
|
const propTypes = {
|
|
start: PropTypes.number.isRequired,
|
|
step: PropTypes.number.isRequired,
|
|
end: PropTypes.number.isRequired,
|
|
values: PropTypes.array.isRequired,
|
|
onChange: PropTypes.func,
|
|
loopDuration: PropTypes.number,
|
|
maxFrames: PropTypes.number,
|
|
orientation: PropTypes.oneOf(['horizontal', 'vertical']),
|
|
reversed: PropTypes.bool,
|
|
disabled: PropTypes.bool,
|
|
};
|
|
|
|
const defaultProps = {
|
|
onChange: () => {},
|
|
loopDuration: 15000,
|
|
maxFrames: 100,
|
|
orientation: 'horizontal',
|
|
reversed: false,
|
|
disabled: false,
|
|
};
|
|
|
|
export default class PlaySlider extends React.PureComponent {
|
|
constructor(props) {
|
|
super(props);
|
|
this.state = { intervalId: null };
|
|
|
|
const range = props.end - props.start;
|
|
const frames = Math.min(props.maxFrames, range / props.step);
|
|
const width = range / frames;
|
|
this.intervalMilliseconds = props.loopDuration / frames;
|
|
this.increment = width < props.step ? props.step : width - (width % props.step);
|
|
|
|
this.onChange = this.onChange.bind(this);
|
|
this.play = this.play.bind(this);
|
|
this.pause = this.pause.bind(this);
|
|
this.step = this.step.bind(this);
|
|
this.getPlayClass = this.getPlayClass.bind(this);
|
|
this.formatter = this.formatter.bind(this);
|
|
}
|
|
componentDidMount() {
|
|
Mousetrap.bind(['space'], this.play);
|
|
}
|
|
componentWillUnmount() {
|
|
Mousetrap.unbind(['space']);
|
|
}
|
|
onChange(event) {
|
|
this.props.onChange(event.target.value);
|
|
if (this.state.intervalId != null) {
|
|
this.pause();
|
|
}
|
|
}
|
|
getPlayClass() {
|
|
if (this.state.intervalId == null) {
|
|
return 'fa fa-play fa-lg slider-button';
|
|
}
|
|
return 'fa fa-pause fa-lg slider-button';
|
|
}
|
|
play() {
|
|
if (this.props.disabled) {
|
|
return;
|
|
}
|
|
if (this.state.intervalId != null) {
|
|
this.pause();
|
|
} else {
|
|
const id = setInterval(this.step, this.intervalMilliseconds);
|
|
this.setState({ intervalId: id });
|
|
}
|
|
}
|
|
pause() {
|
|
clearInterval(this.state.intervalId);
|
|
this.setState({ intervalId: null });
|
|
}
|
|
step() {
|
|
if (this.props.disabled) {
|
|
return;
|
|
}
|
|
let values = this.props.values.map(value => value + this.increment);
|
|
if (values[1] > this.props.end) {
|
|
const cr = values[0] - this.props.start;
|
|
values = values.map(value => value - cr);
|
|
}
|
|
this.props.onChange(values);
|
|
}
|
|
formatter(values) {
|
|
if (this.props.disabled) {
|
|
return t('Data has no time steps');
|
|
}
|
|
|
|
let parts = values;
|
|
if (!Array.isArray(values)) {
|
|
parts = [values];
|
|
} else if (values[0] === values[1]) {
|
|
parts = [values[0]];
|
|
}
|
|
return parts.map(value => (new Date(value)).toUTCString()).join(' : ');
|
|
}
|
|
render() {
|
|
return (
|
|
<Row className="play-slider">
|
|
<Col md={1} className="padded">
|
|
<i className={this.getPlayClass()} onClick={this.play} />
|
|
<i className="fa fa-step-forward fa-lg slider-button " onClick={this.step} />
|
|
</Col>
|
|
<Col md={11} className="padded">
|
|
<ReactBootstrapSlider
|
|
value={this.props.values}
|
|
formatter={this.formatter}
|
|
change={this.onChange}
|
|
min={this.props.start}
|
|
max={this.props.end}
|
|
step={this.props.step}
|
|
orientation={this.props.orientation}
|
|
reversed={this.props.reversed}
|
|
disabled={this.props.disabled ? 'disabled' : 'enabled'}
|
|
/>
|
|
</Col>
|
|
</Row>
|
|
);
|
|
}
|
|
}
|
|
|
|
PlaySlider.propTypes = propTypes;
|
|
PlaySlider.defaultProps = defaultProps;
|