@pie-lib/plot 2.7.4-next.0 → 2.8.1-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.
package/src/root.jsx CHANGED
@@ -8,8 +8,16 @@ import { color, Readable } from '@pie-lib/render-ui';
8
8
  import EditableHtml from '@pie-lib/editable-html';
9
9
  import cn from 'classnames';
10
10
  import Label from './label';
11
+ import { extractTextFromHTML, isEmptyObject, isEmptyString } from './utils';
11
12
 
12
13
  export class Root extends React.Component {
14
+ constructor(props) {
15
+ super(props);
16
+ this.state = {
17
+ titleHeight: 0,
18
+ };
19
+ }
20
+
13
21
  static propTypes = {
14
22
  title: PropTypes.string,
15
23
  children: ChildrenType,
@@ -29,6 +37,8 @@ export class Root extends React.Component {
29
37
  rootRef: PropTypes.func,
30
38
  onChangeLabels: PropTypes.func,
31
39
  titlePlaceholder: PropTypes.string,
40
+ mathMlOptions: PropTypes.object,
41
+ labelsCharactersLimit: PropTypes.number,
32
42
  };
33
43
 
34
44
  mouseMove = (g) => {
@@ -54,6 +64,7 @@ export class Root extends React.Component {
54
64
  componentDidMount() {
55
65
  const g = select(this.g);
56
66
  g.on('mousemove', this.mouseMove.bind(this, g));
67
+ this.measureTitleHeight();
57
68
  }
58
69
 
59
70
  componentWillUnmount() {
@@ -61,9 +72,19 @@ export class Root extends React.Component {
61
72
  g.on('mousemove', null);
62
73
  }
63
74
 
75
+ componentDidUpdate(prevProps) {
76
+ if (prevProps.title !== this.props.title) {
77
+ this.measureTitleHeight();
78
+ }
79
+ }
80
+
64
81
  onChangeLabel = (newValue, side) => {
65
82
  const { labels, onChangeLabels, isChart } = this.props;
66
83
 
84
+ if (!onChangeLabels) {
85
+ return;
86
+ }
87
+
67
88
  if (isChart) {
68
89
  if (side === 'left') {
69
90
  onChangeLabels('range', newValue);
@@ -80,6 +101,18 @@ export class Root extends React.Component {
80
101
  });
81
102
  };
82
103
 
104
+ measureTitleHeight = () => {
105
+ const titleElement = document.getElementById('editable-title');
106
+ if (titleElement) {
107
+ const titleHeight = titleElement.clientHeight;
108
+ this.setState({ titleHeight, prevTitle: this.props.title });
109
+ }
110
+ };
111
+
112
+ handleKeyDown = () => {
113
+ setTimeout(this.measureTitleHeight, 0);
114
+ };
115
+
83
116
  render() {
84
117
  const {
85
118
  disabledTitle,
@@ -99,6 +132,7 @@ export class Root extends React.Component {
99
132
  title,
100
133
  rootRef,
101
134
  mathMlOptions = {},
135
+ labelsCharactersLimit,
102
136
  } = this.props;
103
137
  const {
104
138
  size: { width = 500, height = 500 },
@@ -107,14 +141,18 @@ export class Root extends React.Component {
107
141
  } = graphProps;
108
142
 
109
143
  const topPadding = 40;
110
- const leftPadding = showLabels ? 80 : 60;
111
- const finalWidth = width + leftPadding * 2 + (domain.padding || 0) * 2;
144
+ const leftPadding = isEmptyString(extractTextFromHTML(labels?.left)) && isEmptyObject(labelsPlaceholders) ? 48 : 70;
145
+ const rightPadding =
146
+ isEmptyString(extractTextFromHTML(labels?.right)) && isEmptyObject(labelsPlaceholders) ? 48 : 70;
147
+ const finalWidth = width + leftPadding + rightPadding + (domain.padding || 0) * 2;
112
148
  const finalHeight = height + topPadding * 2 + (range.padding || 0) * 2;
113
149
 
114
150
  const activeTitlePlugins = [
115
151
  'bold',
116
152
  'italic',
117
153
  'underline',
154
+ 'superscript',
155
+ 'subscript',
118
156
  'strikethrough',
119
157
  'math',
120
158
  // 'languageCharacters'
@@ -124,11 +162,11 @@ export class Root extends React.Component {
124
162
  const nbOfVerticalLines = parseInt(width / 100);
125
163
  const nbOfHorizontalLines = parseInt(actualHeight / 100);
126
164
  const sideGridlinesPadding = parseInt(actualHeight % 100);
127
-
165
+ const { titleHeight } = this.state;
128
166
  return (
129
167
  <div className={classes.root}>
130
168
  {showPixelGuides && (
131
- <div className={classes.topPixelGuides} style={{ marginLeft: isChart ? 60 : showLabels ? 30 : 10 }}>
169
+ <div className={classes.topPixelGuides} style={{ marginLeft: isChart ? 80 : showLabels ? 30 : 10 }}>
132
170
  {[...Array(nbOfVerticalLines + 1).keys()].map((value) => (
133
171
  <Readable false key={`top-guide-${value}`}>
134
172
  <div className={classes.topPixelIndicator}>
@@ -142,34 +180,37 @@ export class Root extends React.Component {
142
180
  {showTitle &&
143
181
  (disabledTitle ? (
144
182
  <div
145
- style={
146
- isChart && {
147
- width: finalWidth,
148
- }
149
- }
183
+ id="editable-title"
184
+ style={{
185
+ ...(isChart && { width: finalWidth }),
186
+ ...(isEmptyString(extractTextFromHTML(title)) && { display: 'none' }),
187
+ }}
150
188
  className={cn(isChart ? classes.chartTitle : classes.graphTitle, classes.disabledTitle)}
151
189
  dangerouslySetInnerHTML={{ __html: title || '' }}
152
190
  />
153
191
  ) : (
154
- <EditableHtml
155
- style={
156
- isChart && {
157
- width: finalWidth,
192
+ <div id="editable-title">
193
+ <EditableHtml
194
+ style={
195
+ isChart && {
196
+ width: finalWidth,
197
+ }
158
198
  }
159
- }
160
- className={cn(
161
- { [classes.rightMargin]: showPixelGuides },
162
- isChart ? classes.chartTitle : classes.graphTitle,
163
- )}
164
- markup={title || ''}
165
- onChange={onChangeTitle}
166
- placeholder={
167
- (defineChart && titlePlaceholder) || (!disabledTitle && 'Click here to add a title for this graph')
168
- }
169
- toolbarOpts={{ noBorder: true }}
170
- activePlugins={activeTitlePlugins}
171
- disableScrollbar
172
- />
199
+ className={cn(
200
+ { [classes.rightMargin]: showPixelGuides },
201
+ isChart ? classes.chartTitle : classes.graphTitle,
202
+ )}
203
+ markup={title || ''}
204
+ onChange={onChangeTitle}
205
+ placeholder={
206
+ (defineChart && titlePlaceholder) || (!disabledTitle && 'Click here to add a title for this graph')
207
+ }
208
+ toolbarOpts={{ noPadding: true, noBorder: true }}
209
+ activePlugins={activeTitlePlugins}
210
+ disableScrollbar
211
+ onKeyDown={this.handleKeyDown}
212
+ />
213
+ </div>
173
214
  ))}
174
215
  {showLabels && !isChart && (
175
216
  <Label
@@ -181,6 +222,7 @@ export class Root extends React.Component {
181
222
  graphWidth={finalWidth}
182
223
  onChange={(value) => this.onChangeLabel(value, 'top')}
183
224
  mathMlOptions={mathMlOptions}
225
+ charactersLimit={labelsCharactersLimit}
184
226
  />
185
227
  )}
186
228
  <div className={classes.wrapper}>
@@ -196,6 +238,7 @@ export class Root extends React.Component {
196
238
  isDefineChartLeftLabel={isChart && defineChart}
197
239
  onChange={(value) => this.onChangeLabel(value, 'left')}
198
240
  mathMlOptions={mathMlOptions}
241
+ charactersLimit={labelsCharactersLimit}
199
242
  />
200
243
  )}
201
244
  <svg width={finalWidth} height={finalHeight} className={defineChart ? classes.defineChart : classes.chart}>
@@ -207,7 +250,7 @@ export class Root extends React.Component {
207
250
  }
208
251
  }}
209
252
  className={classes.graphBox}
210
- transform={`translate(${leftPadding}, ${topPadding})`}
253
+ transform={`translate(${leftPadding + (domain.padding || 0)}, ${topPadding + (range.padding || 0)})`}
211
254
  >
212
255
  {children}
213
256
  </g>
@@ -222,6 +265,7 @@ export class Root extends React.Component {
222
265
  graphWidth={finalWidth}
223
266
  onChange={(value) => this.onChangeLabel(value, 'right')}
224
267
  mathMlOptions={mathMlOptions}
268
+ charactersLimit={labelsCharactersLimit}
225
269
  />
226
270
  )}
227
271
  {showPixelGuides && (
@@ -229,7 +273,7 @@ export class Root extends React.Component {
229
273
  className={classes.sidePixelGuides}
230
274
  style={{
231
275
  paddingTop: sideGridlinesPadding,
232
- marginTop: defineChart ? 25 : 31,
276
+ marginTop: 31,
233
277
  }}
234
278
  >
235
279
  {[...Array(nbOfHorizontalLines + 1).keys()].reverse().map((value) => (
@@ -248,10 +292,12 @@ export class Root extends React.Component {
248
292
  placeholder={labelsPlaceholders?.bottom}
249
293
  graphHeight={finalHeight}
250
294
  graphWidth={finalWidth}
295
+ titleHeight={titleHeight}
251
296
  isChartBottomLabel={isChart && !defineChart}
252
297
  isDefineChartBottomLabel={isChart && defineChart}
253
298
  onChange={(value) => this.onChangeLabel(value, 'bottom')}
254
299
  mathMlOptions={mathMlOptions}
300
+ charactersLimit={labelsCharactersLimit}
255
301
  />
256
302
  )}
257
303
  </div>
@@ -259,11 +305,12 @@ export class Root extends React.Component {
259
305
  }
260
306
  }
261
307
 
308
+ // use default color theme style to avoid color contrast issues
262
309
  const styles = (theme) => ({
263
310
  root: {
264
311
  border: `solid 1px ${color.primaryLight()}`,
265
- color: color.text(),
266
- backgroundColor: color.background(),
312
+ color: color.defaults.TEXT,
313
+ backgroundColor: theme.palette.common.white,
267
314
  touchAction: 'none',
268
315
  position: 'relative',
269
316
  },
@@ -284,13 +331,13 @@ const styles = (theme) => ({
284
331
  userSelect: 'none',
285
332
  },
286
333
  graphTitle: {
287
- color: color.text(),
334
+ color: color.defaults.TEXT,
288
335
  fontSize: theme.typography.fontSize + 2,
289
336
  padding: `${theme.spacing.unit * 1.5}px ${theme.spacing.unit / 2}px 0`,
290
337
  textAlign: 'center',
291
338
  },
292
339
  chartTitle: {
293
- color: color.text(),
340
+ color: color.defaults.TEXT,
294
341
  fontSize: theme.typography.fontSize + 4,
295
342
  padding: `${theme.spacing.unit * 1.5}px ${theme.spacing.unit / 2}px 0`,
296
343
  textAlign: 'center',
@@ -306,7 +353,7 @@ const styles = (theme) => ({
306
353
  paddingTop: '6px',
307
354
  },
308
355
  topPixelIndicator: {
309
- color: color.primaryLight(),
356
+ color: color.defaults.PRIMARY_LIGHT,
310
357
  display: 'flex',
311
358
  flexDirection: 'column',
312
359
  alignItems: 'center',
@@ -321,7 +368,7 @@ const styles = (theme) => ({
321
368
  marginRight: '6px',
322
369
  },
323
370
  sidePixelIndicator: {
324
- color: color.primaryLight(),
371
+ color: color.defaults.PRIMARY_LIGHT,
325
372
  textAlign: 'right',
326
373
  height: '20px',
327
374
  pointerEvents: 'none',
package/src/trig.js CHANGED
@@ -1,4 +1,4 @@
1
- import { xy } from '../lib/utils';
1
+ import { xy } from './utils';
2
2
  import Point from '@mapbox/point-geometry';
3
3
  import debug from 'debug';
4
4
  const log = debug('pie-lib:plot:trig');
package/src/utils.js CHANGED
@@ -154,3 +154,17 @@ export const amountToIncreaseWidth = (longestWord) => {
154
154
 
155
155
  return longestWord * 20;
156
156
  };
157
+
158
+ export const extractTextFromHTML = (htmlString) => {
159
+ const parser = new DOMParser();
160
+ const doc = parser?.parseFromString(htmlString, 'text/html');
161
+ return doc?.body?.textContent || '';
162
+ };
163
+
164
+ export const isEmptyObject = (obj) => {
165
+ return obj && Object.keys(obj).length === 0 && obj.constructor === Object;
166
+ };
167
+
168
+ export const isEmptyString = (str) => {
169
+ return typeof str === 'string' && str.trim() === '';
170
+ };
package/lib/draggable.js DELETED
@@ -1,65 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
-
5
- var _typeof = require("@babel/runtime/helpers/typeof");
6
-
7
- Object.defineProperty(exports, "__esModule", {
8
- value: true
9
- });
10
- Object.defineProperty(exports, "DraggableCore", {
11
- enumerable: true,
12
- get: function get() {
13
- return _reactDraggable.DraggableCore;
14
- }
15
- });
16
- exports["default"] = void 0;
17
-
18
- var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
19
-
20
- var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
21
-
22
- var _get2 = _interopRequireDefault(require("@babel/runtime/helpers/get"));
23
-
24
- var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
25
-
26
- var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
27
-
28
- var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
29
-
30
- var _reactDraggable = _interopRequireWildcard(require("react-draggable"));
31
-
32
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
33
-
34
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
35
-
36
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; }
37
-
38
- function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
39
-
40
- var LocalDraggable = /*#__PURE__*/function (_Draggable) {
41
- (0, _inherits2["default"])(LocalDraggable, _Draggable);
42
-
43
- var _super = _createSuper(LocalDraggable);
44
-
45
- function LocalDraggable() {
46
- (0, _classCallCheck2["default"])(this, LocalDraggable);
47
- return _super.apply(this, arguments);
48
- }
49
-
50
- (0, _createClass2["default"])(LocalDraggable, [{
51
- key: "componentWillReceiveProps",
52
- value: function componentWillReceiveProps(next) {
53
- (0, _get2["default"])((0, _getPrototypeOf2["default"])(LocalDraggable.prototype), "componentWillReceiveProps", this).call(this, next); //Remove the x/y state as these values have now been updated and will come through as props.
54
-
55
- this.setState({
56
- x: 0,
57
- y: 0
58
- });
59
- }
60
- }]);
61
- return LocalDraggable;
62
- }(_reactDraggable["default"]);
63
-
64
- exports["default"] = LocalDraggable;
65
- //# sourceMappingURL=draggable.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/draggable.jsx"],"names":["LocalDraggable","next","setState","x","y","Draggable"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;IAEqBA,c;;;;;;;;;;;;WACnB,mCAA0BC,IAA1B,EAAgC;AAC9B,sIAAgCA,IAAhC,EAD8B,CAE9B;;AACA,WAAKC,QAAL,CAAc;AAAEC,QAAAA,CAAC,EAAE,CAAL;AAAQC,QAAAA,CAAC,EAAE;AAAX,OAAd;AACD;;;EALyCC,0B","sourcesContent":["import Draggable, { DraggableCore } from 'react-draggable';\n\nexport default class LocalDraggable extends Draggable {\n componentWillReceiveProps(next) {\n super.componentWillReceiveProps(next);\n //Remove the x/y state as these values have now been updated and will come through as props.\n this.setState({ x: 0, y: 0 });\n }\n}\n\nexport { DraggableCore };\n"],"file":"draggable.js"}
@@ -1,53 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
-
5
- Object.defineProperty(exports, "__esModule", {
6
- value: true
7
- });
8
- exports.create = void 0;
9
-
10
- var _invariant = _interopRequireDefault(require("invariant"));
11
-
12
- var _utils = require("./utils");
13
-
14
- var _d3Scale = require("d3-scale");
15
-
16
- var createSnapMinAndMax = function createSnapMinAndMax(_ref) {
17
- var min = _ref.min,
18
- max = _ref.max,
19
- step = _ref.step;
20
- // for graphing, if step is a value with decimals, we have to calculate the min & max for the grid taking in consideration that 0 has to be exactly in the middle
21
- // for example, if min: -5 & max: 5 & step: 0.75, in order to keep 0 in the middle we have to set min: -4.5 & max: 4.5
22
- return {
23
- step: step,
24
- min: parseInt(min / step) * step,
25
- max: parseInt(max / step) * step
26
- };
27
- };
28
-
29
- var create = function create(domain, range, size, getRootNode) {
30
- (0, _invariant["default"])(domain.min < domain.max, 'domain: min must be less than max');
31
- (0, _invariant["default"])(range.min < range.max, 'range: min must be less than max');
32
- var domainMinMax = createSnapMinAndMax(domain);
33
- var rangeMinMax = createSnapMinAndMax(range);
34
- var scale = {
35
- x: (0, _d3Scale.scaleLinear)().domain([domain.min, domain.max]).range([0, size.width]),
36
- y: (0, _d3Scale.scaleLinear)().domain([range.max, range.min]).range([0, size.height])
37
- };
38
- var snap = {
39
- x: _utils.snapTo.bind(null, domainMinMax.min, domainMinMax.max, domainMinMax.step),
40
- y: _utils.snapTo.bind(null, rangeMinMax.min, rangeMinMax.max, rangeMinMax.step)
41
- };
42
- return {
43
- scale: scale,
44
- snap: snap,
45
- domain: domain,
46
- range: range,
47
- size: size,
48
- getRootNode: getRootNode
49
- };
50
- };
51
-
52
- exports.create = create;
53
- //# sourceMappingURL=graph-props.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/graph-props.js"],"names":["createSnapMinAndMax","min","max","step","parseInt","create","domain","range","size","getRootNode","domainMinMax","rangeMinMax","scale","x","width","y","height","snap","snapTo","bind"],"mappings":";;;;;;;;;AAAA;;AACA;;AACA;;AAEA,IAAMA,mBAAmB,GAAG,SAAtBA,mBAAsB,OAAwB;AAAA,MAArBC,GAAqB,QAArBA,GAAqB;AAAA,MAAhBC,GAAgB,QAAhBA,GAAgB;AAAA,MAAXC,IAAW,QAAXA,IAAW;AAClD;AACA;AAEA,SAAO;AACLA,IAAAA,IAAI,EAAJA,IADK;AAELF,IAAAA,GAAG,EAAEG,QAAQ,CAACH,GAAG,GAAGE,IAAP,CAAR,GAAuBA,IAFvB;AAGLD,IAAAA,GAAG,EAAEE,QAAQ,CAACF,GAAG,GAAGC,IAAP,CAAR,GAAuBA;AAHvB,GAAP;AAKD,CATD;;AAWO,IAAME,MAAM,GAAG,SAATA,MAAS,CAACC,MAAD,EAASC,KAAT,EAAgBC,IAAhB,EAAsBC,WAAtB,EAAsC;AAC1D,6BAAUH,MAAM,CAACL,GAAP,GAAaK,MAAM,CAACJ,GAA9B,EAAmC,mCAAnC;AACA,6BAAUK,KAAK,CAACN,GAAN,GAAYM,KAAK,CAACL,GAA5B,EAAiC,kCAAjC;AAEA,MAAMQ,YAAY,GAAGV,mBAAmB,CAACM,MAAD,CAAxC;AACA,MAAMK,WAAW,GAAGX,mBAAmB,CAACO,KAAD,CAAvC;AAEA,MAAMK,KAAK,GAAG;AACZC,IAAAA,CAAC,EAAE,4BACAP,MADA,CACO,CAACA,MAAM,CAACL,GAAR,EAAaK,MAAM,CAACJ,GAApB,CADP,EAEAK,KAFA,CAEM,CAAC,CAAD,EAAIC,IAAI,CAACM,KAAT,CAFN,CADS;AAIZC,IAAAA,CAAC,EAAE,4BACAT,MADA,CACO,CAACC,KAAK,CAACL,GAAP,EAAYK,KAAK,CAACN,GAAlB,CADP,EAEAM,KAFA,CAEM,CAAC,CAAD,EAAIC,IAAI,CAACQ,MAAT,CAFN;AAJS,GAAd;AASA,MAAMC,IAAI,GAAG;AACXJ,IAAAA,CAAC,EAAEK,cAAOC,IAAP,CAAY,IAAZ,EAAkBT,YAAY,CAACT,GAA/B,EAAoCS,YAAY,CAACR,GAAjD,EAAsDQ,YAAY,CAACP,IAAnE,CADQ;AAEXY,IAAAA,CAAC,EAAEG,cAAOC,IAAP,CAAY,IAAZ,EAAkBR,WAAW,CAACV,GAA9B,EAAmCU,WAAW,CAACT,GAA/C,EAAoDS,WAAW,CAACR,IAAhE;AAFQ,GAAb;AAKA,SAAO;AAAES,IAAAA,KAAK,EAALA,KAAF;AAASK,IAAAA,IAAI,EAAJA,IAAT;AAAeX,IAAAA,MAAM,EAANA,MAAf;AAAuBC,IAAAA,KAAK,EAALA,KAAvB;AAA8BC,IAAAA,IAAI,EAAJA,IAA9B;AAAoCC,IAAAA,WAAW,EAAXA;AAApC,GAAP;AACD,CAtBM","sourcesContent":["import invariant from 'invariant';\nimport { snapTo } from './utils';\nimport { scaleLinear } from 'd3-scale';\n\nconst createSnapMinAndMax = ({ min, max, step }) => {\n // for graphing, if step is a value with decimals, we have to calculate the min & max for the grid taking in consideration that 0 has to be exactly in the middle\n // for example, if min: -5 & max: 5 & step: 0.75, in order to keep 0 in the middle we have to set min: -4.5 & max: 4.5\n\n return {\n step,\n min: parseInt(min / step) * step,\n max: parseInt(max / step) * step,\n };\n};\n\nexport const create = (domain, range, size, getRootNode) => {\n invariant(domain.min < domain.max, 'domain: min must be less than max');\n invariant(range.min < range.max, 'range: min must be less than max');\n\n const domainMinMax = createSnapMinAndMax(domain);\n const rangeMinMax = createSnapMinAndMax(range);\n\n const scale = {\n x: scaleLinear()\n .domain([domain.min, domain.max])\n .range([0, size.width]),\n y: scaleLinear()\n .domain([range.max, range.min])\n .range([0, size.height]),\n };\n\n const snap = {\n x: snapTo.bind(null, domainMinMax.min, domainMinMax.max, domainMinMax.step),\n y: snapTo.bind(null, rangeMinMax.min, rangeMinMax.max, rangeMinMax.step),\n };\n\n return { scale, snap, domain, range, size, getRootNode };\n};\n"],"file":"graph-props.js"}