@auth0/quantum-charts 0.0.3 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +9 -0
  2. package/bar-chart/index.js +46 -21
  3. package/chart-summary/data-table-chart.d.ts +2 -2
  4. package/chart-summary/data-table-chart.js +46 -4
  5. package/chart-summary/index.d.ts +1 -1
  6. package/common/chart.d.ts +6 -0
  7. package/common/chart.js +30 -0
  8. package/common/custom-legend.d.ts +2 -0
  9. package/common/custom-legend.js +69 -0
  10. package/common/custom-tooltip.d.ts +4 -0
  11. package/common/custom-tooltip.js +54 -0
  12. package/donut-chart/decoupled-legend.d.ts +1 -0
  13. package/donut-chart/decoupled-legend.js +24 -22
  14. package/donut-chart/index.d.ts +2 -0
  15. package/donut-chart/index.js +25 -9
  16. package/esm/bar-chart/index.js +47 -22
  17. package/esm/chart-summary/data-table-chart.js +47 -5
  18. package/esm/common/chart.js +28 -1
  19. package/esm/common/custom-legend.js +42 -0
  20. package/esm/common/custom-tooltip.js +26 -0
  21. package/esm/donut-chart/decoupled-legend.js +26 -21
  22. package/esm/donut-chart/index.js +27 -11
  23. package/esm/line-chart/index.js +56 -18
  24. package/esm/styles.js +11 -11
  25. package/esm/theme.js +37 -21
  26. package/line-chart/index.js +55 -17
  27. package/package.json +16 -13
  28. package/styles.d.ts +3 -4
  29. package/styles.js +11 -14
  30. package/theme.d.ts +10 -2
  31. package/theme.js +39 -24
  32. package/esm/line-chart/custom-tooltip.js +0 -20
  33. package/line-chart/custom-tooltip.d.ts +0 -6
  34. package/line-chart/custom-tooltip.js +0 -48
  35. /package/{custom-color-status-dot.d.ts → common/custom-color-status-dot.d.ts} +0 -0
  36. /package/{custom-color-status-dot.js → common/custom-color-status-dot.js} +0 -0
  37. /package/esm/{custom-color-status-dot.js → common/custom-color-status-dot.js} +0 -0
package/README.md ADDED
@@ -0,0 +1,9 @@
1
+ # Quantum Charts
2
+
3
+ ## Installation
4
+ ```bash
5
+ yarn add @auth0/quantum-charts
6
+ ```
7
+
8
+ ## Usage
9
+ Detailed docs and example usage can be found [here](https://quantum.okta.design/?path=/story/quantum-charts-intro--page).
@@ -33,6 +33,22 @@ var __importStar = (this && this.__importStar) || function (mod) {
33
33
  __setModuleDefault(result, mod);
34
34
  return result;
35
35
  };
36
+ var __read = (this && this.__read) || function (o, n) {
37
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
38
+ if (!m) return o;
39
+ var i = m.call(o), r, ar = [], e;
40
+ try {
41
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
42
+ }
43
+ catch (error) { e = { error: error }; }
44
+ finally {
45
+ try {
46
+ if (r && !r.done && (m = i["return"])) m.call(i);
47
+ }
48
+ finally { if (e) throw e.error; }
49
+ }
50
+ return ar;
51
+ };
36
52
  var __importDefault = (this && this.__importDefault) || function (mod) {
37
53
  return (mod && mod.__esModule) ? mod : { "default": mod };
38
54
  };
@@ -43,14 +59,32 @@ var React = __importStar(require("react"));
43
59
  var recharts_1 = require("recharts");
44
60
  var quantum_product_1 = require("@auth0/quantum-product");
45
61
  var theme_1 = require("../theme");
46
- var custom_tooltip_1 = __importDefault(require("../line-chart/custom-tooltip"));
47
- var date_fns_1 = require("date-fns");
62
+ var custom_tooltip_1 = __importDefault(require("../common/custom-tooltip"));
48
63
  var chart_card_1 = require("../chart-card");
64
+ var chart_1 = require("../common/chart");
65
+ var custom_legend_1 = require("../common/custom-legend");
49
66
  function BarChart(props) {
50
- var _a = props, data = _a.data, leftAxis = _a.leftAxis, bottomAxis = _a.bottomAxis, _b = _a.height, height = _b === void 0 ? 300 : _b, title = _a.title, value = _a.value, label = _a.label, helperText = _a.helperText, _c = _a.layout, layout = _c === void 0 ? 'vertical' : _c, _d = _a.isStacked, isStacked = _d === void 0 ? false : _d;
67
+ var _a = props, data = _a.data, leftAxis = _a.leftAxis, bottomAxis = _a.bottomAxis, _b = _a.height, height = _b === void 0 ? 300 : _b, title = _a.title, value = _a.value, label = _a.label, helperText = _a.helperText, _c = _a.layout, layout = _c === void 0 ? 'vertical' : _c, _d = _a.isStacked, isStacked = _d === void 0 ? false : _d, _e = _a.color, color = _e === void 0 ? 'categorical' : _e;
51
68
  var theme = (0, quantum_product_1.useTheme)();
52
69
  // Function to know how many bars we need based of how much different group values are.
53
70
  var groups = lodash_1.default.uniqBy(data, 'group').map(function (item) { return item.group; });
71
+ var initialState = __assign({ hover: null }, groups.reduce(function (acc, group) {
72
+ var _a;
73
+ return (__assign(__assign({}, acc), (_a = {}, _a[group] = false, _a)));
74
+ }, {}));
75
+ var _f = __read(React.useState(initialState), 2), barVisibility = _f[0], setBarVisibility = _f[1];
76
+ var handleLegendMouseEnter = function (e) {
77
+ if (!barVisibility[e.dataKey]) {
78
+ setBarVisibility(__assign(__assign({}, barVisibility), { hover: e.dataKey }));
79
+ }
80
+ };
81
+ var handleLegendMouseLeave = function () {
82
+ setBarVisibility(__assign(__assign({}, barVisibility), { hover: null }));
83
+ };
84
+ var selectBar = function (e) {
85
+ var _a;
86
+ setBarVisibility(__assign(__assign({}, barVisibility), (_a = {}, _a[e.dataKey] = !barVisibility[e.dataKey], _a.hover = null, _a)));
87
+ };
54
88
  var bottomAxisDataKey = bottomAxis.mapsTo || 'date';
55
89
  var leftAxisDataKey = leftAxis.mapsTo || 'value';
56
90
  var entries = {};
@@ -71,35 +105,26 @@ function BarChart(props) {
71
105
  _b[entry.group] = entry[leftAxisDataKey],
72
106
  _b;
73
107
  });
74
- var formatBottomTick = function (value) {
75
- if (bottomAxis.scaleType === 'date') {
76
- return (0, date_fns_1.format)(new Date(value), 'LLL d');
77
- }
78
- if (bottomAxis.scaleType === 'datetime') {
79
- return (0, date_fns_1.format)(new Date(value), 'LLL d p');
80
- }
81
- return value;
82
- };
83
108
  return (React.createElement(chart_card_1.ChartCard, { title: title, value: value, dataTable: data, label: label, helperText: helperText },
84
109
  React.createElement(recharts_1.ResponsiveContainer, { width: "100%", height: height }, data.length ? (React.createElement(recharts_1.BarChart, { width: 500, layout: layout === 'horizontal' ? 'vertical' : 'horizontal', height: height, data: Object.values(entries), margin: {
85
110
  top: 24,
86
111
  right: 10,
87
- left: layout === 'vertical' ? -24 : -6,
112
+ left: layout === 'vertical' ? -24 : 16,
88
113
  bottom: 0,
89
114
  } },
90
115
  React.createElement(recharts_1.CartesianGrid, { vertical: false, stroke: theme.tokens.color_border_default }),
91
- React.createElement(recharts_1.XAxis, __assign({}, (layout === 'horizontal'
92
- ? { type: 'number' }
93
- : { tickFormatter: formatBottomTick, dataKey: bottomAxisDataKey }), { height: 30 })),
116
+ React.createElement(recharts_1.XAxis, __assign({}, (layout === 'horizontal' ? { type: 'number' } : { dataKey: bottomAxisDataKey }), { height: 30, tickFormatter: function (value) { return (0, chart_1.tickFormatter)(value, bottomAxis.scaleType); }, axisLine: { stroke: theme.tokens.color_border_bold }, tickLine: { stroke: theme.tokens.color_border_bold } })),
94
117
  React.createElement(recharts_1.YAxis, __assign({}, (layout === 'horizontal' && {
95
118
  type: 'category',
96
- tickFormatter: formatBottomTick,
119
+ tickFormatter: function (value) { return (0, chart_1.tickFormatter)(value, leftAxis.scaleType); },
97
120
  dataKey: bottomAxisDataKey,
98
- }), { domain: ['auto', 'auto'] })),
99
- React.createElement(recharts_1.Tooltip, { content: React.createElement(custom_tooltip_1.default, { active: undefined, payload: undefined }) }),
100
- React.createElement(recharts_1.Legend, { align: "center", iconType: "square", iconSize: 14, wrapperStyle: { paddingTop: 16 } }),
121
+ }), { domain: ['auto', 'auto'], axisLine: { stroke: theme.tokens.color_border_bold }, tickLine: { stroke: theme.tokens.color_border_bold } })),
122
+ React.createElement(recharts_1.Tooltip, { wrapperStyle: { outline: 'none' }, content: React.createElement(custom_tooltip_1.default, { active: undefined, payload: undefined, scaleType: bottomAxis.scaleType }) }),
123
+ React.createElement(recharts_1.Legend, { align: "center", iconType: "square", iconSize: 14, wrapperStyle: { paddingTop: 16 }, content: React.createElement(custom_legend_1.CustomLegend, { selectData: selectBar, handleLegendMouseEnter: handleLegendMouseEnter, handleLegendMouseLeave: handleLegendMouseLeave, dataVisibility: barVisibility }) }),
101
124
  groups.map(function (group, index) {
102
- return (React.createElement(recharts_1.Bar, __assign({ key: group, dataKey: group }, (isStacked && { stackId: 'stack' }), { name: group, maxBarSize: 70, fill: (0, theme_1.getBaseColorScale)(theme)[index], radius: !isStacked || index == groups.length - 1
125
+ return (React.createElement(recharts_1.Bar, __assign({ key: group, dataKey: group }, (isStacked && { stackId: 'stack' }), { name: group, maxBarSize: 70, hide: barVisibility[group] === true, fill: barVisibility.hover === group || !barVisibility.hover
126
+ ? (0, theme_1.getColorScale)(theme)[color]['base'][index]
127
+ : (0, theme_1.getColorScale)(theme)[color]['muted'][index], radius: !isStacked || index == groups.length - 1
103
128
  ? layout === 'vertical'
104
129
  ? [4, 4, 0, 0]
105
130
  : [0, 4, 4, 0]
@@ -1,6 +1,6 @@
1
- import * as React from 'react';
1
+ /// <reference types="react" />
2
2
  export interface IDataTableChartProps {
3
- title: React.ReactNode;
3
+ title?: string;
4
4
  isOpen: boolean;
5
5
  toggleIsOpen: () => void;
6
6
  data: any;
@@ -52,8 +52,47 @@ function DataTableChart(props) {
52
52
  var isDonut = data[0] && data[0].name !== undefined;
53
53
  var groups = lodash_1.default.groupBy(data, 'group');
54
54
  var _a = __read(React.useState(Object.keys(groups)[0]), 2), selectedTab = _a[0], setSelectedTab = _a[1];
55
+ var hasKey = data[0] && data[0].key !== undefined;
56
+ var downloadCSV = function (filename) {
57
+ if (filename === void 0) { filename = 'chart data'; }
58
+ var mappedData = data.map(function (row) {
59
+ if (row.date) {
60
+ row.date = (0, date_fns_1.format)(new Date(row.date), 'LLL d p');
61
+ }
62
+ return Object.values(row).map(function (column) { return "\"".concat(column === '&ndash;' ? '–' : column, "\""); });
63
+ });
64
+ mappedData.unshift(Object.keys(data[0]));
65
+ var content = '', csvData = '';
66
+ mappedData.forEach(function (d, i) {
67
+ csvData = d.join(',');
68
+ content += i < data.length ? csvData + '\n' : csvData;
69
+ });
70
+ var anchor = document.createElement('a');
71
+ var mimeType = 'text/csv;encoding:utf-8';
72
+ if (navigator['msSaveBlob']) {
73
+ // Internet Explorer 10
74
+ navigator['msSaveBlob'](new Blob([content], {
75
+ type: mimeType,
76
+ }), filename);
77
+ }
78
+ else if (URL && 'download' in anchor) {
79
+ // HTML5
80
+ var href = URL.createObjectURL(new Blob([content], {
81
+ type: mimeType,
82
+ }));
83
+ anchor.href = href;
84
+ anchor.setAttribute('download', filename);
85
+ document.body.appendChild(anchor);
86
+ anchor.click();
87
+ document.body.removeChild(anchor);
88
+ URL.revokeObjectURL(href);
89
+ }
90
+ else {
91
+ location.href = "data:application/octet-stream,".concat(encodeURIComponent(content));
92
+ }
93
+ };
55
94
  return (React.createElement(quantum_product_1.Dialog, { open: isOpen, fullWidth: true, title: title, onClose: toggleIsOpen, actions: React.createElement(React.Fragment, null,
56
- React.createElement(quantum_product_1.Button, { color: "primary", variant: "contained" }, "Download CSV")) },
95
+ React.createElement(quantum_product_1.Button, { color: "primary", variant: "contained", startIcon: React.createElement(quantum_product_1.DownloadIcon, null), onClick: function () { return downloadCSV(title); } }, "Download")) },
57
96
  React.createElement(quantum_product_1.Box, { p: 2 },
58
97
  React.createElement(quantum_product_1.Tabs, { baseId: 'example', onChange: setSelectedTab, value: selectedTab },
59
98
  React.createElement(quantum_product_1.TabList, { classes: { indicator: 'chromatic-ignore' } }, !isDonut &&
@@ -74,10 +113,13 @@ function DataTableChart(props) {
74
113
  var item = _a.item;
75
114
  return item.value || 'N/A';
76
115
  } },
77
- { title: 'date', render: function (_a) {
116
+ {
117
+ title: hasKey ? 'key' : 'date',
118
+ render: function (_a) {
78
119
  var item = _a.item;
79
- return (0, date_fns_1.format)(new Date(item.date), 'LLL d p');
80
- } },
120
+ return (hasKey ? item.key : (0, date_fns_1.format)(new Date(item.date), 'LLL d p'));
121
+ },
122
+ },
81
123
  ] })));
82
124
  })))))));
83
125
  }
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  export interface IChartSummaryProps {
3
- title?: React.ReactNode;
3
+ title?: string;
4
4
  value?: string | number;
5
5
  label?: React.ReactNode;
6
6
  /** Renders help icon with tooltip as passed value **/
package/common/chart.d.ts CHANGED
@@ -1,6 +1,10 @@
1
1
  /// <reference types="react" />
2
+ import { TooltipProps } from 'recharts';
2
3
  import { IChartCardProps } from '../chart-card';
3
4
  export declare type ScaleType = 'date' | 'datetime' | 'label' | 'number';
5
+ export interface ICustomTooltipProps extends TooltipProps<number, string> {
6
+ scaleType?: 'datetime' | 'date';
7
+ }
4
8
  export interface ILegendOptions {
5
9
  enabled?: boolean;
6
10
  }
@@ -21,4 +25,6 @@ export interface IBaseChartProps<DataType = unknown> extends IChartCardProps {
21
25
  bottomAxis: IAxisOptions<DataType>;
22
26
  leftAxis: IAxisOptions<DataType>;
23
27
  legend?: ILegendOptions;
28
+ color?: 'categorical' | 'sequential';
24
29
  }
30
+ export declare const tickFormatter: (value: any, scaleType: any) => any;
package/common/chart.js CHANGED
@@ -1,2 +1,32 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.tickFormatter = void 0;
4
+ var date_fns_1 = require("date-fns");
5
+ var tickFormatter = function (value, scaleType) {
6
+ switch (scaleType) {
7
+ case 'number':
8
+ if (value > 1000000000) {
9
+ return (value / 1000000000).toString() + 'B';
10
+ }
11
+ else if (value > 1000000) {
12
+ return (value / 1000000).toString() + 'M';
13
+ }
14
+ else if (value > 1000) {
15
+ return (value / 1000).toString() + 'K';
16
+ }
17
+ else {
18
+ return value.toString();
19
+ }
20
+ case 'label':
21
+ if (value.length <= 8)
22
+ return value;
23
+ return "".concat(value.substring(0, 8), "...");
24
+ case 'date':
25
+ return (0, date_fns_1.format)(new Date(value), 'LLL d');
26
+ case 'datetime':
27
+ return (0, date_fns_1.format)(new Date(value), 'LLL d p');
28
+ default:
29
+ break;
30
+ }
31
+ };
32
+ exports.tickFormatter = tickFormatter;
@@ -0,0 +1,2 @@
1
+ /// <reference types="react" />
2
+ export declare const CustomLegend: (props: any) => JSX.Element;
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ var desc = Object.getOwnPropertyDescriptor(m, k);
16
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
17
+ desc = { enumerable: true, get: function() { return m[k]; } };
18
+ }
19
+ Object.defineProperty(o, k2, desc);
20
+ }) : (function(o, m, k, k2) {
21
+ if (k2 === undefined) k2 = k;
22
+ o[k2] = m[k];
23
+ }));
24
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
25
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
26
+ }) : function(o, v) {
27
+ o["default"] = v;
28
+ });
29
+ var __importStar = (this && this.__importStar) || function (mod) {
30
+ if (mod && mod.__esModule) return mod;
31
+ var result = {};
32
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
33
+ __setModuleDefault(result, mod);
34
+ return result;
35
+ };
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.CustomLegend = void 0;
38
+ var quantum_product_1 = require("@auth0/quantum-product");
39
+ var React = __importStar(require("react"));
40
+ var Root = (0, quantum_product_1.styled)(quantum_product_1.StackLayout)(function (_a) {
41
+ var theme = _a.theme;
42
+ return ({
43
+ justifyContent: 'center',
44
+ marginTop: theme.spacing(3),
45
+ });
46
+ });
47
+ var LegendIcon = (0, quantum_product_1.styled)('div')(function (_a) {
48
+ var theme = _a.theme, ownerState = _a.ownerState;
49
+ return (__assign({}, (ownerState.isHide
50
+ ? {
51
+ borderRadius: theme.spacing(0.5),
52
+ border: "2px solid ".concat(ownerState.color),
53
+ width: '14px',
54
+ height: '14px',
55
+ }
56
+ : {
57
+ background: ownerState.color,
58
+ width: '14px',
59
+ height: '14px',
60
+ borderRadius: '4px',
61
+ })));
62
+ });
63
+ var CustomLegend = function (props) {
64
+ var payload = props.payload, selectData = props.selectData, handleLegendMouseEnter = props.handleLegendMouseEnter, handleLegendMouseLeave = props.handleLegendMouseLeave, dataVisibility = props.dataVisibility;
65
+ return (React.createElement(Root, { gutter: 1 }, payload.map(function (entry, index) { return (React.createElement(quantum_product_1.StackLayout, { sx: { padding: '4px 8px', cursor: 'pointer' }, key: index, gutter: 1, onClick: function () { return selectData(entry); }, onMouseEnter: function () { return handleLegendMouseEnter(entry); }, onMouseLeave: function () { return handleLegendMouseLeave(entry); } },
66
+ React.createElement(LegendIcon, { ownerState: { isHide: dataVisibility[entry.dataKey], color: entry.color } }),
67
+ React.createElement(quantum_product_1.Text, { variant: "body2" }, entry.value))); })));
68
+ };
69
+ exports.CustomLegend = CustomLegend;
@@ -0,0 +1,4 @@
1
+ /// <reference types="react" />
2
+ import { ICustomTooltipProps } from './chart';
3
+ declare const CustomTooltip: (props: ICustomTooltipProps) => JSX.Element | null;
4
+ export default CustomTooltip;
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ var React = __importStar(require("react"));
30
+ var quantum_product_1 = require("@auth0/quantum-product");
31
+ var custom_color_status_dot_1 = __importDefault(require("./custom-color-status-dot"));
32
+ var date_fns_1 = require("date-fns");
33
+ var styles_1 = require("../styles");
34
+ var CustomTooltip = function (props) {
35
+ var _a, _b, _c;
36
+ var active = props.active, payload = props.payload, scaleType = props.scaleType, labelProp = props.label;
37
+ if (active && payload && payload.length) {
38
+ var label = ((_a = payload[0].payload) === null || _a === void 0 ? void 0 : _a.date)
39
+ ? scaleType === 'datetime'
40
+ ? "".concat((0, date_fns_1.format)(new Date((_b = payload[0].payload) === null || _b === void 0 ? void 0 : _b.date), 'LLL d HH:mm'))
41
+ : "".concat((0, date_fns_1.format)(new Date((_c = payload[0].payload) === null || _c === void 0 ? void 0 : _c.date), 'LLL d'))
42
+ : labelProp;
43
+ return (React.createElement(styles_1.CustomTooltip, null,
44
+ React.createElement(quantum_product_1.Text, { color: "text.secondary" }, label),
45
+ React.createElement(quantum_product_1.Box, null,
46
+ React.createElement(quantum_product_1.RowLayout, { gutter: 1 }, payload.map(function (x, index) {
47
+ return (React.createElement(quantum_product_1.StackLayout, { key: index, gutter: 0.5 },
48
+ React.createElement(custom_color_status_dot_1.default, { key: index, dotColor: x.color || 'grey', label: "".concat(x.name, ":") + ' ' }),
49
+ React.createElement(quantum_product_1.Text, { color: "text.secondary" }, x.payload[x.name || ''])));
50
+ })))));
51
+ }
52
+ return null;
53
+ };
54
+ exports.default = CustomTooltip;
@@ -4,6 +4,7 @@ export declare type IDecoupledLegendProps<DataType = unknown> = {
4
4
  data: IDonutChartDataPoint<DataType>[];
5
5
  activeIndex?: number;
6
6
  setActiveIndex: (index: number | undefined) => void;
7
+ color?: 'categorical' | 'sequential';
7
8
  };
8
9
  declare function DecoupledLegend<DataType = unknown>(props: IDecoupledLegendProps<DataType>): JSX.Element;
9
10
  export default DecoupledLegend;
@@ -1,8 +1,4 @@
1
1
  "use strict";
2
- var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
3
- if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
4
- return cooked;
5
- };
6
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
3
  if (k2 === undefined) k2 = k;
8
4
  var desc = Object.getOwnPropertyDescriptor(m, k);
@@ -26,21 +22,37 @@ var __importStar = (this && this.__importStar) || function (mod) {
26
22
  __setModuleDefault(result, mod);
27
23
  return result;
28
24
  };
29
- var __importDefault = (this && this.__importDefault) || function (mod) {
30
- return (mod && mod.__esModule) ? mod : { "default": mod };
31
- };
32
25
  Object.defineProperty(exports, "__esModule", { value: true });
33
26
  var React = __importStar(require("react"));
34
- var styled_components_1 = __importDefault(require("styled-components"));
35
27
  var quantum_product_1 = require("@auth0/quantum-product");
36
28
  var theme_1 = require("../theme");
29
+ var Root = (0, quantum_product_1.styled)('div')({
30
+ display: 'flex',
31
+ flexDirection: 'column',
32
+ gap: '8px',
33
+ height: '150px',
34
+ flexWrap: 'wrap',
35
+ });
36
+ var LegendDot = (0, quantum_product_1.styled)('div')({
37
+ height: '14px',
38
+ width: '14px',
39
+ borderRadius: '4px',
40
+ });
41
+ var LegendText = (0, quantum_product_1.styled)('span')({
42
+ whiteSpace: 'nowrap',
43
+ overflow: 'hidden',
44
+ textOverflow: 'ellipsis',
45
+ cursor: 'default',
46
+ });
37
47
  function DecoupledLegend(props) {
38
- var data = props.data, activeIndex = props.activeIndex, setActiveIndex = props.setActiveIndex;
48
+ var data = props.data, activeIndex = props.activeIndex, setActiveIndex = props.setActiveIndex, _a = props.color, color = _a === void 0 ? 'categorical' : _a;
39
49
  var theme = (0, quantum_product_1.useTheme)();
40
- var BASE_COLORS = (0, theme_1.getBaseColorScale)(theme);
41
- return (React.createElement("div", { style: { display: 'flex', flexDirection: 'column', gap: '8px', height: '150px', flexWrap: 'wrap' } }, data.map(function (datum, index) {
50
+ var BASE_COLORS = (0, theme_1.getColorScale)(theme)[color]['base'];
51
+ var MUTED_COLORS = (0, theme_1.getColorScale)(theme)[color]['muted'];
52
+ return (React.createElement(Root, null, data.map(function (datum, index) {
42
53
  var isActive = activeIndex !== undefined && activeIndex === index;
43
54
  var color = BASE_COLORS[index % BASE_COLORS.length];
55
+ var mutedColor = MUTED_COLORS[index % MUTED_COLORS.length];
44
56
  return (React.createElement(React.Fragment, { key: index },
45
57
  React.createElement(quantum_product_1.StackLayout, { gutter: 1, onMouseEnter: function () {
46
58
  setActiveIndex(index);
@@ -52,21 +64,11 @@ function DecoupledLegend(props) {
52
64
  React.createElement(quantum_product_1.StackLayoutItem, { sx: {
53
65
  alignSelf: 'center',
54
66
  } },
55
- React.createElement(LegendDotWrapper, { style: {
56
- border: '2px solid ' + (isActive ? color : 'white'),
57
- } },
58
- React.createElement(LegendDot, { style: { backgroundColor: color } }))),
67
+ React.createElement(LegendDot, { style: { backgroundColor: activeIndex === undefined ? color : isActive ? color : mutedColor } })),
59
68
  React.createElement(quantum_product_1.StackLayoutItem, { sx: {
60
69
  alignSelf: 'center',
61
70
  } },
62
71
  React.createElement(LegendText, { color: isActive ? 'primary' : 'secondary' }, datum.name)))));
63
72
  })));
64
73
  }
65
- var LegendDot = styled_components_1.default.div(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n height: 12px;\n width: 12px;\n border: 2px solid white;\n border-radius: 2px;\n"], ["\n height: 12px;\n width: 12px;\n border: 2px solid white;\n border-radius: 2px;\n"])));
66
- var LegendDotWrapper = styled_components_1.default.div(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n border-radius: 4px;\n"], ["\n border-radius: 4px;\n"])));
67
- var LegendText = styled_components_1.default.span(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n color: ", ";\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n cursor: default;\n"], ["\n color: ", ";\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n cursor: default;\n"])), function (_a) {
68
- var theme = _a.theme, color = _a.color;
69
- return theme.palette.text[color !== null && color !== void 0 ? color : 'secondary'];
70
- });
71
74
  exports.default = DecoupledLegend;
72
- var templateObject_1, templateObject_2, templateObject_3;
@@ -7,6 +7,8 @@ export declare type IDonutChartDataPoint<DataType = unknown> = {
7
7
  interface IDonutChartProps<DataType = unknown> extends IChartCardProps {
8
8
  data: IDonutChartDataPoint<DataType>[];
9
9
  displayType: 'absolute' | 'percent';
10
+ layout?: 'horizontal' | 'vertical';
11
+ color?: 'categorical' | 'sequential';
10
12
  }
11
13
  export declare function DonutChart(props: IDonutChartProps): JSX.Element;
12
14
  export {};
@@ -1,4 +1,15 @@
1
1
  "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
2
13
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
14
  if (k2 === undefined) k2 = k;
4
15
  var desc = Object.getOwnPropertyDescriptor(m, k);
@@ -50,17 +61,22 @@ var theme_1 = require("../theme");
50
61
  var center_1 = __importDefault(require("./center"));
51
62
  var decoupled_legend_1 = __importDefault(require("./decoupled-legend"));
52
63
  var chart_card_1 = require("../chart-card");
64
+ var ResponsiveChartCard = (0, quantum_product_1.styled)(quantum_product_1.StackLayout)(function (_a) {
65
+ var _b;
66
+ var theme = _a.theme, ownerState = _a.ownerState;
67
+ return (__assign((_b = {}, _b[theme.breakpoints.down('sm')] = {
68
+ flexDirection: 'column',
69
+ }, _b.flexWrap = 'nowrap', _b.marginTop = theme.spacing(3), _b), (ownerState.layout === 'vertical' && {
70
+ flexDirection: 'column',
71
+ })));
72
+ });
53
73
  function DonutChart(props) {
54
- var data = props.data, displayType = props.displayType, title = props.title, value = props.value, label = props.label, helperText = props.helperText;
55
- var _a = __read(React.useState(undefined), 2), activeIndex = _a[0], setActiveIndex = _a[1];
74
+ var data = props.data, displayType = props.displayType, title = props.title, value = props.value, label = props.label, helperText = props.helperText, _a = props.layout, layout = _a === void 0 ? 'horizontal' : _a, _b = props.color, color = _b === void 0 ? 'categorical' : _b;
75
+ var _c = __read(React.useState(undefined), 2), activeIndex = _c[0], setActiveIndex = _c[1];
56
76
  var theme = (0, quantum_product_1.useTheme)();
57
- var BASE_COLORS = (0, theme_1.getBaseColorScale)(theme);
77
+ var BASE_COLORS = (0, theme_1.getColorScale)(theme)[color]['base'];
58
78
  return (React.createElement(chart_card_1.ChartCard, { title: title, value: value, dataTable: data, label: label, helperText: helperText },
59
- React.createElement(quantum_product_1.StackLayout, { sx: {
60
- height: '150px',
61
- flexWrap: 'nowrap',
62
- mt: '24px',
63
- } },
79
+ React.createElement(ResponsiveChartCard, { ownerState: { layout: layout } },
64
80
  React.createElement(quantum_product_1.StackLayoutItem, { sx: {
65
81
  height: '150px',
66
82
  width: '150px',
@@ -77,6 +93,6 @@ function DonutChart(props) {
77
93
  return (React.createElement(recharts_1.Cell, { key: "cell-".concat(index), fill: BASE_COLORS[index % BASE_COLORS.length], opacity: activeIndex === undefined ? 1 : activeIndex === index ? 1 : 0.5 }));
78
94
  }))))),
79
95
  React.createElement(quantum_product_1.StackLayoutItem, null,
80
- React.createElement(decoupled_legend_1.default, { activeIndex: activeIndex, setActiveIndex: setActiveIndex, data: data })))));
96
+ React.createElement(decoupled_legend_1.default, { activeIndex: activeIndex, setActiveIndex: setActiveIndex, data: data, color: color })))));
81
97
  }
82
98
  exports.DonutChart = DonutChart;
@@ -9,19 +9,53 @@ var __assign = (this && this.__assign) || function () {
9
9
  };
10
10
  return __assign.apply(this, arguments);
11
11
  };
12
+ var __read = (this && this.__read) || function (o, n) {
13
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
14
+ if (!m) return o;
15
+ var i = m.call(o), r, ar = [], e;
16
+ try {
17
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
18
+ }
19
+ catch (error) { e = { error: error }; }
20
+ finally {
21
+ try {
22
+ if (r && !r.done && (m = i["return"])) m.call(i);
23
+ }
24
+ finally { if (e) throw e.error; }
25
+ }
26
+ return ar;
27
+ };
12
28
  import _ from 'lodash';
13
29
  import * as React from 'react';
14
30
  import { BarChart as RechartsBarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, } from 'recharts';
15
31
  import { useTheme, Text } from '@auth0/quantum-product';
16
- import { getBaseColorScale } from '../theme';
17
- import CustomTooltip from '../line-chart/custom-tooltip';
18
- import { format } from 'date-fns';
32
+ import { getColorScale } from '../theme';
33
+ import CustomTooltip from '../common/custom-tooltip';
19
34
  import { ChartCard } from '../chart-card';
35
+ import { tickFormatter } from '../common/chart';
36
+ import { CustomLegend } from '../common/custom-legend';
20
37
  export function BarChart(props) {
21
- var _a = props, data = _a.data, leftAxis = _a.leftAxis, bottomAxis = _a.bottomAxis, _b = _a.height, height = _b === void 0 ? 300 : _b, title = _a.title, value = _a.value, label = _a.label, helperText = _a.helperText, _c = _a.layout, layout = _c === void 0 ? 'vertical' : _c, _d = _a.isStacked, isStacked = _d === void 0 ? false : _d;
38
+ var _a = props, data = _a.data, leftAxis = _a.leftAxis, bottomAxis = _a.bottomAxis, _b = _a.height, height = _b === void 0 ? 300 : _b, title = _a.title, value = _a.value, label = _a.label, helperText = _a.helperText, _c = _a.layout, layout = _c === void 0 ? 'vertical' : _c, _d = _a.isStacked, isStacked = _d === void 0 ? false : _d, _e = _a.color, color = _e === void 0 ? 'categorical' : _e;
22
39
  var theme = useTheme();
23
40
  // Function to know how many bars we need based of how much different group values are.
24
41
  var groups = _.uniqBy(data, 'group').map(function (item) { return item.group; });
42
+ var initialState = __assign({ hover: null }, groups.reduce(function (acc, group) {
43
+ var _a;
44
+ return (__assign(__assign({}, acc), (_a = {}, _a[group] = false, _a)));
45
+ }, {}));
46
+ var _f = __read(React.useState(initialState), 2), barVisibility = _f[0], setBarVisibility = _f[1];
47
+ var handleLegendMouseEnter = function (e) {
48
+ if (!barVisibility[e.dataKey]) {
49
+ setBarVisibility(__assign(__assign({}, barVisibility), { hover: e.dataKey }));
50
+ }
51
+ };
52
+ var handleLegendMouseLeave = function () {
53
+ setBarVisibility(__assign(__assign({}, barVisibility), { hover: null }));
54
+ };
55
+ var selectBar = function (e) {
56
+ var _a;
57
+ setBarVisibility(__assign(__assign({}, barVisibility), (_a = {}, _a[e.dataKey] = !barVisibility[e.dataKey], _a.hover = null, _a)));
58
+ };
25
59
  var bottomAxisDataKey = bottomAxis.mapsTo || 'date';
26
60
  var leftAxisDataKey = leftAxis.mapsTo || 'value';
27
61
  var entries = {};
@@ -42,35 +76,26 @@ export function BarChart(props) {
42
76
  _b[entry.group] = entry[leftAxisDataKey],
43
77
  _b;
44
78
  });
45
- var formatBottomTick = function (value) {
46
- if (bottomAxis.scaleType === 'date') {
47
- return format(new Date(value), 'LLL d');
48
- }
49
- if (bottomAxis.scaleType === 'datetime') {
50
- return format(new Date(value), 'LLL d p');
51
- }
52
- return value;
53
- };
54
79
  return (React.createElement(ChartCard, { title: title, value: value, dataTable: data, label: label, helperText: helperText },
55
80
  React.createElement(ResponsiveContainer, { width: "100%", height: height }, data.length ? (React.createElement(RechartsBarChart, { width: 500, layout: layout === 'horizontal' ? 'vertical' : 'horizontal', height: height, data: Object.values(entries), margin: {
56
81
  top: 24,
57
82
  right: 10,
58
- left: layout === 'vertical' ? -24 : -6,
83
+ left: layout === 'vertical' ? -24 : 16,
59
84
  bottom: 0,
60
85
  } },
61
86
  React.createElement(CartesianGrid, { vertical: false, stroke: theme.tokens.color_border_default }),
62
- React.createElement(XAxis, __assign({}, (layout === 'horizontal'
63
- ? { type: 'number' }
64
- : { tickFormatter: formatBottomTick, dataKey: bottomAxisDataKey }), { height: 30 })),
87
+ React.createElement(XAxis, __assign({}, (layout === 'horizontal' ? { type: 'number' } : { dataKey: bottomAxisDataKey }), { height: 30, tickFormatter: function (value) { return tickFormatter(value, bottomAxis.scaleType); }, axisLine: { stroke: theme.tokens.color_border_bold }, tickLine: { stroke: theme.tokens.color_border_bold } })),
65
88
  React.createElement(YAxis, __assign({}, (layout === 'horizontal' && {
66
89
  type: 'category',
67
- tickFormatter: formatBottomTick,
90
+ tickFormatter: function (value) { return tickFormatter(value, leftAxis.scaleType); },
68
91
  dataKey: bottomAxisDataKey,
69
- }), { domain: ['auto', 'auto'] })),
70
- React.createElement(Tooltip, { content: React.createElement(CustomTooltip, { active: undefined, payload: undefined }) }),
71
- React.createElement(Legend, { align: "center", iconType: "square", iconSize: 14, wrapperStyle: { paddingTop: 16 } }),
92
+ }), { domain: ['auto', 'auto'], axisLine: { stroke: theme.tokens.color_border_bold }, tickLine: { stroke: theme.tokens.color_border_bold } })),
93
+ React.createElement(Tooltip, { wrapperStyle: { outline: 'none' }, content: React.createElement(CustomTooltip, { active: undefined, payload: undefined, scaleType: bottomAxis.scaleType }) }),
94
+ React.createElement(Legend, { align: "center", iconType: "square", iconSize: 14, wrapperStyle: { paddingTop: 16 }, content: React.createElement(CustomLegend, { selectData: selectBar, handleLegendMouseEnter: handleLegendMouseEnter, handleLegendMouseLeave: handleLegendMouseLeave, dataVisibility: barVisibility }) }),
72
95
  groups.map(function (group, index) {
73
- return (React.createElement(Bar, __assign({ key: group, dataKey: group }, (isStacked && { stackId: 'stack' }), { name: group, maxBarSize: 70, fill: getBaseColorScale(theme)[index], radius: !isStacked || index == groups.length - 1
96
+ return (React.createElement(Bar, __assign({ key: group, dataKey: group }, (isStacked && { stackId: 'stack' }), { name: group, maxBarSize: 70, hide: barVisibility[group] === true, fill: barVisibility.hover === group || !barVisibility.hover
97
+ ? getColorScale(theme)[color]['base'][index]
98
+ : getColorScale(theme)[color]['muted'][index], radius: !isStacked || index == groups.length - 1
74
99
  ? layout === 'vertical'
75
100
  ? [4, 4, 0, 0]
76
101
  : [0, 4, 4, 0]