@pie-lib/graphing 2.4.3-next.271 → 2.4.3-next.303

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 (62) hide show
  1. package/lib/axis/arrow.js.map +1 -1
  2. package/lib/axis/axes.js.map +1 -1
  3. package/lib/axis/index.js.map +1 -1
  4. package/lib/bg.js.map +1 -1
  5. package/lib/container/actions.js.map +1 -1
  6. package/lib/container/index.js.map +1 -1
  7. package/lib/container/marks.js.map +1 -1
  8. package/lib/container/reducer.js.map +1 -1
  9. package/lib/coordinates-label.js.map +1 -1
  10. package/lib/graph-with-controls.js.map +1 -1
  11. package/lib/graph.js +7 -7
  12. package/lib/graph.js.map +1 -1
  13. package/lib/grid-setup.js +376 -0
  14. package/lib/grid-setup.js.map +1 -0
  15. package/lib/grid.js.map +1 -1
  16. package/lib/index.js +8 -0
  17. package/lib/index.js.map +1 -1
  18. package/lib/labels.js +7 -3
  19. package/lib/labels.js.map +1 -1
  20. package/lib/mark-label.js.map +1 -1
  21. package/lib/toggle-bar.js.map +1 -1
  22. package/lib/tool-menu.js.map +1 -1
  23. package/lib/tools/circle/bg-circle.js.map +1 -1
  24. package/lib/tools/circle/component.js.map +1 -1
  25. package/lib/tools/circle/index.js.map +1 -1
  26. package/lib/tools/index.js.map +1 -1
  27. package/lib/tools/line/component.js.map +1 -1
  28. package/lib/tools/line/index.js.map +1 -1
  29. package/lib/tools/parabola/component.js.map +1 -1
  30. package/lib/tools/parabola/index.js.map +1 -1
  31. package/lib/tools/point/component.js.map +1 -1
  32. package/lib/tools/point/index.js.map +1 -1
  33. package/lib/tools/polygon/component.js.map +1 -1
  34. package/lib/tools/polygon/index.js.map +1 -1
  35. package/lib/tools/polygon/line.js.map +1 -1
  36. package/lib/tools/polygon/polygon.js.map +1 -1
  37. package/lib/tools/ray/component.js.map +1 -1
  38. package/lib/tools/ray/index.js.map +1 -1
  39. package/lib/tools/segment/component.js.map +1 -1
  40. package/lib/tools/segment/index.js.map +1 -1
  41. package/lib/tools/shared/arrow-head.js.map +1 -1
  42. package/lib/tools/shared/line/index.js.map +1 -1
  43. package/lib/tools/shared/line/line-path.js.map +1 -1
  44. package/lib/tools/shared/line/with-root-edge.js.map +1 -1
  45. package/lib/tools/shared/point/arrow-point.js.map +1 -1
  46. package/lib/tools/shared/point/arrow.js.map +1 -1
  47. package/lib/tools/shared/point/base-point.js.map +1 -1
  48. package/lib/tools/shared/point/index.js.map +1 -1
  49. package/lib/tools/shared/styles.js.map +1 -1
  50. package/lib/tools/shared/types.js.map +1 -1
  51. package/lib/tools/sine/component.js.map +1 -1
  52. package/lib/tools/sine/index.js.map +1 -1
  53. package/lib/tools/vector/component.js.map +1 -1
  54. package/lib/tools/vector/index.js.map +1 -1
  55. package/lib/undo-redo.js.map +1 -1
  56. package/lib/use-debounce.js.map +1 -1
  57. package/lib/utils.js.map +1 -1
  58. package/package.json +2 -2
  59. package/src/graph.jsx +53 -57
  60. package/src/grid-setup.jsx +340 -0
  61. package/src/index.js +2 -1
  62. package/src/labels.jsx +7 -4
package/src/graph.jsx CHANGED
@@ -165,64 +165,60 @@ export class Graph extends React.Component {
165
165
  marks = removeBuildingToolIfCurrentToolDiffers({ marks: marks || [], currentTool });
166
166
 
167
167
  return (
168
- <Root
169
- // left side requires an extra padding of 10, in order to fit next to tick labels like 1.5, 1.55...
170
- paddingLeft={60}
171
- rootRef={r => (this.rootNode = r)}
172
- title={title}
173
- {...common}
174
- >
175
- <Grid {...common} />
176
- <Axes {...axesSettings} {...common} />
177
- <Bg {...size} onClick={this.onBgClick} {...common} />
168
+ <Root rootRef={r => (this.rootNode = r)} title={title} {...common}>
178
169
  <Labels value={labels} {...common} />
179
- <mask id="myMask">
180
- <rect {...maskSize} fill="white" /> {/* TODO hardcoded color */}
181
- </mask>
182
-
183
- <g id="marks" mask="url('#myMask')">
184
- {(backgroundMarks || []).map((m, index) => {
185
- const Component = this.getComponent(m);
186
- const markType = m.type;
187
-
188
- return (
189
- <Component
190
- key={`${markType}-${index}-bg`}
191
- mark={{ ...m, disabled: true, isBackground: true }}
192
- labelNode={this.state.labelNode}
193
- {...common}
194
- />
195
- );
196
- })}
197
-
198
- {marks.map((m, index) => {
199
- const Component = this.getComponent(m);
200
- const markType = m.type;
201
-
202
- return (
203
- <Component
204
- key={`${markType}-${index}`}
205
- mark={m}
206
- coordinatesOnHover={coordinatesOnHover}
207
- onChange={this.changeMark}
208
- onComplete={this.completeMark}
209
- onClick={this.onBgClick}
210
- onDragStart={this.startDrag}
211
- onDragStop={this.stopDrag}
212
- labelNode={this.state.labelNode}
213
- isToolActive={currentTool && markType === currentTool.type}
214
- {...common}
215
- />
216
- );
217
- })}
218
-
219
- <foreignObject
220
- ref={labelNode => (this.labelNode = labelNode)}
221
- x="0"
222
- y="0"
223
- {...size}
224
- style={{ pointerEvents: 'none' }}
225
- />
170
+ <g transform={`translate(${domain.padding}, ${range.padding})`}>
171
+ <Grid {...common} />
172
+ <Axes {...axesSettings} {...common} />
173
+ <Bg {...size} onClick={this.onBgClick} {...common} />
174
+ <mask id="myMask">
175
+ <rect {...maskSize} fill="white" /> {/* TODO hardcoded color */}
176
+ </mask>
177
+
178
+ <g id="marks" mask="url('#myMask')">
179
+ {(backgroundMarks || []).map((m, index) => {
180
+ const Component = this.getComponent(m);
181
+ const markType = m.type;
182
+
183
+ return (
184
+ <Component
185
+ key={`${markType}-${index}-bg`}
186
+ mark={{ ...m, disabled: true, isBackground: true }}
187
+ labelNode={this.state.labelNode}
188
+ {...common}
189
+ />
190
+ );
191
+ })}
192
+
193
+ {marks.map((m, index) => {
194
+ const Component = this.getComponent(m);
195
+ const markType = m.type;
196
+
197
+ return (
198
+ <Component
199
+ key={`${markType}-${index}`}
200
+ mark={m}
201
+ coordinatesOnHover={coordinatesOnHover}
202
+ onChange={this.changeMark}
203
+ onComplete={this.completeMark}
204
+ onClick={this.onBgClick}
205
+ onDragStart={this.startDrag}
206
+ onDragStop={this.stopDrag}
207
+ labelNode={this.state.labelNode}
208
+ isToolActive={currentTool && markType === currentTool.type}
209
+ {...common}
210
+ />
211
+ );
212
+ })}
213
+
214
+ <foreignObject
215
+ ref={labelNode => (this.labelNode = labelNode)}
216
+ x="0"
217
+ y="0"
218
+ {...size}
219
+ style={{ pointerEvents: 'none' }}
220
+ />
221
+ </g>
226
222
  </g>
227
223
  </Root>
228
224
  );
@@ -0,0 +1,340 @@
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 ExpansionPanelSummary from '@material-ui/core/ExpansionPanelSummary';
6
+ import Typography from '@material-ui/core/Typography';
7
+ import ExpansionPanelDetails from '@material-ui/core/ExpansionPanelDetails';
8
+ import ExpansionPanel from '@material-ui/core/ExpansionPanel';
9
+ import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
10
+ import TextField from '@material-ui/core/TextField';
11
+ import { NumberTextFieldCustom, Toggle } from '@pie-lib/config-ui';
12
+
13
+ const GridConfig = props => {
14
+ const { classes, disabled, labelValue, labelValues, gridValue, gridValues, onChange } = props;
15
+
16
+ return (
17
+ <div className={classes.columnView}>
18
+ <NumberTextFieldCustom
19
+ className={classes.textField}
20
+ label="Grid Interval"
21
+ value={gridValue}
22
+ customValues={gridValues}
23
+ variant="outlined"
24
+ disabled={disabled}
25
+ onChange={(e, v) => onChange('step', v)}
26
+ />
27
+ <NumberTextFieldCustom
28
+ className={classes.textField}
29
+ label="Label Interval"
30
+ value={labelValue}
31
+ customValues={labelValues}
32
+ variant="outlined"
33
+ disabled={disabled}
34
+ onChange={(e, v) => onChange('labelStep', v)}
35
+ />
36
+ </div>
37
+ );
38
+ };
39
+
40
+ const AxisConfig = props => {
41
+ const { classes, disabled, label, maxValue, minValue, onChange, type } = props;
42
+
43
+ return (
44
+ <div className={classes.columnView}>
45
+ <Typography variant="subtitle2">
46
+ <i>{type === 'domain' ? 'x' : 'y'}</i>
47
+ -axis
48
+ </Typography>
49
+ <NumberTextFieldCustom
50
+ className={classes.textField}
51
+ label="Min Value"
52
+ value={minValue}
53
+ variant="outlined"
54
+ disabled={disabled}
55
+ onChange={(e, v) => onChange('min', v)}
56
+ />
57
+ <NumberTextFieldCustom
58
+ className={classes.textField}
59
+ label="Max Value"
60
+ value={maxValue}
61
+ variant="outlined"
62
+ disabled={disabled}
63
+ onChange={(e, v) => onChange('max', v)}
64
+ />
65
+ <TextField
66
+ label="Label"
67
+ value={label}
68
+ inputProps={{
69
+ maxLength: 5,
70
+ style: { textAlign: 'center' }
71
+ }}
72
+ variant="outlined"
73
+ className={classes.textField}
74
+ onChange={e => onChange('axisLabel', e.target.value)}
75
+ />
76
+ </div>
77
+ );
78
+ };
79
+
80
+ const GridSetup = props => {
81
+ const {
82
+ classes,
83
+ sizeConstraints,
84
+ domain,
85
+ dimensionsEnabled,
86
+ gridValues,
87
+ includeAxes,
88
+ labelValues,
89
+ onChange,
90
+ range,
91
+ size,
92
+ standardGrid
93
+ } = props;
94
+ const gridProps = { min: 2, max: 41 };
95
+
96
+ const onIncludeAxes = includeAxes => {
97
+ const noAxesConfig = type => {
98
+ const axis = type === 'domain' ? domain : range;
99
+
100
+ return {
101
+ min: 1,
102
+ max: axis.max < gridProps.min || axis.max > gridProps.max ? 16 : axis.max,
103
+ step: 1,
104
+ labelStep: 0
105
+ };
106
+ };
107
+
108
+ const updatedRange = {
109
+ ...range,
110
+ ...(includeAxes ? { labelStep: 1 } : noAxesConfig('range'))
111
+ };
112
+ const updatedDomain = {
113
+ ...domain,
114
+ ...(includeAxes ? { labelStep: 1 } : noAxesConfig('domain'))
115
+ };
116
+
117
+ onChange({ includeAxes, range: updatedRange, domain: updatedDomain });
118
+ };
119
+
120
+ const onStandardGridChanged = value => {
121
+ onChange({
122
+ standardGrid: value,
123
+ range: {
124
+ ...domain,
125
+ axisLabel: range.axisLabel
126
+ },
127
+ graph: {
128
+ ...size,
129
+ height: size.width
130
+ }
131
+ });
132
+ };
133
+
134
+ const onSizeChanged = (key, value) => {
135
+ const graph = { ...size, [key]: value };
136
+
137
+ if (standardGrid) {
138
+ graph.height = value;
139
+ }
140
+
141
+ onChange({ graph });
142
+ };
143
+
144
+ const onDomainChanged = (key, value) => {
145
+ domain[key] = value;
146
+
147
+ if (standardGrid && key !== 'axisLabel') {
148
+ range[key] = value;
149
+ }
150
+
151
+ onChange({ domain, range });
152
+ };
153
+
154
+ const onRangeChanged = (key, value) => {
155
+ range[key] = value;
156
+
157
+ onChange({ range });
158
+ };
159
+
160
+ const axesConfig = (
161
+ <React.Fragment>
162
+ <div className={classes.rowView}>
163
+ <AxisConfig
164
+ classes={classes}
165
+ type="domain"
166
+ minValue={domain.min}
167
+ maxValue={domain.max}
168
+ label={domain.axisLabel}
169
+ includeAxes={includeAxes}
170
+ onChange={onDomainChanged}
171
+ />
172
+ <AxisConfig
173
+ classes={classes}
174
+ type="range"
175
+ minValue={range.min}
176
+ maxValue={range.max}
177
+ label={range.axisLabel}
178
+ disabled={standardGrid}
179
+ includeAxes={includeAxes}
180
+ onChange={onRangeChanged}
181
+ />
182
+ </div>
183
+ <Typography className={classes.text}>
184
+ If you want the axis to be visible, use a zero or negative Min Value, and a positive Max
185
+ Value
186
+ </Typography>
187
+ <div className={classes.rowView}>
188
+ <GridConfig
189
+ classes={classes}
190
+ gridValue={domain.step}
191
+ labelValue={domain.labelStep}
192
+ gridValues={gridValues}
193
+ labelValues={labelValues}
194
+ onChange={onDomainChanged}
195
+ />
196
+ <GridConfig
197
+ classes={classes}
198
+ disabled={standardGrid}
199
+ gridValue={range.step}
200
+ labelValue={range.labelStep}
201
+ onChange={onRangeChanged}
202
+ />
203
+ </div>
204
+ <Typography className={classes.text}>
205
+ For unnumbered gridlines, enter a label interval of 0
206
+ </Typography>
207
+ </React.Fragment>
208
+ );
209
+
210
+ const gridlinesConfig = (
211
+ <div className={classes.columnView}>
212
+ <NumberTextFieldCustom
213
+ className={classes.largeTextField}
214
+ label="Number of Horizontal Gridlines"
215
+ value={domain.max}
216
+ min={!includeAxes && gridProps.min}
217
+ max={!includeAxes && gridProps.max}
218
+ variant="outlined"
219
+ onChange={(e, v) => onDomainChanged('max', v)}
220
+ />
221
+ <NumberTextFieldCustom
222
+ className={classes.largeTextField}
223
+ label="Number of Vertical Gridlines"
224
+ value={range.max}
225
+ min={!includeAxes && gridProps.min}
226
+ max={!includeAxes && gridProps.max}
227
+ variant="outlined"
228
+ disabled={standardGrid}
229
+ onChange={(e, v) => onRangeChanged('max', v)}
230
+ />
231
+ </div>
232
+ );
233
+
234
+ return (
235
+ <div className={classes.wrapper}>
236
+ <ExpansionPanel>
237
+ <ExpansionPanelSummary expandIcon={<ExpandMoreIcon />}>
238
+ <Typography variant="subtitle1">Customize Grid Setup</Typography>
239
+ </ExpansionPanelSummary>
240
+ <ExpansionPanelDetails>
241
+ <div className={classes.content}>
242
+ <Toggle label="Include axes and labels?" toggle={onIncludeAxes} checked={includeAxes} />
243
+ <Toggle
244
+ label="Constrain to standard coordinate grid?"
245
+ toggle={onStandardGridChanged}
246
+ checked={standardGrid}
247
+ />
248
+ {includeAxes ? axesConfig : gridlinesConfig}
249
+ {dimensionsEnabled && (
250
+ <div className={classes.dimensions}>
251
+ <div>
252
+ <Typography>Dimensions(px)</Typography>
253
+ <Typography className={classes.disabled}>Min 150, Max 700</Typography>
254
+ </div>
255
+ <NumberTextFieldCustom
256
+ className={classes.textField}
257
+ label="Width"
258
+ value={size.width}
259
+ min={sizeConstraints.min}
260
+ max={sizeConstraints.max}
261
+ step={sizeConstraints.step}
262
+ variant="outlined"
263
+ onChange={(e, v) => onSizeChanged('width', v)}
264
+ />
265
+ <NumberTextFieldCustom
266
+ className={classes.textField}
267
+ label="Height"
268
+ value={size.height}
269
+ min={sizeConstraints.min}
270
+ max={sizeConstraints.max}
271
+ step={sizeConstraints.step}
272
+ variant="outlined"
273
+ disabled={standardGrid}
274
+ onChange={(e, v) => onSizeChanged('height', v)}
275
+ />
276
+ </div>
277
+ )}
278
+ </div>
279
+ </ExpansionPanelDetails>
280
+ </ExpansionPanel>
281
+ </div>
282
+ );
283
+ };
284
+
285
+ GridSetup.propTypes = {
286
+ classes: PropTypes.object,
287
+ domain: PropTypes.object,
288
+ dimensionsEnabled: PropTypes.object,
289
+ gridValues: PropTypes.object,
290
+ includeAxes: PropTypes.bool,
291
+ labelValues: PropTypes.object,
292
+ onChange: PropTypes.function,
293
+ range: PropTypes.object,
294
+ size: PropTypes.object,
295
+ sizeConstraints: PropTypes.object,
296
+ standardGrid: PropTypes.bool
297
+ };
298
+
299
+ const styles = theme => ({
300
+ wrapper: {
301
+ width: '450px'
302
+ },
303
+ content: {
304
+ display: 'flex',
305
+ flexDirection: 'column',
306
+ width: '100%'
307
+ },
308
+ columnView: {
309
+ display: 'flex',
310
+ flexDirection: 'column',
311
+ alignItems: 'center'
312
+ },
313
+ rowView: {
314
+ display: 'flex',
315
+ justifyContent: 'space-around',
316
+ alignItems: 'center'
317
+ },
318
+ textField: {
319
+ width: '130px',
320
+ margin: `${theme.spacing.unit}px ${theme.spacing.unit / 2}px`
321
+ },
322
+ largeTextField: {
323
+ width: '230px',
324
+ margin: `${theme.spacing.unit}px ${theme.spacing.unit / 2}px`
325
+ },
326
+ text: {
327
+ fontStyle: 'italic',
328
+ margin: `${theme.spacing.unit}px 0`
329
+ },
330
+ dimensions: {
331
+ display: 'flex',
332
+ justifyContent: 'space-between',
333
+ alignItems: 'center'
334
+ },
335
+ disabled: {
336
+ color: color.disabled()
337
+ }
338
+ });
339
+
340
+ export default withStyles(styles)(GridSetup);
package/src/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import Graph from './graph';
2
2
  import GraphContainer from './container';
3
+ import GridSetup from './grid-setup';
3
4
  import * as tools from './tools';
4
5
  import ToolMenu from './tool-menu';
5
6
 
6
- export { Graph, GraphContainer, ToolMenu, tools };
7
+ export { Graph, GraphContainer, GridSetup, ToolMenu, tools };
package/src/labels.jsx CHANGED
@@ -51,11 +51,12 @@ class RawLabel extends React.Component {
51
51
 
52
52
  render() {
53
53
  const { text, side, graphProps, classes } = this.props;
54
+ const { size, domain, range } = graphProps;
55
+ const totalHeight = (size.height || 500) + (range.padding || 0) * 2;
56
+ const totalWidth = (size.width || 500) + (domain.padding || 0) * 2;
54
57
 
55
- const { size } = graphProps;
56
-
57
- const transform = getTransform(side, size.width, size.height);
58
- const width = side === 'left' || side === 'right' ? size.height : size.width;
58
+ const transform = getTransform(side, totalWidth, totalHeight);
59
+ const width = side === 'left' || side === 'right' ? totalHeight : totalWidth;
59
60
  const height = 36;
60
61
  const y = getY(side, height);
61
62
 
@@ -102,8 +103,10 @@ export class Labels extends React.Component {
102
103
  };
103
104
 
104
105
  static defaultProps = {};
106
+
105
107
  render() {
106
108
  const { value, graphProps } = this.props;
109
+
107
110
  return (
108
111
  <React.Fragment>
109
112
  {value && value.left && (