From 35b4bc1e0319f991f9bb72c681c6be7f7991b478 Mon Sep 17 00:00:00 2001 From: Grégoire Aubert Date: Thu, 22 Jun 2017 11:22:24 +0200 Subject: SONAR-9402 Add wheel zoom to the project history graphs --- .../apps/projectActivity/components/GraphsZoom.js | 16 +---- .../components/ProjectActivityGraphs.js | 25 ++++++- .../projectActivity/components/StaticGraphs.js | 6 +- .../__tests__/ProjectActivityGraphs-test.js | 2 +- .../ProjectActivityGraphs-test.js.snap | 78 ++++++++++++---------- 5 files changed, 73 insertions(+), 54 deletions(-) (limited to 'server/sonar-web/src/main/js/apps') 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, 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} /> )} 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) => { + 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} /> ); 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, eventFilter: string, + graphEndDate: ?Date, graphStartDate: ?Date, leakPeriodDate: Date, loading: boolean, metricsType: string, series: Array, 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} /> )} 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()).toMatchSnapshot(); }); -it('should render correctly filter history on dates', () => { +it('should render correctly with filter history on dates', () => { const wrapper = shallow( + `; + +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", + }, + ], +} +`; -- cgit v1.2.3