@pie-lib/charting 5.24.1 → 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.
Files changed (54) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/lib/actions-button.js +4 -3
  3. package/lib/actions-button.js.map +1 -1
  4. package/lib/axes.js +44 -10
  5. package/lib/axes.js.map +1 -1
  6. package/lib/bars/common/bars.js +63 -9
  7. package/lib/bars/common/bars.js.map +1 -1
  8. package/lib/bars/common/correct-check-icon.js +55 -0
  9. package/lib/bars/common/correct-check-icon.js.map +1 -0
  10. package/lib/chart.js +17 -10
  11. package/lib/chart.js.map +1 -1
  12. package/lib/common/correctness-indicators.js +99 -0
  13. package/lib/common/correctness-indicators.js.map +1 -0
  14. package/lib/common/drag-handle.js +36 -8
  15. package/lib/common/drag-handle.js.map +1 -1
  16. package/lib/line/common/drag-handle.js +32 -9
  17. package/lib/line/common/drag-handle.js.map +1 -1
  18. package/lib/line/common/line.js +5 -2
  19. package/lib/line/common/line.js.map +1 -1
  20. package/lib/line/line-cross.js +26 -5
  21. package/lib/line/line-cross.js.map +1 -1
  22. package/lib/line/line-dot.js +24 -4
  23. package/lib/line/line-dot.js.map +1 -1
  24. package/lib/mark-label.js +18 -7
  25. package/lib/mark-label.js.map +1 -1
  26. package/lib/plot/common/plot.js +119 -9
  27. package/lib/plot/common/plot.js.map +1 -1
  28. package/lib/plot/dot.js +17 -4
  29. package/lib/plot/dot.js.map +1 -1
  30. package/lib/plot/line.js +19 -6
  31. package/lib/plot/line.js.map +1 -1
  32. package/package.json +5 -5
  33. package/src/__tests__/__snapshots__/axes.test.jsx.snap +5 -1
  34. package/src/__tests__/__snapshots__/chart.test.jsx.snap +6 -3
  35. package/src/__tests__/__snapshots__/mark-label.test.jsx.snap +62 -56
  36. package/src/actions-button.jsx +3 -2
  37. package/src/axes.jsx +37 -3
  38. package/src/bars/common/bars.jsx +57 -4
  39. package/src/bars/common/correct-check-icon.jsx +20 -0
  40. package/src/chart.jsx +12 -3
  41. package/src/common/__tests__/__snapshots__/drag-handle.test.jsx.snap +3 -0
  42. package/src/common/correctness-indicators.jsx +55 -0
  43. package/src/common/drag-handle.jsx +28 -14
  44. package/src/line/common/__tests__/__snapshots__/drag-handle.test.jsx.snap +5 -0
  45. package/src/line/common/__tests__/__snapshots__/line.test.jsx.snap +2 -0
  46. package/src/line/common/drag-handle.jsx +31 -8
  47. package/src/line/common/line.jsx +3 -1
  48. package/src/line/line-cross.js +25 -3
  49. package/src/line/line-dot.js +40 -3
  50. package/src/mark-label.jsx +73 -58
  51. package/src/plot/common/__tests__/__snapshots__/plot.test.jsx.snap +1 -0
  52. package/src/plot/common/plot.jsx +114 -5
  53. package/src/plot/dot.js +19 -3
  54. package/src/plot/line.js +18 -4
@@ -1,13 +1,15 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import { types } from '@pie-lib/plot';
4
3
  import { Group } from '@vx/group';
5
- import { color } from '@pie-lib/render-ui';
6
4
  import { Bar as VxBar } from '@vx/shape';
7
5
  import { withStyles } from '@material-ui/core/styles/index';
8
6
  import debug from 'debug';
7
+
8
+ import { color } from '@pie-lib/render-ui';
9
+ import { types } from '@pie-lib/plot';
9
10
  import { bandKey } from '../../utils';
10
11
  import DraggableHandle, { DragHandle } from '../../common/drag-handle';
12
+ import { CorrectCheckIcon } from './correct-check-icon';
11
13
 
12
14
  const log = debug('pie-lib:chart:bars');
13
15
  const histogramColors = [
@@ -64,6 +66,7 @@ export class RawBar extends React.Component {
64
66
  value: PropTypes.string,
65
67
  label: PropTypes.string,
66
68
  }),
69
+ correctData: PropTypes.array,
67
70
  };
68
71
 
69
72
  constructor(props) {
@@ -144,6 +147,7 @@ export class RawBar extends React.Component {
144
147
  correctness,
145
148
  barColor,
146
149
  defineChart,
150
+ correctData,
147
151
  } = this.props;
148
152
  const { scale, range } = graphProps;
149
153
  const { dragValue, isHovered } = this.state;
@@ -156,9 +160,11 @@ export class RawBar extends React.Component {
156
160
  const barX = xBand(bandKey({ label }, index));
157
161
  const rawY = range.max - v;
158
162
  const yy = range.max - rawY;
163
+ const correctValue = correctData ? correctData.find((d) => d.label === label) : null;
159
164
  log('label:', label, 'barX:', barX, 'v: ', v, 'barHeight:', barHeight, 'barWidth: ', barWidth);
160
165
 
161
166
  const Component = interactive ? DraggableHandle : DragHandle;
167
+ const isHistogram = !!barColor;
162
168
 
163
169
  return (
164
170
  <g
@@ -176,6 +182,40 @@ export class RawBar extends React.Component {
176
182
  className={classes.bar}
177
183
  style={{ fill: fillColor }}
178
184
  />
185
+ {correctness &&
186
+ correctness.value === 'incorrect' &&
187
+ (() => {
188
+ const correctVal = parseFloat(correctValue && correctValue.value);
189
+ if (isNaN(correctVal)) return null;
190
+ const correctPxHeight = scale.y(range.max - correctVal);
191
+ const actualPxHeight = barHeight;
192
+ const diffPx = Math.abs(correctPxHeight - actualPxHeight);
193
+ const yDiff = scale.y(correctVal);
194
+ const indicatorBarColor = correctPxHeight > actualPxHeight ? color.borderGray() : color.defaults.WHITE;
195
+ const yToRender = correctPxHeight > actualPxHeight ? yDiff : yDiff - diffPx;
196
+
197
+ return (
198
+ <>
199
+ <VxBar
200
+ x={barX + 2} // add 2px for the stroke (the dashed border)
201
+ y={yToRender}
202
+ width={barWidth - 4} // substract 4px for the total stroke
203
+ height={diffPx}
204
+ className={classes.bar}
205
+ style={{
206
+ stroke: indicatorBarColor,
207
+ strokeWidth: 2,
208
+ strokeDasharray: '5,2',
209
+ fill: 'none',
210
+ }}
211
+ />
212
+ {/* adjust the position based on whether it's a histogram or not, because the histogram does not have space for the icon on the side */}
213
+ <foreignObject x={barX + barWidth - (isHistogram ? 24 : 14)} y={yDiff - 12} width={24} height={24}>
214
+ <CorrectCheckIcon dashColor={indicatorBarColor} />
215
+ </foreignObject>
216
+ </>
217
+ );
218
+ })()}
179
219
  <Component
180
220
  x={barX}
181
221
  y={v}
@@ -194,15 +234,27 @@ export class RawBar extends React.Component {
194
234
  }
195
235
  }
196
236
 
197
- const Bar = withStyles(() => ({
237
+ const Bar = withStyles((theme) => ({
198
238
  bar: {
199
239
  fill: color.defaults.TERTIARY,
200
240
  },
241
+ correctIcon: {
242
+ backgroundColor: color.correct(),
243
+ borderRadius: theme.spacing.unit * 2,
244
+ color: color.defaults.WHITE,
245
+ fontSize: '10px',
246
+ width: '10px',
247
+ height: '10px',
248
+ padding: '2px',
249
+ border: `1px solid ${color.defaults.WHITE}`,
250
+ boxSizing: 'unset', // to override the default border-box in IBX
251
+ },
201
252
  }))(RawBar);
202
253
 
203
254
  export class Bars extends React.Component {
204
255
  static propTypes = {
205
256
  data: PropTypes.array,
257
+ correctData: PropTypes.array,
206
258
  onChangeCategory: PropTypes.func,
207
259
  defineChart: PropTypes.bool,
208
260
  xBand: PropTypes.func,
@@ -211,7 +263,7 @@ export class Bars extends React.Component {
211
263
  };
212
264
 
213
265
  render() {
214
- const { data, graphProps, xBand, onChangeCategory, defineChart, histogram } = this.props;
266
+ const { data, graphProps, xBand, onChangeCategory, defineChart, histogram, correctData } = this.props;
215
267
 
216
268
  return (
217
269
  <Group>
@@ -227,6 +279,7 @@ export class Bars extends React.Component {
227
279
  onChangeCategory={(category) => onChangeCategory(index, category)}
228
280
  graphProps={graphProps}
229
281
  correctness={d.correctness}
282
+ correctData={correctData}
230
283
  barColor={
231
284
  histogram &&
232
285
  (histogramColors[index] ? histogramColors[index] : histogramColors[index % histogramColors.length])
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+
3
+ export const CorrectCheckIcon = ({ dashColor }) => (
4
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
5
+ <circle cx="12" cy="12" r="11" fill="white" stroke={dashColor || '#7E8494'} strokeWidth="2" strokeDasharray="5 5" />
6
+ <mask id="path-2-outside-1_3089_3799" maskUnits="userSpaceOnUse" x="2" y="3" width="19" height="18" fill="black">
7
+ <rect fill="white" x="2" y="3" width="19" height="18" />
8
+ <path d="M12 20C9.125 20 6.5 18.5 5.0625 16C3.625 13.5312 3.625 10.5 5.0625 8C6.5 5.53125 9.125 4 12 4C14.8438 4 17.4688 5.53125 18.9062 8C20.3438 10.5 20.3438 13.5312 18.9062 16C17.4688 18.5 14.8438 20 12 20ZM15.5312 10.5312H15.5C15.8125 10.25 15.8125 9.78125 15.5 9.46875C15.2188 9.1875 14.75 9.1875 14.4688 9.46875L11 12.9688L9.53125 11.5C9.21875 11.1875 8.75 11.1875 8.46875 11.5C8.15625 11.7812 8.15625 12.25 8.46875 12.5312L10.4688 14.5312C10.75 14.8438 11.2188 14.8438 11.5312 14.5312L15.5312 10.5312Z" />
9
+ </mask>
10
+ <path
11
+ d="M12 20C9.125 20 6.5 18.5 5.0625 16C3.625 13.5312 3.625 10.5 5.0625 8C6.5 5.53125 9.125 4 12 4C14.8438 4 17.4688 5.53125 18.9062 8C20.3438 10.5 20.3438 13.5312 18.9062 16C17.4688 18.5 14.8438 20 12 20ZM15.5312 10.5312H15.5C15.8125 10.25 15.8125 9.78125 15.5 9.46875C15.2188 9.1875 14.75 9.1875 14.4688 9.46875L11 12.9688L9.53125 11.5C9.21875 11.1875 8.75 11.1875 8.46875 11.5C8.15625 11.7812 8.15625 12.25 8.46875 12.5312L10.4688 14.5312C10.75 14.8438 11.2188 14.8438 11.5312 14.5312L15.5312 10.5312Z"
12
+ fill="#0EA449"
13
+ />
14
+ <path
15
+ d="M5.0625 16L5.92942 15.5015L5.92668 15.4968L5.0625 16ZM5.0625 8L4.19831 7.4968L4.19559 7.50153L5.0625 8ZM18.9062 8L19.7732 7.50152L19.7704 7.49681L18.9062 8ZM18.9062 16L18.0421 15.4968L18.0393 15.5015L18.9062 16ZM15.5312 10.5312L16.2384 11.2384L17.9455 9.53125H15.5312V10.5312ZM15.5 10.5312L14.831 9.78796L12.894 11.5312H15.5V10.5312ZM14.4688 9.46875L13.7616 8.76164L13.7585 8.76482L14.4688 9.46875ZM11 12.9688L10.2929 13.6759L11.0032 14.3861L11.7103 13.6727L11 12.9688ZM8.46875 11.5L9.13771 12.2433L9.17684 12.2081L9.21204 12.169L8.46875 11.5ZM8.46875 12.5312L9.17586 11.8241L9.15726 11.8055L9.13771 11.788L8.46875 12.5312ZM10.4688 14.5312L11.212 13.8623L11.1945 13.8427L11.1759 13.8241L10.4688 14.5312ZM12 20V19C9.479 19 7.18657 17.6879 5.92941 15.5015L5.0625 16L4.19559 16.4985C5.81343 19.3121 8.771 21 12 21V20ZM5.0625 16L5.92668 15.4968C4.6714 13.341 4.66824 10.6918 5.92941 8.49847L5.0625 8L4.19559 7.50153C2.58176 10.3082 2.5786 13.7215 4.19832 16.5032L5.0625 16ZM5.0625 8L5.92668 8.50319C7.18712 6.33851 9.48502 5 12 5V4V3C8.76498 3 5.81288 4.72399 4.19832 7.49681L5.0625 8ZM12 4V5C14.4816 5 16.7805 6.33661 18.0421 8.50319L18.9062 8L19.7704 7.49681C18.157 4.72589 15.2059 3 12 3V4ZM18.9062 8L18.0393 8.49847C19.3005 10.6918 19.2973 13.341 18.0421 15.4968L18.9062 16L19.7704 16.5032C21.3902 13.7215 21.387 10.3082 19.7732 7.50153L18.9062 8ZM18.9062 16L18.0393 15.5015C16.7811 17.6898 14.4876 19 12 19V20V21C15.1999 21 18.1564 19.3102 19.7732 16.4985L18.9062 16ZM15.5312 10.5312V9.53125H15.5V10.5312V11.5312H15.5312V10.5312ZM15.5 10.5312L16.169 11.2745C16.9447 10.5764 16.8883 9.44281 16.2071 8.76164L15.5 9.46875L14.7929 10.1759C14.7696 10.1525 14.7344 10.0966 14.7344 10.0117C14.7344 9.92377 14.7735 9.83972 14.831 9.78796L15.5 10.5312ZM15.5 9.46875L16.2071 8.76164C15.5353 8.08987 14.4334 8.08987 13.7616 8.76164L14.4688 9.46875L15.1759 10.1759C15.1167 10.235 15.0442 10.2578 14.9844 10.2578C14.9245 10.2578 14.8521 10.235 14.7929 10.1759L15.5 9.46875ZM14.4688 9.46875L13.7585 8.76482L10.2897 12.2648L11 12.9688L11.7103 13.6727L15.179 10.1727L14.4688 9.46875ZM11 12.9688L11.7071 12.2616L10.2384 10.7929L9.53125 11.5L8.82414 12.2071L10.2929 13.6759L11 12.9688ZM9.53125 11.5L10.2384 10.7929C9.55719 10.1117 8.42362 10.0553 7.72546 10.831L8.46875 11.5L9.21204 12.169C9.16028 12.2265 9.07623 12.2656 8.98828 12.2656C8.90344 12.2656 8.84748 12.2304 8.82414 12.2071L9.53125 11.5ZM8.46875 11.5L7.79979 10.7567C7.04591 11.4352 7.04591 12.5961 7.79979 13.2745L8.46875 12.5312L9.13771 11.788C9.19301 11.8377 9.23438 11.9208 9.23438 12.0156C9.23438 12.1105 9.19301 12.1935 9.13771 12.2433L8.46875 11.5ZM8.46875 12.5312L7.76164 13.2384L9.76164 15.2384L10.4688 14.5312L11.1759 13.8241L9.17586 11.8241L8.46875 12.5312ZM10.4688 14.5312L9.72546 15.2002C10.4236 15.976 11.5572 15.9195 12.2384 15.2384L11.5312 14.5312L10.8241 13.8241C10.8475 13.8008 10.9034 13.7656 10.9883 13.7656C11.0762 13.7656 11.1603 13.8048 11.212 13.8623L10.4688 14.5312ZM11.5312 14.5312L12.2384 15.2384L16.2384 11.2384L15.5312 10.5312L14.8241 9.82414L10.8241 13.8241L11.5312 14.5312Z"
16
+ fill="white"
17
+ mask="url(#path-2-outside-1_3089_3799)"
18
+ />
19
+ </svg>
20
+ );
package/src/chart.jsx CHANGED
@@ -73,6 +73,12 @@ export class Chart extends React.Component {
73
73
  language: PropTypes.string,
74
74
  mathMlOptions: PropTypes.object,
75
75
  labelsCharactersLimit: PropTypes.number,
76
+ correctData: PropTypes.arrayOf(
77
+ PropTypes.shape({
78
+ label: PropTypes.string,
79
+ value: PropTypes.number,
80
+ }),
81
+ ),
76
82
  };
77
83
 
78
84
  static defaultProps = {
@@ -223,6 +229,7 @@ export class Chart extends React.Component {
223
229
  mathMlOptions = {},
224
230
  language,
225
231
  labelsCharactersLimit,
232
+ correctData,
226
233
  } = this.props;
227
234
  let { chartType } = this.props;
228
235
 
@@ -244,7 +251,7 @@ export class Chart extends React.Component {
244
251
 
245
252
  log('[render] common:', common);
246
253
 
247
- const maskSize = { x: -10, y: -75, width: width + 20, height: height + 80 };
254
+ const maskSize = { x: -10, y: -75, width: width + 20, height: height + 130 };
248
255
  const { scale } = common.graphProps;
249
256
  const xBand = dataToXBand(scale.x, categories, width, chartType);
250
257
 
@@ -300,10 +307,11 @@ export class Chart extends React.Component {
300
307
  changeEditableEnabled={changeEditableEnabled}
301
308
  top={top}
302
309
  error={error}
310
+ showCorrectness={chartType === 'linePlot' || chartType === 'dotPlot'}
303
311
  />
304
312
  {addCategoryEnabled ? (
305
- <foreignObject x={width - 8} y={height - 8} width={100} height={40}>
306
- <div xmlns="http://www.w3.org/1999/xhtml" style={{ display: 'flex', justifyContent: 'center' }}>
313
+ <foreignObject x={width} y={height - 16} width={width} height={height}>
314
+ <div xmlns="http://www.w3.org/1999/xhtml" style={{ display: 'flex', justifyContent: 'flex-start' }}>
307
315
  <ActionsButton
308
316
  categories={categories}
309
317
  addCategory={this.addCategory}
@@ -324,6 +332,7 @@ export class Chart extends React.Component {
324
332
  defineChart={defineChart}
325
333
  onChange={this.changeData}
326
334
  onChangeCategory={this.changeCategory}
335
+ correctData={correctData}
327
336
  />
328
337
  </g>
329
338
  </Root>
@@ -5,8 +5,11 @@ exports[`BasePoint snapshot renders 1`] = `
5
5
  className="className"
6
6
  classes={
7
7
  Object {
8
+ "correctIcon": "RawDragHandle-correctIcon-5",
9
+ "correctnessIcon": "RawDragHandle-correctnessIcon-7",
8
10
  "handle": "RawDragHandle-handle-1",
9
11
  "handleContainer": "RawDragHandle-handleContainer-3",
12
+ "incorrectIcon": "RawDragHandle-incorrectIcon-6",
10
13
  "svgOverflowVisible": "RawDragHandle-svgOverflowVisible-4",
11
14
  "transparentHandle": "RawDragHandle-transparentHandle-2",
12
15
  }
@@ -0,0 +1,55 @@
1
+ import React from 'react';
2
+ import classNames from 'classnames';
3
+ import Check from '@material-ui/icons/Check';
4
+ import Close from '@material-ui/icons/Close';
5
+
6
+ export const CorrectnessIndicator = ({ scale, x, y, classes, r, correctness, interactive }) => {
7
+ if (!correctness || !interactive) return null;
8
+ const cx = scale ? scale.x(x) : x;
9
+ const cy = scale ? scale.y(y) : y;
10
+ const isCorrect = correctness.value === 'correct';
11
+ const iconClass = isCorrect ? classes.correctIcon : classes.incorrectIcon;
12
+
13
+ // the icon is 16px + 2px padding + 1px border, so total size is 22px
14
+ return (
15
+ <foreignObject x={cx - 11} y={cy - 11} width={22} height={22}>
16
+ {isCorrect ? (
17
+ <Check className={classNames(classes.correctnessIcon, iconClass)} title={correctness.label} />
18
+ ) : (
19
+ <Close className={classNames(classes.correctnessIcon, iconClass)} title={correctness.label} />
20
+ )}
21
+ </foreignObject>
22
+ );
23
+ };
24
+
25
+ export const SmallCorrectPointIndicator = ({ scale, x, r, correctness, classes, correctData, label }) => {
26
+ if (correctness && correctness.value === 'incorrect') {
27
+ const correctVal = parseFloat(correctData.find((d) => d.label === label)?.value);
28
+ if (isNaN(correctVal)) return null;
29
+ const correctPxY = scale.y(correctVal);
30
+ const yToRender = correctPxY - 7.5;
31
+ const xToRender = scale.x(x) - 7.5;
32
+
33
+ // small circle has 10px font + 2px padding + 1px border, so total size is 15px
34
+ return (
35
+ <foreignObject x={xToRender} y={yToRender} width={15} height={15}>
36
+ <Check
37
+ className={classNames(classes.correctnessIcon, classes.correctIcon, classes.smallIcon)}
38
+ title={correctness.label}
39
+ />
40
+ </foreignObject>
41
+ );
42
+ }
43
+
44
+ return null;
45
+ };
46
+
47
+ export const TickCorrectnessIndicator = ({ classes, correctness, interactive }) => {
48
+ if (!correctness || !interactive) return null;
49
+
50
+ return correctness.value === 'correct' ? (
51
+ <Check className={classNames(classes.correctnessIcon, classes.correctIcon)} title={correctness.label} />
52
+ ) : (
53
+ <Close className={classNames(classes.correctnessIcon, classes.incorrectIcon)} title={correctness.label} />
54
+ );
55
+ };
@@ -2,6 +2,9 @@ import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import classNames from 'classnames';
4
4
  import { withStyles } from '@material-ui/core/styles';
5
+ import Check from '@material-ui/icons/Check';
6
+ import Close from '@material-ui/icons/Close';
7
+
5
8
  import { gridDraggable, utils, types } from '@pie-lib/plot';
6
9
  import { color as enumColor } from '@pie-lib/render-ui';
7
10
  import { correct, incorrect, disabled } from './styles';
@@ -20,6 +23,7 @@ const RawDragHandle = ({
20
23
  isHovered,
21
24
  correctness,
22
25
  color,
26
+ isPlot,
23
27
  ...rest
24
28
  }) => {
25
29
  const { scale } = graphProps;
@@ -55,20 +59,14 @@ const RawDragHandle = ({
55
59
  </filter>
56
60
  </defs>
57
61
 
58
- {correctness && (
59
- <rect
60
- y={10}
61
- width={width}
62
- filter="url(#bottomShadow)"
63
- className={classNames(
64
- classes.handle,
65
- 'handle',
66
- className,
67
- !interactive && 'non-interactive',
68
- interactive && correctness && correctness.value,
62
+ {correctness && interactive && !isPlot && (
63
+ <foreignObject x={width / 2 - 14} y={0} width={40} height={40}>
64
+ {correctness.value === 'correct' ? (
65
+ <Check className={classNames(classes.correctnessIcon, classes.correctIcon)} title={correctness.label} />
66
+ ) : (
67
+ <Close className={classNames(classes.correctnessIcon, classes.incorrectIcon)} title={correctness.label} />
69
68
  )}
70
- {...rest}
71
- />
69
+ </foreignObject>
72
70
  )}
73
71
  </svg>
74
72
  );
@@ -90,7 +88,7 @@ RawDragHandle.propTypes = {
90
88
  color: PropTypes.string,
91
89
  };
92
90
 
93
- export const DragHandle = withStyles(() => ({
91
+ export const DragHandle = withStyles((theme) => ({
94
92
  handle: {
95
93
  height: '10px',
96
94
  fill: 'transparent',
@@ -118,6 +116,22 @@ export const DragHandle = withStyles(() => ({
118
116
  svgOverflowVisible: {
119
117
  overflow: 'visible !important',
120
118
  },
119
+ correctIcon: {
120
+ backgroundColor: enumColor.correct(),
121
+ },
122
+ incorrectIcon: {
123
+ backgroundColor: enumColor.incorrectWithIcon(),
124
+ },
125
+ correctnessIcon: {
126
+ borderRadius: theme.spacing.unit * 2,
127
+ color: enumColor.defaults.WHITE,
128
+ fontSize: '16px',
129
+ padding: '2px',
130
+ border: `4px solid ${enumColor.defaults.WHITE}`,
131
+ width: '16px',
132
+ height: '16px',
133
+ boxSizing: 'unset', // to override the default border-box in IBX
134
+ },
121
135
  }))(RawDragHandle);
122
136
 
123
137
  export const D = gridDraggable({
@@ -5,8 +5,13 @@ exports[`BasePoint snapshot renders 1`] = `
5
5
  className="className"
6
6
  classes={
7
7
  Object {
8
+ "correctIcon": "RawDragHandle-correctIcon-5",
9
+ "correctnessIcon": "RawDragHandle-correctnessIcon-7",
10
+ "disabledPoint": "RawDragHandle-disabledPoint-4",
8
11
  "handle": "RawDragHandle-handle-1",
12
+ "incorrectIcon": "RawDragHandle-incorrectIcon-6",
9
13
  "line": "RawDragHandle-line-3",
14
+ "smallIcon": "RawDragHandle-smallIcon-8",
10
15
  "transparentHandle": "RawDragHandle-transparentHandle-2",
11
16
  }
12
17
  }
@@ -95,6 +95,7 @@ exports[`RawLine snapshot renders 1`] = `
95
95
  }
96
96
  }
97
97
  key="point-0-0"
98
+ label="A"
98
99
  onDrag={[Function]}
99
100
  onDragStart={[Function]}
100
101
  onDragStop={[Function]}
@@ -130,6 +131,7 @@ exports[`RawLine snapshot renders 1`] = `
130
131
  }
131
132
  }
132
133
  key="point-1-1"
134
+ label="B"
133
135
  onDrag={[Function]}
134
136
  onDragStart={[Function]}
135
137
  onDragStop={[Function]}
@@ -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 = {
@@ -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
- '&.correct': correct('stroke'),
71
- '&.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',
72
95
  },
73
96
  }))(RawDragHandle);
74
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
  })}
@@ -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 && correctness.value)}>
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
  };
@@ -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 classNames from 'classnames';
9
+ import { CorrectnessIndicator, SmallCorrectPointIndicator } from '../common/correctness-indicators';
8
10
 
9
- const DraggableComponent = ({ scale, x, y, className, classes, r, correctness, interactive, ...rest }) => {
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 && correctness.value)}
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}