Merge pull request #64 from acelaya/bugfix/graphs-height

Bugfix/graphs height
This commit is contained in:
Alejandro Celaya 2018-10-19 21:12:38 +02:00 committed by GitHub
commit 169c69df2c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 82 additions and 46 deletions

View file

@ -8,51 +8,86 @@ const propTypes = {
title: PropTypes.string,
isBarChart: PropTypes.bool,
stats: PropTypes.object,
matchMedia: PropTypes.func,
};
const defaultProps = {
matchMedia: global.window ? global.window.matchMedia : () => {},
};
export function GraphCard({ title, isBarChart, stats }) {
const generateGraphData = (stats) => ({
labels: keys(stats),
datasets: [
{
title,
data: values(stats),
backgroundColor: isBarChart ? 'rgba(70, 150, 229, 0.4)' : [
'#97BBCD',
'#DCDCDC',
'#F7464A',
'#46BFBD',
'#FDB45C',
'#949FB1',
'#4D5360',
],
borderColor: isBarChart ? 'rgba(70, 150, 229, 1)' : 'white',
borderWidth: 2,
},
],
});
const renderGraph = () => {
const Component = isBarChart ? HorizontalBar : Doughnut;
const options = {
legend: isBarChart ? { display: false } : { position: 'right' },
scales: isBarChart ? {
xAxes: [
{
ticks: { beginAtZero: true },
},
],
} : null,
};
const generateGraphData = (title, isBarChart, labels, data) => ({
labels,
datasets: [
{
title,
data,
backgroundColor: isBarChart ? 'rgba(70, 150, 229, 0.4)' : [
'#97BBCD',
'#DCDCDC',
'#F7464A',
'#46BFBD',
'#FDB45C',
'#949FB1',
'#4D5360',
],
borderColor: isBarChart ? 'rgba(70, 150, 229, 1)' : 'white',
borderWidth: 2,
},
],
});
return <Component data={generateGraphData(stats)} options={options} />;
const determineGraphAspectRatio = (barsCount, isBarChart, matchMedia) => {
const determineAspectRationModifier = () => {
switch (true) {
case matchMedia('(max-width: 1200px)').matches:
return 1.5; // eslint-disable-line no-magic-numbers
case matchMedia('(max-width: 992px)').matches:
return 1.75; // eslint-disable-line no-magic-numbers
case matchMedia('(max-width: 768px)').matches:
return 2; // eslint-disable-line no-magic-numbers
case matchMedia('(max-width: 576px)').matches:
return 2.25; // eslint-disable-line no-magic-numbers
default:
return 1;
}
};
return (
<Card className="mt-4">
<CardHeader>{title}</CardHeader>
<CardBody>{renderGraph()}</CardBody>
</Card>
);
}
const MAX_BARS_WITHOUT_HEIGHT = 20;
const DEFAULT_ASPECT_RATION = 2;
const shouldCalculateAspectRatio = isBarChart && barsCount > MAX_BARS_WITHOUT_HEIGHT;
return shouldCalculateAspectRatio
? MAX_BARS_WITHOUT_HEIGHT / determineAspectRationModifier() * DEFAULT_ASPECT_RATION / barsCount
: DEFAULT_ASPECT_RATION;
};
const renderGraph = (title, isBarChart, stats, matchMedia) => {
const Component = isBarChart ? HorizontalBar : Doughnut;
const labels = keys(stats);
const data = values(stats);
const aspectRatio = determineGraphAspectRatio(labels.length, isBarChart, matchMedia);
const options = {
aspectRatio,
legend: isBarChart ? { display: false } : { position: 'right' },
scales: isBarChart ? {
xAxes: [
{
ticks: { beginAtZero: true },
},
],
} : null,
};
return <Component data={generateGraphData(title, isBarChart, labels, data)} options={options} height={null} />;
};
const GraphCard = ({ title, isBarChart, stats, matchMedia }) => (
<Card className="mt-4">
<CardHeader>{title}</CardHeader>
<CardBody>{renderGraph(title, isBarChart, stats, matchMedia)}</CardBody>
</Card>
);
GraphCard.propTypes = propTypes;
GraphCard.defaultProps = defaultProps;
export default GraphCard;

View file

@ -15,7 +15,7 @@ import {
processReferrersStats,
} from './services/VisitsParser';
import { VisitsHeader } from './VisitsHeader';
import { GraphCard } from './GraphCard';
import GraphCard from './GraphCard';
import { getShortUrlDetail, shortUrlDetailType } from './reducers/shortUrlDetail';
import './ShortUrlVisits.scss';

View file

@ -2,7 +2,7 @@ import React from 'react';
import { shallow } from 'enzyme';
import { Doughnut, HorizontalBar } from 'react-chartjs-2';
import { keys, values } from 'ramda';
import { GraphCard } from '../../src/visits/GraphCard';
import GraphCard from '../../src/visits/GraphCard';
describe('<GraphCard />', () => {
let wrapper;
@ -10,6 +10,7 @@ describe('<GraphCard />', () => {
foo: 123,
bar: 456,
};
const matchMedia = () => ({ matches: false });
afterEach(() => {
if (wrapper) {
@ -18,7 +19,7 @@ describe('<GraphCard />', () => {
});
it('renders Doughnut when is not a bar chart', () => {
wrapper = shallow(<GraphCard title="The chart" stats={stats} />);
wrapper = shallow(<GraphCard matchMedia={matchMedia} title="The chart" stats={stats} />);
const doughnut = wrapper.find(Doughnut);
const horizontal = wrapper.find(HorizontalBar);
@ -46,7 +47,7 @@ describe('<GraphCard />', () => {
});
it('renders HorizontalBar when is not a bar chart', () => {
wrapper = shallow(<GraphCard isBarChart title="The chart" stats={stats} />);
wrapper = shallow(<GraphCard matchMedia={matchMedia} isBarChart title="The chart" stats={stats} />);
const doughnut = wrapper.find(Doughnut);
const horizontal = wrapper.find(HorizontalBar);

View file

@ -5,7 +5,7 @@ import { Card } from 'reactstrap';
import * as sinon from 'sinon';
import { ShortUrlsVisitsComponent as ShortUrlsVisits } from '../../src/visits/ShortUrlVisits';
import MutedMessage from '../../src/utils/MuttedMessage';
import { GraphCard } from '../../src/visits/GraphCard';
import GraphCard from '../../src/visits/GraphCard';
import DateInput from '../../src/common/DateInput';
describe('<ShortUrlVisits />', () => {