Completed
Push — master ( 158ed8...34f194 )
by Alejandro
04:53 queued 02:19
created

src/visits/GraphCard.js   A

Complexity

Total Complexity 7
Complexity/F 0

Size

Lines of Code 77
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 7
eloc 62
mnd 7
bc 7
fnc 0
dl 0
loc 77
ccs 15
cts 15
cp 1
rs 10
bpm 0
cpm 0
noi 0
c 0
b 0
f 0
1
import { Card, CardHeader, CardBody, CardFooter } from 'reactstrap';
2
import { Doughnut, HorizontalBar } from 'react-chartjs-2';
3
import PropTypes from 'prop-types';
4
import React from 'react';
5
import { keys, values } from 'ramda';
6
import './GraphCard.scss';
7
8 3
const propTypes = {
9
  title: PropTypes.oneOfType([ PropTypes.string, PropTypes.func ]),
10
  footer: PropTypes.oneOfType([ PropTypes.string, PropTypes.node ]),
11
  isBarChart: PropTypes.bool,
12
  stats: PropTypes.object,
13
  max: PropTypes.number,
14
};
15
16 3
const generateGraphData = (title, isBarChart, labels, data) => ({
17
  labels,
18
  datasets: [
19
    {
20
      title,
21
      data,
22
      backgroundColor: isBarChart ? 'rgba(70, 150, 229, 0.4)' : [
23
        '#97BBCD',
24
        '#DCDCDC',
25
        '#F7464A',
26
        '#46BFBD',
27
        '#FDB45C',
28
        '#949FB1',
29
        '#4D5360',
30
      ],
31
      borderColor: isBarChart ? 'rgba(70, 150, 229, 1)' : 'white',
32
      borderWidth: 2,
33
    },
34
  ],
35
});
36
37 4
const dropLabelIfHidden = (label) => label.startsWith('hidden') ? '' : label;
38
39 3
const renderGraph = (title, isBarChart, stats, max) => {
40 2
  const Component = isBarChart ? HorizontalBar : Doughnut;
41 2
  const labels = keys(stats).map(dropLabelIfHidden);
42 2
  const data = values(stats);
43 2
  const options = {
44
    legend: isBarChart ? { display: false } : { position: 'right' },
45
    scales: isBarChart && {
46
      xAxes: [
47
        {
48
          ticks: { beginAtZero: true, max },
49
        },
50
      ],
51
    },
52
    tooltips: {
53
      intersect: !isBarChart,
54
55
      // Do not show tooltip on items with empty label when in a bar chart
56 2
      filter: ({ yLabel }) => !isBarChart || yLabel !== '',
57
    },
58
  };
59 2
  const graphData = generateGraphData(title, isBarChart, labels, data);
60 4
  const height = isBarChart && labels.length > 20 ? labels.length * 8 : null;
61
62
  // Provide a key based on the height, so that every time the dataset changes, a new graph is rendered
63 2
  return <Component key={height} data={graphData} options={options} height={height} />;
64
};
65
66 3
const GraphCard = ({ title, footer, isBarChart, stats, max }) => (
67 2
  <Card className="mt-4">
68
    <CardHeader className="graph-card__header">{typeof title === 'function' ? title() : title}</CardHeader>
69
    <CardBody>{renderGraph(title, isBarChart, stats, max)}</CardBody>
70
    {footer && <CardFooter className="graph-card__footer--sticky">{footer}</CardFooter>}
71
  </Card>
72
);
73
74 3
GraphCard.propTypes = propTypes;
75
76
export default GraphCard;
77