@complat/react-spectra-editor 1.7.1 → 1.8.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 (111) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/LICENSE +21 -662
  3. package/README.md +5 -0
  4. package/dist/__tests__/fixtures/lc_ms_jcamp.js +2329 -0
  5. package/dist/__tests__/fixtures/lc_ms_jcamp_2.js +2874 -0
  6. package/dist/__tests__/fixtures/lc_ms_jcamp_mz_chemstation.js +3242 -0
  7. package/dist/__tests__/fixtures/lc_ms_jcamp_tic_chemstation.js +854 -0
  8. package/dist/__tests__/fixtures/lc_ms_jcamp_tic_neg.js +1233 -0
  9. package/dist/__tests__/fixtures/lc_ms_jcamp_tic_pos.js +1233 -0
  10. package/dist/__tests__/fixtures/lc_ms_jcamp_uvvis.js +48908 -0
  11. package/dist/__tests__/fixtures/lc_ms_jcamp_uvvis_chemstation.js +15424 -0
  12. package/dist/__tests__/units/components/cmd_bar/r05_submit_btn.test.js +158 -3
  13. package/dist/__tests__/units/components/d3_line_rect.test.js +85 -0
  14. package/dist/__tests__/units/components/d3_multi/multi_focus.test.js +43 -0
  15. package/dist/__tests__/units/components/hplc_viewer.test.js +123 -0
  16. package/dist/__tests__/units/components/panel/info.test.js +55 -15
  17. package/dist/__tests__/units/features/lc-ms/parsing/lcmsCategory.test.js +73 -0
  18. package/dist/__tests__/units/features/lc-ms/submit/peaks.test.js +310 -0
  19. package/dist/actions/curve.js +5 -2
  20. package/dist/actions/hplc_ms.js +66 -0
  21. package/dist/actions/integration.js +17 -2
  22. package/dist/actions/ui.js +39 -11
  23. package/dist/app.js +21 -8
  24. package/dist/components/cmd_bar/01_viewer.js +15 -11
  25. package/dist/components/cmd_bar/03_peak.js +25 -16
  26. package/dist/components/cmd_bar/04_integration.js +116 -17
  27. package/dist/components/cmd_bar/08_peak_group.js +83 -0
  28. package/dist/components/cmd_bar/collapsible_toolbar_group.js +101 -0
  29. package/dist/components/cmd_bar/common.js +4 -3
  30. package/dist/components/cmd_bar/index.js +76 -18
  31. package/dist/components/cmd_bar/r01_layout.js +6 -0
  32. package/dist/components/cmd_bar/r02_scan.js +15 -11
  33. package/dist/components/cmd_bar/r03_threshold.js +19 -3
  34. package/dist/components/cmd_bar/r04_submit.js +61 -6
  35. package/dist/components/cmd_bar/r05_submit_btn.js +60 -13
  36. package/dist/components/cmd_bar/r06_predict_btn.js +4 -4
  37. package/dist/components/cmd_bar/r07_wavelength_btn.js +10 -9
  38. package/dist/components/cmd_bar/r09_detector.js +2 -2
  39. package/dist/components/cmd_bar/tri_btn.js +4 -1
  40. package/dist/components/common/draw.js +6 -5
  41. package/dist/components/d3_line/index.js +70 -15
  42. package/dist/components/d3_line/line_focus.js +104 -67
  43. package/dist/components/d3_line_rect/index.js +836 -0
  44. package/dist/components/d3_line_rect/line_focus.js +526 -0
  45. package/dist/components/d3_line_rect/multi_focus.js +433 -0
  46. package/dist/components/d3_line_rect/rect_focus.js +247 -0
  47. package/dist/components/d3_multi/index.js +154 -163
  48. package/dist/components/d3_multi/multi_focus.js +117 -68
  49. package/dist/components/d3_rect/index.js +6 -0
  50. package/dist/components/d3_rect/rect_focus.js +17 -5
  51. package/dist/components/hplc_viewer.js +169 -0
  52. package/dist/components/lc_ms_uv_tools_bar.js +175 -0
  53. package/dist/components/multi_jcamps_viewer.js +17 -5
  54. package/dist/components/panel/compare.js +84 -62
  55. package/dist/components/panel/cyclic_voltamery_data.js +15 -14
  56. package/dist/components/panel/graph_selection.js +32 -30
  57. package/dist/components/panel/index.js +28 -22
  58. package/dist/components/panel/info.js +75 -26
  59. package/dist/constants/action_type.js +23 -2
  60. package/dist/constants/list_graph.js +16 -0
  61. package/dist/constants/list_layout.js +2 -1
  62. package/dist/constants/list_ui.js +5 -2
  63. package/dist/features/lc-ms/entities/extractEntityLCMS.js +187 -0
  64. package/dist/features/lc-ms/parsing/chemstation.js +108 -0
  65. package/dist/features/lc-ms/parsing/index.js +46 -0
  66. package/dist/features/lc-ms/parsing/lcmsCategory.js +44 -0
  67. package/dist/features/lc-ms/parsing/lcmsJcampInfo.js +18 -0
  68. package/dist/features/lc-ms/parsing/lcmsMsPage.js +241 -0
  69. package/dist/features/lc-ms/parsing/pageValue.js +27 -0
  70. package/dist/features/lc-ms/submit/index.js +24 -0
  71. package/dist/features/lc-ms/submit/peaks.js +66 -0
  72. package/dist/features/lc-ms/ui/wavelengthSelect.js +54 -0
  73. package/dist/fn.js +4 -1
  74. package/dist/helpers/brush.js +74 -19
  75. package/dist/helpers/calc.js +4 -2
  76. package/dist/helpers/cfg.js +5 -4
  77. package/dist/helpers/chem.js +449 -71
  78. package/dist/helpers/compass.js +181 -17
  79. package/dist/helpers/extractEntityLCMS.js +24 -0
  80. package/dist/helpers/extractParams.js +118 -33
  81. package/dist/helpers/extractPeaksEdit.js +29 -9
  82. package/dist/helpers/format.js +189 -4
  83. package/dist/helpers/init.js +25 -5
  84. package/dist/helpers/integration.js +130 -17
  85. package/dist/helpers/integration_draft.js +43 -0
  86. package/dist/helpers/integration_focus.js +155 -0
  87. package/dist/helpers/integration_jcamp.js +68 -0
  88. package/dist/helpers/integration_split.js +202 -0
  89. package/dist/helpers/mount.js +8 -1
  90. package/dist/helpers/sweep.js +39 -0
  91. package/dist/index.js +284 -26
  92. package/dist/layer_content.js +17 -3
  93. package/dist/layer_init.js +124 -14
  94. package/dist/layer_prism.js +31 -5
  95. package/dist/reducers/index.js +3 -1
  96. package/dist/reducers/reducer_curve.js +54 -36
  97. package/dist/reducers/reducer_hplc_ms/hydrate.js +289 -0
  98. package/dist/reducers/reducer_hplc_ms/index.js +122 -0
  99. package/dist/reducers/reducer_hplc_ms/persistence.js +74 -0
  100. package/dist/reducers/reducer_hplc_ms/tic.js +70 -0
  101. package/dist/reducers/reducer_hplc_ms/utils.js +70 -0
  102. package/dist/reducers/reducer_hplc_ms/uvvis.js +377 -0
  103. package/dist/reducers/reducer_integration.js +265 -7
  104. package/dist/reducers/reducer_layout.js +1 -1
  105. package/dist/reducers/reducer_submit.js +2 -1
  106. package/dist/reducers/reducer_ui.js +149 -13
  107. package/dist/reducers/undo_redo_config.js +2 -2
  108. package/dist/sagas/saga_lcms_ui.js +85 -0
  109. package/dist/sagas/saga_ui.js +177 -74
  110. package/dist/setupTests.js +5 -5
  111. package/package.json +10 -7
@@ -0,0 +1,433 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.pickTicIndex = exports.default = void 0;
8
+ var _init = require("../../helpers/init");
9
+ var _mount = require("../../helpers/mount");
10
+ var _brush = _interopRequireDefault(require("../../helpers/brush"));
11
+ var _compass = require("../../helpers/compass");
12
+ var _list_layout = require("../../constants/list_layout");
13
+ var _format = _interopRequireDefault(require("../../helpers/format"));
14
+ var _list_graph = require("../../constants/list_graph");
15
+ var _chem = require("../../helpers/chem");
16
+ var _extractEntityLCMS = require("../../helpers/extractEntityLCMS");
17
+ /* eslint-disable no-unused-vars, prefer-object-spread, no-mixed-operators,
18
+ no-unneeded-ternary, arrow-body-style, max-len */
19
+
20
+ const d3 = require('d3');
21
+ const pickTicIndex = (ticEntities, curveIdx, polarity) => {
22
+ if (!Array.isArray(ticEntities) || ticEntities.length === 0) return 0;
23
+ if (polarity) {
24
+ const idxByPolarity = ticEntities.findIndex(ent => (0, _extractEntityLCMS.getLcMsInfo)(ent).polarity === polarity);
25
+ if (idxByPolarity >= 0) return idxByPolarity;
26
+ }
27
+ if (Number.isInteger(curveIdx) && curveIdx >= 0 && curveIdx < ticEntities.length) {
28
+ return curveIdx;
29
+ }
30
+ return 0;
31
+ };
32
+ exports.pickTicIndex = pickTicIndex;
33
+ class MultiFocus {
34
+ constructor(props) {
35
+ const {
36
+ W,
37
+ H,
38
+ clickUiTargetAct,
39
+ selectUiSweepAct,
40
+ scrollUiWheelAct,
41
+ ticEntities,
42
+ graphIndex,
43
+ uiSt
44
+ } = props;
45
+ this.graphIndex = graphIndex;
46
+ this.uiSt = uiSt;
47
+ this.ticEntities = ticEntities;
48
+ this.jcampIdx = 0;
49
+ this.isShowAllCurves = false;
50
+ this.rootKlass = `.${_list_graph.LIST_ROOT_SVG_GRAPH.MULTI}`;
51
+ this.brushClass = `.${_list_graph.LIST_BRUSH_SVG_GRAPH.MULTI}`;
52
+ this.margin = {
53
+ t: 5,
54
+ b: 40,
55
+ l: 60,
56
+ r: 5
57
+ };
58
+ this.w = W - this.margin.l - this.margin.r;
59
+ this.h = H - this.margin.t - this.margin.b;
60
+ this.clickUiTargetAct = clickUiTargetAct;
61
+ this.selectUiSweepAct = selectUiSweepAct;
62
+ this.scrollUiWheelAct = scrollUiWheelAct;
63
+ this.brush = d3.brush();
64
+ this.brushX = d3.brushX();
65
+ this.axis = null;
66
+ this.path = null;
67
+ this.grid = null;
68
+ this.tags = null;
69
+ this.data = [];
70
+ this.otherLineData = [];
71
+ this.pathColor = 'steelblue';
72
+ this.tTrEndPts = null;
73
+ this.root = null;
74
+ this.svg = null;
75
+ this.axisCall = (0, _init.InitAxisCall)(5);
76
+ this.pathCall = null;
77
+ this.tip = null;
78
+ this.factor = 0.125;
79
+ this.currentExtent = null;
80
+ this.shouldUpdate = {};
81
+ this.layout = _list_layout.LIST_LAYOUT.LC_MS;
82
+ this.getShouldUpdate = this.getShouldUpdate.bind(this);
83
+ this.resetShouldUpdate = this.resetShouldUpdate.bind(this);
84
+ this.setTip = this.setTip.bind(this);
85
+ this.setDataParams = this.setDataParams.bind(this);
86
+ this.create = this.create.bind(this);
87
+ this.update = this.update.bind(this);
88
+ this.setConfig = this.setConfig.bind(this);
89
+ this.drawLine = this.drawLine.bind(this);
90
+ this.drawOtherLines = this.drawOtherLines.bind(this);
91
+ this.drawGrid = this.drawGrid.bind(this);
92
+ this.drawPageMarker = this.drawPageMarker.bind(this);
93
+ this.onClickTarget = this.onClickTarget.bind(this);
94
+ this.isFirefox = typeof InstallTrigger !== 'undefined';
95
+ }
96
+ colorForPolarity = polarity => {
97
+ if (polarity === 'negative') return '#2980b9';
98
+ if (polarity === 'neutral') return '#2980b9';
99
+ return '#d35400';
100
+ };
101
+ getTicLegendEntries = (ticEntities, hplcMsSt) => {
102
+ const available = hplcMsSt?.tic?.available;
103
+ const selected = hplcMsSt?.tic?.polarity;
104
+ const baseEntries = [{
105
+ key: 'positive',
106
+ label: 'PLUS'
107
+ }, {
108
+ key: 'negative',
109
+ label: 'MINUS'
110
+ }, {
111
+ key: 'neutral',
112
+ label: 'NEUTRAL'
113
+ }];
114
+ let entries = [];
115
+ if (available && typeof available === 'object') {
116
+ const filtered = baseEntries.filter(entry => available[entry.key]);
117
+ if (filtered.length > 0) entries = filtered;
118
+ }
119
+ if (entries.length === 0 && Array.isArray(ticEntities)) {
120
+ const found = new Set();
121
+ ticEntities.forEach(entry => {
122
+ const {
123
+ polarity
124
+ } = (0, _extractEntityLCMS.getLcMsInfo)(entry);
125
+ if (polarity) found.add(polarity);
126
+ });
127
+ if (found.size > 0) {
128
+ entries = baseEntries.filter(entry => found.has(entry.key));
129
+ }
130
+ }
131
+ if (entries.length === 0) entries = baseEntries;
132
+ return entries.map(entry => ({
133
+ ...entry,
134
+ color: this.colorForPolarity(entry.key),
135
+ selected: entry.key === selected
136
+ }));
137
+ };
138
+ drawTicLegend = (ticEntities, hplcMsSt) => {
139
+ if (!this.root) return;
140
+ this.root.selectAll('.tic-legend').remove();
141
+ const entries = this.getTicLegendEntries(ticEntities, hplcMsSt);
142
+ if (entries.length <= 1) return;
143
+ const lineLength = 14;
144
+ const lineGap = 6;
145
+ const legendX = this.w - 8 - lineLength;
146
+ const legendY = 10;
147
+ const rowHeight = 14;
148
+ const legend = this.root.append('g').attr('class', 'tic-legend');
149
+ entries.forEach((entry, idx) => {
150
+ const row = legend.append('g').attr('transform', `translate(${legendX}, ${legendY + idx * rowHeight})`);
151
+ const opacity = entry.selected ? 1 : 0.35;
152
+ row.append('line').attr('x1', 0).attr('x2', lineLength).attr('y1', 0).attr('y2', 0).attr('stroke', entry.color).attr('stroke-width', entry.selected ? 2 : 1).attr('stroke-opacity', opacity).attr('stroke-linecap', 'round');
153
+ row.append('text').attr('x', -lineGap).attr('y', 0).attr('dy', '0.32em').attr('text-anchor', 'end').attr('font-family', 'Helvetica').style('font-size', '11px').style('fill', entry.color).style('opacity', opacity).text(entry.label);
154
+ });
155
+ };
156
+ getShouldUpdate() {
157
+ const {
158
+ prevXt,
159
+ prevYt,
160
+ prevLySt,
161
+ prevTePt,
162
+ prevData
163
+ } = this.shouldUpdate;
164
+ const {
165
+ xt,
166
+ yt
167
+ } = (0, _compass.TfRescale)(this);
168
+ const sameXY = xt(1.1) === prevXt && prevYt === yt(1.1);
169
+ const sameLySt = prevLySt === this.layout;
170
+ const sameTePt = prevTePt === this.tTrEndPts.length;
171
+ const sameData = prevData === this.data.length;
172
+ this.shouldUpdate = Object.assign({}, this.shouldUpdate, {
173
+ sameXY,
174
+ sameLySt,
175
+ // eslint-disable-line
176
+ sameTePt,
177
+ sameData // eslint-disable-line
178
+ });
179
+ }
180
+ resetShouldUpdate() {
181
+ const {
182
+ xt,
183
+ yt
184
+ } = (0, _compass.TfRescale)(this);
185
+ const prevXt = xt(1.1);
186
+ const prevYt = yt(1.1);
187
+ const prevTePt = this.tTrEndPts.length;
188
+ const prevData = this.data.length;
189
+ const prevLySt = this.layout;
190
+ this.shouldUpdate = Object.assign({}, this.shouldUpdate, {
191
+ prevXt,
192
+ prevYt,
193
+ prevLySt,
194
+ // eslint-disable-line
195
+ prevTePt,
196
+ prevData // eslint-disable-line
197
+ });
198
+ }
199
+ setTip() {
200
+ this.tip = (0, _init.InitTip)();
201
+ this.root.call(this.tip);
202
+ }
203
+ setDataParams(tTrEndPts, layout, jcampIdx = 0) {
204
+ this.data = [];
205
+ this.otherLineData = [];
206
+ const ticEntities = Array.isArray(this.ticEntities) ? this.ticEntities : [];
207
+ ticEntities.forEach((entry, idx) => {
208
+ const {
209
+ topic,
210
+ feature
211
+ } = entry;
212
+ const {
213
+ polarity = 'neutral'
214
+ } = (0, _extractEntityLCMS.getLcMsInfo)(entry);
215
+ const fixedColor = this.colorForPolarity(polarity);
216
+ if (!feature || !topic) return;
217
+ const currData = (0, _chem.convertTopic)(topic, layout, feature, 0);
218
+ if (idx === jcampIdx) {
219
+ this.data = currData;
220
+ this.pathColor = fixedColor;
221
+ } else {
222
+ this.otherLineData.push({
223
+ data: currData,
224
+ polarity,
225
+ color: fixedColor,
226
+ idx
227
+ });
228
+ }
229
+ });
230
+ this.tTrEndPts = tTrEndPts;
231
+ if (layout) {
232
+ this.layout = layout;
233
+ }
234
+ this.jcampIdx = jcampIdx;
235
+ this.xOnlyBrush = this.layout === _list_layout.LIST_LAYOUT.LC_MS;
236
+ }
237
+ updatePathCall(xt, yt) {
238
+ this.pathCall = d3.line().x(d => xt(d.x)).y(d => yt(d.y));
239
+ }
240
+ setConfig(sweepExtentSt) {
241
+ // Domain Calculate
242
+ let {
243
+ xExtent,
244
+ yExtent
245
+ } = sweepExtentSt || {
246
+ xExtent: false,
247
+ yExtent: false
248
+ };
249
+ let allData = null;
250
+ if (!xExtent || !yExtent) {
251
+ allData = [...this.data];
252
+ if (this.otherLineData) {
253
+ this.otherLineData.forEach(lineData => {
254
+ allData = [...allData, ...lineData.data];
255
+ });
256
+ }
257
+ }
258
+ if (!xExtent) {
259
+ const xes = d3.extent(allData, d => d.x).sort((a, b) => a - b);
260
+ xExtent = {
261
+ xL: xes[0],
262
+ xU: xes[1]
263
+ };
264
+ }
265
+ if (!yExtent) {
266
+ const btm = d3.min(allData, d => d.y);
267
+ const top = d3.max(allData, d => d.y);
268
+ const height = top - btm;
269
+ yExtent = {
270
+ yL: btm - this.factor * height,
271
+ yU: top + this.factor * height
272
+ };
273
+ }
274
+ this.scales.x.domain([xExtent.xL, xExtent.xU]);
275
+ this.scales.y.domain([yExtent.yL, yExtent.yU]);
276
+
277
+ // rescale for zoom
278
+ const {
279
+ xt,
280
+ yt
281
+ } = (0, _compass.TfRescale)(this);
282
+
283
+ // Axis Call
284
+ this.axisCall.x.scale(xt);
285
+ this.axisCall.y.scale(yt);
286
+ this.currentExtent = {
287
+ xExtent,
288
+ yExtent
289
+ };
290
+ }
291
+ drawLine() {
292
+ if (!this.path) return;
293
+ const {
294
+ xt,
295
+ yt
296
+ } = (0, _compass.TfRescale)(this);
297
+ this.updatePathCall(xt, yt);
298
+ this.path.attr('d', this.pathCall(this.data));
299
+ this.path.style('stroke', this.pathColor);
300
+ if (this.layout === _list_layout.LIST_LAYOUT.AIF) {
301
+ this.path.attr('marker-mid', 'url(#arrow-left)');
302
+ }
303
+ }
304
+ drawOtherLines(layout) {
305
+ d3.selectAll('.line-clip-compare').remove();
306
+ if (!this.otherLineData) return null;
307
+ const {
308
+ xt,
309
+ yt
310
+ } = (0, _compass.TfRescale)(this);
311
+ this.updatePathCall(xt, yt);
312
+ this.otherLineData.forEach((entry, idx) => {
313
+ const {
314
+ data,
315
+ color: pathColor
316
+ } = entry;
317
+ const path = (0, _mount.MountComparePath)(this, pathColor, idx, 0.4);
318
+ path.attr('d', this.pathCall(data));
319
+ if (this.layout === _list_layout.LIST_LAYOUT.AIF && this.isShowAllCurves === true) {
320
+ path.attr('marker-mid', 'url(#arrow-left)');
321
+ }
322
+ });
323
+ return null;
324
+ }
325
+ drawGrid() {
326
+ const {
327
+ sameXY
328
+ } = this.shouldUpdate;
329
+ if (sameXY || !this.grid || !this.axisCall) return;
330
+ if (this.grid.x && this.axisCall.x) {
331
+ this.grid.x.call(this.axisCall.x.tickSize(-this.h, 0, 0)).selectAll('line').attr('stroke', '#ddd').attr('stroke-opacity', 0.6).attr('fill', 'none');
332
+ }
333
+ if (this.grid.y && this.axisCall.y) {
334
+ this.grid.y.call(this.axisCall.y.tickSize(-this.w, 0, 0)).selectAll('line').attr('stroke', '#ddd').attr('stroke-opacity', 0.6).attr('fill', 'none');
335
+ }
336
+ }
337
+ drawPageMarker(hplcMsSt) {
338
+ if (!this.root) return;
339
+ const currentPageValue = hplcMsSt?.tic?.currentPageValue;
340
+ const hasValue = Number.isFinite(currentPageValue);
341
+ const marker = this.root.selectAll('.tic-page-marker').data(hasValue ? [currentPageValue] : []);
342
+ marker.exit().remove();
343
+ if (!hasValue) return;
344
+ const {
345
+ xt
346
+ } = (0, _compass.TfRescale)(this);
347
+ marker.enter().append('line').attr('class', 'tic-page-marker').attr('stroke', 'red').attr('stroke-width', 1).attr('stroke-opacity', 0.8).merge(marker).attr('x1', xt(currentPageValue)).attr('x2', xt(currentPageValue)).attr('y1', 0).attr('y2', this.h);
348
+ }
349
+ onClickTarget(event, data) {
350
+ event.stopPropagation();
351
+ event.preventDefault();
352
+ const onPeak = true;
353
+ this.clickUiTargetAct(data, onPeak, false, this.jcampIdx, false, 'lcms_tic');
354
+ }
355
+ create({
356
+ ticEntities,
357
+ curveSt,
358
+ hplcMsSt,
359
+ tTrEndPts,
360
+ layoutSt,
361
+ sweepExtentSt,
362
+ isUiNoBrushSt
363
+ }) {
364
+ this.svg = d3.select(this.rootKlass).select(this.brushClass);
365
+ (0, _mount.MountMainFrame)(this, 'focus');
366
+ (0, _mount.MountClip)(this);
367
+ const {
368
+ curveIdx,
369
+ isShowAllCurve
370
+ } = curveSt;
371
+ const selectedPolarity = hplcMsSt?.tic?.polarity;
372
+ const jcampIdx = pickTicIndex(ticEntities, curveIdx, selectedPolarity);
373
+ this.isShowAllCurves = isShowAllCurve;
374
+ this.ticEntities = Array.isArray(ticEntities) ? ticEntities : [];
375
+ this.root = d3.select(this.rootKlass).selectAll('.focus-main');
376
+ this.scales = (0, _init.InitScale)(this, false);
377
+ this.setTip();
378
+ this.setDataParams(tTrEndPts, layoutSt, jcampIdx);
379
+ (0, _compass.MountCompass)(this);
380
+ this.axis = (0, _mount.MountAxis)(this);
381
+ this.path = (0, _mount.MountPath)(this, this.pathColor);
382
+ this.grid = (0, _mount.MountGrid)(this);
383
+ this.tags = (0, _mount.MountTags)(this);
384
+ (0, _mount.MountAxisLabelX)(this);
385
+ (0, _mount.MountAxisLabelY)(this);
386
+ if (this.data && this.data.length > 0) {
387
+ this.setConfig(sweepExtentSt);
388
+ this.drawLine();
389
+ this.drawGrid();
390
+ this.drawPageMarker(hplcMsSt);
391
+ this.drawOtherLines(layoutSt);
392
+ this.drawTicLegend(ticEntities, hplcMsSt);
393
+ }
394
+ (0, _brush.default)(this, false, isUiNoBrushSt, this.brushClass);
395
+ this.resetShouldUpdate();
396
+ }
397
+ update({
398
+ curveSt,
399
+ tTrEndPts,
400
+ layoutSt,
401
+ ticEntities,
402
+ hplcMsSt,
403
+ sweepExtentSt,
404
+ isUiNoBrushSt,
405
+ uiSt
406
+ }) {
407
+ this.svg = d3.select(this.rootKlass).select(this.brushClass);
408
+ this.root = d3.select(this.rootKlass).selectAll('.focus-main');
409
+ this.scales = (0, _init.InitScale)(this, false);
410
+ const {
411
+ curveIdx,
412
+ isShowAllCurve
413
+ } = curveSt;
414
+ const selectedPolarity = hplcMsSt?.tic?.polarity;
415
+ const jcampIdx = pickTicIndex(ticEntities, curveIdx, selectedPolarity);
416
+ this.isShowAllCurves = isShowAllCurve;
417
+ this.ticEntities = Array.isArray(ticEntities) ? ticEntities : [];
418
+ this.uiSt = uiSt;
419
+ this.setDataParams(tTrEndPts, layoutSt, jcampIdx);
420
+ if (this.data && this.data.length > 0) {
421
+ this.setConfig(sweepExtentSt);
422
+ this.getShouldUpdate();
423
+ this.drawLine();
424
+ this.drawGrid();
425
+ this.drawPageMarker(hplcMsSt);
426
+ this.drawOtherLines(layoutSt);
427
+ this.drawTicLegend(ticEntities, hplcMsSt);
428
+ }
429
+ (0, _brush.default)(this, false, isUiNoBrushSt, this.brushClass);
430
+ this.resetShouldUpdate();
431
+ }
432
+ }
433
+ var _default = exports.default = MultiFocus;
@@ -0,0 +1,247 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = void 0;
8
+ var _init = require("../../helpers/init");
9
+ var _brush = _interopRequireDefault(require("../../helpers/brush"));
10
+ var _mount = require("../../helpers/mount");
11
+ var _compass = require("../../helpers/compass");
12
+ var _converter = require("../../helpers/converter");
13
+ var _list_layout = require("../../constants/list_layout");
14
+ var _list_graph = require("../../constants/list_graph");
15
+ const d3 = require('d3');
16
+ class RectFocus {
17
+ constructor(props) {
18
+ const {
19
+ W,
20
+ H,
21
+ clickUiTargetAct,
22
+ selectUiSweepAct,
23
+ scrollUiWheelAct,
24
+ graphIndex,
25
+ uiSt
26
+ } = props;
27
+ this.graphIndex = graphIndex;
28
+ this.uiSt = uiSt;
29
+ this.rootKlass = `.${_list_graph.LIST_ROOT_SVG_GRAPH.RECT}`;
30
+ this.brushClass = `.${_list_graph.LIST_BRUSH_SVG_GRAPH.RECT}`;
31
+ this.margin = {
32
+ t: 5,
33
+ b: 40,
34
+ l: 60,
35
+ r: 5
36
+ };
37
+ this.w = W - this.margin.l - this.margin.r;
38
+ this.h = H - this.margin.t - this.margin.b;
39
+ this.clickUiTargetAct = clickUiTargetAct;
40
+ this.selectUiSweepAct = selectUiSweepAct;
41
+ this.scrollUiWheelAct = scrollUiWheelAct;
42
+ this.brush = d3.brush();
43
+ this.brushX = d3.brushX();
44
+ this.axis = null;
45
+ this.thresLine = null;
46
+ this.grid = null;
47
+ this.ref = null;
48
+ this.ccPattern = null;
49
+ this.data = [];
50
+ this.dataPks = [];
51
+ this.tTrEndPts = null;
52
+ this.tSfPeaks = null;
53
+ this.root = null;
54
+ this.svg = null;
55
+ this.bars = null;
56
+ this.scales = (0, _init.InitScale)(this, false);
57
+ this.axisCall = (0, _init.InitAxisCall)(5);
58
+ this.pathCall = null;
59
+ this.tip = null;
60
+ this.factor = 0.125;
61
+ this.currentExtent = null;
62
+ this.layout = _list_layout.LIST_LAYOUT.MS;
63
+ this.setTip = this.setTip.bind(this);
64
+ this.setDataParams = this.setDataParams.bind(this);
65
+ this.create = this.create.bind(this);
66
+ this.update = this.update.bind(this);
67
+ this.setConfig = this.setConfig.bind(this);
68
+ this.drawBar = this.drawBar.bind(this);
69
+ this.drawThres = this.drawThres.bind(this);
70
+ this.drawGrid = this.drawGrid.bind(this);
71
+ this.mergedPeaks = this.mergedPeaks.bind(this);
72
+ this.isFirefox = typeof InstallTrigger !== 'undefined';
73
+ }
74
+ setTip() {
75
+ this.tip = (0, _init.InitTip)();
76
+ this.root.call(this.tip);
77
+ }
78
+ setDataParams(data, peaks, tTrEndPts, tSfPeaks, layout = null) {
79
+ this.data = [...data];
80
+ this.dataPks = [...peaks];
81
+ this.tTrEndPts = tTrEndPts;
82
+ this.tSfPeaks = tSfPeaks;
83
+ if (layout) {
84
+ this.layout = layout;
85
+ }
86
+ this.xOnlyBrush = this.layout === _list_layout.LIST_LAYOUT.LC_MS;
87
+ const xExtent = d3.extent(this.data, d => d.x);
88
+ this.scales.x.domain(xExtent);
89
+ }
90
+ updatePathCall(xt, yt) {
91
+ this.pathCall = d3.line().x(d => xt(d.x)).y(d => yt(d.y));
92
+ }
93
+ setConfig(sweepExtentSt) {
94
+ // Domain Calculate
95
+ let {
96
+ xExtent,
97
+ yExtent
98
+ } = sweepExtentSt || {
99
+ xExtent: false,
100
+ yExtent: false
101
+ };
102
+ if (!xExtent || !yExtent) {
103
+ const xes = d3.extent(this.data, d => d.x).sort((a, b) => a - b);
104
+ const padding = (xes[1] - xes[0]) * 0.005;
105
+ xExtent = {
106
+ xL: Math.max(0, xes[0] - padding),
107
+ xU: xes[1] + padding
108
+ };
109
+ const btm = 0; // MS baseline is always 0.
110
+ const top = d3.max(this.data, d => d.y);
111
+ const height = top - btm;
112
+ yExtent = {
113
+ yL: btm - this.factor * height,
114
+ yU: top + this.factor * height
115
+ };
116
+ }
117
+ this.scales.x.domain([xExtent.xL, xExtent.xU]);
118
+ this.scales.y.domain([yExtent.yL, yExtent.yU]);
119
+
120
+ // rescale for zoom
121
+ const {
122
+ xt,
123
+ yt
124
+ } = (0, _compass.TfRescale)(this);
125
+
126
+ // Axis Call
127
+ this.axisCall.x.scale(xt);
128
+ this.axisCall.y.scale(yt);
129
+ this.currentExtent = {
130
+ xExtent,
131
+ yExtent
132
+ };
133
+ }
134
+ posHeight(gnd, val) {
135
+ const h = gnd - val;
136
+ return h >= 0 ? h : 0;
137
+ }
138
+ barColor(y, yRef) {
139
+ return y >= yRef ? 'steelblue' : '#aaa';
140
+ }
141
+ drawBar() {
142
+ if (!this.bars) {
143
+ return;
144
+ }
145
+ const {
146
+ xt,
147
+ yt
148
+ } = (0, _compass.TfRescale)(this);
149
+ this.updatePathCall(xt, yt);
150
+ if (!this.tTrEndPts.length) return;
151
+ const yRef = this.tTrEndPts[0].y;
152
+ const bars = this.bars.selectAll('rect').data(this.data);
153
+ bars.exit().attr('class', 'exit').remove();
154
+ const gnd = yt(0);
155
+ bars.enter().append('rect').attr('class', 'enter-bar').attr('width', 1.5).merge(bars).attr('fill', d => this.barColor(d.y, yRef)).attr('height', d => this.posHeight(gnd, yt(d.y))).attr('id', d => `mpp${Math.round(1000 * d.x)}`).attr('transform', d => `translate(${xt(d.x)}, ${yt(d.y)})`).on('mouseover', (event, d) => {
156
+ d3.select(`#mpp${Math.round(1000 * d.x)}`).attr('stroke-opacity', '1.0');
157
+ d3.select(`#bpt${Math.round(1000 * d.x)}`).style('fill', 'blue');
158
+ const tipParams = {
159
+ d,
160
+ layout: this.layout
161
+ };
162
+ this.tip.show(tipParams, event.target);
163
+ }).on('mouseout', (event, d) => {
164
+ d3.select(`#mpp${Math.round(1000 * d.x)}`).attr('stroke-opacity', '1.0');
165
+ d3.select(`#bpt${Math.round(1000 * d.x)}`).style('fill', 'red');
166
+ const tipParams = {
167
+ d,
168
+ layout: this.layout
169
+ };
170
+ this.tip.hide(tipParams, event.target);
171
+ });
172
+ }
173
+ drawThres() {
174
+ if (this.thresLine && this.tTrEndPts.length > 0) {
175
+ this.thresLine.attr('d', this.pathCall(this.tTrEndPts));
176
+ this.thresLine.attr('visibility', 'visible');
177
+ } else if (this.thresLine) {
178
+ this.thresLine.attr('visibility', 'hidden');
179
+ }
180
+ }
181
+ drawGrid() {
182
+ if (!this.grid) return;
183
+ this.grid.x.call(this.axisCall.x.tickSize(-this.h, 0, 0)).selectAll('line').attr('stroke', '#ddd').attr('stroke-opacity', 0.6).attr('fill', 'none');
184
+ this.grid.y.call(this.axisCall.y.tickSize(-this.w, 0, 0)).selectAll('line').attr('stroke', '#ddd').attr('stroke-opacity', 0.6).attr('fill', 'none');
185
+ }
186
+ mergedPeaks(editPeakSt) {
187
+ if (!editPeakSt) return this.dataPks;
188
+ this.dataPks = (0, _converter.PksEdit)(this.dataPks, editPeakSt);
189
+ return this.dataPks;
190
+ }
191
+ create({
192
+ filterSeed,
193
+ filterPeak,
194
+ tTrEndPts,
195
+ tSfPeaks,
196
+ layoutSt,
197
+ sweepExtentSt,
198
+ isUiAddIntgSt,
199
+ isUiNoBrushSt
200
+ }) {
201
+ this.svg = d3.select(this.brushClass);
202
+ (0, _mount.MountMainFrame)(this, 'focus');
203
+ (0, _mount.MountClip)(this);
204
+ this.root = d3.select(this.rootKlass).selectAll('.focus-main');
205
+ this.setTip();
206
+ this.setDataParams(filterSeed, filterPeak, tTrEndPts, tSfPeaks, layoutSt);
207
+ (0, _compass.MountCompass)(this);
208
+ this.axis = (0, _mount.MountAxis)(this);
209
+ [this.thresLine] = (0, _mount.MountThresLine)(this, 'green');
210
+ this.grid = (0, _mount.MountGrid)(this);
211
+ this.ref = (0, _mount.MountRef)(this);
212
+ this.bars = (0, _mount.MountBars)(this);
213
+ (0, _mount.MountAxisLabelX)(this);
214
+ (0, _mount.MountAxisLabelY)(this);
215
+ (0, _mount.MountGraphLabel)(this);
216
+ if (this.data && this.data.length > 0) {
217
+ this.setConfig(sweepExtentSt);
218
+ this.drawBar();
219
+ this.drawThres();
220
+ this.drawGrid();
221
+ }
222
+ (0, _brush.default)(this, isUiAddIntgSt, isUiNoBrushSt, this.brushClass);
223
+ }
224
+ update({
225
+ filterSeed,
226
+ filterPeak,
227
+ tTrEndPts,
228
+ tSfPeaks,
229
+ layoutSt,
230
+ sweepExtentSt,
231
+ isUiAddIntgSt,
232
+ isUiNoBrushSt,
233
+ uiSt
234
+ }) {
235
+ this.root = d3.select(this.rootKlass).selectAll('.focus-main');
236
+ this.setDataParams(filterSeed, filterPeak, tTrEndPts, tSfPeaks, layoutSt);
237
+ this.uiSt = uiSt;
238
+ if (this.data && this.data.length > 0) {
239
+ this.setConfig(sweepExtentSt);
240
+ this.drawBar();
241
+ this.drawThres();
242
+ this.drawGrid();
243
+ }
244
+ (0, _brush.default)(this, isUiAddIntgSt, isUiNoBrushSt, this.brushClass);
245
+ }
246
+ }
247
+ var _default = exports.default = RectFocus;