Построение нескольких временных рядов со связанными осями X - PullRequest
0 голосов
/ 21 декабря 2018

Возможно ли реализовать несколько стековых диаграмм, которые связаны осями X в Победе?Я строю несколько наборов временных рядов и хотел бы иметь возможность прокручивать и масштабировать их одновременно.

Вот пример GIF того, что я пытаюсь выполнить , используя реакцию-timeseries-charts library.

С точки зрения фактической реализации этого с помощью Victory, я попытался изменить пример кода в документации Victory , чтобы передать this.state.zoomedXDomain в VictoryZoomContainer каждого графикакак опора zoomDomain, но это вызывает неожиданное поведение - когда один график увеличивается, область данных другого сужается (правильно), но данные не растягиваются, чтобы заполнить график ( вот GIF этогопроисходит ).

Вот модифицированный пример кода (единственной измененной частью был метод рендеринга: я просто установил zoomDomain опору VictoryZoomContainer со значением zoomedXDomain, сохраненным в состоянии компонента):

const allData = _.range(0, 10, 0.001).map(x => ({
    x: x,
    y: Math.sin(Math.PI*x/2) * x / 10
}));

class CustomChart extends React.Component {
    constructor(props) {
        super();
        this.entireDomain = this.getEntireDomain(props);
        this.state = {
            zoomedXDomain: this.entireDomain.x,
        };
    }
    onDomainChange(domain) {
        this.setState({
            zoomedXDomain: domain.x,
        });
    }
    getData() {
        const { zoomedXDomain } = this.state;
        const { data, maxPoints } = this.props;
        const filtered = data.filter(
            (d) => (d.x >= zoomedXDomain[0] && d.x <= zoomedXDomain[1]));

        if (filtered.length > maxPoints ) {
            const k = Math.ceil(filtered.length / maxPoints);
            return filtered.filter(
                (d, i) => ((i % k) === 0)
            );
        }
        return filtered;
    }
    getEntireDomain(props) {
        const { data } = props;
        return {
            y: [_.minBy(data, d => d.y).y, _.maxBy(data, d => d.y).y],
            x: [ data[0].x, _.last(data).x ]
        };
    }
    getZoomFactor() {
        const { zoomedXDomain } = this.state;
        const factor = 10 / (zoomedXDomain[1] - zoomedXDomain[0]);
        return _.round(factor, factor < 3 ? 1 : 0);
    }
    render() {
        const renderedData = this.getData();
        return (
            <div>

                <VictoryChart
                    domain={this.entireDomain}
                    containerComponent={<VictoryZoomContainer
                        zoomDimension="x"
                        zoomDomain={this.state.zoomedXDomain}
                        onZoomDomainChange={this.onDomainChange.bind(this)}
                        minimumZoom={{x: 1/10000}}
                    />}
                >
                    <VictoryScatter data={renderedData} />
                </VictoryChart>

                <VictoryChart
                    domain={this.entireDomain}
                    containerComponent={<VictoryZoomContainer
                        zoomDimension="x"
                        zoomDomain={this.state.zoomedXDomain}
                        onZoomDomainChange={this.onDomainChange.bind(this)}
                        minimumZoom={{x: 1/10000}}
                    />}
                >
                    <VictoryScatter data={renderedData} />
                </VictoryChart>

                <div>
                    {this.getZoomFactor()}x zoom;
                    rendering {renderedData.length} of {this.props.data.length}
                </div>
            </div>
        );
    }
}

ReactDOM.render(<CustomChart data={allData} maxPoints={120} />, mountNode);
...