@pie-lib/charting 5.0.0 → 5.1.2

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 (56) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/lib/axes.js +33 -60
  3. package/lib/axes.js.map +1 -1
  4. package/lib/bars/bar.js +19 -30
  5. package/lib/bars/bar.js.map +1 -1
  6. package/lib/bars/common/bars.js +33 -47
  7. package/lib/bars/common/bars.js.map +1 -1
  8. package/lib/bars/histogram.js +19 -30
  9. package/lib/bars/histogram.js.map +1 -1
  10. package/lib/chart-setup.js +243 -0
  11. package/lib/chart-setup.js.map +1 -0
  12. package/lib/chart-type.js +68 -0
  13. package/lib/chart-type.js.map +1 -0
  14. package/lib/chart-types.js +2 -2
  15. package/lib/chart-types.js.map +1 -1
  16. package/lib/chart.js +41 -66
  17. package/lib/chart.js.map +1 -1
  18. package/lib/common/drag-handle.js +26 -41
  19. package/lib/common/drag-handle.js.map +1 -1
  20. package/lib/common/styles.js +7 -5
  21. package/lib/common/styles.js.map +1 -1
  22. package/lib/grid.js +19 -31
  23. package/lib/grid.js.map +1 -1
  24. package/lib/index.js +17 -1
  25. package/lib/index.js.map +1 -1
  26. package/lib/line/common/drag-handle.js +25 -39
  27. package/lib/line/common/drag-handle.js.map +1 -1
  28. package/lib/line/common/line.js +45 -73
  29. package/lib/line/common/line.js.map +1 -1
  30. package/lib/line/line-cross.js +25 -39
  31. package/lib/line/line-cross.js.map +1 -1
  32. package/lib/line/line-dot.js +24 -38
  33. package/lib/line/line-dot.js.map +1 -1
  34. package/lib/mark-label.js +10 -20
  35. package/lib/mark-label.js.map +1 -1
  36. package/lib/plot/common/plot.js +33 -47
  37. package/lib/plot/common/plot.js.map +1 -1
  38. package/lib/plot/dot.js +20 -31
  39. package/lib/plot/dot.js.map +1 -1
  40. package/lib/plot/line.js +21 -32
  41. package/lib/plot/line.js.map +1 -1
  42. package/lib/tool-menu.js +19 -32
  43. package/lib/tool-menu.js.map +1 -1
  44. package/lib/utils.js +10 -75
  45. package/lib/utils.js.map +1 -1
  46. package/package.json +2 -2
  47. package/src/axes.jsx +1 -1
  48. package/src/bars/common/bars.jsx +5 -2
  49. package/src/chart-setup.jsx +186 -0
  50. package/src/chart-type.js +39 -0
  51. package/src/chart.jsx +3 -8
  52. package/src/index.js +4 -1
  53. package/src/line/common/drag-handle.jsx +2 -1
  54. package/src/line/common/line.jsx +5 -3
  55. package/src/plot/common/plot.jsx +4 -2
  56. package/src/utils.js +4 -75
@@ -0,0 +1,186 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { color } from '@pie-lib/render-ui';
4
+ import { withStyles } from '@material-ui/core/styles';
5
+ import Typography from '@material-ui/core/Typography';
6
+ import ChartType from './chart-type';
7
+ import { NumberTextFieldCustom } from '@pie-lib/config-ui';
8
+
9
+ const ConfigureChartPanel = props => {
10
+ const { classes, model, onChange, gridValues = {}, labelValues = {} } = props;
11
+ const { range } = model;
12
+ const size = model.graph;
13
+
14
+ const gridOptions =
15
+ gridValues && gridValues.range ? { customValues: gridValues.range } : { min: 0, max: 10000 };
16
+ const labelOptions =
17
+ labelValues && labelValues.range ? { customValues: labelValues.range } : { min: 0, max: 10000 };
18
+
19
+ const stepConfig = (
20
+ <div className={classes.rowView}>
21
+ <NumberTextFieldCustom
22
+ className={classes.mediumTextField}
23
+ label="Grid Interval"
24
+ value={range.step}
25
+ variant="outlined"
26
+ onChange={(e, v) => onRangeChanged('step', v)}
27
+ {...gridOptions}
28
+ />
29
+ <NumberTextFieldCustom
30
+ className={classes.mediumTextField}
31
+ label={'Label Interval'}
32
+ value={range.labelStep}
33
+ variant={'outlined'}
34
+ onChange={(e, v) => onRangeChanged('labelStep', v)}
35
+ {...labelOptions}
36
+ />
37
+ </div>
38
+ );
39
+
40
+ const rangeProps = chartType => {
41
+ return chartType.includes('Plot') ? { min: 3, max: 10 } : { min: 0.05, max: 10000 };
42
+ };
43
+
44
+ const onSizeChanged = (key, value) => {
45
+ const graph = { ...size, [key]: value };
46
+
47
+ onChange({ ...model, graph });
48
+ };
49
+
50
+ const onRangeChanged = (key, value) => {
51
+ range[key] = value;
52
+
53
+ onChange({ ...model, range });
54
+ };
55
+
56
+ const onChartTypeChange = chartType => {
57
+ if (chartType.includes('Plot')) {
58
+ rangeProps.min = 3;
59
+ rangeProps.max = 10;
60
+
61
+ if (range.max > 10 || range.max < 3) {
62
+ range.max = 10;
63
+ }
64
+
65
+ range.step = 1;
66
+ range.labelStep = 1;
67
+
68
+ onChange({ ...model, range, chartType });
69
+
70
+ return;
71
+ }
72
+
73
+ onChange({ ...model, chartType });
74
+ };
75
+
76
+ return (
77
+ <div className={classes.wrapper}>
78
+ <Typography variant={'subtitle1'}>Configure Chart</Typography>
79
+ <div className={classes.content}>
80
+ <div className={classes.rowView}>
81
+ <ChartType value={model.chartType} onChange={e => onChartTypeChange(e.target.value)} />
82
+ <NumberTextFieldCustom
83
+ className={classes.mediumTextField}
84
+ label="Max Value"
85
+ value={range.max}
86
+ min={rangeProps(model.chartType).min}
87
+ max={rangeProps(model.chartType).max}
88
+ variant="outlined"
89
+ onChange={(e, v) => onRangeChanged('max', v)}
90
+ />
91
+ </div>
92
+ {!model.chartType.includes('Plot') && stepConfig}
93
+ <div className={classes.dimensions}>
94
+ <div>
95
+ <Typography>Dimensions(px)</Typography>
96
+ </div>
97
+ <div className={classes.columnView}>
98
+ <NumberTextFieldCustom
99
+ className={classes.textField}
100
+ label={'Width'}
101
+ value={size.width}
102
+ min={50}
103
+ max={700}
104
+ variant={'outlined'}
105
+ onChange={(e, v) => onSizeChanged('width', v)}
106
+ />
107
+ <Typography className={classes.disabled}>Min 50, Max 700</Typography>
108
+ </div>
109
+ <div className={classes.columnView}>
110
+ <NumberTextFieldCustom
111
+ className={classes.textField}
112
+ label={'Height'}
113
+ value={size.height}
114
+ min={400}
115
+ max={700}
116
+ variant={'outlined'}
117
+ onChange={(e, v) => onSizeChanged('height', v)}
118
+ />
119
+ <Typography className={classes.disabled}>Min 400, Max 700</Typography>
120
+ </div>
121
+ </div>
122
+ </div>
123
+ </div>
124
+ );
125
+ };
126
+
127
+ ConfigureChartPanel.propTypes = {
128
+ classes: PropTypes.object,
129
+ sizeConstraints: PropTypes.object,
130
+ domain: PropTypes.object,
131
+ gridIntervalValues: PropTypes.object,
132
+ includeAxes: PropTypes.bool,
133
+ labelIntervalValues: PropTypes.object,
134
+ onChange: PropTypes.function,
135
+ range: PropTypes.object,
136
+ size: PropTypes.object
137
+ };
138
+
139
+ const styles = theme => ({
140
+ wrapper: {
141
+ width: '450px'
142
+ },
143
+ content: {
144
+ display: 'flex',
145
+ flexDirection: 'column',
146
+ width: '100%',
147
+ marginTop: '24px'
148
+ },
149
+ columnView: {
150
+ display: 'flex',
151
+ flexDirection: 'column',
152
+ alignItems: 'center'
153
+ },
154
+ rowView: {
155
+ display: 'flex',
156
+ justifyContent: 'space-around',
157
+ alignItems: 'center'
158
+ },
159
+ textField: {
160
+ width: '130px',
161
+ margin: `${theme.spacing.unit}px ${theme.spacing.unit / 2}px`
162
+ },
163
+ mediumTextField: {
164
+ width: '160px',
165
+ margin: `${theme.spacing.unit}px ${theme.spacing.unit / 2}px`
166
+ },
167
+ largeTextField: {
168
+ width: '230px',
169
+ margin: `${theme.spacing.unit}px ${theme.spacing.unit / 2}px`
170
+ },
171
+ text: {
172
+ fontStyle: 'italic',
173
+ margin: `${theme.spacing.unit}px 0`
174
+ },
175
+ dimensions: {
176
+ display: 'flex',
177
+ justifyContent: 'space-between',
178
+ alignItems: 'center',
179
+ margin: '24px 0px'
180
+ },
181
+ disabled: {
182
+ color: color.disabled()
183
+ }
184
+ });
185
+
186
+ export default withStyles(styles)(ConfigureChartPanel);
@@ -0,0 +1,39 @@
1
+ import React from 'react';
2
+ import { withStyles } from '@material-ui/core/styles';
3
+ import MenuItem from '@material-ui/core/MenuItem';
4
+ import FormControl from '@material-ui/core/FormControl';
5
+ import InputLabel from '@material-ui/core/InputLabel';
6
+ import Select from '@material-ui/core/Select';
7
+ import OutlinedInput from '@material-ui/core/OutlinedInput';
8
+
9
+ const ChartType = withStyles(theme => ({
10
+ chartType: {
11
+ width: '160px'
12
+ },
13
+ chartTypeLabel: {
14
+ backgroundColor: 'transparent'
15
+ }
16
+ }))(({ onChange, value, classes }) => (
17
+ <div className={classes.chartType}>
18
+ <FormControl variant={'outlined'} className={classes.chartType}>
19
+ <InputLabel htmlFor="type-helper" className={classes.chartTypeLabel}>
20
+ ChartType
21
+ </InputLabel>
22
+
23
+ <Select
24
+ value={value}
25
+ onChange={onChange}
26
+ input={<OutlinedInput name="type" id="type-helper" />}
27
+ >
28
+ <MenuItem value={'histogram'}>Histogram</MenuItem>
29
+ <MenuItem value={'bar'}>Bar</MenuItem>
30
+ <MenuItem value={'lineDot'}>Line Dot</MenuItem>
31
+ <MenuItem value={'lineCross'}>Line Cross</MenuItem>
32
+ <MenuItem value={'dotPlot'}>Dot Plot</MenuItem>
33
+ <MenuItem value={'linePlot'}>Line Plot</MenuItem>
34
+ </Select>
35
+ </FormControl>
36
+ </div>
37
+ ));
38
+
39
+ export default ChartType;
package/src/chart.jsx CHANGED
@@ -48,6 +48,7 @@ export class Chart extends React.Component {
48
48
  onDataChange: PropTypes.func,
49
49
  addCategoryEnabled: PropTypes.bool,
50
50
  categoryDefaultLabel: PropTypes.string,
51
+ defineChart: PropTypes.bool,
51
52
  theme: PropTypes.object
52
53
  };
53
54
 
@@ -155,14 +156,7 @@ export class Chart extends React.Component {
155
156
  const { ChartComponent } = this.getChart();
156
157
  const categories = this.getFilteredCategories();
157
158
 
158
- const labelFontSize = (theme && theme.typography && theme.typography.fontSize) || 14;
159
- const correctValues = getDomainAndRangeByChartType(
160
- domain,
161
- range,
162
- size,
163
- chartType,
164
- labelFontSize
165
- );
159
+ const correctValues = getDomainAndRangeByChartType(domain, range, chartType);
166
160
 
167
161
  const { verticalLines, horizontalLines, leftAxis } = getGridLinesAndAxisByChartType(
168
162
  correctValues.range,
@@ -231,6 +225,7 @@ export class Chart extends React.Component {
231
225
  <ChartComponent
232
226
  {...common}
233
227
  data={categories}
228
+ defineChart={defineChart}
234
229
  onChange={this.changeData}
235
230
  onChangeCategory={this.changeCategory}
236
231
  />
package/src/index.js CHANGED
@@ -1,3 +1,6 @@
1
1
  import Chart from './chart';
2
2
  import chartTypes from './chart-types';
3
- export { Chart, chartTypes };
3
+ import ConfigureChartPanel from './chart-setup';
4
+ import ChartType from './chart-type';
5
+
6
+ export { Chart, chartTypes, ChartType, ConfigureChartPanel };
@@ -34,6 +34,7 @@ class RawDragHandle extends React.Component {
34
34
  correctness,
35
35
  ...rest
36
36
  } = this.props;
37
+
37
38
  const { scale } = graphProps;
38
39
  return (
39
40
  <CustomDraggableComponent
@@ -42,7 +43,7 @@ class RawDragHandle extends React.Component {
42
43
  y={y}
43
44
  classes={classes}
44
45
  className={classNames(className, !interactive && 'non-interactive')}
45
- correctness={interactive && correctness}
46
+ correctness={correctness}
46
47
  {...rest}
47
48
  />
48
49
  );
@@ -32,6 +32,7 @@ export class RawLine extends React.Component {
32
32
  xBand: PropTypes.func,
33
33
  index: PropTypes.number.isRequired,
34
34
  graphProps: types.GraphPropsType.isRequired,
35
+ defineChart: PropTypes.bool,
35
36
  data: PropTypes.arrayOf(
36
37
  PropTypes.shape({
37
38
  label: PropTypes.string,
@@ -77,7 +78,7 @@ export class RawLine extends React.Component {
77
78
  };
78
79
 
79
80
  render() {
80
- const { graphProps, data, classes, CustomDraggableComponent } = this.props;
81
+ const { graphProps, data, classes, CustomDraggableComponent, defineChart } = this.props;
81
82
  const { line: lineState, dragging } = this.state;
82
83
  const { scale } = graphProps;
83
84
  const lineToUse = dragging ? lineState : getData(data, graphProps.domain);
@@ -93,14 +94,15 @@ export class RawLine extends React.Component {
93
94
  {lineToUse &&
94
95
  lineToUse.map((point, i) => {
95
96
  const r = 6;
96
- const Component = point.interactive ? DraggableHandle : DragHandle;
97
+ const enableDraggable = defineChart || point.interactive;
98
+ const Component = enableDraggable ? DraggableHandle : DragHandle;
97
99
 
98
100
  return (
99
101
  <Component
100
102
  key={`point-${point.x}-${i}`}
101
103
  x={point.x}
102
104
  y={point.dragValue !== undefined ? point.dragValue : point.y}
103
- interactive={point.interactive}
105
+ interactive={enableDraggable}
104
106
  r={r}
105
107
  onDragStart={() => this.setState({ dragging: true })}
106
108
  onDrag={v =>
@@ -67,6 +67,7 @@ export class RawPlot extends React.Component {
67
67
  interactive,
68
68
  correctness
69
69
  } = this.props;
70
+
70
71
  const { scale, range, size } = graphProps;
71
72
  const { max } = range || {};
72
73
  const { dragValue } = this.state;
@@ -137,11 +138,12 @@ export class Plot extends React.Component {
137
138
  onChangeCategory: PropTypes.func,
138
139
  xBand: PropTypes.func,
139
140
  graphProps: types.GraphPropsType.isRequired,
141
+ defineChart: PropTypes.bool,
140
142
  CustomBarElement: PropTypes.func
141
143
  };
142
144
 
143
145
  render() {
144
- const { data, graphProps, xBand, CustomBarElement, onChangeCategory } = this.props;
146
+ const { data, graphProps, xBand, CustomBarElement, onChangeCategory, defineChart } = this.props;
145
147
 
146
148
  return (
147
149
  <Group>
@@ -149,7 +151,7 @@ export class Plot extends React.Component {
149
151
  <Bar
150
152
  value={d.value}
151
153
  label={d.label}
152
- interactive={d.interactive}
154
+ interactive={defineChart || d.interactive}
153
155
  xBand={xBand}
154
156
  index={index}
155
157
  key={`bar-${d.label}-${d.value}-${index}`}
package/src/utils.js CHANGED
@@ -50,53 +50,7 @@ export const getTickValues = (prop = {}) => {
50
50
  return tickValues;
51
51
  };
52
52
 
53
- export const customLabelStep = (rangeMax, size, labelFontSize) => {
54
- const ceilMax = Math.ceil(rangeMax);
55
- const segmentLength = size.height / ceilMax;
56
- const ticksToFitInOneSegment = 2;
57
-
58
- // how many ticksWidth fit in a segment
59
- const tickWidthPerSegment = segmentLength / labelFontSize;
60
- const rawLabelStep = ticksToFitInOneSegment / tickWidthPerSegment;
61
- const roundedStep = Math.ceil((rawLabelStep * 10) / 10);
62
-
63
- let labelStep;
64
-
65
- if (rawLabelStep > 0.15) {
66
- labelStep = roundedStep;
67
- } else if (rawLabelStep < 0.05) {
68
- labelStep = 0.1;
69
- } else {
70
- labelStep = 0.5;
71
- }
72
-
73
- return labelStep;
74
- };
75
-
76
- export const crowdedTicks = (rangeMax, customLabelStep, size, labelFontSize) => {
77
- const ceilMax = Math.ceil(rangeMax);
78
-
79
- const numberOfSegments = ceilMax * customLabelStep;
80
-
81
- return size.height / numberOfSegments < labelFontSize && size.height / numberOfSegments > 0.5;
82
- };
83
-
84
- // multiply values with 10^number_of_decimals if needed because modulo function(%) is only defined for integers
85
- const modulo = (a, b) => {
86
- if (Number.isInteger(b)) {
87
- return a % b;
88
- }
89
-
90
- const decimals = b
91
- .toString()
92
- .split('.')
93
- .pop().length;
94
- const aux = Math.pow(10, decimals);
95
-
96
- return (a * aux) % (b * aux);
97
- };
98
-
99
- export const getDomainAndRangeByChartType = (domain, range, size, chartType, labelFontSize) => {
53
+ export const getDomainAndRangeByChartType = (domain, range, chartType) => {
100
54
  let { step, labelStep, min, max } = range || {};
101
55
 
102
56
  if (!min) {
@@ -107,36 +61,11 @@ export const getDomainAndRangeByChartType = (domain, range, size, chartType, lab
107
61
  max = range.min + 1;
108
62
  }
109
63
 
110
- if (labelStep && !step) {
111
- step = labelStep;
64
+ if (!step) {
65
+ step = labelStep || 1;
112
66
  }
113
67
  if (!labelStep || (isNaN(labelStep) && step)) {
114
- let customLabelStep = step;
115
- let crowded = crowdedTicks(max, customLabelStep, size, labelFontSize);
116
-
117
- if (crowded) {
118
- customLabelStep = customLabelStep * 2;
119
- }
120
-
121
- labelStep = customLabelStep;
122
- }
123
-
124
- if (!step || (isNaN(step) && !labelStep) || isNaN(labelStep)) {
125
- labelStep = customLabelStep(max, size, labelFontSize);
126
-
127
- if (labelStep <= 1) {
128
- step = labelStep;
129
- } else if (labelStep <= 4) {
130
- step = 1;
131
- } else if (labelStep > 4 && labelStep < 10) {
132
- step = labelStep / 2;
133
- } else {
134
- step = labelStep / 3;
135
- }
136
- }
137
-
138
- if (modulo(max, step) !== 0) {
139
- max = max + step;
68
+ labelStep = step || 1;
140
69
  }
141
70
 
142
71
  range.max = max;