@pie-lib/graphing-solution-set 2.16.0-beta.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 (151) hide show
  1. package/CHANGELOG.json +1 -0
  2. package/CHANGELOG.md +16 -0
  3. package/LICENSE.md +5 -0
  4. package/NEXT.CHANGELOG.json +1 -0
  5. package/lib/__tests__/graph-with-controls.test.js +191 -0
  6. package/lib/__tests__/graph.test.js +290 -0
  7. package/lib/__tests__/grid.test.js +40 -0
  8. package/lib/__tests__/labels.test.js +59 -0
  9. package/lib/__tests__/mark-label.test.js +154 -0
  10. package/lib/__tests__/toggle-bar.test.js +54 -0
  11. package/lib/__tests__/tool-menu.test.js +43 -0
  12. package/lib/__tests__/undo-redo.test.js +42 -0
  13. package/lib/__tests__/use-debounce.test.js +28 -0
  14. package/lib/__tests__/utils.js +72 -0
  15. package/lib/__tests__/utils.test.js +133 -0
  16. package/lib/axis/__tests__/arrow.test.js +68 -0
  17. package/lib/axis/__tests__/axes.test.js +214 -0
  18. package/lib/axis/arrow.js +115 -0
  19. package/lib/axis/axes.js +415 -0
  20. package/lib/axis/index.js +26 -0
  21. package/lib/bg.js +139 -0
  22. package/lib/container/actions.js +24 -0
  23. package/lib/container/index.js +166 -0
  24. package/lib/container/marks.js +27 -0
  25. package/lib/container/middleware.js +25 -0
  26. package/lib/container/reducer.js +25 -0
  27. package/lib/coordinates-label.js +109 -0
  28. package/lib/graph-with-controls.js +372 -0
  29. package/lib/graph.js +419 -0
  30. package/lib/grid-setup.js +462 -0
  31. package/lib/grid.js +176 -0
  32. package/lib/index.js +51 -0
  33. package/lib/labels.js +299 -0
  34. package/lib/mark-label.js +208 -0
  35. package/lib/toggle-bar.js +336 -0
  36. package/lib/tool-menu.js +325 -0
  37. package/lib/tools/index.js +29 -0
  38. package/lib/tools/line/__tests__/component.test.js +56 -0
  39. package/lib/tools/line/component.js +106 -0
  40. package/lib/tools/line/index.js +16 -0
  41. package/lib/tools/polygon/__tests__/component.test.js +245 -0
  42. package/lib/tools/polygon/__tests__/index.test.js +95 -0
  43. package/lib/tools/polygon/__tests__/line.test.js +43 -0
  44. package/lib/tools/polygon/__tests__/polygon.test.js +73 -0
  45. package/lib/tools/polygon/component.js +457 -0
  46. package/lib/tools/polygon/index.js +106 -0
  47. package/lib/tools/polygon/line.js +151 -0
  48. package/lib/tools/polygon/polygon.js +171 -0
  49. package/lib/tools/shared/__tests__/arrow-head.test.js +62 -0
  50. package/lib/tools/shared/arrow-head.js +75 -0
  51. package/lib/tools/shared/line/__tests__/index.test.js +291 -0
  52. package/lib/tools/shared/line/__tests__/line-path.test.js +78 -0
  53. package/lib/tools/shared/line/__tests__/with-root-edge.test.js +122 -0
  54. package/lib/tools/shared/line/index.js +637 -0
  55. package/lib/tools/shared/line/line-path.js +145 -0
  56. package/lib/tools/shared/line/with-root-edge.js +155 -0
  57. package/lib/tools/shared/point/__tests__/arrow-point.test.js +137 -0
  58. package/lib/tools/shared/point/__tests__/base-point.test.js +134 -0
  59. package/lib/tools/shared/point/arrow-point.js +113 -0
  60. package/lib/tools/shared/point/arrow.js +96 -0
  61. package/lib/tools/shared/point/base-point.js +151 -0
  62. package/lib/tools/shared/point/index.js +94 -0
  63. package/lib/tools/shared/styles.js +49 -0
  64. package/lib/tools/shared/types.js +19 -0
  65. package/lib/undo-redo.js +107 -0
  66. package/lib/use-debounce.js +32 -0
  67. package/lib/utils.js +314 -0
  68. package/package.json +50 -0
  69. package/src/__tests__/__snapshots__/graph-with-controls.test.jsx.snap +114 -0
  70. package/src/__tests__/__snapshots__/graph.test.jsx.snap +213 -0
  71. package/src/__tests__/__snapshots__/grid.test.jsx.snap +54 -0
  72. package/src/__tests__/__snapshots__/labels.test.jsx.snap +30 -0
  73. package/src/__tests__/__snapshots__/mark-label.test.jsx.snap +37 -0
  74. package/src/__tests__/__snapshots__/toggle-bar.test.jsx.snap +7 -0
  75. package/src/__tests__/__snapshots__/tool-menu.test.jsx.snap +35 -0
  76. package/src/__tests__/__snapshots__/undo-redo.test.jsx.snap +15 -0
  77. package/src/__tests__/graph-with-controls.test.jsx +131 -0
  78. package/src/__tests__/graph.test.jsx +230 -0
  79. package/src/__tests__/grid.test.jsx +20 -0
  80. package/src/__tests__/labels.test.jsx +38 -0
  81. package/src/__tests__/mark-label.test.jsx +68 -0
  82. package/src/__tests__/toggle-bar.test.jsx +36 -0
  83. package/src/__tests__/tool-menu.test.jsx +29 -0
  84. package/src/__tests__/undo-redo.test.jsx +25 -0
  85. package/src/__tests__/use-debounce.test.js +21 -0
  86. package/src/__tests__/utils.js +38 -0
  87. package/src/__tests__/utils.test.js +151 -0
  88. package/src/axis/__tests__/__snapshots__/arrow.test.jsx.snap +33 -0
  89. package/src/axis/__tests__/__snapshots__/axes.test.jsx.snap +122 -0
  90. package/src/axis/__tests__/arrow.test.jsx +39 -0
  91. package/src/axis/__tests__/axes.test.jsx +220 -0
  92. package/src/axis/arrow.jsx +62 -0
  93. package/src/axis/axes.jsx +307 -0
  94. package/src/axis/index.js +2 -0
  95. package/src/bg.jsx +96 -0
  96. package/src/container/actions.js +8 -0
  97. package/src/container/index.jsx +86 -0
  98. package/src/container/marks.js +14 -0
  99. package/src/container/middleware.js +7 -0
  100. package/src/container/reducer.js +5 -0
  101. package/src/coordinates-label.jsx +73 -0
  102. package/src/graph-with-controls.jsx +263 -0
  103. package/src/graph.jsx +334 -0
  104. package/src/grid-setup.jsx +427 -0
  105. package/src/grid.jsx +135 -0
  106. package/src/index.js +7 -0
  107. package/src/labels.jsx +214 -0
  108. package/src/mark-label.jsx +136 -0
  109. package/src/toggle-bar.jsx +242 -0
  110. package/src/tool-menu.jsx +294 -0
  111. package/src/tools/index.js +8 -0
  112. package/src/tools/line/__tests__/__snapshots__/component.test.jsx.snap +20 -0
  113. package/src/tools/line/__tests__/component.test.jsx +36 -0
  114. package/src/tools/line/component.jsx +77 -0
  115. package/src/tools/line/index.js +4 -0
  116. package/src/tools/polygon/__tests__/__snapshots__/component.test.jsx.snap +94 -0
  117. package/src/tools/polygon/__tests__/__snapshots__/line.test.jsx.snap +44 -0
  118. package/src/tools/polygon/__tests__/__snapshots__/polygon.test.jsx.snap +53 -0
  119. package/src/tools/polygon/__tests__/component.test.jsx +214 -0
  120. package/src/tools/polygon/__tests__/index.test.js +65 -0
  121. package/src/tools/polygon/__tests__/line.test.jsx +25 -0
  122. package/src/tools/polygon/__tests__/polygon.test.jsx +44 -0
  123. package/src/tools/polygon/component.jsx +336 -0
  124. package/src/tools/polygon/index.js +52 -0
  125. package/src/tools/polygon/line.jsx +78 -0
  126. package/src/tools/polygon/polygon.jsx +101 -0
  127. package/src/tools/shared/__tests__/__snapshots__/arrow-head.test.jsx.snap +32 -0
  128. package/src/tools/shared/__tests__/arrow-head.test.jsx +34 -0
  129. package/src/tools/shared/arrow-head.jsx +46 -0
  130. package/src/tools/shared/line/__tests__/__snapshots__/index.test.jsx.snap +360 -0
  131. package/src/tools/shared/line/__tests__/__snapshots__/line-path.test.jsx.snap +57 -0
  132. package/src/tools/shared/line/__tests__/__snapshots__/with-root-edge.test.jsx.snap +63 -0
  133. package/src/tools/shared/line/__tests__/index.test.jsx +247 -0
  134. package/src/tools/shared/line/__tests__/line-path.test.jsx +53 -0
  135. package/src/tools/shared/line/__tests__/with-root-edge.test.jsx +73 -0
  136. package/src/tools/shared/line/index.jsx +473 -0
  137. package/src/tools/shared/line/line-path.jsx +88 -0
  138. package/src/tools/shared/line/with-root-edge.jsx +97 -0
  139. package/src/tools/shared/point/__tests__/__snapshots__/arrow-point.test.jsx.snap +55 -0
  140. package/src/tools/shared/point/__tests__/__snapshots__/base-point.test.jsx.snap +43 -0
  141. package/src/tools/shared/point/__tests__/arrow-point.test.jsx +87 -0
  142. package/src/tools/shared/point/__tests__/base-point.test.jsx +84 -0
  143. package/src/tools/shared/point/arrow-point.jsx +60 -0
  144. package/src/tools/shared/point/arrow.jsx +40 -0
  145. package/src/tools/shared/point/base-point.jsx +86 -0
  146. package/src/tools/shared/point/index.jsx +60 -0
  147. package/src/tools/shared/styles.js +20 -0
  148. package/src/tools/shared/types.js +8 -0
  149. package/src/undo-redo.jsx +47 -0
  150. package/src/use-debounce.js +13 -0
  151. package/src/utils.js +234 -0
@@ -0,0 +1,427 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { color, InputContainer } 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 { NumberTextFieldCustom, Toggle } from '@pie-lib/config-ui';
11
+ import EditableHTML from '@pie-lib/editable-html';
12
+
13
+ const GridConfig = (props) => {
14
+ const { classes, disabled, displayedFields, labelValue, labelValues, gridValue, gridValues, onChange } = props;
15
+ const { labelStep = {}, step = {} } = displayedFields;
16
+
17
+ return (
18
+ <div className={classes.columnView}>
19
+ {step && step.enabled && (
20
+ <NumberTextFieldCustom
21
+ className={classes.mediumTextField}
22
+ label={step.label || ''}
23
+ value={gridValue}
24
+ customValues={gridValues}
25
+ variant="outlined"
26
+ disabled={disabled}
27
+ onChange={(e, v) => onChange('step', v)}
28
+ />
29
+ )}
30
+ {labelStep && labelStep.enabled && (
31
+ <NumberTextFieldCustom
32
+ className={classes.mediumTextField}
33
+ label={labelStep.label || ''}
34
+ value={labelValue}
35
+ customValues={labelValues}
36
+ variant="outlined"
37
+ disabled={disabled}
38
+ onChange={(e, v) => onChange('labelStep', v)}
39
+ />
40
+ )}
41
+ </div>
42
+ );
43
+ };
44
+
45
+ GridConfig.propTypes = {
46
+ classes: PropTypes.object,
47
+ disabled: PropTypes.bool,
48
+ displayedFields: PropTypes.object,
49
+ labelValue: PropTypes.number,
50
+ labelValues: PropTypes.array,
51
+ gridValue: PropTypes.number,
52
+ gridValues: PropTypes.array,
53
+ onChange: PropTypes.func,
54
+ };
55
+
56
+ const AxisConfig = (props) => {
57
+ const { classes, disabled, displayedFields, displayHeader, label, maxValue, minValue, onChange, type } = props;
58
+ const { axisLabel = {}, min = {}, max = {} } = displayedFields;
59
+ const activePlugins = [
60
+ 'bold',
61
+ 'italic',
62
+ 'underline',
63
+ 'strikethrough',
64
+ // 'languageCharacters'
65
+ ];
66
+
67
+ return (
68
+ <div className={classes.columnView}>
69
+ {displayHeader && (
70
+ <Typography variant="subtitle2">
71
+ <i>{type === 'domain' ? 'x' : 'y'}</i>
72
+ -axis
73
+ </Typography>
74
+ )}
75
+ {min && min.enabled && (
76
+ <NumberTextFieldCustom
77
+ className={classes.mediumTextField}
78
+ label={min.label || ''}
79
+ value={minValue}
80
+ min={-10000}
81
+ max={maxValue - 0.05}
82
+ variant="outlined"
83
+ disabled={disabled}
84
+ onChange={(e, v) => onChange('min', v)}
85
+ />
86
+ )}
87
+ {max && max.enabled && (
88
+ <NumberTextFieldCustom
89
+ className={classes.mediumTextField}
90
+ label={max.label || ''}
91
+ value={maxValue}
92
+ min={minValue + 0.05}
93
+ max={10000}
94
+ variant="outlined"
95
+ disabled={disabled}
96
+ onChange={(e, v) => onChange('max', v)}
97
+ />
98
+ )}
99
+ {axisLabel && axisLabel.enabled && (
100
+ <InputContainer label={axisLabel.label || ''} className={classes.mediumTextField}>
101
+ <EditableHTML
102
+ className={classes.axisLabel}
103
+ onChange={(value) => onChange('axisLabel', value)}
104
+ markup={label || ''}
105
+ charactersLimit={5}
106
+ activePlugins={activePlugins}
107
+ />
108
+ </InputContainer>
109
+ )}
110
+ </div>
111
+ );
112
+ };
113
+
114
+ AxisConfig.propTypes = {
115
+ classes: PropTypes.object,
116
+ disabled: PropTypes.bool,
117
+ displayedFields: PropTypes.object,
118
+ displayHeader: PropTypes.bool,
119
+ label: PropTypes.string,
120
+ maxValue: PropTypes.number,
121
+ minValue: PropTypes.number,
122
+ type: PropTypes.string,
123
+ onChange: PropTypes.func,
124
+ };
125
+ const GridSetup = (props) => {
126
+ const {
127
+ classes,
128
+ domain,
129
+ displayedFields = {},
130
+ gridValues = {},
131
+ includeAxes,
132
+ labelValues = {},
133
+ onChange,
134
+ onChangeView,
135
+ range,
136
+ size,
137
+ sizeConstraints,
138
+ standardGrid,
139
+ } = props;
140
+ const gridProps = { min: 2, max: 41 };
141
+ const {
142
+ axisLabel = {},
143
+ dimensionsEnabled,
144
+ includeAxesEnabled,
145
+ labelStep = {},
146
+ min = {},
147
+ max = {},
148
+ standardGridEnabled,
149
+ step = {},
150
+ } = displayedFields || {};
151
+ const displayAxisType = min.enabled || max.enabled || axisLabel.enabled || step.enabled || labelStep.enabled;
152
+ const gridConfigFields = { step, labelStep };
153
+ const axisConfigFields = { min, max, axisLabel };
154
+
155
+ const onIncludeAxes = (includeAxes) => {
156
+ const noAxesConfig = (type) => {
157
+ const axis = type === 'domain' ? domain : range;
158
+
159
+ return {
160
+ min: 1,
161
+ max: axis.max < gridProps.min || axis.max > gridProps.max ? 16 : axis.max,
162
+ step: 1,
163
+ labelStep: 0,
164
+ };
165
+ };
166
+
167
+ const updatedRange = {
168
+ ...range,
169
+ ...(includeAxes ? { labelStep: 1 } : noAxesConfig('range')),
170
+ };
171
+ const updatedDomain = {
172
+ ...domain,
173
+ ...(includeAxes ? { labelStep: 1 } : noAxesConfig('domain')),
174
+ };
175
+
176
+ onChange({ includeAxes, range: updatedRange, domain: updatedDomain });
177
+ };
178
+
179
+ const onStandardGridChanged = (value) => {
180
+ onChange({
181
+ standardGrid: value,
182
+ range: {
183
+ ...domain,
184
+ axisLabel: range.axisLabel,
185
+ },
186
+ graph: {
187
+ ...size,
188
+ height: size.width,
189
+ },
190
+ });
191
+ };
192
+
193
+ const onSizeChanged = (key, value) => {
194
+ const graph = { ...size, [key]: value };
195
+
196
+ if (standardGrid) {
197
+ graph.height = value;
198
+ }
199
+
200
+ onChange({ graph });
201
+ };
202
+
203
+ const onDomainChanged = (key, value) => {
204
+ domain[key] = value;
205
+
206
+ if (standardGrid && key !== 'axisLabel') {
207
+ range[key] = value;
208
+ }
209
+
210
+ onChange({ domain, range });
211
+ };
212
+
213
+ const onRangeChanged = (key, value) => {
214
+ range[key] = value;
215
+
216
+ onChange({ range });
217
+ };
218
+
219
+ const axesConfig = (
220
+ <React.Fragment>
221
+ <div className={classes.rowView}>
222
+ <AxisConfig
223
+ classes={classes}
224
+ displayedFields={axisConfigFields}
225
+ displayHeader={displayAxisType}
226
+ type="domain"
227
+ minValue={domain.min}
228
+ maxValue={domain.max}
229
+ label={domain.axisLabel}
230
+ includeAxes={includeAxes}
231
+ onChange={onDomainChanged}
232
+ />
233
+ <AxisConfig
234
+ classes={classes}
235
+ displayedFields={axisConfigFields}
236
+ displayHeader={displayAxisType}
237
+ type="range"
238
+ minValue={range.min}
239
+ maxValue={range.max}
240
+ label={range.axisLabel}
241
+ disabled={standardGrid}
242
+ includeAxes={includeAxes}
243
+ onChange={onRangeChanged}
244
+ />
245
+ </div>
246
+ {(min.enabled || max.enabled) && (
247
+ <Typography className={classes.text}>
248
+ If you want the axis to be visible, use a zero or negative Min Value, and a positive Max Value
249
+ </Typography>
250
+ )}
251
+ {(step.enabled || labelStep.enabled) && (
252
+ <div className={classes.rowView}>
253
+ <GridConfig
254
+ classes={classes}
255
+ displayedFields={gridConfigFields}
256
+ gridValue={domain.step}
257
+ labelValue={domain.labelStep}
258
+ gridValues={gridValues.domain || []}
259
+ labelValues={labelValues.domain || []}
260
+ onChange={onDomainChanged}
261
+ />
262
+ <GridConfig
263
+ classes={classes}
264
+ disabled={standardGrid}
265
+ displayedFields={gridConfigFields}
266
+ gridValue={range.step}
267
+ labelValue={range.labelStep}
268
+ gridValues={gridValues.range || []}
269
+ labelValues={labelValues.range || []}
270
+ onChange={onRangeChanged}
271
+ />
272
+ </div>
273
+ )}
274
+ {labelStep.enabled && (
275
+ <Typography className={classes.text}>For unnumbered gridlines, enter a label interval of 0</Typography>
276
+ )}
277
+ </React.Fragment>
278
+ );
279
+
280
+ const gridlinesConfig = max.enabled ? (
281
+ <div className={classes.columnView}>
282
+ <NumberTextFieldCustom
283
+ className={classes.largeTextField}
284
+ label="Number of Vertical Gridlines"
285
+ value={domain.max}
286
+ min={!includeAxes && gridProps.min}
287
+ max={!includeAxes && gridProps.max}
288
+ variant="outlined"
289
+ onChange={(e, v) => onDomainChanged('max', v)}
290
+ />
291
+ <NumberTextFieldCustom
292
+ className={classes.largeTextField}
293
+ label="Number of Horizontal Gridlines"
294
+ value={range.max}
295
+ min={!includeAxes && gridProps.min}
296
+ max={!includeAxes && gridProps.max}
297
+ variant="outlined"
298
+ disabled={standardGrid}
299
+ onChange={(e, v) => onRangeChanged('max', v)}
300
+ />
301
+ </div>
302
+ ) : null;
303
+
304
+ return (
305
+ <div className={classes.wrapper}>
306
+ <ExpansionPanel onChange={onChangeView}>
307
+ <ExpansionPanelSummary expandIcon={<ExpandMoreIcon />}>
308
+ <Typography variant="subtitle1">Customize Grid Setup</Typography>
309
+ </ExpansionPanelSummary>
310
+ <ExpansionPanelDetails>
311
+ <div className={classes.content}>
312
+ {includeAxesEnabled && (
313
+ <Toggle
314
+ label="Include axes and labels?"
315
+ toggle={onIncludeAxes}
316
+ checked={includeAxes} />
317
+ )}
318
+ {standardGridEnabled && (
319
+ <Toggle
320
+ label="Constrain to standard coordinate grid?"
321
+ toggle={onStandardGridChanged}
322
+ checked={standardGrid}
323
+ />
324
+ )}
325
+ {includeAxes ? axesConfig : gridlinesConfig}
326
+ {dimensionsEnabled && (
327
+ <div className={classes.dimensions}>
328
+ <div>
329
+ <Typography>Dimensions(px)</Typography>
330
+ <Typography className={classes.disabled}>
331
+ Min {sizeConstraints.min}, Max {sizeConstraints.max}
332
+ </Typography>
333
+ </div>
334
+ <NumberTextFieldCustom
335
+ className={classes.textField}
336
+ label="Width"
337
+ value={size.width}
338
+ min={sizeConstraints.min}
339
+ max={sizeConstraints.max}
340
+ step={sizeConstraints.step}
341
+ variant="outlined"
342
+ onChange={(e, v) => onSizeChanged('width', v)}
343
+ />
344
+ <NumberTextFieldCustom
345
+ className={classes.textField}
346
+ label="Height"
347
+ value={size.height}
348
+ min={sizeConstraints.min}
349
+ max={sizeConstraints.max}
350
+ step={sizeConstraints.step}
351
+ variant="outlined"
352
+ disabled={standardGrid}
353
+ onChange={(e, v) => onSizeChanged('height', v)}
354
+ />
355
+ </div>
356
+ )}
357
+ </div>
358
+ </ExpansionPanelDetails>
359
+ </ExpansionPanel>
360
+ </div>
361
+ );
362
+ };
363
+
364
+ GridSetup.propTypes = {
365
+ classes: PropTypes.object,
366
+ domain: PropTypes.object,
367
+ displayedFields: PropTypes.object,
368
+ gridValues: PropTypes.object,
369
+ includeAxes: PropTypes.bool,
370
+ labelValues: PropTypes.object,
371
+ onChange: PropTypes.func,
372
+ onChangeView: PropTypes.func,
373
+ range: PropTypes.object,
374
+ size: PropTypes.object,
375
+ sizeConstraints: PropTypes.object,
376
+ standardGrid: PropTypes.bool,
377
+ };
378
+
379
+ const styles = (theme) => ({
380
+ wrapper: {
381
+ width: '450px',
382
+ },
383
+ content: {
384
+ display: 'flex',
385
+ flexDirection: 'column',
386
+ width: '100%',
387
+ },
388
+ columnView: {
389
+ display: 'flex',
390
+ flexDirection: 'column',
391
+ alignItems: 'center',
392
+ },
393
+ rowView: {
394
+ display: 'flex',
395
+ justifyContent: 'space-around',
396
+ alignItems: 'center',
397
+ },
398
+ textField: {
399
+ width: '130px',
400
+ margin: `${theme.spacing.unit}px ${theme.spacing.unit / 2}px`,
401
+ },
402
+ mediumTextField: {
403
+ width: '160px',
404
+ margin: `${theme.spacing.unit}px ${theme.spacing.unit / 2}px`,
405
+ },
406
+ largeTextField: {
407
+ width: '230px',
408
+ margin: `${theme.spacing.unit}px ${theme.spacing.unit / 2}px`,
409
+ },
410
+ text: {
411
+ fontStyle: 'italic',
412
+ margin: `${theme.spacing.unit}px 0`,
413
+ },
414
+ dimensions: {
415
+ display: 'flex',
416
+ justifyContent: 'space-between',
417
+ alignItems: 'center',
418
+ },
419
+ disabled: {
420
+ color: color.disabled(),
421
+ },
422
+ axisLabel: {
423
+ paddingTop: theme.spacing.unit * 2,
424
+ },
425
+ });
426
+
427
+ export default withStyles(styles)(GridSetup);
package/src/grid.jsx ADDED
@@ -0,0 +1,135 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import * as vx from '@vx/grid';
4
+ import { types } from '@pie-lib/plot';
5
+ import { withStyles } from '@material-ui/core/styles';
6
+ import { getTickValues } from './utils';
7
+
8
+ export class Grid extends React.Component {
9
+ static propTypes = {
10
+ disabled: PropTypes.bool,
11
+ disabledAdditionalGrid: PropTypes.bool,
12
+ classes: PropTypes.object.isRequired,
13
+ graphProps: types.GraphPropsType.isRequired,
14
+ };
15
+
16
+ getAdditionalGridProps = (rowTickValues, columnTickValues) => {
17
+ const {
18
+ graphProps: {
19
+ scale,
20
+ size: { width, height },
21
+ domain,
22
+ range,
23
+ },
24
+ } = this.props;
25
+ const rowTickLabelValues = getTickValues({
26
+ ...range,
27
+ step: range.labelStep,
28
+ }).filter((value) => rowTickValues.includes(value));
29
+ const columnTickLabelValues = getTickValues({
30
+ ...domain,
31
+ step: domain.labelStep,
32
+ }).filter((value) => columnTickValues.includes(value));
33
+
34
+ const minValueLength =
35
+ (rowTickLabelValues.length &&
36
+ Math.min(...rowTickLabelValues)
37
+ .toString()
38
+ .replace(/[.-]/g, '').length) ||
39
+ 1;
40
+ const maxValueLength =
41
+ (rowTickLabelValues.length &&
42
+ Math.max(...rowTickLabelValues)
43
+ .toString()
44
+ .replace(/[.-]/g, '').length) ||
45
+ 1;
46
+
47
+ const rowLabelLength = Math.max(minValueLength, maxValueLength) * 9 + 22;
48
+ const horizontalDistanceToZero = scale.x(0);
49
+ const verticalDistanceToZero = scale.y(0);
50
+ const columnLabelLength = 28;
51
+ const rowStrokeDasharray = `${horizontalDistanceToZero - rowLabelLength} ${rowLabelLength} ${width}`;
52
+ const columnStrokeDasharray = `${verticalDistanceToZero} ${columnLabelLength} ${height}`;
53
+
54
+ const displayAdditionalGrid =
55
+ domain.labelStep > 0 &&
56
+ range.labelStep > 0 &&
57
+ rowTickLabelValues &&
58
+ columnTickLabelValues &&
59
+ rowTickLabelValues.length > 1 &&
60
+ columnTickLabelValues.length > 1 &&
61
+ (rowTickLabelValues.length !== rowTickValues.length || columnTickLabelValues.length !== columnTickValues.length);
62
+
63
+ const filteredColumnValues = columnTickLabelValues.filter(
64
+ (value) => value >= 0 || horizontalDistanceToZero - scale.x(value) > rowLabelLength,
65
+ );
66
+ const filteredRowValues = rowTickLabelValues.filter(
67
+ (value) => value >= 0 || scale.y(value) - verticalDistanceToZero > columnLabelLength,
68
+ );
69
+
70
+ return {
71
+ rowTickLabelValues: filteredRowValues,
72
+ columnTickLabelValues: filteredColumnValues,
73
+ rowStrokeDasharray,
74
+ columnStrokeDasharray,
75
+ displayAdditionalGrid,
76
+ };
77
+ };
78
+
79
+ render() {
80
+ const { graphProps } = this.props;
81
+ const {
82
+ scale,
83
+ size: { height, width },
84
+ domain,
85
+ range,
86
+ } = graphProps;
87
+ const rowTickValues = getTickValues(range);
88
+ const columnTickValues = getTickValues(domain);
89
+ const {
90
+ rowTickLabelValues,
91
+ columnTickLabelValues,
92
+ rowStrokeDasharray,
93
+ columnStrokeDasharray,
94
+ displayAdditionalGrid,
95
+ } = this.getAdditionalGridProps(rowTickValues, columnTickValues);
96
+
97
+ const additionalGridStroke =
98
+ domain.labelStep * 2 === domain.step || range.labelStep * 2 === range.step ? '#9FA8DA' : '#7985CB';
99
+
100
+ return (
101
+ <>
102
+ <vx.Grid
103
+ innerRef={(r) => (this.grid = r)}
104
+ xScale={scale.x}
105
+ yScale={scale.y}
106
+ width={width}
107
+ height={height}
108
+ stroke="#D3D3D3"
109
+ rowTickValues={rowTickValues}
110
+ columnTickValues={columnTickValues}
111
+ />
112
+ {displayAdditionalGrid && (
113
+ <>
114
+ <vx.GridRows
115
+ scale={scale.y}
116
+ width={width}
117
+ tickValues={rowTickLabelValues}
118
+ stroke={additionalGridStroke}
119
+ strokeDasharray={rowStrokeDasharray}
120
+ />
121
+ <vx.GridColumns
122
+ scale={scale.x}
123
+ height={height}
124
+ tickValues={columnTickLabelValues}
125
+ stroke={additionalGridStroke}
126
+ strokeDasharray={columnStrokeDasharray}
127
+ />
128
+ </>
129
+ )}
130
+ </>
131
+ );
132
+ }
133
+ }
134
+
135
+ export default withStyles(() => ({}))(Grid);
package/src/index.js ADDED
@@ -0,0 +1,7 @@
1
+ import Graph from './graph';
2
+ import GraphContainer from './container';
3
+ import GridSetup from './grid-setup';
4
+ import * as tools from './tools';
5
+ import ToolMenu from './tool-menu';
6
+
7
+ export { Graph, GraphContainer, GridSetup, ToolMenu, tools };