Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion output/components.eslint.txt
Original file line number Diff line number Diff line change
Expand Up @@ -317,4 +317,4 @@
679:56 error ["resizable"] is better written in dot notation dot-notation

✖ 155 problems (135 errors, 20 warnings)
15 errors and 0 warnings potentially fixable with the `--fix` option.
15 errors and 0 warnings potentially fixable with the `--fix` option.
35 changes: 31 additions & 4 deletions packages/components/src/QualityBar/QualityBar.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import RatioBar from '../RatioBar';
import {
QualityEmptyLine,
QualityInvalidLine,
QualityType,
QualityValidLine,
} from './QualityRatioBar.component';
import I18N_DOMAIN_COMPONENTS from '../constants';
Expand Down Expand Up @@ -39,7 +40,7 @@ export function getQualityPercentagesRounded(invalid, empty, valid, digits = 0)
return [invalidRounded, emptyRounded, validRounded];
}

export function QualityBar({ invalid, valid, empty, digits = 1 }) {
export function QualityBar({ invalid, valid, empty, onClick, getDataFeature, digits = 1 }) {
const { t } = useTranslation(I18N_DOMAIN_COMPONENTS);

const [invalidPercentage, emptyPercentage, validPercentage] = getQualityPercentagesRounded(
Expand All @@ -51,9 +52,33 @@ export function QualityBar({ invalid, valid, empty, digits = 1 }) {

return (
<RatioBar.Composition>
<QualityInvalidLine value={invalid} percentage={invalidPercentage} t={t} />
<QualityEmptyLine value={empty} percentage={emptyPercentage} t={t} />
<QualityValidLine value={valid} percentage={validPercentage} t={t} />
<QualityInvalidLine
onClick={onClick ? (e) => onClick(e, {
type: QualityType.INVALID
}) : null}
dataFeature={getDataFeature ? getDataFeature(QualityType.INVALID) : null}
value={invalid}
percentage={invalidPercentage}
t={t}
/>
<QualityEmptyLine
onClick={onClick ? (e) => onClick(e, {
type: QualityType.EMPTY
}) : null}
dataFeature={getDataFeature ? getDataFeature(QualityType.EMPTY) : null}
value={empty}
percentage={emptyPercentage}
t={t}
/>
<QualityValidLine
onClick={onClick ? (e) => onClick(e, {
type: QualityType.VALID
}) : null}
dataFeature={getDataFeature ? getDataFeature(QualityType.VALID) : null}
value={valid}
percentage={validPercentage}
t={t}
/>
</RatioBar.Composition>
);
}
Expand All @@ -62,5 +87,7 @@ QualityBar.propTypes = {
invalid: PropTypes.number.isRequired,
empty: PropTypes.number.isRequired,
valid: PropTypes.number.isRequired,
onClick: PropTypes.func,
dataFeature: PropTypes.func,
digits: PropTypes.number,
};
29 changes: 28 additions & 1 deletion packages/components/src/QualityBar/QualityBar.component.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { shallow } from 'enzyme';
import { shallow, mount } from 'enzyme';
import { QualityBar } from './QualityBar.component';

describe('QualityBar', () => {
Expand All @@ -21,5 +21,32 @@ describe('QualityBar', () => {
expect(wrapper.find('QualityValidLine').props().percentage).toBe(53.5);
expect(wrapper.find('QualityValidLine').props().value).toBe(523);
});
it('should render an chart with action button', () => {
// given
const mockFunctionAction = jest.fn();
const props = {
valid: 523,
invalid: 123,
empty: 332,
onClick: mockFunctionAction,
getDataFeature: (qualityType) => { return `data-feature-${qualityType}` },
};
// when
const wrapper = mount(<QualityBar {...props} />);
wrapper.find('div').filterWhere((item) => {
return item.prop('data-feature') === 'data-feature-valid';
}).simulate('click');
// then
expect(mockFunctionAction).toHaveBeenCalled();;
expect(wrapper.find('div').filterWhere((item) => {
return item.prop('data-feature') === 'data-feature-valid';
}).length).toBe(1);
expect(wrapper.find('div').filterWhere((item) => {
return item.prop('data-feature') === 'data-feature-invalid';
}).length).toBe(1);
expect(wrapper.find('div').filterWhere((item) => {
return item.prop('data-feature') === 'data-feature-empty';
}).length).toBe(1);
});
});
});
26 changes: 17 additions & 9 deletions packages/components/src/QualityBar/QualityBar.stories.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { storiesOf } from '@storybook/react';

import { action } from '@storybook/addon-actions';
import { QualityBar } from './QualityBar.component';

const stories = storiesOf('Data/Dataviz/QualityBar', module);
Expand All @@ -12,21 +12,29 @@ stories
<header>Quality Bar</header>
<div>
<div>Homogeneous Quality</div>
<QualityBar invalid={30} valid={30} empty={30}></QualityBar>
<QualityBar invalid={30} valid={30} empty={30} />
<div>Very invalid</div>
<QualityBar invalid={30} valid={0} empty={0}></QualityBar>
<QualityBar invalid={30} valid={0} empty={0} />
<div>Best quality ever</div>
<QualityBar invalid={0} valid={30} empty={0}></QualityBar>
<QualityBar invalid={0} valid={30} empty={0} />
<div>Nothing to see here</div>
<QualityBar invalid={0} valid={0} empty={30}></QualityBar>
<QualityBar invalid={0} valid={0} empty={30} />
<div>Invalid and Empty</div>
<QualityBar invalid={0} valid={30} empty={30}></QualityBar>
<QualityBar invalid={0} valid={30} empty={30} />
<div>Classic look</div>
<QualityBar invalid={2} valid={88} empty={3}></QualityBar>
<QualityBar invalid={2} valid={88} empty={3} />
<div>Classic look (again yep)</div>
<QualityBar invalid={122} valid={1088} empty={293}></QualityBar>
<QualityBar invalid={122} valid={1088} empty={293} />
<div>I really like the digits !</div>
<QualityBar invalid={30} valid={30} empty={30} digits={5}></QualityBar>
<QualityBar invalid={30} valid={30} empty={30} digits={5} />
<div>Classic look with action button</div>
<QualityBar
invalid={2}
valid={88}
empty={3}
onClick={action('onClickAction')}
getDataFeature={(qualityType) => { return `data-feature.${qualityType}` }}
/>
</div>
</section>
</div>
Expand Down
38 changes: 35 additions & 3 deletions packages/components/src/QualityBar/QualityRatioBar.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ const qualityBarLinePropTypes = {
value: PropTypes.number.isRequired,
percentage: PropTypes.number.isRequired,
t: PropTypes.func.isRequired,
dataFeature: PropTypes.string,
onClick: PropTypes.func,
};

/**
Expand All @@ -26,7 +28,19 @@ function formatNumber(value = '') {
return parts.join('.');
}

export function QualityInvalidLine({ value, percentage, t }) {
export const QualityType = {
VALID: "valid",
INVALID: "invalid",
EMPTY: "empty"
}

export function QualityInvalidLine({
value,
percentage,
t,
dataFeature,
onClick,
}) {
return (
<RatioBar.Line
percentage={percentage}
Expand All @@ -37,14 +51,22 @@ export function QualityInvalidLine({ value, percentage, t }) {
percentage,
value: formatNumber(value),
})}
dataFeature={dataFeature}
onClick={onClick}
value={value}
className={theme('tc-ratio-bar-line-quality-invalid')}
/>
);
}
QualityInvalidLine.propTypes = qualityBarLinePropTypes;

export function QualityValidLine({ value, percentage, t }) {
export function QualityValidLine({
value,
percentage,
t,
dataFeature,
onClick,
}) {
return (
<RatioBar.Line
percentage={percentage}
Expand All @@ -55,14 +77,22 @@ export function QualityValidLine({ value, percentage, t }) {
percentage,
value: formatNumber(value),
})}
dataFeature={dataFeature}
onClick={onClick}
value={value}
className={theme('tc-ratio-bar-line-quality-valid')}
/>
);
}
QualityValidLine.propTypes = qualityBarLinePropTypes;

export function QualityEmptyLine({ value, percentage, t }) {
export function QualityEmptyLine({
value,
percentage,
t,
dataFeature,
onClick,
}) {
return (
<RatioBar.Line
percentage={percentage}
Expand All @@ -73,6 +103,8 @@ export function QualityEmptyLine({ value, percentage, t }) {
percentage,
value: formatNumber(value),
})}
dataFeature={dataFeature}
onClick={onClick}
value={value}
className={theme('tc-ratio-bar-line-quality-empty')}
/>
Expand Down
3 changes: 2 additions & 1 deletion packages/components/src/QualityBar/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { QualityBar } from './QualityBar.component';

import { QualityType } from './QualityRatioBar.component';
QualityBar.QualityType = QualityType
export default QualityBar;
Original file line number Diff line number Diff line change
@@ -1,17 +1,40 @@
import React from 'react';
import PropTypes from 'prop-types';
import keycode from 'keycode';
import TooltipTrigger from '../TooltipTrigger';
import { getTheme } from '../theme';
import ratioBarTheme from './RatioBar.scss';

const theme = getTheme(ratioBarTheme);
const minPercentage = 5;

export function RatioBarLine({ percentage, tooltipLabel, className, value }) {
export function RatioBarLine({
percentage,
tooltipLabel,
className,
value,
dataFeature,
onClick,
}) {
const canGrow = percentage >= minPercentage;

if (!value || value < 0) return null;

function onKeyDown(event) {
switch (event.keyCode) {
case keycode.codes.enter:
onClick(event);
break;
case keycode.codes.space:
event.preventDefault(); // prevent scroll with space
event.stopPropagation();
onClick(event);
break;
default:
break;
}
};

const content = (
<div
className={theme(
Expand All @@ -26,6 +49,10 @@ export function RatioBarLine({ percentage, tooltipLabel, className, value }) {
style={{
flexBasis: `${Math.max(percentage, minPercentage)}%`,
}}
role={onClick && "button"}
data-feature={dataFeature}
onClick={onClick}
onKeyDown={onClick}
/>
);

Expand All @@ -44,6 +71,8 @@ RatioBarLine.propTypes = {
value: PropTypes.number.isRequired,
tooltipLabel: PropTypes.string,
className: PropTypes.string.isRequired,
dataFeature: PropTypes.string,
onClick: PropTypes.func,
};

export function RatioBarComposition({ children }) {
Expand Down