@pie-lib/charting 5.15.6 → 5.15.7-next.1618

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 (109) hide show
  1. package/CHANGELOG.json +1 -581
  2. package/CHANGELOG.md +206 -38
  3. package/NEXT.CHANGELOG.json +1 -0
  4. package/lib/actions-button.js +175 -0
  5. package/lib/actions-button.js.map +1 -0
  6. package/lib/axes.js +154 -104
  7. package/lib/axes.js.map +1 -1
  8. package/lib/bars/common/bars.js +105 -19
  9. package/lib/bars/common/bars.js.map +1 -1
  10. package/lib/bars/common/correct-check-icon.js +55 -0
  11. package/lib/bars/common/correct-check-icon.js.map +1 -0
  12. package/lib/chart-type.js +4 -4
  13. package/lib/chart-type.js.map +1 -1
  14. package/lib/chart.js +96 -65
  15. package/lib/chart.js.map +1 -1
  16. package/lib/common/correctness-indicators.js +99 -0
  17. package/lib/common/correctness-indicators.js.map +1 -0
  18. package/lib/common/drag-handle.js +47 -13
  19. package/lib/common/drag-handle.js.map +1 -1
  20. package/lib/common/drag-icon.js +7 -24
  21. package/lib/common/drag-icon.js.map +1 -1
  22. package/lib/grid.js +47 -10
  23. package/lib/grid.js.map +1 -1
  24. package/lib/index.js +8 -0
  25. package/lib/index.js.map +1 -1
  26. package/lib/key-legend.js +111 -0
  27. package/lib/key-legend.js.map +1 -0
  28. package/lib/line/common/drag-handle.js +40 -18
  29. package/lib/line/common/drag-handle.js.map +1 -1
  30. package/lib/line/common/line.js +7 -8
  31. package/lib/line/common/line.js.map +1 -1
  32. package/lib/line/line-cross.js +76 -9
  33. package/lib/line/line-cross.js.map +1 -1
  34. package/lib/line/line-dot.js +58 -5
  35. package/lib/line/line-dot.js.map +1 -1
  36. package/lib/mark-label.js +40 -15
  37. package/lib/mark-label.js.map +1 -1
  38. package/lib/plot/common/plot.js +129 -16
  39. package/lib/plot/common/plot.js.map +1 -1
  40. package/lib/plot/dot.js +17 -4
  41. package/lib/plot/dot.js.map +1 -1
  42. package/lib/plot/line.js +19 -6
  43. package/lib/plot/line.js.map +1 -1
  44. package/lib/tool-menu.js +0 -4
  45. package/lib/tool-menu.js.map +1 -1
  46. package/package.json +6 -8
  47. package/src/__tests__/__snapshots__/axes.test.jsx.snap +569 -0
  48. package/src/__tests__/__snapshots__/chart-type.test.jsx.snap +14 -0
  49. package/src/__tests__/__snapshots__/chart.test.jsx.snap +595 -0
  50. package/src/__tests__/__snapshots__/grid.test.jsx.snap +72 -0
  51. package/src/__tests__/__snapshots__/mark-label.test.jsx.snap +73 -0
  52. package/src/__tests__/axes.test.jsx +141 -0
  53. package/src/__tests__/chart-setup.test.jsx +47 -0
  54. package/src/__tests__/chart-type.test.jsx +29 -0
  55. package/src/__tests__/chart.test.jsx +95 -0
  56. package/src/__tests__/grid.test.jsx +25 -0
  57. package/src/__tests__/mark-label.test.jsx +31 -0
  58. package/src/__tests__/utils.js +30 -0
  59. package/src/__tests__/utils.test.js +100 -0
  60. package/src/actions-button.jsx +110 -0
  61. package/src/axes.jsx +98 -54
  62. package/src/bars/__tests__/__snapshots__/bar.test.jsx.snap +43 -0
  63. package/src/bars/__tests__/__snapshots__/histogram.test.jsx.snap +45 -0
  64. package/src/bars/__tests__/bar.test.jsx +37 -0
  65. package/src/bars/__tests__/histogram.test.jsx +38 -0
  66. package/src/bars/__tests__/utils.js +30 -0
  67. package/src/bars/common/__tests__/__snapshots__/bars.test.jsx.snap +110 -0
  68. package/src/bars/common/__tests__/bars.test.jsx +69 -0
  69. package/src/bars/common/__tests__/utils.js +30 -0
  70. package/src/bars/common/bars.jsx +101 -14
  71. package/src/bars/common/correct-check-icon.jsx +20 -0
  72. package/src/chart-type.js +7 -3
  73. package/src/chart.jsx +53 -29
  74. package/src/common/__tests__/__snapshots__/drag-handle.test.jsx.snap +48 -0
  75. package/src/common/__tests__/drag-handle.test.jsx +88 -0
  76. package/src/common/__tests__/utils.js +30 -0
  77. package/src/common/correctness-indicators.jsx +55 -0
  78. package/src/common/drag-handle.jsx +48 -26
  79. package/src/common/drag-icon.jsx +6 -21
  80. package/src/grid.jsx +37 -12
  81. package/src/index.js +2 -1
  82. package/src/key-legend.jsx +75 -0
  83. package/src/line/__tests__/__snapshots__/line-cross.test.jsx.snap +45 -0
  84. package/src/line/__tests__/__snapshots__/line-dot.test.jsx.snap +45 -0
  85. package/src/line/__tests__/line-cross.test.jsx +38 -0
  86. package/src/line/__tests__/line-dot.test.jsx +38 -0
  87. package/src/line/__tests__/utils.js +30 -0
  88. package/src/line/common/__tests__/__snapshots__/drag-handle.test.jsx.snap +49 -0
  89. package/src/line/common/__tests__/__snapshots__/line.test.jsx.snap +143 -0
  90. package/src/line/common/__tests__/drag-handle.test.jsx +88 -0
  91. package/src/line/common/__tests__/line.test.jsx +82 -0
  92. package/src/line/common/__tests__/utils.js +30 -0
  93. package/src/line/common/drag-handle.jsx +38 -16
  94. package/src/line/common/line.jsx +4 -6
  95. package/src/line/line-cross.js +56 -4
  96. package/src/line/line-dot.js +74 -10
  97. package/src/mark-label.jsx +83 -51
  98. package/src/plot/__tests__/__snapshots__/dot.test.jsx.snap +45 -0
  99. package/src/plot/__tests__/__snapshots__/line.test.jsx.snap +45 -0
  100. package/src/plot/__tests__/dot.test.jsx +38 -0
  101. package/src/plot/__tests__/line.test.jsx +38 -0
  102. package/src/plot/__tests__/utils.js +30 -0
  103. package/src/plot/common/__tests__/__snapshots__/plot.test.jsx.snap +97 -0
  104. package/src/plot/common/__tests__/plot.test.jsx +70 -0
  105. package/src/plot/common/__tests__/utils.js +30 -0
  106. package/src/plot/common/plot.jsx +127 -10
  107. package/src/plot/dot.js +19 -3
  108. package/src/plot/line.js +18 -4
  109. package/src/tool-menu.jsx +0 -4
@@ -0,0 +1,143 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Line snapshot renders 1`] = `
4
+ <t>
5
+ <WithStyles(RawLine)
6
+ className="className"
7
+ classes={Object {}}
8
+ data={
9
+ Array [
10
+ Object {
11
+ "label": "0",
12
+ "value": 0,
13
+ },
14
+ ]
15
+ }
16
+ graphProps={
17
+ Object {
18
+ "domain": Object {
19
+ "max": 1,
20
+ "min": 0,
21
+ "step": 1,
22
+ },
23
+ "range": Object {
24
+ "max": 1,
25
+ "min": 0,
26
+ "step": 1,
27
+ },
28
+ "scale": Object {
29
+ "x": [MockFunction],
30
+ "y": [MockFunction],
31
+ },
32
+ "size": Object {
33
+ "height": 400,
34
+ "width": 400,
35
+ },
36
+ "snap": Object {
37
+ "x": [MockFunction],
38
+ "y": [MockFunction],
39
+ },
40
+ }
41
+ }
42
+ onChange={[Function]}
43
+ xBand={[Function]}
44
+ />
45
+ </t>
46
+ `;
47
+
48
+ exports[`RawLine snapshot renders 1`] = `
49
+ <Fragment>
50
+ <u
51
+ data={
52
+ Array [
53
+ Object {
54
+ "label": "A",
55
+ "value": 0,
56
+ "x": 0,
57
+ "y": 0,
58
+ },
59
+ Object {
60
+ "label": "B",
61
+ "value": 1,
62
+ "x": 1,
63
+ "y": 1,
64
+ },
65
+ ]
66
+ }
67
+ x={[Function]}
68
+ y={[Function]}
69
+ />
70
+ <WithStyles(RawDragHandle)
71
+ graphProps={
72
+ Object {
73
+ "domain": Object {
74
+ "max": 1,
75
+ "min": 0,
76
+ "step": 1,
77
+ },
78
+ "range": Object {
79
+ "max": 1,
80
+ "min": 0,
81
+ "step": 1,
82
+ },
83
+ "scale": Object {
84
+ "x": [MockFunction],
85
+ "y": [MockFunction],
86
+ },
87
+ "size": Object {
88
+ "height": 400,
89
+ "width": 400,
90
+ },
91
+ "snap": Object {
92
+ "x": [MockFunction],
93
+ "y": [MockFunction],
94
+ },
95
+ }
96
+ }
97
+ key="point-0-0"
98
+ label="A"
99
+ onDrag={[Function]}
100
+ onDragStart={[Function]}
101
+ onDragStop={[Function]}
102
+ r={6}
103
+ x={0}
104
+ y={0}
105
+ />
106
+ <WithStyles(RawDragHandle)
107
+ graphProps={
108
+ Object {
109
+ "domain": Object {
110
+ "max": 1,
111
+ "min": 0,
112
+ "step": 1,
113
+ },
114
+ "range": Object {
115
+ "max": 1,
116
+ "min": 0,
117
+ "step": 1,
118
+ },
119
+ "scale": Object {
120
+ "x": [MockFunction],
121
+ "y": [MockFunction],
122
+ },
123
+ "size": Object {
124
+ "height": 400,
125
+ "width": 400,
126
+ },
127
+ "snap": Object {
128
+ "x": [MockFunction],
129
+ "y": [MockFunction],
130
+ },
131
+ }
132
+ }
133
+ key="point-1-1"
134
+ label="B"
135
+ onDrag={[Function]}
136
+ onDragStart={[Function]}
137
+ onDragStop={[Function]}
138
+ r={6}
139
+ x={1}
140
+ y={1}
141
+ />
142
+ </Fragment>
143
+ `;
@@ -0,0 +1,88 @@
1
+ import { shallow } from 'enzyme/build';
2
+ import React from 'react';
3
+ import DragHandle from '../drag-handle';
4
+ import { gridDraggable } from '@pie-lib/plot';
5
+ import { graphProps } from './utils';
6
+ import { bounds } from '../../../utils';
7
+
8
+ jest.mock('../../../utils', () => {
9
+ const { point } = jest.requireActual('../../../utils');
10
+ return {
11
+ bounds: jest.fn(),
12
+ point,
13
+ };
14
+ });
15
+
16
+ jest.mock('@pie-lib/plot', () => {
17
+ const { types, utils } = jest.requireActual('@pie-lib/plot');
18
+ return {
19
+ gridDraggable: jest.fn((opts) => (Comp) => Comp),
20
+ types,
21
+ utils,
22
+ };
23
+ });
24
+
25
+ describe('BasePoint', () => {
26
+ let w;
27
+ let onChange = jest.fn();
28
+ const wrapper = (extras) => {
29
+ const defaults = {
30
+ classes: {},
31
+ className: 'className',
32
+ onChange,
33
+ graphProps: graphProps(),
34
+ x: 0,
35
+ y: 0,
36
+ width: 100,
37
+ };
38
+ const props = { ...defaults, ...extras };
39
+ return shallow(<DragHandle {...props} />);
40
+ };
41
+
42
+ describe('snapshot', () => {
43
+ it('renders', () => {
44
+ w = wrapper();
45
+ expect(w).toMatchSnapshot();
46
+ });
47
+ });
48
+ describe('gridDraggable options', () => {
49
+ let opts;
50
+ let domain;
51
+ let range;
52
+ beforeEach(() => {
53
+ domain = {
54
+ min: 0,
55
+ max: 1,
56
+ step: 1,
57
+ };
58
+ range = {
59
+ min: 0,
60
+ max: 1,
61
+ step: 1,
62
+ };
63
+ const w = wrapper();
64
+ opts = gridDraggable.mock.calls[0][0];
65
+ });
66
+
67
+ describe('bounds', () => {
68
+ it('calls utils.bounds with area', () => {
69
+ const result = opts.bounds({ x: 0, y: 0 }, { domain, range });
70
+
71
+ expect(result).toEqual({ left: 0, top: 1, bottom: 0, right: 1 });
72
+ });
73
+ });
74
+ describe('anchorPoint', () => {
75
+ it('returns x/y', () => {
76
+ const result = opts.anchorPoint({ x: 0, y: 0 });
77
+ expect(result).toEqual({ x: 0, y: 0 });
78
+ });
79
+ });
80
+
81
+ describe('fromDelta', () => {
82
+ it('returns y coordinate of a new point from the x/y + delta', () => {
83
+ const result = opts.fromDelta({ x: -1, y: 0 }, { x: 1, y: 3 });
84
+ expect(result).toEqual(3);
85
+ });
86
+ });
87
+ });
88
+ });
@@ -0,0 +1,82 @@
1
+ import { shallow } from 'enzyme';
2
+ import React from 'react';
3
+ import Line, { RawLine } from '../line';
4
+ import { graphProps } from './utils';
5
+
6
+ describe('Line', () => {
7
+ const xBand = () => {};
8
+ xBand.bandwidth = () => {};
9
+ const onChange = jest.fn();
10
+
11
+ const wrapper = (extras) => {
12
+ const defaults = {
13
+ classes: {},
14
+ className: 'className',
15
+ graphProps: graphProps(),
16
+ xBand,
17
+ onChange,
18
+ data: [{ value: 0, label: '0' }],
19
+ };
20
+ const props = { ...defaults, ...extras };
21
+ return shallow(<Line {...props} />);
22
+ };
23
+
24
+ describe('snapshot', () => {
25
+ it('renders', () => expect(wrapper()).toMatchSnapshot());
26
+ });
27
+
28
+ describe('logic', () => {
29
+ it('changeLine', () => {
30
+ const w = wrapper();
31
+
32
+ w.instance().changeLine(0, { dragValue: 1, label: '0' });
33
+
34
+ expect(onChange).toHaveBeenCalledWith([{ value: 1, label: '0' }]);
35
+ });
36
+ });
37
+ });
38
+
39
+ describe('RawLine', () => {
40
+ const xBand = () => {};
41
+ xBand.bandwidth = () => {};
42
+ const onChange = jest.fn();
43
+
44
+ const wrapper = (extras) => {
45
+ const defaults = {
46
+ classes: {},
47
+ className: 'className',
48
+ graphProps: graphProps(),
49
+ xBand,
50
+ onChange,
51
+ data: [
52
+ { label: 'A', value: 0 },
53
+ { label: 'B', value: 1 },
54
+ ],
55
+ label: 'label',
56
+ CustomBarElement: () => <div />,
57
+ };
58
+ const props = { ...defaults, ...extras };
59
+ return shallow(<RawLine {...props} />);
60
+ };
61
+
62
+ describe('snapshot', () => {
63
+ it('renders', () => expect(wrapper()).toMatchSnapshot());
64
+ });
65
+
66
+ describe('logic', () => {
67
+ const w = wrapper();
68
+
69
+ it('dragStop', () => {
70
+ w.instance().setState({
71
+ line: [
72
+ { x: 0, y: 0, dragValue: 2 },
73
+ { x: 1, y: 1 },
74
+ ],
75
+ });
76
+
77
+ w.instance().dragStop(0);
78
+
79
+ expect(onChange).toHaveBeenCalledWith(0, { x: 0, y: 0, dragValue: 2 });
80
+ });
81
+ });
82
+ });
@@ -0,0 +1,30 @@
1
+ export const scaleMock = () => {
2
+ const fn = jest.fn((n) => n);
3
+ fn.invert = jest.fn((n) => n);
4
+ return fn;
5
+ };
6
+
7
+ export const graphProps = (dmin = 0, dmax = 1, rmin = 0, rmax = 1) => ({
8
+ scale: {
9
+ x: scaleMock(),
10
+ y: scaleMock(),
11
+ },
12
+ snap: {
13
+ x: jest.fn((n) => n),
14
+ y: jest.fn((n) => n),
15
+ },
16
+ domain: {
17
+ min: dmin,
18
+ max: dmax,
19
+ step: 1,
20
+ },
21
+ range: {
22
+ min: rmin,
23
+ max: rmax,
24
+ step: 1,
25
+ },
26
+ size: {
27
+ width: 400,
28
+ height: 400,
29
+ },
30
+ });
@@ -1,10 +1,11 @@
1
1
  import React from 'react';
2
2
  import classNames from 'classnames';
3
- import { gridDraggable, utils, types } from '@pie-lib/plot';
3
+ import PropTypes from 'prop-types';
4
4
  import { withStyles } from '@material-ui/core/styles/index';
5
+
6
+ import { gridDraggable, utils, types } from '@pie-lib/plot';
5
7
  import { color } from '@pie-lib/render-ui';
6
- import PropTypes from 'prop-types';
7
- import { correct, incorrect, disabled } from '../../common/styles';
8
+ import { disabled } from '../../common/styles';
8
9
 
9
10
  class RawDragHandle extends React.Component {
10
11
  static propTypes = {
@@ -44,32 +45,53 @@ class RawDragHandle extends React.Component {
44
45
  classes={classes}
45
46
  className={classNames(className, !interactive && 'non-interactive')}
46
47
  correctness={correctness}
48
+ interactive={interactive}
47
49
  {...rest}
48
50
  />
49
51
  );
50
52
  }
51
53
  }
52
54
 
53
- export const DragHandle = withStyles(() => ({
55
+ export const DragHandle = withStyles((theme) => ({
54
56
  handle: {
55
- fill: color.secondary(),
56
57
  transition: 'fill 200ms linear, height 200ms linear',
57
- '&:hover': {
58
- fill: color.secondaryDark(),
59
- },
60
- '&.correct': correct('fill'),
61
- '&.incorrect': incorrect('fill'),
62
58
  '&.non-interactive': disabled('fill'),
63
59
  },
60
+ transparentHandle: {
61
+ height: '20px',
62
+ fill: 'transparent',
63
+ stroke: 'transparent',
64
+ },
64
65
  line: {
65
- stroke: color.secondary(),
66
+ stroke: color.defaults.TEXT,
66
67
  transition: 'fill 200ms linear, height 200ms linear',
67
- '&:hover': {
68
- stroke: color.secondaryDark(),
69
- },
70
68
  '&.non-interactive': disabled('stroke'),
71
- '&.correct': correct('stroke'),
72
- '&.incorrect': incorrect('stroke'),
69
+ },
70
+ disabledPoint: {
71
+ fill: color.defaults.BLACK + ' !important',
72
+ stroke: color.defaults.BLACK + ' !important',
73
+ },
74
+ correctIcon: {
75
+ backgroundColor: color.correct(),
76
+ },
77
+ incorrectIcon: {
78
+ backgroundColor: color.incorrectWithIcon(),
79
+ },
80
+ correctnessIcon: {
81
+ borderRadius: theme.spacing.unit * 2,
82
+ color: color.defaults.WHITE,
83
+ fontSize: '16px',
84
+ width: '16px',
85
+ height: '16px',
86
+ padding: '2px',
87
+ border: `1px solid ${color.defaults.WHITE}`,
88
+ stroke: 'initial',
89
+ boxSizing: 'unset', // to override the default border-box in IBX
90
+ },
91
+ smallIcon: {
92
+ fontSize: '10px',
93
+ width: '10px',
94
+ height: '10px',
73
95
  },
74
96
  }))(RawDragHandle);
75
97
 
@@ -78,7 +78,7 @@ export class RawLine extends React.Component {
78
78
  };
79
79
 
80
80
  render() {
81
- const { graphProps, data, classes, CustomDraggableComponent, defineChart } = this.props;
81
+ const { graphProps, data, classes, CustomDraggableComponent, defineChart, correctData } = this.props;
82
82
  const { line: lineState, dragging } = this.state;
83
83
  const { scale } = graphProps;
84
84
  const lineToUse = dragging ? lineState : getData(data, graphProps.domain);
@@ -110,6 +110,8 @@ export class RawLine extends React.Component {
110
110
  graphProps={graphProps}
111
111
  CustomDraggableComponent={CustomDraggableComponent}
112
112
  correctness={point.correctness}
113
+ correctData={correctData}
114
+ label={point.label}
113
115
  />
114
116
  );
115
117
  })}
@@ -121,13 +123,9 @@ export class RawLine extends React.Component {
121
123
  const StyledLine = withStyles(() => ({
122
124
  line: {
123
125
  fill: 'transparent',
124
- stroke: color.primaryLight(),
126
+ stroke: color.defaults.TERTIARY,
125
127
  strokeWidth: 3,
126
128
  transition: 'stroke 200ms ease-in, stroke-width 200ms ease-in',
127
- '&:hover': {
128
- strokeWidth: 6,
129
- stroke: color.primaryDark(),
130
- },
131
129
  },
132
130
  }))(RawLine);
133
131
 
@@ -1,17 +1,26 @@
1
- import React from 'react';
1
+ import React, { useState } from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import { types } from '@pie-lib/plot';
4
3
  import { LinePath } from '@vx/shape';
5
4
  import { Group } from '@vx/group';
6
5
  import classNames from 'classnames';
6
+
7
+ import { color } from '@pie-lib/render-ui';
7
8
  import { dataToXBand } from '../utils';
9
+ import { types } from '@pie-lib/plot';
8
10
  import RawLine from './common/line';
11
+ import { CorrectnessIndicator, SmallCorrectPointIndicator } from '../common/correctness-indicators';
9
12
 
10
13
  const DraggableComponent = (props) => {
11
- const { classes = {}, className, scale, x, y, r, correctness, ...rest } = props;
14
+ const { classes = {}, className, scale, x, y, r, correctness, interactive, correctData, label, ...rest } = props;
15
+ const [hover, setHover] = useState(false);
16
+
17
+ const squareSize = r * 4;
18
+ const squareHalf = squareSize / 2;
19
+ const cx = scale.x(x);
20
+ const cy = scale.y(y);
12
21
 
13
22
  return (
14
- <Group {...rest} className={classNames(className, classes.line, correctness && correctness.value)}>
23
+ <Group className={classNames(className, classes.line, correctness && !interactive && classes.disabledPoint)}>
15
24
  <LinePath
16
25
  data={[
17
26
  { x: scale.x(x) - r, y: scale.y(y) + r },
@@ -21,6 +30,7 @@ const DraggableComponent = (props) => {
21
30
  x={(d) => d.x}
22
31
  y={(d) => d.y}
23
32
  strokeWidth={5}
33
+ style={{ pointerEvents: 'none' }}
24
34
  />
25
35
  <LinePath
26
36
  data={[
@@ -31,6 +41,48 @@ const DraggableComponent = (props) => {
31
41
  x={(d) => d.x}
32
42
  y={(d) => d.y}
33
43
  strokeWidth={5}
44
+ style={{ pointerEvents: 'none' }}
45
+ />
46
+ {hover && (
47
+ <rect
48
+ x={cx - squareHalf}
49
+ y={cy - squareHalf}
50
+ width={squareSize}
51
+ height={squareSize}
52
+ stroke={color.defaults.BORDER_GRAY}
53
+ fill="none"
54
+ strokeWidth={2}
55
+ pointerEvents="none"
56
+ />
57
+ )}
58
+ <circle
59
+ cx={cx}
60
+ cy={cy}
61
+ r={r * 2}
62
+ className={classNames(classes.transparentHandle)}
63
+ onMouseEnter={() => setHover(true)}
64
+ onMouseLeave={() => setHover(false)}
65
+ {...rest}
66
+ />
67
+ {/* show correctness indicators */}
68
+ <CorrectnessIndicator
69
+ scale={scale}
70
+ x={x}
71
+ y={y}
72
+ classes={classes}
73
+ r={r}
74
+ correctness={correctness}
75
+ interactive={interactive}
76
+ />
77
+ {/* show correct point if answer was incorrect */}
78
+ <SmallCorrectPointIndicator
79
+ scale={scale}
80
+ x={x}
81
+ r={r}
82
+ correctness={correctness}
83
+ classes={classes}
84
+ correctData={correctData}
85
+ label={label}
34
86
  />
35
87
  </Group>
36
88
  );
@@ -1,19 +1,83 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
+ import classNames from 'classnames';
4
+
3
5
  import { types } from '@pie-lib/plot';
6
+ import { color } from '@pie-lib/render-ui';
4
7
  import { dataToXBand } from '../utils';
5
8
  import RawLine from './common/line';
6
- import classNames from 'classnames';
9
+ import { CorrectnessIndicator, SmallCorrectPointIndicator } from '../common/correctness-indicators';
10
+
11
+ const DraggableComponent = ({
12
+ scale,
13
+ x,
14
+ y,
15
+ className,
16
+ classes,
17
+ r,
18
+ correctness,
19
+ interactive,
20
+ correctData,
21
+ label,
22
+ ...rest
23
+ }) => {
24
+ const [isHovered, setIsHovered] = React.useState(false);
25
+ const allowRolloverEvent = !correctness && interactive;
7
26
 
8
- const DraggableComponent = ({ scale, x, y, className, classes, r, correctness, ...rest }) => (
9
- <circle
10
- cx={scale.x(x)}
11
- cy={scale.y(y)}
12
- r={r}
13
- className={classNames(className, classes.handle, correctness && correctness.value)}
14
- {...rest}
15
- />
16
- );
27
+ return (
28
+ <g onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)}>
29
+ <circle
30
+ cx={scale.x(x)}
31
+ cy={scale.y(y)}
32
+ r={r * 3}
33
+ className={classNames(classes.transparentHandle, className)}
34
+ pointerEvents={correctness ? 'none' : ''}
35
+ {...rest}
36
+ />
37
+ <circle
38
+ cx={scale.x(x)}
39
+ cy={scale.y(y)}
40
+ r={r}
41
+ className={classNames(className, classes.handle, correctness && !interactive && classes.disabledPoint)}
42
+ {...rest}
43
+ />
44
+ {/* show correctness indicators */}
45
+ <CorrectnessIndicator
46
+ scale={scale}
47
+ x={x}
48
+ y={y}
49
+ classes={classes}
50
+ r={r}
51
+ correctness={correctness}
52
+ interactive={interactive}
53
+ />
54
+
55
+ {/* show correct point if answer was incorrect */}
56
+ <SmallCorrectPointIndicator
57
+ scale={scale}
58
+ x={x}
59
+ r={r}
60
+ correctness={correctness}
61
+ classes={classes}
62
+ correctData={correctData}
63
+ label={label}
64
+ />
65
+
66
+ {/* show rollover rectangle */}
67
+ {isHovered && allowRolloverEvent && (
68
+ <rect
69
+ x={scale.x(x) - r * 2}
70
+ y={scale.y(y) - r * 2}
71
+ width={r * 4}
72
+ height={r * 4}
73
+ stroke={color.defaults.BORDER_GRAY}
74
+ strokeWidth="1"
75
+ fill="none"
76
+ />
77
+ )}
78
+ </g>
79
+ );
80
+ };
17
81
 
18
82
  DraggableComponent.propTypes = {
19
83
  scale: PropTypes.object,