diff options
author | Grégoire Aubert <gregoire.aubert@sonarsource.com> | 2017-06-22 11:22:24 +0200 |
---|---|---|
committer | Grégoire Aubert <gregoire.aubert@sonarsource.com> | 2017-07-04 14:15:34 +0200 |
commit | 35b4bc1e0319f991f9bb72c681c6be7f7991b478 (patch) | |
tree | 139e7f78caab331629e7a697c6d1dd046a35e241 /server/sonar-web/src/main/js/apps | |
parent | 7feb62d1317819a82df8dcbc71969d9c1d51bdc7 (diff) | |
download | sonarqube-35b4bc1e0319f991f9bb72c681c6be7f7991b478.tar.gz sonarqube-35b4bc1e0319f991f9bb72c681c6be7f7991b478.zip |
SONAR-9402 Add wheel zoom to the project history graphs
Diffstat (limited to 'server/sonar-web/src/main/js/apps')
5 files changed, 73 insertions, 54 deletions
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/GraphsZoom.js b/server/sonar-web/src/main/js/apps/projectActivity/components/GraphsZoom.js index 3dea9f1a188..73e9411b862 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/components/GraphsZoom.js +++ b/server/sonar-web/src/main/js/apps/projectActivity/components/GraphsZoom.js @@ -19,10 +19,9 @@ */ // @flow import React from 'react'; -import { some, throttle } from 'lodash'; +import { some } from 'lodash'; import { AutoSizer } from 'react-virtualized'; import ZoomTimeLine from '../../../components/charts/ZoomTimeLine'; -import type { RawQuery } from '../../../helpers/query'; import type { Serie } from '../../../components/charts/AdvancedTimeline'; type Props = { @@ -33,22 +32,14 @@ type Props = { metricsType: string, series: Array<Serie>, showAreas?: boolean, - updateGraphZoom: (from: ?Date, to: ?Date) => void, - updateQuery: RawQuery => void + updateGraphZoom: (from: ?Date, to: ?Date) => void }; export default class GraphsZoom extends React.PureComponent { props: Props; - constructor(props: Props) { - super(props); - this.updateDateRange = throttle(this.updateDateRange, 100); - } - hasHistoryData = () => some(this.props.series, serie => serie.data && serie.data.length > 2); - updateDateRange = (from: ?Date, to: ?Date) => this.props.updateQuery({ from, to }); - render() { const { loading } = this.props; if (loading || !this.hasHistoryData()) { @@ -70,8 +61,7 @@ export default class GraphsZoom extends React.PureComponent { series={this.props.series} showAreas={this.props.showAreas} startDate={this.props.graphStartDate} - updateZoom={this.updateDateRange} - updateZoomFast={this.props.updateGraphZoom} + updateZoom={this.props.updateGraphZoom} /> )} </AutoSizer> diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityGraphs.js b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityGraphs.js index db1eb841dac..004ef709197 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityGraphs.js +++ b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityGraphs.js @@ -19,6 +19,7 @@ */ // @flow import React from 'react'; +import { debounce, sortBy } from 'lodash'; import ProjectActivityGraphsHeader from './ProjectActivityGraphsHeader'; import GraphsZoom from './GraphsZoom'; import StaticGraphs from './StaticGraphs'; @@ -62,6 +63,7 @@ export default class ProjectActivityGraphs extends React.PureComponent { graphEndDate: props.query.to || null, series }; + this.updateQueryDateRange = debounce(this.updateQueryDateRange, 250); } componentWillReceiveProps(nextProps: Props) { @@ -100,8 +102,27 @@ export default class ProjectActivityGraphs extends React.PureComponent { }; }); - updateGraphZoom = (graphStartDate: ?Date, graphEndDate: ?Date) => + updateGraphZoom = (graphStartDate: ?Date, graphEndDate: ?Date) => { + if (graphEndDate != null && graphStartDate != null) { + const msDiff = Math.abs(graphEndDate.valueOf() - graphStartDate.valueOf()); + // 12 hours minimum between the two dates + if (msDiff < 1000 * 60 * 60 * 12) { + return; + } + } + this.setState({ graphStartDate, graphEndDate }); + this.updateQueryDateRange([graphStartDate, graphEndDate]); + }; + + updateQueryDateRange = (dates: Array<?Date>) => { + if (dates[0] == null || dates[1] == null) { + this.props.updateQuery({ from: dates[0], to: dates[1] }); + } else { + const sortedDates = sortBy(dates); + this.props.updateQuery({ from: sortedDates[0], to: sortedDates[1] }); + } + }; render() { const { leakPeriodDate, loading, metricsType, query } = this.props; @@ -120,6 +141,7 @@ export default class ProjectActivityGraphs extends React.PureComponent { project={this.props.project} series={series} showAreas={['coverage', 'duplications'].includes(query.graph)} + updateGraphZoom={this.updateGraphZoom} /> <GraphsZoom graphEndDate={this.state.graphEndDate} @@ -130,7 +152,6 @@ export default class ProjectActivityGraphs extends React.PureComponent { series={series} showAreas={['coverage', 'duplications'].includes(query.graph)} updateGraphZoom={this.updateGraphZoom} - updateQuery={this.props.updateQuery} /> </div> ); diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/StaticGraphs.js b/server/sonar-web/src/main/js/apps/projectActivity/components/StaticGraphs.js index e14f5f097fb..7428bdd3282 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/components/StaticGraphs.js +++ b/server/sonar-web/src/main/js/apps/projectActivity/components/StaticGraphs.js @@ -32,13 +32,14 @@ import type { Serie } from '../../../components/charts/AdvancedTimeline'; type Props = { analyses: Array<Analysis>, eventFilter: string, + graphEndDate: ?Date, graphStartDate: ?Date, leakPeriodDate: Date, loading: boolean, metricsType: string, series: Array<Serie>, showAreas?: boolean, - graphEndDate: ?Date + updateGraphZoom: (from: ?Date, to: ?Date) => void }; export default class StaticGraphs extends React.PureComponent { @@ -108,6 +109,7 @@ export default class StaticGraphs extends React.PureComponent { endDate={this.props.graphEndDate} events={this.getEvents()} height={height} + width={width} interpolate="linear" formatValue={this.formatValue} formatYTick={this.formatYTick} @@ -116,7 +118,7 @@ export default class StaticGraphs extends React.PureComponent { series={series} showAreas={this.props.showAreas} startDate={this.props.graphStartDate} - width={width} + updateZoom={this.props.updateGraphZoom} /> )} </AutoSizer> diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/ProjectActivityGraphs-test.js b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/ProjectActivityGraphs-test.js index 3434f552fae..2b27845d57c 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/ProjectActivityGraphs-test.js +++ b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/ProjectActivityGraphs-test.js @@ -80,7 +80,7 @@ it('should render correctly the graph and legends', () => { expect(shallow(<ProjectActivityGraphs {...DEFAULT_PROPS} />)).toMatchSnapshot(); }); -it('should render correctly filter history on dates', () => { +it('should render correctly with filter history on dates', () => { const wrapper = shallow( <ProjectActivityGraphs {...DEFAULT_PROPS} diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityGraphs-test.js.snap b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityGraphs-test.js.snap index 0fa696ab435..67899574868 100644 --- a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityGraphs-test.js.snap +++ b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityGraphs-test.js.snap @@ -1,39 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`should render correctly filter history on dates 1`] = ` -Object { - "filteredSeries": Array [ - Object { - "data": Array [], - "name": "code_smells", - "style": 1, - "translatedName": "metric.code_smells.name", - }, - ], - "series": Array [ - Object { - "data": Array [ - Object { - "x": 2016-10-26T10:17:29.000Z, - "y": 2286, - }, - Object { - "x": 2016-10-27T10:21:15.000Z, - "y": 1749, - }, - Object { - "x": 2016-10-27T14:33:50.000Z, - "y": 500, - }, - ], - "name": "code_smells", - "style": 1, - "translatedName": "metric.code_smells.name", - }, - ], -} -`; - exports[`should render correctly the graph and legends 1`] = ` <div className="project-activity-layout-page-main-inner boxed-group boxed-group-inner" @@ -80,7 +46,13 @@ exports[`should render correctly the graph and legends 1`] = ` ] } eventFilter="" - filteredSeries={ + graphEndDate={null} + graphStartDate={null} + leakPeriodDate="2017-05-16T13:50:02+0200" + loading={false} + metricsType="INT" + project="org.sonarsource.sonarqube:sonarqube" + series={ Array [ Object { "data": Array [ @@ -103,10 +75,15 @@ exports[`should render correctly the graph and legends 1`] = ` }, ] } + showAreas={false} + updateGraphZoom={[Function]} + /> + <GraphsZoom + graphEndDate={null} + graphStartDate={null} leakPeriodDate="2017-05-16T13:50:02+0200" loading={false} metricsType="INT" - project="org.sonarsource.sonarqube:sonarqube" series={ Array [ Object { @@ -131,6 +108,35 @@ exports[`should render correctly the graph and legends 1`] = ` ] } showAreas={false} + updateGraphZoom={[Function]} /> </div> `; + +exports[`should render correctly with filter history on dates 1`] = ` +Object { + "graphEndDate": null, + "graphStartDate": "2016-10-27T12:21:15+0200", + "series": Array [ + Object { + "data": Array [ + Object { + "x": 2016-10-26T10:17:29.000Z, + "y": 2286, + }, + Object { + "x": 2016-10-27T10:21:15.000Z, + "y": 1749, + }, + Object { + "x": 2016-10-27T14:33:50.000Z, + "y": 500, + }, + ], + "name": "code_smells", + "style": 1, + "translatedName": "metric.code_smells.name", + }, + ], +} +`; |