diff options
author | Grégoire Aubert <gregoire.aubert@sonarsource.com> | 2017-08-04 15:13:42 +0200 |
---|---|---|
committer | Grégoire Aubert <gregoire.aubert@sonarsource.com> | 2017-08-14 11:44:44 +0200 |
commit | 21cd227ec55a54d22edfddbb45ec011359bdba3e (patch) | |
tree | 6f5ce29210e56ed0de885bcbebc17c60744540c9 | |
parent | 0024569cab9918efb65fb83756c82373e48dfbd8 (diff) | |
download | sonarqube-21cd227ec55a54d22edfddbb45ec011359bdba3e.tar.gz sonarqube-21cd227ec55a54d22edfddbb45ec011359bdba3e.zip |
SONAR-9608 Move the secondary measure under the measure detail header
6 files changed, 184 insertions, 167 deletions
diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/MeasureHeader.js b/server/sonar-web/src/main/js/apps/component-measures/components/MeasureHeader.js index e27bfd396f3..b08974be9b6 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/components/MeasureHeader.js +++ b/server/sonar-web/src/main/js/apps/component-measures/components/MeasureHeader.js @@ -45,44 +45,46 @@ export default function MeasureHeader({ component, leakPeriod, measure, secondar const hasHistory = ['TRK', 'VW', 'SVW', 'APP'].includes(component.qualifier); return ( <div className="measure-details-header big-spacer-bottom"> - <div className="measure-details-metric"> - <IssueTypeIcon query={metric.key} className="little-spacer-right text-text-bottom" /> - {getLocalizedMetricName(metric)} - <span className="measure-details-value spacer-left"> - <strong> - {isDiff - ? <Measure className="domain-measures-leak" measure={measure} metric={metric} /> - : <Measure measure={measure} metric={metric} />} - </strong> - </span> - {!isDiff && - hasHistory && - <Tooltip placement="right" overlay={translate('component_measures.show_metric_history')}> - <Link - className="js-show-history spacer-left button button-small button-compact" - to={getComponentMeasureHistory(component.key, metric.key)}> - <HistoryIcon /> - </Link> - </Tooltip>} - {secondaryMeasure && - secondaryMeasure.metric.key === 'ncloc_language_distribution' && - <div className="measure-details-secondary"> - <LanguageDistribution distribution={secondaryMeasure.value} /> - </div>} - - {secondaryMeasure && - secondaryMeasure.metric.key === 'function_complexity_distribution' && - <div className="measure-details-secondary"> - <ComplexityDistribution distribution={secondaryMeasure.value} of="function" /> - </div>} - - {secondaryMeasure && - secondaryMeasure.metric.key === 'file_complexity_distribution' && - <div className="measure-details-secondary"> - <ComplexityDistribution distribution={secondaryMeasure.value} of="file" /> - </div>} + <div className="measure-details-primary"> + <div className="measure-details-metric"> + <IssueTypeIcon query={metric.key} className="little-spacer-right text-text-bottom" /> + {getLocalizedMetricName(metric)} + <span className="measure-details-value spacer-left"> + <strong> + {isDiff + ? <Measure className="domain-measures-leak" measure={measure} metric={metric} /> + : <Measure measure={measure} metric={metric} />} + </strong> + </span> + {!isDiff && + hasHistory && + <Tooltip + placement="right" + overlay={translate('component_measures.show_metric_history')}> + <Link + className="js-show-history spacer-left button button-small button-compact" + to={getComponentMeasureHistory(component.key, metric.key)}> + <HistoryIcon /> + </Link> + </Tooltip>} + </div> + {leakPeriod != null && <LeakPeriodLegend component={component} period={leakPeriod} />} </div> - {leakPeriod != null && <LeakPeriodLegend component={component} period={leakPeriod} />} + {secondaryMeasure && + secondaryMeasure.metric.key === 'ncloc_language_distribution' && + <div className="measure-details-secondary"> + <LanguageDistribution alignTicks={true} distribution={secondaryMeasure.value} /> + </div>} + {secondaryMeasure && + secondaryMeasure.metric.key === 'function_complexity_distribution' && + <div className="measure-details-secondary"> + <ComplexityDistribution distribution={secondaryMeasure.value} of="function" /> + </div>} + {secondaryMeasure && + secondaryMeasure.metric.key === 'file_complexity_distribution' && + <div className="measure-details-secondary"> + <ComplexityDistribution distribution={secondaryMeasure.value} of="file" /> + </div>} </div> ); } diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/__tests__/__snapshots__/MeasureHeader-test.js.snap b/server/sonar-web/src/main/js/apps/component-measures/components/__tests__/__snapshots__/MeasureHeader-test.js.snap index cd412e31862..775d3af72a4 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/components/__tests__/__snapshots__/MeasureHeader-test.js.snap +++ b/server/sonar-web/src/main/js/apps/component-measures/components/__tests__/__snapshots__/MeasureHeader-test.js.snap @@ -5,84 +5,88 @@ exports[`should render correctly 1`] = ` className="measure-details-header big-spacer-bottom" > <div - className="measure-details-metric" + className="measure-details-primary" > - <IssueTypeIcon - className="little-spacer-right text-text-bottom" - query="reliability_rating" - /> - Reliability Rating - <span - className="measure-details-value spacer-left" + <div + className="measure-details-metric" > - <strong> - <Measure - measure={ - Object { - "leak": "0.0", - "metric": Object { + <IssueTypeIcon + className="little-spacer-right text-text-bottom" + query="reliability_rating" + /> + Reliability Rating + <span + className="measure-details-value spacer-left" + > + <strong> + <Measure + measure={ + Object { + "leak": "0.0", + "metric": Object { + "key": "reliability_rating", + "name": "Reliability Rating", + "type": "RATING", + }, + "periods": Array [ + Object { + "index": 1, + "value": "0.0", + }, + ], + "value": "3.0", + } + } + metric={ + Object { "key": "reliability_rating", "name": "Reliability Rating", "type": "RATING", - }, - "periods": Array [ - Object { - "index": 1, - "value": "0.0", - }, - ], - "value": "3.0", + } } - } - metric={ + /> + </strong> + </span> + <Tooltip + overlay="component_measures.show_metric_history" + placement="right" + > + <Link + className="js-show-history spacer-left button button-small button-compact" + onlyActiveOnIndex={false} + style={Object {}} + to={ Object { - "key": "reliability_rating", - "name": "Reliability Rating", - "type": "RATING", + "pathname": "/project/activity", + "query": Object { + "custom_metrics": "reliability_rating", + "graph": "custom", + "id": "foo", + }, } } - /> - </strong> - </span> - <Tooltip - overlay="component_measures.show_metric_history" - placement="right" - > - <Link - className="js-show-history spacer-left button button-small button-compact" - onlyActiveOnIndex={false} - style={Object {}} - to={ - Object { - "pathname": "/project/activity", - "query": Object { - "custom_metrics": "reliability_rating", - "graph": "custom", - "id": "foo", - }, - } + > + <IconHistory /> + </Link> + </Tooltip> + </div> + <LeakPeriodLegend + component={ + Object { + "key": "foo", + "qualifier": "TRK", } - > - <IconHistory /> - </Link> - </Tooltip> - </div> - <LeakPeriodLegend - component={ - Object { - "key": "foo", - "qualifier": "TRK", } - } - period={ - Object { - "date": "2017-05-16T13:50:02+0200", - "index": 1, - "mode": "previous_version", - "parameter": "6,4", + period={ + Object { + "date": "2017-05-16T13:50:02+0200", + "index": 1, + "mode": "previous_version", + "parameter": "6,4", + } } - } - /> + /> + </div> </div> `; @@ -91,61 +95,65 @@ exports[`should render correctly for leak 1`] = ` className="measure-details-header big-spacer-bottom" > <div - className="measure-details-metric" + className="measure-details-primary" > - <IssueTypeIcon - className="little-spacer-right text-text-bottom" - query="new_reliability_rating" - /> - Reliability Rating on New Code - <span - className="measure-details-value spacer-left" + <div + className="measure-details-metric" > - <strong> - <Measure - className="domain-measures-leak" - measure={ - Object { - "leak": "3.0", - "metric": Object { + <IssueTypeIcon + className="little-spacer-right text-text-bottom" + query="new_reliability_rating" + /> + Reliability Rating on New Code + <span + className="measure-details-value spacer-left" + > + <strong> + <Measure + className="domain-measures-leak" + measure={ + Object { + "leak": "3.0", + "metric": Object { + "key": "new_reliability_rating", + "name": "Reliability Rating on New Code", + "type": "RATING", + }, + "periods": Array [ + Object { + "index": 1, + "value": "3.0", + }, + ], + } + } + metric={ + Object { "key": "new_reliability_rating", "name": "Reliability Rating on New Code", "type": "RATING", - }, - "periods": Array [ - Object { - "index": 1, - "value": "3.0", - }, - ], - } - } - metric={ - Object { - "key": "new_reliability_rating", - "name": "Reliability Rating on New Code", - "type": "RATING", + } } - } - /> - </strong> - </span> - </div> - <LeakPeriodLegend - component={ - Object { - "key": "foo", - "qualifier": "TRK", + /> + </strong> + </span> + </div> + <LeakPeriodLegend + component={ + Object { + "key": "foo", + "qualifier": "TRK", + } } - } - period={ - Object { - "date": "2017-05-16T13:50:02+0200", - "index": 1, - "mode": "previous_version", - "parameter": "6,4", + period={ + Object { + "date": "2017-05-16T13:50:02+0200", + "index": 1, + "mode": "previous_version", + "parameter": "6,4", + } } - } - /> + /> + </div> </div> `; diff --git a/server/sonar-web/src/main/js/apps/component-measures/style.css b/server/sonar-web/src/main/js/apps/component-measures/style.css index 72834db9921..0f9c831dfb7 100644 --- a/server/sonar-web/src/main/js/apps/component-measures/style.css +++ b/server/sonar-web/src/main/js/apps/component-measures/style.css @@ -35,26 +35,22 @@ vertical-align: text-bottom; } -.measure-details-header { +.measure-details-metric { display: flex; - flex-wrap: nowrap; - justify-content: space-between; align-items: center; } -.measure-details-metric { +.measure-details-primary { display: flex; + flex-wrap: nowrap; + justify-content: space-between; align-items: center; } .measure-details-secondary { display: inline-block; width: 260px; - margin-left: 4px; -} - -.measure-details-secondary .bar-chart { - margin-top: -10px; + margin-top: 4px; } .measure-details-component-cell { diff --git a/server/sonar-web/src/main/js/components/charts/LanguageDistribution.js b/server/sonar-web/src/main/js/components/charts/LanguageDistribution.js index 696ad6c6e24..60901a97d98 100644 --- a/server/sonar-web/src/main/js/components/charts/LanguageDistribution.js +++ b/server/sonar-web/src/main/js/components/charts/LanguageDistribution.js @@ -27,6 +27,7 @@ import { translate } from '../../helpers/l10n'; export default class LanguageDistribution extends React.PureComponent { static propTypes = { + alignTicks: PropTypes.bool, distribution: PropTypes.string.isRequired }; @@ -75,6 +76,7 @@ export default class LanguageDistribution extends React.PureComponent { return ( <Histogram + alignTicks={this.props.alignTicks} data={data} yTicks={yTicks} yValues={yValues} diff --git a/server/sonar-web/src/main/js/components/charts/histogram.js b/server/sonar-web/src/main/js/components/charts/histogram.js index b6fdeb7b6c5..ddf8726181e 100644 --- a/server/sonar-web/src/main/js/components/charts/histogram.js +++ b/server/sonar-web/src/main/js/components/charts/histogram.js @@ -29,6 +29,7 @@ export const Histogram = createReactClass({ displayName: 'Histogram', propTypes: { + alignTicks: PropTypes.bool, data: PropTypes.arrayOf(PropTypes.object).isRequired, yTicks: PropTypes.arrayOf(PropTypes.any), yValues: PropTypes.arrayOf(PropTypes.any), @@ -68,17 +69,18 @@ export const Histogram = createReactClass({ const y = Math.round(yScale(point.y) + yScale.bandwidth() / 2 + this.props.barsHeight / 2); const label = tick.label ? tick.label : tick; const tooltip = tick.tooltip ? tick.tooltip : null; + const historyTickClass = this.props.alignTicks ? 'histogram-tick-start' : 'histogram-tick'; return ( <text key={index} - className="bar-chart-tick histogram-tick" + className={'bar-chart-tick ' + historyTickClass} onClick={this.props.onBarClick && this.handleClick.bind(this, point)} style={{ cursor: this.props.onBarClick ? 'pointer' : 'default' }} data-title={tooltip} data-toggle={tooltip ? 'tooltip' : null} x={x} y={y} - dx="-1em" + dx={this.props.alignTicks ? 0 : '-1em'} dy="0.3em"> {label} </text> @@ -97,7 +99,7 @@ export const Histogram = createReactClass({ } const ticks = this.props.yValues.map((value, index) => { const point = this.props.data[index]; - const x = xScale(point.x); + const x = xScale(point.x) + (this.props.alignTicks ? this.props.padding[3] : 0); const y = Math.round(yScale(point.y) + yScale.bandwidth() / 2 + this.props.barsHeight / 2); return ( <text @@ -122,7 +124,8 @@ export const Histogram = createReactClass({ renderBars(xScale, yScale) { const bars = this.props.data.map((d, index) => { - const x = Math.round(xScale(d.x)) + /* minimum bar width */ 1; + const width = Math.round(xScale(d.x)) + /* minimum bar width */ 1; + const x = xScale.range()[0] + (this.props.alignTicks ? this.props.padding[3] : 0); const y = Math.round(yScale(d.y) + yScale.bandwidth() / 2); return ( <rect @@ -130,9 +133,9 @@ export const Histogram = createReactClass({ className="bar-chart-bar" onClick={this.props.onBarClick && this.handleClick.bind(this, d)} style={{ cursor: this.props.onBarClick ? 'pointer' : 'default' }} - x={0} + x={x} y={y} - width={x} + width={width} height={this.props.barsHeight} /> ); @@ -160,7 +163,9 @@ export const Histogram = createReactClass({ return ( <svg className="bar-chart" width={this.state.width} height={this.state.height}> - <g transform={`translate(${this.props.padding[3]}, ${this.props.padding[0]})`}> + <g + transform={`translate(${this.props.alignTicks ? 4 : this.props.padding[3]}, ${this.props + .padding[0]})`}> {this.renderTicks(xScale, yScale)} {this.renderValues(xScale, yScale)} {this.renderBars(xScale, yScale)} diff --git a/server/sonar-web/src/main/less/components/graphics.less b/server/sonar-web/src/main/less/components/graphics.less index 32648b5b3ff..47b0390b2f0 100644 --- a/server/sonar-web/src/main/less/components/graphics.less +++ b/server/sonar-web/src/main/less/components/graphics.less @@ -283,6 +283,10 @@ text-anchor: end; } +.histogram-tick-start { + text-anchor: start; +} + .histogram-value { text-anchor: start; } |