@pie-lib/charting 5.24.0 → 5.25.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.
- package/CHANGELOG.md +29 -1
- package/lib/actions-button.js +4 -3
- package/lib/actions-button.js.map +1 -1
- package/lib/axes.js +44 -10
- package/lib/axes.js.map +1 -1
- package/lib/bars/common/bars.js +63 -9
- package/lib/bars/common/bars.js.map +1 -1
- package/lib/bars/common/correct-check-icon.js +55 -0
- package/lib/bars/common/correct-check-icon.js.map +1 -0
- package/lib/chart.js +17 -10
- package/lib/chart.js.map +1 -1
- package/lib/common/correctness-indicators.js +99 -0
- package/lib/common/correctness-indicators.js.map +1 -0
- package/lib/common/drag-handle.js +36 -8
- package/lib/common/drag-handle.js.map +1 -1
- package/lib/line/common/drag-handle.js +32 -9
- package/lib/line/common/drag-handle.js.map +1 -1
- package/lib/line/common/line.js +5 -2
- package/lib/line/common/line.js.map +1 -1
- package/lib/line/line-cross.js +26 -5
- package/lib/line/line-cross.js.map +1 -1
- package/lib/line/line-dot.js +24 -4
- package/lib/line/line-dot.js.map +1 -1
- package/lib/mark-label.js +18 -7
- package/lib/mark-label.js.map +1 -1
- package/lib/plot/common/plot.js +119 -9
- package/lib/plot/common/plot.js.map +1 -1
- package/lib/plot/dot.js +17 -4
- package/lib/plot/dot.js.map +1 -1
- package/lib/plot/line.js +19 -6
- package/lib/plot/line.js.map +1 -1
- package/package.json +5 -5
- package/src/__tests__/__snapshots__/axes.test.jsx.snap +5 -1
- package/src/__tests__/__snapshots__/chart.test.jsx.snap +6 -3
- package/src/__tests__/__snapshots__/mark-label.test.jsx.snap +62 -56
- package/src/actions-button.jsx +3 -2
- package/src/axes.jsx +37 -3
- package/src/bars/common/bars.jsx +57 -4
- package/src/bars/common/correct-check-icon.jsx +20 -0
- package/src/chart.jsx +12 -3
- package/src/common/__tests__/__snapshots__/drag-handle.test.jsx.snap +3 -0
- package/src/common/correctness-indicators.jsx +55 -0
- package/src/common/drag-handle.jsx +28 -14
- package/src/line/common/__tests__/__snapshots__/drag-handle.test.jsx.snap +5 -0
- package/src/line/common/__tests__/__snapshots__/line.test.jsx.snap +2 -0
- package/src/line/common/drag-handle.jsx +31 -8
- package/src/line/common/line.jsx +3 -1
- package/src/line/line-cross.js +25 -3
- package/src/line/line-dot.js +40 -3
- package/src/mark-label.jsx +73 -58
- package/src/plot/common/__tests__/__snapshots__/plot.test.jsx.snap +1 -0
- package/src/plot/common/plot.jsx +114 -5
- package/src/plot/dot.js +19 -3
- package/src/plot/line.js +18 -4
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import classNames from 'classnames';
|
|
3
|
-
import
|
|
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
|
|
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 = {
|
|
@@ -51,11 +52,9 @@ class RawDragHandle extends React.Component {
|
|
|
51
52
|
}
|
|
52
53
|
}
|
|
53
54
|
|
|
54
|
-
export const DragHandle = withStyles(() => ({
|
|
55
|
+
export const DragHandle = withStyles((theme) => ({
|
|
55
56
|
handle: {
|
|
56
57
|
transition: 'fill 200ms linear, height 200ms linear',
|
|
57
|
-
'&.correct': correct('fill'),
|
|
58
|
-
'&.incorrect': incorrect('fill'),
|
|
59
58
|
'&.non-interactive': disabled('fill'),
|
|
60
59
|
},
|
|
61
60
|
transparentHandle: {
|
|
@@ -67,8 +66,32 @@ export const DragHandle = withStyles(() => ({
|
|
|
67
66
|
stroke: color.defaults.TEXT,
|
|
68
67
|
transition: 'fill 200ms linear, height 200ms linear',
|
|
69
68
|
'&.non-interactive': disabled('stroke'),
|
|
70
|
-
|
|
71
|
-
|
|
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',
|
|
72
95
|
},
|
|
73
96
|
}))(RawDragHandle);
|
|
74
97
|
|
package/src/line/common/line.jsx
CHANGED
|
@@ -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
|
})}
|
package/src/line/line-cross.js
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
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
7
|
import { color } from '@pie-lib/render-ui';
|
|
8
8
|
import { dataToXBand } from '../utils';
|
|
9
|
+
import { types } from '@pie-lib/plot';
|
|
9
10
|
import RawLine from './common/line';
|
|
11
|
+
import { CorrectnessIndicator, SmallCorrectPointIndicator } from '../common/correctness-indicators';
|
|
10
12
|
|
|
11
13
|
const DraggableComponent = (props) => {
|
|
12
|
-
const { classes = {}, className, scale, x, y, r, correctness, ...rest } = props;
|
|
14
|
+
const { classes = {}, className, scale, x, y, r, correctness, interactive, correctData, label, ...rest } = props;
|
|
13
15
|
const [hover, setHover] = useState(false);
|
|
14
16
|
|
|
15
17
|
const squareSize = r * 4;
|
|
@@ -18,7 +20,7 @@ const DraggableComponent = (props) => {
|
|
|
18
20
|
const cy = scale.y(y);
|
|
19
21
|
|
|
20
22
|
return (
|
|
21
|
-
<Group className={classNames(className, classes.line, correctness &&
|
|
23
|
+
<Group className={classNames(className, classes.line, correctness && !interactive && classes.disabledPoint)}>
|
|
22
24
|
<LinePath
|
|
23
25
|
data={[
|
|
24
26
|
{ x: scale.x(x) - r, y: scale.y(y) + r },
|
|
@@ -62,6 +64,26 @@ const DraggableComponent = (props) => {
|
|
|
62
64
|
onMouseLeave={() => setHover(false)}
|
|
63
65
|
{...rest}
|
|
64
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}
|
|
86
|
+
/>
|
|
65
87
|
</Group>
|
|
66
88
|
);
|
|
67
89
|
};
|
package/src/line/line-dot.js
CHANGED
|
@@ -1,12 +1,26 @@
|
|
|
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';
|
|
4
6
|
import { color } from '@pie-lib/render-ui';
|
|
5
7
|
import { dataToXBand } from '../utils';
|
|
6
8
|
import RawLine from './common/line';
|
|
7
|
-
import
|
|
9
|
+
import { CorrectnessIndicator, SmallCorrectPointIndicator } from '../common/correctness-indicators';
|
|
8
10
|
|
|
9
|
-
const DraggableComponent = ({
|
|
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
|
+
}) => {
|
|
10
24
|
const [isHovered, setIsHovered] = React.useState(false);
|
|
11
25
|
const allowRolloverEvent = !correctness && interactive;
|
|
12
26
|
|
|
@@ -24,9 +38,32 @@ const DraggableComponent = ({ scale, x, y, className, classes, r, correctness, i
|
|
|
24
38
|
cx={scale.x(x)}
|
|
25
39
|
cy={scale.y(y)}
|
|
26
40
|
r={r}
|
|
27
|
-
className={classNames(className, classes.handle, correctness &&
|
|
41
|
+
className={classNames(className, classes.handle, correctness && !interactive && classes.disabledPoint)}
|
|
28
42
|
{...rest}
|
|
29
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 */}
|
|
30
67
|
{isHovered && allowRolloverEvent && (
|
|
31
68
|
<rect
|
|
32
69
|
x={scale.x(x) - r * 2}
|
package/src/mark-label.jsx
CHANGED
|
@@ -3,6 +3,7 @@ import classNames from 'classnames';
|
|
|
3
3
|
import { withStyles } from '@material-ui/core/styles';
|
|
4
4
|
import AutosizeInput from 'react-input-autosize';
|
|
5
5
|
import PropTypes from 'prop-types';
|
|
6
|
+
|
|
6
7
|
import { types } from '@pie-lib/plot';
|
|
7
8
|
import { correct, incorrect, disabled } from './common/styles';
|
|
8
9
|
import { color } from '@pie-lib/render-ui';
|
|
@@ -42,6 +43,11 @@ const styles = (theme) => ({
|
|
|
42
43
|
incorrect: {
|
|
43
44
|
...incorrect('color'),
|
|
44
45
|
},
|
|
46
|
+
flexContainer: {
|
|
47
|
+
display: 'flex',
|
|
48
|
+
flexDirection: 'column',
|
|
49
|
+
alignItems: 'center',
|
|
50
|
+
},
|
|
45
51
|
});
|
|
46
52
|
|
|
47
53
|
function isFractionFormat(label) {
|
|
@@ -89,6 +95,7 @@ export const MarkLabel = (props) => {
|
|
|
89
95
|
error,
|
|
90
96
|
isHiddenLabel,
|
|
91
97
|
limitCharacters,
|
|
98
|
+
correctnessIndicator,
|
|
92
99
|
} = props;
|
|
93
100
|
|
|
94
101
|
const [label, setLabel] = useState(mark.label);
|
|
@@ -131,65 +138,72 @@ export const MarkLabel = (props) => {
|
|
|
131
138
|
renderMath(root);
|
|
132
139
|
}, []);
|
|
133
140
|
|
|
134
|
-
return
|
|
135
|
-
<div
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
141
|
+
return (
|
|
142
|
+
<div className={classes.flexContainer}>
|
|
143
|
+
{correctnessIndicator}
|
|
144
|
+
{isMathRendering() ? (
|
|
145
|
+
<div
|
|
146
|
+
ref={(r) => {
|
|
147
|
+
root = r;
|
|
148
|
+
externalInputRef(r);
|
|
149
|
+
}}
|
|
150
|
+
dangerouslySetInnerHTML={{ __html: getLabelMathFormat(label) }}
|
|
151
|
+
className={classNames(classes.mathInput, {
|
|
152
|
+
[classes.disabled]: disabled,
|
|
153
|
+
[classes.error]: error,
|
|
154
|
+
[classes.correct]: mark.editable && correctness?.label === 'correct',
|
|
155
|
+
[classes.incorrect]: mark.editable && correctness?.label === 'incorrect',
|
|
156
|
+
})}
|
|
157
|
+
onClick={() => setIsEditing(true)}
|
|
158
|
+
style={{
|
|
159
|
+
minWidth: barWidth,
|
|
160
|
+
position: 'fixed',
|
|
161
|
+
transformOrigin: 'left',
|
|
162
|
+
transform: `rotate(${rotate}deg)`,
|
|
163
|
+
visibility: isHiddenLabel ? 'hidden' : 'unset',
|
|
164
|
+
marginTop: correctnessIndicator ? '24px' : '0',
|
|
165
|
+
}}
|
|
166
|
+
></div>
|
|
167
|
+
) : (
|
|
168
|
+
<AutosizeInput
|
|
169
|
+
inputRef={(r) => {
|
|
170
|
+
_ref(r);
|
|
171
|
+
externalInputRef(r);
|
|
172
|
+
}}
|
|
173
|
+
autoFocus={isEditing || autoFocus}
|
|
174
|
+
disabled={disabled}
|
|
175
|
+
inputClassName={classNames(
|
|
176
|
+
classes.input,
|
|
177
|
+
correctness && mark.editable ? correctness.label : null,
|
|
178
|
+
disabled && 'disabled',
|
|
179
|
+
error && 'error',
|
|
180
|
+
)}
|
|
181
|
+
inputStyle={{
|
|
182
|
+
minWidth: barWidth,
|
|
183
|
+
textAlign: 'center',
|
|
184
|
+
background: 'transparent',
|
|
185
|
+
boxSizing: 'border-box',
|
|
186
|
+
paddingLeft: 0,
|
|
187
|
+
paddingRight: 0,
|
|
188
|
+
...extraStyle,
|
|
189
|
+
}}
|
|
190
|
+
value={label}
|
|
191
|
+
style={{
|
|
192
|
+
position: 'fixed',
|
|
193
|
+
pointerEvents: 'auto',
|
|
194
|
+
top: 0,
|
|
195
|
+
left: 0,
|
|
196
|
+
minWidth: barWidth,
|
|
197
|
+
transformOrigin: 'left',
|
|
198
|
+
transform: `rotate(${rotate}deg)`,
|
|
199
|
+
visibility: isHiddenLabel ? 'hidden' : 'unset',
|
|
200
|
+
marginTop: correctnessIndicator ? '24px' : '0',
|
|
201
|
+
}}
|
|
202
|
+
onChange={onChange}
|
|
203
|
+
onBlur={onChangeProp}
|
|
204
|
+
/>
|
|
169
205
|
)}
|
|
170
|
-
|
|
171
|
-
minWidth: barWidth,
|
|
172
|
-
textAlign: 'center',
|
|
173
|
-
background: 'transparent',
|
|
174
|
-
boxSizing: 'border-box',
|
|
175
|
-
paddingLeft: 0,
|
|
176
|
-
paddingRight: 0,
|
|
177
|
-
...extraStyle,
|
|
178
|
-
}}
|
|
179
|
-
value={label}
|
|
180
|
-
style={{
|
|
181
|
-
position: 'fixed',
|
|
182
|
-
pointerEvents: 'auto',
|
|
183
|
-
top: 0,
|
|
184
|
-
left: 0,
|
|
185
|
-
minWidth: barWidth,
|
|
186
|
-
transformOrigin: 'left',
|
|
187
|
-
transform: `rotate(${rotate}deg)`,
|
|
188
|
-
visibility: isHiddenLabel ? 'hidden' : 'unset',
|
|
189
|
-
}}
|
|
190
|
-
onChange={onChange}
|
|
191
|
-
onBlur={onChangeProp}
|
|
192
|
-
/>
|
|
206
|
+
</div>
|
|
193
207
|
);
|
|
194
208
|
};
|
|
195
209
|
|
|
@@ -210,6 +224,7 @@ MarkLabel.propTypes = {
|
|
|
210
224
|
}),
|
|
211
225
|
isHiddenLabel: PropTypes.bool,
|
|
212
226
|
limitCharacters: PropTypes.bool,
|
|
227
|
+
correctnessIndicator: PropTypes.node,
|
|
213
228
|
};
|
|
214
229
|
|
|
215
230
|
export default withStyles(styles)(MarkLabel);
|
package/src/plot/common/plot.jsx
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import
|
|
4
|
-
import
|
|
3
|
+
import classNames from 'classnames';
|
|
4
|
+
import Check from '@material-ui/icons/Check';
|
|
5
5
|
import { withStyles } from '@material-ui/core/styles/index';
|
|
6
|
-
import
|
|
6
|
+
import { Group } from '@vx/group';
|
|
7
7
|
import debug from 'debug';
|
|
8
|
+
|
|
9
|
+
import { types } from '@pie-lib/plot';
|
|
10
|
+
import DraggableHandle, { DragHandle } from '../../common/drag-handle';
|
|
8
11
|
import { color } from '@pie-lib/render-ui';
|
|
9
12
|
import { bandKey } from '../../utils';
|
|
10
13
|
import { correct, incorrect } from '../../common/styles';
|
|
11
14
|
|
|
12
15
|
const log = debug('pie-lib:chart:bars');
|
|
16
|
+
const ICON_SIZE = 16; // 10px icon + 2px padding on all sides + 1px border
|
|
13
17
|
|
|
14
18
|
export class RawPlot extends React.Component {
|
|
15
19
|
static propTypes = {
|
|
@@ -64,6 +68,20 @@ export class RawPlot extends React.Component {
|
|
|
64
68
|
this.setDragValue(next);
|
|
65
69
|
};
|
|
66
70
|
|
|
71
|
+
renderCorrectnessIcon = (barX, barWidth, correctVal, correctness, classes, scale) => (
|
|
72
|
+
<foreignObject
|
|
73
|
+
x={barX + barWidth / 2 - ICON_SIZE / 2}
|
|
74
|
+
y={scale.y(correctVal) + ICON_SIZE}
|
|
75
|
+
width={ICON_SIZE}
|
|
76
|
+
height={ICON_SIZE}
|
|
77
|
+
>
|
|
78
|
+
<Check
|
|
79
|
+
className={classNames(classes.correctnessIcon, classes.correctIcon, classes.smallIcon)}
|
|
80
|
+
title={correctness.label}
|
|
81
|
+
/>
|
|
82
|
+
</foreignObject>
|
|
83
|
+
);
|
|
84
|
+
|
|
67
85
|
render() {
|
|
68
86
|
const {
|
|
69
87
|
graphProps,
|
|
@@ -76,6 +94,7 @@ export class RawPlot extends React.Component {
|
|
|
76
94
|
interactive,
|
|
77
95
|
correctness,
|
|
78
96
|
defineChart,
|
|
97
|
+
correctData,
|
|
79
98
|
} = this.props;
|
|
80
99
|
|
|
81
100
|
const { scale, range, size } = graphProps;
|
|
@@ -132,6 +151,67 @@ export class RawPlot extends React.Component {
|
|
|
132
151
|
scale,
|
|
133
152
|
}),
|
|
134
153
|
)}
|
|
154
|
+
{correctness &&
|
|
155
|
+
correctness.value === 'incorrect' &&
|
|
156
|
+
(() => {
|
|
157
|
+
const correctVal = parseFloat(correctData[index] && correctData[index].value);
|
|
158
|
+
if (isNaN(correctVal)) return null;
|
|
159
|
+
const selectedVal = v;
|
|
160
|
+
if (selectedVal > correctVal) {
|
|
161
|
+
// selected is higher than correct: overlay the correct last segment
|
|
162
|
+
const overlayValues = [];
|
|
163
|
+
for (let i = 0; i < correctVal; i++) {
|
|
164
|
+
overlayValues.push(i);
|
|
165
|
+
}
|
|
166
|
+
const lastIndexOfOverlay = overlayValues.length - 1;
|
|
167
|
+
const lastOverlayValue = overlayValues[lastIndexOfOverlay];
|
|
168
|
+
const barX = xBand(bandKey({ label }, index));
|
|
169
|
+
const barWidth = xBand.bandwidth();
|
|
170
|
+
const pointHeight = size.height / max;
|
|
171
|
+
const pointDiameter = (pointHeight > barWidth ? barWidth : pointHeight) * 0.8;
|
|
172
|
+
return (
|
|
173
|
+
<>
|
|
174
|
+
<CustomBarElement
|
|
175
|
+
index={lastOverlayValue}
|
|
176
|
+
pointDiameter={pointDiameter + 10} // increase point diameter for dotted line
|
|
177
|
+
barX={barX}
|
|
178
|
+
barWidth={barWidth}
|
|
179
|
+
pointHeight={pointHeight}
|
|
180
|
+
label={label}
|
|
181
|
+
value={value}
|
|
182
|
+
classes={classes}
|
|
183
|
+
scale={scale}
|
|
184
|
+
dottedOverline={true}
|
|
185
|
+
/>
|
|
186
|
+
{this.renderCorrectnessIcon(barX, barWidth, correctVal, correctness, classes, scale)}
|
|
187
|
+
</>
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
// selected is lower than correct, render missing segment below the correct bar
|
|
191
|
+
const valuesToRender = [];
|
|
192
|
+
for (let i = selectedVal; i < correctVal; i++) {
|
|
193
|
+
valuesToRender.push(i);
|
|
194
|
+
}
|
|
195
|
+
return (
|
|
196
|
+
<>
|
|
197
|
+
{valuesToRender.map((idx) =>
|
|
198
|
+
CustomBarElement({
|
|
199
|
+
index: idx,
|
|
200
|
+
pointDiameter,
|
|
201
|
+
barX,
|
|
202
|
+
barWidth,
|
|
203
|
+
pointHeight,
|
|
204
|
+
label,
|
|
205
|
+
value,
|
|
206
|
+
classes,
|
|
207
|
+
scale,
|
|
208
|
+
dottedOverline: true,
|
|
209
|
+
}),
|
|
210
|
+
)}
|
|
211
|
+
{this.renderCorrectnessIcon(barX, barWidth, correctVal, correctness, classes, scale)}
|
|
212
|
+
</>
|
|
213
|
+
);
|
|
214
|
+
})()}
|
|
135
215
|
<Component
|
|
136
216
|
x={barX}
|
|
137
217
|
y={v}
|
|
@@ -144,6 +224,7 @@ export class RawPlot extends React.Component {
|
|
|
144
224
|
isHovered={isHovered}
|
|
145
225
|
defineChart={defineChart}
|
|
146
226
|
color={color.primaryDark()}
|
|
227
|
+
isPlot
|
|
147
228
|
/>
|
|
148
229
|
</g>
|
|
149
230
|
</React.Fragment>
|
|
@@ -151,17 +232,44 @@ export class RawPlot extends React.Component {
|
|
|
151
232
|
}
|
|
152
233
|
}
|
|
153
234
|
|
|
154
|
-
const Bar = withStyles(() => ({
|
|
235
|
+
const Bar = withStyles((theme) => ({
|
|
155
236
|
dot: {
|
|
156
237
|
fill: color.visualElementsColors.PLOT_FILL_COLOR,
|
|
157
238
|
'&.correct': correct('stroke'),
|
|
158
239
|
'&.incorrect': incorrect('stroke'),
|
|
159
240
|
},
|
|
241
|
+
dotColor: {
|
|
242
|
+
fill: color.visualElementsColors.PLOT_FILL_COLOR,
|
|
243
|
+
'&.correct': correct('fill'),
|
|
244
|
+
'&.incorrect': incorrect('fill'),
|
|
245
|
+
},
|
|
160
246
|
line: {
|
|
161
247
|
stroke: color.visualElementsColors.PLOT_FILL_COLOR,
|
|
162
248
|
'&.correct': correct('stroke'),
|
|
163
249
|
'&.incorrect': incorrect('stroke'),
|
|
164
250
|
},
|
|
251
|
+
correctIcon: {
|
|
252
|
+
backgroundColor: color.correct(),
|
|
253
|
+
},
|
|
254
|
+
incorrectIcon: {
|
|
255
|
+
backgroundColor: color.incorrectWithIcon(),
|
|
256
|
+
},
|
|
257
|
+
correctnessIcon: {
|
|
258
|
+
borderRadius: theme.spacing.unit * 2,
|
|
259
|
+
color: color.defaults.WHITE,
|
|
260
|
+
fontSize: '16px',
|
|
261
|
+
width: '16px',
|
|
262
|
+
height: '16px',
|
|
263
|
+
padding: '2px',
|
|
264
|
+
border: `1px solid ${color.defaults.WHITE}`,
|
|
265
|
+
stroke: 'initial',
|
|
266
|
+
boxSizing: 'unset', // to override the default border-box in IBX
|
|
267
|
+
},
|
|
268
|
+
smallIcon: {
|
|
269
|
+
fontSize: '10px',
|
|
270
|
+
width: '10px',
|
|
271
|
+
height: '10px',
|
|
272
|
+
},
|
|
165
273
|
}))(RawPlot);
|
|
166
274
|
|
|
167
275
|
export class Plot extends React.Component {
|
|
@@ -175,7 +283,7 @@ export class Plot extends React.Component {
|
|
|
175
283
|
};
|
|
176
284
|
|
|
177
285
|
render() {
|
|
178
|
-
const { data, graphProps, xBand, CustomBarElement, onChangeCategory, defineChart } = this.props;
|
|
286
|
+
const { data, graphProps, xBand, CustomBarElement, onChangeCategory, defineChart, correctData } = this.props;
|
|
179
287
|
|
|
180
288
|
return (
|
|
181
289
|
<Group>
|
|
@@ -192,6 +300,7 @@ export class Plot extends React.Component {
|
|
|
192
300
|
graphProps={graphProps}
|
|
193
301
|
CustomBarElement={CustomBarElement}
|
|
194
302
|
correctness={d.correctness}
|
|
303
|
+
correctData={correctData}
|
|
195
304
|
/>
|
|
196
305
|
))}
|
|
197
306
|
</Group>
|
package/src/plot/dot.js
CHANGED
|
@@ -1,18 +1,33 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
+
import { Circle } from '@vx/shape';
|
|
4
|
+
|
|
3
5
|
import { types } from '@pie-lib/plot';
|
|
4
6
|
import { dataToXBand } from '../utils';
|
|
5
7
|
import Plot from './common/plot';
|
|
6
|
-
import {
|
|
8
|
+
import { color } from '@pie-lib/render-ui';
|
|
7
9
|
|
|
8
10
|
const CustomBarElement = (props) => {
|
|
9
|
-
const { index, pointDiameter, barX, barWidth, pointHeight, label, value, classes, scale } = props;
|
|
11
|
+
const { index, pointDiameter, barX, barWidth, pointHeight, label, value, classes, scale, dottedOverline } = props;
|
|
10
12
|
|
|
11
13
|
const r = pointDiameter / 2;
|
|
12
14
|
const cx = barX + (barWidth - pointDiameter) / 2 + r;
|
|
13
15
|
const cy = scale.y(index) - (pointHeight - pointDiameter) / 2 - r;
|
|
16
|
+
const EXTRA_PADDING = 2;
|
|
14
17
|
|
|
15
|
-
return
|
|
18
|
+
return dottedOverline ? (
|
|
19
|
+
<Circle
|
|
20
|
+
key={`point-${label}-${value}-${index}`}
|
|
21
|
+
cx={cx}
|
|
22
|
+
cy={cy}
|
|
23
|
+
r={r + EXTRA_PADDING}
|
|
24
|
+
strokeDasharray="4,4"
|
|
25
|
+
stroke={color.defaults.BORDER_GRAY}
|
|
26
|
+
fill="none"
|
|
27
|
+
/>
|
|
28
|
+
) : (
|
|
29
|
+
<Circle key={`point-${label}-${value}-${index}`} className={classes.dot} cx={cx} cy={cy} r={r} />
|
|
30
|
+
);
|
|
16
31
|
};
|
|
17
32
|
|
|
18
33
|
CustomBarElement.propTypes = {
|
|
@@ -25,6 +40,7 @@ CustomBarElement.propTypes = {
|
|
|
25
40
|
label: PropTypes.string,
|
|
26
41
|
classes: PropTypes.object,
|
|
27
42
|
scale: PropTypes.object,
|
|
43
|
+
dottedOverline: PropTypes.bool,
|
|
28
44
|
};
|
|
29
45
|
|
|
30
46
|
export class DotPlot extends React.Component {
|
package/src/plot/line.js
CHANGED
|
@@ -1,18 +1,32 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
+
import { LinePath } from '@vx/shape';
|
|
4
|
+
import { Group } from '@vx/group';
|
|
5
|
+
|
|
3
6
|
import { types } from '@pie-lib/plot';
|
|
4
7
|
import { dataToXBand } from '../utils';
|
|
8
|
+
import { color } from '@pie-lib/render-ui';
|
|
5
9
|
import Plot from './common/plot';
|
|
6
|
-
import { LinePath } from '@vx/shape';
|
|
7
|
-
import { Group } from '@vx/group';
|
|
8
10
|
|
|
9
11
|
const CustomBarElement = (props) => {
|
|
10
|
-
const { index, pointDiameter, barX, barWidth, pointHeight, label, value, classes, scale } = props;
|
|
12
|
+
const { index, pointDiameter, barX, barWidth, pointHeight, label, value, classes, scale, dottedOverline } = props;
|
|
11
13
|
|
|
12
14
|
const x = barX + (barWidth - pointDiameter) / 2;
|
|
13
15
|
const y = scale.y(index) - (pointHeight - pointDiameter) / 2;
|
|
16
|
+
const EXTRA_PADDING = 2;
|
|
14
17
|
|
|
15
|
-
return (
|
|
18
|
+
return dottedOverline ? (
|
|
19
|
+
<rect
|
|
20
|
+
key={`point-${label}-${value}-${index}`}
|
|
21
|
+
x={x - EXTRA_PADDING}
|
|
22
|
+
y={y - pointDiameter - EXTRA_PADDING}
|
|
23
|
+
width={pointDiameter + EXTRA_PADDING * 2}
|
|
24
|
+
height={pointDiameter + EXTRA_PADDING * 2}
|
|
25
|
+
strokeDasharray="4,4"
|
|
26
|
+
stroke={color.defaults.BORDER_GRAY}
|
|
27
|
+
fill="none"
|
|
28
|
+
/>
|
|
29
|
+
) : (
|
|
16
30
|
<Group>
|
|
17
31
|
<LinePath
|
|
18
32
|
data={[
|