diff --git a/src/visits/GraphCard.js b/src/visits/GraphCard.js
index e1a814da..4351fefa 100644
--- a/src/visits/GraphCard.js
+++ b/src/visits/GraphCard.js
@@ -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 ;
+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 (
-
- {title}
- {renderGraph()}
-
- );
-}
+ 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 ;
+};
+
+const GraphCard = ({ title, isBarChart, stats, matchMedia }) => (
+
+ {title}
+ {renderGraph(title, isBarChart, stats, matchMedia)}
+
+);
GraphCard.propTypes = propTypes;
+GraphCard.defaultProps = defaultProps;
+
+export default GraphCard;
diff --git a/src/visits/ShortUrlVisits.js b/src/visits/ShortUrlVisits.js
index 11256c0e..72d162cb 100644
--- a/src/visits/ShortUrlVisits.js
+++ b/src/visits/ShortUrlVisits.js
@@ -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';
diff --git a/test/visits/GraphCard.test.js b/test/visits/GraphCard.test.js
index 50d2ae14..0525efd0 100644
--- a/test/visits/GraphCard.test.js
+++ b/test/visits/GraphCard.test.js
@@ -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('', () => {
let wrapper;
@@ -10,6 +10,7 @@ describe('', () => {
foo: 123,
bar: 456,
};
+ const matchMedia = () => ({ matches: false });
afterEach(() => {
if (wrapper) {
@@ -18,7 +19,7 @@ describe('', () => {
});
it('renders Doughnut when is not a bar chart', () => {
- wrapper = shallow();
+ wrapper = shallow();
const doughnut = wrapper.find(Doughnut);
const horizontal = wrapper.find(HorizontalBar);
@@ -46,7 +47,7 @@ describe('', () => {
});
it('renders HorizontalBar when is not a bar chart', () => {
- wrapper = shallow();
+ wrapper = shallow();
const doughnut = wrapper.find(Doughnut);
const horizontal = wrapper.find(HorizontalBar);
diff --git a/test/visits/ShortUrlVisits.test.js b/test/visits/ShortUrlVisits.test.js
index d7d2a3e8..56837968 100644
--- a/test/visits/ShortUrlVisits.test.js
+++ b/test/visits/ShortUrlVisits.test.js
@@ -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('', () => {