@pie-lib/graphing 4.0.3-next.3 → 4.0.4-next.11

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.
@@ -103,7 +103,7 @@ export const coordinates = (graphProps, mark, rect = { width: 0, height: 0 }, po
103
103
  }
104
104
  };
105
105
 
106
- const LabelInput = ({ _ref, externalInputRef, label, disabled, inputStyle, onChange }) => (
106
+ const LabelInput = ({ _ref, externalInputRef, label, disabled, inputStyle, onChange, onBlur }) => (
107
107
  <AutosizeInput
108
108
  inputRef={(r) => {
109
109
  _ref(r);
@@ -113,6 +113,7 @@ const LabelInput = ({ _ref, externalInputRef, label, disabled, inputStyle, onCha
113
113
  inputStyle={inputStyle}
114
114
  value={label}
115
115
  onChange={onChange}
116
+ onBlur={onBlur}
116
117
  />
117
118
  );
118
119
 
@@ -123,6 +124,7 @@ LabelInput.propTypes = {
123
124
  disabled: PropTypes.bool,
124
125
  inputStyle: PropTypes.object,
125
126
  onChange: PropTypes.func,
127
+ onBlur: PropTypes.func,
126
128
  };
127
129
 
128
130
  export const MarkLabel = (props) => {
@@ -134,8 +136,15 @@ export const MarkLabel = (props) => {
134
136
 
135
137
  const [label, setLabel] = useState(mark.label);
136
138
  const { correctness, correctnesslabel, correctlabel } = mark;
139
+
137
140
  const onChange = (e) => setLabel(e.target.value);
138
141
 
142
+ const handleBlur = useCallback(() => {
143
+ if (label === '') {
144
+ props.onChange('');
145
+ }
146
+ }, [label, props.onChange]);
147
+
139
148
  const debouncedLabel = useDebounce(label, 200);
140
149
 
141
150
  // useState only sets the value once, to synch props to state need useEffect
@@ -178,6 +187,7 @@ export const MarkLabel = (props) => {
178
187
  disabled={disabledInput}
179
188
  inputStyle={inputStyle}
180
189
  onChange={onChange}
190
+ onBlur={handleBlur}
181
191
  />
182
192
  );
183
193
 
@@ -192,7 +202,6 @@ export const MarkLabel = (props) => {
192
202
  );
193
203
  }
194
204
 
195
- // avoid rendering empty label when a correct point without label was provided
196
205
  if (correctness === 'correct' && correctnesslabel === 'correct' && !correctlabel) {
197
206
  return null;
198
207
  }
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
3
3
  import classNames from 'classnames';
4
4
  import { BasePoint } from '../shared/point';
5
5
  import BgCircle from './bg-circle';
6
- import { equalPoints, getMiddleOfTwoPoints, point } from '../../utils';
6
+ import { equalPoints, getMiddleOfTwoPoints, point, stripEmptyLabel } from '../../utils';
7
7
  import { types } from '@pie-lib/plot';
8
8
  import { rootEdgeComponent } from '../shared/line/with-root-edge';
9
9
  import ReactDOM from 'react-dom';
@@ -103,7 +103,7 @@ export class RawBaseCircle extends React.Component {
103
103
  };
104
104
 
105
105
  clickPoint = (point, type, data) => {
106
- const { changeMarkProps, disabled, from, to, labelModeEnabled, limitLabeling, onClick } = this.props;
106
+ const { changeMarkProps, disabled, from, to, middle, labelModeEnabled, limitLabeling, onClick } = this.props;
107
107
 
108
108
  if (!labelModeEnabled) {
109
109
  onClick(point || data);
@@ -115,8 +115,12 @@ export class RawBaseCircle extends React.Component {
115
115
  if (type === 'middle' && !point && from && to) {
116
116
  point = { ...point, ...getMiddleOfTwoPoints(from, to) };
117
117
  }
118
-
119
- changeMarkProps({ from, to, [type]: { label: '', ...point } });
118
+ changeMarkProps({
119
+ from: stripEmptyLabel(from),
120
+ to: stripEmptyLabel(to),
121
+ middle: stripEmptyLabel(middle),
122
+ [type]: { label: '', ...point },
123
+ });
120
124
 
121
125
  if (this.input[type]) {
122
126
  this.input[type].focus();
@@ -10,7 +10,7 @@ import { types } from '@pie-lib/plot';
10
10
  import invariant from 'invariant';
11
11
  import ReactDOM from 'react-dom';
12
12
  import MarkLabel from '../../mark-label';
13
- import { equalPoints, getMiddleOfTwoPoints, getRightestPoints } from '../../utils';
13
+ import { equalPoints, getMiddleOfTwoPoints, getRightestPoints, stripEmptyLabel } from '../../utils';
14
14
 
15
15
  const log = debug('pie-lib:graphing:polygon');
16
16
 
@@ -82,6 +82,7 @@ export class RawBaseComponent extends React.Component {
82
82
  labelModeEnabled: PropTypes.bool,
83
83
  limitLabeling: PropTypes.bool,
84
84
  onChangeLabelProps: PropTypes.func,
85
+ onSetMiddleLabel: PropTypes.func,
85
86
  onChangeProps: PropTypes.func,
86
87
  };
87
88
 
@@ -165,12 +166,12 @@ export class RawBaseComponent extends React.Component {
165
166
  const {
166
167
  closed,
167
168
  disabled,
169
+ middle: currentMiddle,
168
170
  onClick,
169
171
  isToolActive,
170
172
  labelModeEnabled,
171
173
  limitLabeling,
172
- onChangeProps,
173
- onChangeLabelProps,
174
+ onSetMiddleLabel,
174
175
  points,
175
176
  } = this.props;
176
177
 
@@ -184,12 +185,13 @@ export class RawBaseComponent extends React.Component {
184
185
  const { a, b } = getRightestPoints(points);
185
186
  const middle = { label: '', ...point, ...getMiddleOfTwoPoints(a, b) };
186
187
 
187
- onChangeLabelProps(middle);
188
+ onSetMiddleLabel(middle, points.map(stripEmptyLabel));
188
189
  } else {
189
- const update = [...points];
190
+ const strippedPoints = points.map(stripEmptyLabel);
191
+ strippedPoints.splice(index, 1, { label: '', ...point });
190
192
 
191
- update.splice(index, 1, { label: '', ...point });
192
- onChangeProps(update);
193
+ const strippedMiddle = currentMiddle ? stripEmptyLabel(currentMiddle) : currentMiddle;
194
+ onSetMiddleLabel(strippedMiddle, strippedPoints);
193
195
  }
194
196
 
195
197
  // defer the focus() call with setTimeout to allow the re-render to complete first.
@@ -237,7 +239,7 @@ export class RawBaseComponent extends React.Component {
237
239
  polygonLabelNode = ReactDOM.createPortal(
238
240
  <MarkLabel
239
241
  inputRef={(r) => (this.input[polygonLabelIndex] = r)}
240
- disabled={!labelModeEnabled}
242
+ disabled={disabled || !labelModeEnabled}
241
243
  mark={middle}
242
244
  graphProps={graphProps}
243
245
  onChange={(label) => onChangeLabelProps({ ...middle, label })}
@@ -289,7 +291,7 @@ export class RawBaseComponent extends React.Component {
289
291
  ? ReactDOM.createPortal(
290
292
  <MarkLabel
291
293
  inputRef={(r) => (this.input[index] = r)}
292
- disabled={!labelModeEnabled}
294
+ disabled={disabled || !labelModeEnabled}
293
295
  mark={p}
294
296
  graphProps={graphProps}
295
297
  onChange={(label) => this.labelChange({ ...p, label }, index)}
@@ -344,9 +346,22 @@ export default class Component extends React.Component {
344
346
  const { mark, onChange } = this.props;
345
347
  const middle = { ...mark.middle, ...point };
346
348
 
349
+ if (!middle.label || isEmpty(middle.label)) {
350
+ delete middle.label;
351
+ }
352
+
347
353
  onChange(mark, { ...mark, middle });
348
354
  };
349
355
 
356
+ setMiddleLabel = (middle, strippedPoints) => {
357
+ const { mark, onChange } = this.props;
358
+ const next = { ...mark, middle };
359
+ if (strippedPoints) {
360
+ next.points = strippedPoints;
361
+ }
362
+ onChange(mark, next);
363
+ };
364
+
350
365
  closePolygon = () => {
351
366
  log('[closePolygon] ...');
352
367
  const { onComplete, mark } = this.props;
@@ -377,6 +392,7 @@ export default class Component extends React.Component {
377
392
  coordinatesOnHover={coordinatesOnHover}
378
393
  onChange={this.change}
379
394
  onChangeLabelProps={this.changeLabelProps}
395
+ onSetMiddleLabel={this.setMiddleLabel}
380
396
  onChangeProps={this.changeProps}
381
397
  onClosePolygon={this.closePolygon}
382
398
  onDragStart={this.dragStart}
@@ -15,17 +15,7 @@ const StyledLine = styled('line')(({ disabled: isDisabled, correctness }) => ({
15
15
  strokeWidth: 4,
16
16
  stroke: color.defaults.BLACK,
17
17
  },
18
- ...(isDisabled && {
19
- ...disabled('stroke'),
20
- strokeWidth: 2,
21
- }),
22
- ...(correctness === 'correct' && correct('stroke')),
23
- ...(correctness === 'incorrect' && incorrect('stroke')),
24
- ...(correctness === 'missing' && {
25
- ...missing('stroke'),
26
- strokeWidth: 1,
27
- strokeDasharray: '4 3',
28
- }),
18
+ ...((isDisabled || correctness) && { pointerEvents: 'none' }),
29
19
  }));
30
20
 
31
21
  class RawLine extends React.Component {
@@ -26,9 +26,21 @@ export const Line = (props) => {
26
26
  return (
27
27
  <g>
28
28
  {/* Transparent wider line captures pointer events (+2px each side) */}
29
- <line x1={x1} y1={y1} x2={x2} y2={y2} stroke="transparent" strokeWidth={7} style={{ cursor: 'pointer', pointerEvents: 'stroke' }} />
29
+ <line
30
+ className="hit-area"
31
+ x1={x1}
32
+ y1={y1}
33
+ x2={x2}
34
+ y2={y2}
35
+ stroke="transparent"
36
+ strokeWidth={7}
37
+ style={{ cursor: 'pointer', pointerEvents: 'stroke' }}
38
+ />
30
39
  <StyledLineRoot
31
- x1={x1} y1={y1} x2={x2} y2={y2}
40
+ x1={x1}
41
+ y1={y1}
42
+ x2={x2}
43
+ y2={y2}
32
44
  className={className}
33
45
  disabled={disabled}
34
46
  correctness={correctness}
@@ -7,11 +7,11 @@ import { correct, disabled, disabledSecondary, incorrect, missing } from '../sty
7
7
  import ReactDOM from 'react-dom';
8
8
  import MarkLabel from '../../../mark-label';
9
9
  import { color } from '@pie-lib/render-ui';
10
- import { equalPoints, getMiddleOfTwoPoints, sameAxes } from '../../../utils';
10
+ import { equalPoints, getMiddleOfTwoPoints, sameAxes, stripEmptyLabel } from '../../../utils';
11
11
  import { styled } from '@mui/material/styles';
12
12
 
13
13
  const StyledLineGroup = styled('g')(({ disabled, correctness }) => ({
14
- '& line': {
14
+ '& line:not(.hit-area)': {
15
15
  fill: 'transparent',
16
16
  stroke: color.defaults.BLACK,
17
17
  strokeWidth: 3,
@@ -22,23 +22,23 @@ const StyledLineGroup = styled('g')(({ disabled, correctness }) => ({
22
22
  },
23
23
  },
24
24
  ...(disabled && {
25
- '& line': {
25
+ '& line:not(.hit-area)': {
26
26
  ...disabledSecondary('stroke'),
27
27
  strokeWidth: 2,
28
28
  },
29
29
  }),
30
30
  ...(correctness === 'correct' && {
31
- '& line': {
31
+ '& line:not(.hit-area)': {
32
32
  ...correct('stroke'),
33
33
  },
34
34
  }),
35
35
  ...(correctness === 'incorrect' && {
36
- '& line': {
36
+ '& line:not(.hit-area)': {
37
37
  ...incorrect('stroke'),
38
38
  },
39
39
  }),
40
40
  ...(correctness === 'missing' && {
41
- '& line': {
41
+ '& line:not(.hit-area)': {
42
42
  ...missing('stroke'),
43
43
  strokeWidth: 1,
44
44
  strokeDasharray: '4 3',
@@ -304,7 +304,7 @@ export const lineBase = (Comp, opts) => {
304
304
  };
305
305
 
306
306
  clickPoint = (point, type, data) => {
307
- const { changeMarkProps, disabled, from, to, labelModeEnabled, limitLabeling, onClick } = this.props;
307
+ const { changeMarkProps, disabled, from, to, middle, labelModeEnabled, limitLabeling, onClick } = this.props;
308
308
 
309
309
  if (!labelModeEnabled) {
310
310
  onClick(point || data);
@@ -324,7 +324,12 @@ export const lineBase = (Comp, opts) => {
324
324
  point = { ...point, ...getMiddleOfTwoPoints(from, to) };
325
325
  }
326
326
 
327
- changeMarkProps({ from, to, [type]: { label: '', ...point } });
327
+ changeMarkProps({
328
+ from: stripEmptyLabel(from),
329
+ to: stripEmptyLabel(to),
330
+ middle: stripEmptyLabel(middle),
331
+ [type]: { label: '', ...point },
332
+ });
328
333
 
329
334
  if (this.input[type]) {
330
335
  this.input[type].focus();
@@ -13,7 +13,7 @@ const dragging = () => ({
13
13
 
14
14
  const StyledDrawLine = styled(vx.LinePath)(({ disabled: isDisabled, correctness }) => ({
15
15
  fill: 'none',
16
- strokeWidth: 2,
16
+ strokeWidth: 3,
17
17
  stroke: color.black(),
18
18
  ...(isDisabled && {
19
19
  ...disabledSecondary('stroke'),
@@ -36,17 +36,7 @@ const StyledLine = styled(vx.LinePath)(({ theme, disabled: isDisabled, correctne
36
36
  pointerEvents: 'stroke',
37
37
  '&:hover': dragging(theme),
38
38
  ...(isDragging && dragging(theme)),
39
- ...(isDisabled && {
40
- ...disabled('stroke'),
41
- strokeWidth: 2,
42
- }),
43
- ...(correctness === 'correct' && correct('stroke')),
44
- ...(correctness === 'incorrect' && incorrect('stroke')),
45
- ...(correctness === 'missing' && {
46
- ...missing('stroke'),
47
- strokeWidth: 1,
48
- strokeDasharray: '4 3',
49
- }),
39
+ ...((isDisabled || correctness) && { pointerEvents: 'none' }),
50
40
  }));
51
41
 
52
42
  export class RawLinePath extends React.Component {
package/src/utils.js CHANGED
@@ -1,6 +1,8 @@
1
1
  import { utils } from '@pie-lib/plot';
2
2
  import invariant from 'invariant';
3
- import { cloneDeep, head, isEmpty, isEqual, tail } from 'lodash-es';
3
+ import { cloneDeep, head, isEmpty, isEqual, omit, tail } from 'lodash-es';
4
+
5
+ export const stripEmptyLabel = (pt) => (pt?.label === '' ? omit(pt, 'label') : pt);
4
6
 
5
7
  export const tickCount = utils.tickCount;
6
8
  export const bounds = utils.bounds;