Browse Source

SONAR-15515 Fix Language Distribution UI

tags/9.2.0.49834
guillaume-peoch-sonarsource 2 years ago
parent
commit
02f96eb6af

+ 2
- 6
server/sonar-web/src/main/js/apps/component-measures/components/MeasureHeader.tsx View File

*/ */
import * as React from 'react'; import * as React from 'react';
import { Link } from 'react-router'; import { Link } from 'react-router';
import LanguageDistributionContainer from '../../../components/charts/LanguageDistributionContainer';
import LanguageDistribution from '../../../components/charts/LanguageDistribution';
import Tooltip from '../../../components/controls/Tooltip'; import Tooltip from '../../../components/controls/Tooltip';
import HistoryIcon from '../../../components/icons/HistoryIcon'; import HistoryIcon from '../../../components/icons/HistoryIcon';
import IssueTypeIcon from '../../../components/icons/IssueTypeIcon'; import IssueTypeIcon from '../../../components/icons/IssueTypeIcon';
secondaryMeasure.metric === 'ncloc_language_distribution' && secondaryMeasure.metric === 'ncloc_language_distribution' &&
secondaryMeasure.value !== undefined && ( secondaryMeasure.value !== undefined && (
<div className="measure-details-secondary"> <div className="measure-details-secondary">
<LanguageDistributionContainer
alignTicks={true}
distribution={secondaryMeasure.value}
width={260}
/>
<LanguageDistribution distribution={secondaryMeasure.value} />
</div> </div>
)} )}
</div> </div>

+ 3
- 3
server/sonar-web/src/main/js/components/charts/Histogram.css View File

* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
.histogram-tick { .histogram-tick {
text-anchor: end;
text-anchor: end !important;
} }


.histogram-tick-start { .histogram-tick-start {
text-anchor: start;
text-anchor: start !important;
} }


.histogram-value { .histogram-value {
text-anchor: start;
text-anchor: start !important;
} }

+ 18
- 8
server/sonar-web/src/main/js/components/charts/LanguageDistribution.tsx View File

*/ */
import { sortBy } from 'lodash'; import { sortBy } from 'lodash';
import * as React from 'react'; import * as React from 'react';
import { connect } from 'react-redux';
import Histogram from '../../components/charts/Histogram'; import Histogram from '../../components/charts/Histogram';
import { translate } from '../../helpers/l10n'; import { translate } from '../../helpers/l10n';
import { formatMeasure } from '../../helpers/measures'; import { formatMeasure } from '../../helpers/measures';
import { getLanguages, Store } from '../../store/rootReducer';
import { MetricType } from '../../types/metrics';


interface Props {
alignTicks?: boolean;
interface LanguageDistributionProps {
distribution: string; distribution: string;
languages: T.Languages; languages: T.Languages;
width: number;
} }


export default function LanguageDistribution(props: Props) {
const NUMBER_FORMAT_THRESHOLD = 1000;

export function LanguageDistribution(props: LanguageDistributionProps) {
let distribution = props.distribution.split(';').map(point => { let distribution = props.distribution.split(';').map(point => {
const tokens = point.split('='); const tokens = point.split('=');
return { language: tokens[0], lines: parseInt(tokens[1], 10) }; return { language: tokens[0], lines: parseInt(tokens[1], 10) };


const data = distribution.map(d => d.lines); const data = distribution.map(d => d.lines);
const yTicks = distribution.map(d => getLanguageName(d.language)).map(cutLanguageName); const yTicks = distribution.map(d => getLanguageName(d.language)).map(cutLanguageName);
const yTooltips = distribution.map(d => (d.lines > 1000 ? formatMeasure(d.lines, 'INT') : ''));
const yValues = distribution.map(d => formatMeasure(d.lines, 'SHORT_INT'));
const yTooltips = distribution.map(d =>
d.lines > NUMBER_FORMAT_THRESHOLD ? formatMeasure(d.lines, MetricType.Integer) : ''
);
const yValues = distribution.map(d => formatMeasure(d.lines, MetricType.ShortInteger));


return ( return (
<Histogram <Histogram
alignTicks={props.alignTicks}
bars={data} bars={data}
height={distribution.length * 25} height={distribution.length * 25}
padding={[0, 60, 0, 80]} padding={[0, 60, 0, 80]}
width={props.width}
width={260}
yTicks={yTicks} yTicks={yTicks}
yTooltips={yTooltips} yTooltips={yTooltips}
yValues={yValues} yValues={yValues}
function cutLanguageName(name: string) { function cutLanguageName(name: string) {
return name.length > 10 ? `${name.substr(0, 7)}...` : name; return name.length > 10 ? `${name.substr(0, 7)}...` : name;
} }

const mapStateToProps = (state: Store) => ({
languages: getLanguages(state)
});

export default connect(mapStateToProps)(LanguageDistribution);

+ 0
- 28
server/sonar-web/src/main/js/components/charts/LanguageDistributionContainer.tsx View File

/*
* SonarQube
* Copyright (C) 2009-2021 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { connect } from 'react-redux';
import { getLanguages, Store } from '../../store/rootReducer';
import LanguageDistribution from './LanguageDistribution';

const mapStateToProps = (state: Store) => ({
languages: getLanguages(state)
});

export default connect(mapStateToProps)(LanguageDistribution);

+ 1
- 2
server/sonar-web/src/main/js/components/charts/__tests__/LanguageDistribution-test.tsx View File

*/ */
import { shallow } from 'enzyme'; import { shallow } from 'enzyme';
import * as React from 'react'; import * as React from 'react';
import LanguageDistribution from '../LanguageDistribution';
import { LanguageDistribution } from '../LanguageDistribution';


it('renders', () => { it('renders', () => {
expect( expect(
<LanguageDistribution <LanguageDistribution
distribution="java=1734;js=845;cpp=73;<null>=15" distribution="java=1734;js=845;cpp=73;<null>=15"
languages={{ java: { key: 'java', name: 'Java' }, js: { key: 'js', name: 'JavaScript' } }} languages={{ java: { key: 'java', name: 'Java' }, js: { key: 'js', name: 'JavaScript' } }}
width={100}
/> />
) )
).toMatchSnapshot(); ).toMatchSnapshot();

+ 1
- 1
server/sonar-web/src/main/js/components/charts/__tests__/__snapshots__/LanguageDistribution-test.tsx.snap View File

80, 80,
] ]
} }
width={100}
width={260}
yTicks={ yTicks={
Array [ Array [
"Java", "Java",

Loading…
Cancel
Save