From 208886757cf027a931ead00b578a1959f04604dc Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Fri, 27 Nov 2015 16:50:05 +0100 Subject: [PATCH] SONAR-7064 Replace treemap on the size overview page with histogram --- .../overview/components/ncloc-distribution.js | 84 +++++++++++++++++++ .../js/apps/overview/domains/size-domain.js | 4 +- server/sonar-web/src/main/js/helpers/path.js | 24 ++++++ 3 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 server/sonar-web/src/main/js/apps/overview/components/ncloc-distribution.js create mode 100644 server/sonar-web/src/main/js/helpers/path.js diff --git a/server/sonar-web/src/main/js/apps/overview/components/ncloc-distribution.js b/server/sonar-web/src/main/js/apps/overview/components/ncloc-distribution.js new file mode 100644 index 00000000000..ad03795df80 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/overview/components/ncloc-distribution.js @@ -0,0 +1,84 @@ +import _ from 'underscore'; +import React from 'react'; + +import { Histogram } from '../../../components/charts/histogram'; +import { formatMeasure } from '../../../helpers/measures'; +import { collapsePath } from '../../../helpers/path'; +import { getChildren } from '../../../api/components'; + + +const HEIGHT = 302; +const METRIC = 'ncloc'; + + +export const NclocDistribution = React.createClass({ + propTypes: { + component: React.PropTypes.object.isRequired + }, + + getInitialState() { + return { loading: true, files: [] }; + }, + + componentDidMount () { + this.requestComponents(); + }, + + requestComponents () { + let metrics = [METRIC]; + return getChildren(this.props.component.key, metrics).then(r => { + let components = r.map(component => { + let measures = {}; + (component.msr || []).forEach(measure => { + measures[measure.key] = measure.val; + }); + return _.extend(component, { measures }); + }); + this.setState({ loading: false, components }); + }); + }, + + renderLoading () { + return
+ +
; + }, + + renderBarChart () { + if (this.state.loading) { + return this.renderLoading(); + } + + let data = this.state.components.map((component, index) => { + return { + x: parseInt(component.measures[METRIC], 10), + y: index, + value: component.name + }; + }); + + data = _.sortBy(data, d => -d.x); + + let yTicks = data.map(d => collapsePath(d.value, 20)); + + let yValues = data.map(d => formatMeasure(d.x, 'SHORT_INT')); + + return ; + }, + + render () { + return
+
+

{window.t('overview.chart.components')}

+
+
+ {this.renderBarChart()} +
+
; + } +}); diff --git a/server/sonar-web/src/main/js/apps/overview/domains/size-domain.js b/server/sonar-web/src/main/js/apps/overview/domains/size-domain.js index a5e0f2e7fab..dcdab0821fd 100644 --- a/server/sonar-web/src/main/js/apps/overview/domains/size-domain.js +++ b/server/sonar-web/src/main/js/apps/overview/domains/size-domain.js @@ -2,10 +2,10 @@ import React from 'react'; import { LanguageDistribution } from './../components/language-distribution'; import { ComplexityDistribution } from './../components/complexity-distribution'; +import { NclocDistribution } from '../components/ncloc-distribution'; import { getMeasuresAndVariations } from '../../../api/measures'; import { DetailedMeasure } from '../components/detailed-measure'; import { DomainTimeline } from '../components/domain-timeline'; -import { DomainTreemap } from '../components/domain-treemap'; import { getPeriodLabel, getPeriodDate } from './../helpers/periods'; import { TooltipsMixin } from '../../../components/mixins/tooltips-mixin'; import { filterMetrics, filterMetricsForDomains } from '../helpers/metrics'; @@ -146,7 +146,7 @@ export const SizeMain = React.createClass({ allMetrics={this.getAllMetricsForTimeline()}/>
- +
; diff --git a/server/sonar-web/src/main/js/helpers/path.js b/server/sonar-web/src/main/js/helpers/path.js new file mode 100644 index 00000000000..ea389d48cb8 --- /dev/null +++ b/server/sonar-web/src/main/js/helpers/path.js @@ -0,0 +1,24 @@ +export function collapsePath (path, limit = 30) { + if (typeof path !== 'string') { + return ''; + } + + var tokens = path.split('/'); + + if (tokens.length <= 2) { + return path; + } + + var head = _.first(tokens), + tail = _.last(tokens), + middle = _.initial(_.rest(tokens)), + cut = false; + + while (middle.join().length > limit && middle.length > 0) { + middle.shift(); + cut = true; + } + + var body = [].concat(head, cut ? ['...'] : [], middle, tail); + return body.join('/'); +} -- 2.39.5