@aics/vole-app 3.3.1 → 3.4.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/es/aics-image-viewer/components/App/index.js +1 -0
- package/es/aics-image-viewer/components/BottomPanel/index.js +48 -19
- package/es/aics-image-viewer/components/BottomPanel/styles.css +16 -7
- package/es/aics-image-viewer/components/CellViewerCanvasWrapper/index.js +39 -19
- package/es/aics-image-viewer/components/ControlPanel/index.js +2 -0
- package/es/aics-image-viewer/components/dimension_sliders/AxisClipSliders.js +148 -0
- package/es/aics-image-viewer/components/dimension_sliders/RotationSliders.js +165 -0
- package/es/aics-image-viewer/components/dimension_sliders/SliderRows.js +167 -0
- package/es/aics-image-viewer/components/{AxisClipSliders → dimension_sliders}/styles.css +7 -1
- package/es/aics-image-viewer/components/shared/NumericInput/index.js +4 -2
- package/es/aics-image-viewer/components/shared/SliderRow/index.js +2 -0
- package/es/aics-image-viewer/components/shared/SliderRow/styles.css +2 -1
- package/es/aics-image-viewer/shared/constants.js +1 -1
- package/es/aics-image-viewer/shared/utils/camera.js +122 -0
- package/es/aics-image-viewer/shared/utils/test/camera.test.js +127 -0
- package/es/aics-image-viewer/shared/utils/test/urlParsing.test.js +23 -702
- package/es/aics-image-viewer/shared/utils/urlParsing.js +14 -828
- package/es/aics-image-viewer/state/deserialize.js +437 -0
- package/es/aics-image-viewer/state/serialize.js +145 -0
- package/es/aics-image-viewer/state/test/deserialize.test.js +432 -0
- package/es/aics-image-viewer/state/test/serialize.test.js +97 -0
- package/es/aics-image-viewer/state/test/test_data.js +168 -0
- package/es/aics-image-viewer/state/types.js +265 -1
- package/package.json +2 -1
- package/type-declarations/aics-image-viewer/components/App/types.d.ts +1 -1
- package/type-declarations/aics-image-viewer/components/BottomPanel/index.d.ts +6 -3
- package/type-declarations/aics-image-viewer/components/CellViewerCanvasWrapper/index.d.ts +1 -0
- package/type-declarations/aics-image-viewer/components/{AxisClipSliders/index.d.ts → dimension_sliders/AxisClipSliders.d.ts} +2 -3
- package/type-declarations/aics-image-viewer/components/dimension_sliders/RotationSliders.d.ts +6 -0
- package/type-declarations/aics-image-viewer/components/dimension_sliders/SliderRows.d.ts +31 -0
- package/type-declarations/aics-image-viewer/components/shared/NumericInput/index.d.ts +1 -0
- package/type-declarations/aics-image-viewer/components/shared/SliderRow/index.d.ts +3 -1
- package/type-declarations/aics-image-viewer/shared/utils/camera.d.ts +19 -0
- package/type-declarations/aics-image-viewer/shared/utils/urlParsing.d.ts +1 -307
- package/type-declarations/aics-image-viewer/state/deserialize.d.ts +70 -0
- package/type-declarations/aics-image-viewer/state/serialize.d.ts +20 -0
- package/type-declarations/aics-image-viewer/state/types.d.ts +216 -0
- package/es/aics-image-viewer/components/AxisClipSliders/index.js +0 -295
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
2
|
+
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
3
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
4
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
5
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
6
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
7
|
+
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
8
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
9
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
10
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
11
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
12
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
13
|
+
import { describe, expect, it } from "@jest/globals";
|
|
14
|
+
import { RenderMode, ViewMode } from "../../shared/enums";
|
|
15
|
+
import { CONTROL_POINTS_REGEX, deserializeViewerChannelSetting, deserializeViewerState, LEGACY_CONTROL_POINTS_REGEX, parseHexColorAsColorArray, parseKeyValueList, parseStringEnum, parseStringFloat, parseStringInt } from "../deserialize";
|
|
16
|
+
import { serializeViewerState } from "../serialize";
|
|
17
|
+
import { CUSTOM_TEST_VIEWER_STATE, DEFAULT_TEST_VIEWER_CHANNEL_SETTING, DEFAULT_TEST_VIEWER_STATE, SERIALIZED_CUSTOM_TEST_VIEWER_STATE, SERIALIZED_DEFAULT_TEST_VIEWER_STATE } from "./test_data";
|
|
18
|
+
|
|
19
|
+
//// VALUE PARSING ////////////////////////////////////////
|
|
20
|
+
|
|
21
|
+
describe("LEGACY_CONTROL_POINTS_REGEX", function () {
|
|
22
|
+
it("accepts single control points", function () {
|
|
23
|
+
var data = "1:0.5:ffffff";
|
|
24
|
+
expect(LEGACY_CONTROL_POINTS_REGEX.test(data)).toBe(true);
|
|
25
|
+
});
|
|
26
|
+
it("accepts multiple control points", function () {
|
|
27
|
+
var data = "1:0.5:ff0000,128:0.7:ffff00,255:1:ff0000";
|
|
28
|
+
expect(LEGACY_CONTROL_POINTS_REGEX.test(data)).toBe(true);
|
|
29
|
+
});
|
|
30
|
+
it("accepts negative numbers", function () {
|
|
31
|
+
var data = "-1:0.5:ff0000,-255:1:ff0000";
|
|
32
|
+
expect(LEGACY_CONTROL_POINTS_REGEX.test(data)).toBe(true);
|
|
33
|
+
});
|
|
34
|
+
it("allows 'w' as a placeholder for color strings", function () {
|
|
35
|
+
var data = "1:0.5:1,255:1:1";
|
|
36
|
+
expect(LEGACY_CONTROL_POINTS_REGEX.test(data)).toBe(true);
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
describe("CONTROL_POINTS_REGEX", function () {
|
|
40
|
+
it("accepts single control points", function () {
|
|
41
|
+
var data = "1:0.5:ffffff";
|
|
42
|
+
expect(CONTROL_POINTS_REGEX.test(data)).toBe(true);
|
|
43
|
+
});
|
|
44
|
+
it("accepts multiple control points", function () {
|
|
45
|
+
var data = "1:0.5:ff0000:128:0.7:ffff00:255:1:ff0000";
|
|
46
|
+
expect(CONTROL_POINTS_REGEX.test(data)).toBe(true);
|
|
47
|
+
});
|
|
48
|
+
it("accepts negative numbers", function () {
|
|
49
|
+
var data = "-1:0.5:ff0000:-255:1:ff0000";
|
|
50
|
+
expect(CONTROL_POINTS_REGEX.test(data)).toBe(true);
|
|
51
|
+
});
|
|
52
|
+
it("allows empty color strings", function () {
|
|
53
|
+
var data = "1:0.5:1:255:1:1";
|
|
54
|
+
expect(CONTROL_POINTS_REGEX.test(data)).toBe(true);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
describe("parseKeyValueList", function () {
|
|
58
|
+
it("returns expected key value pairs", function () {
|
|
59
|
+
var data = "key1:value1,key2:value2";
|
|
60
|
+
var result = parseKeyValueList(data);
|
|
61
|
+
expect(result).toEqual({
|
|
62
|
+
key1: "value1",
|
|
63
|
+
key2: "value2"
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
it("decodes encoded key and value string names", function () {
|
|
67
|
+
var data = "ampersand%26:ampersand%26,comma%2C:comma%2C,colon%3A:colon%3A";
|
|
68
|
+
var result = parseKeyValueList(data);
|
|
69
|
+
expect(result).toEqual({
|
|
70
|
+
"ampersand&": "ampersand&",
|
|
71
|
+
"comma,": "comma,",
|
|
72
|
+
"colon:": "colon:"
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
it("ignores repeat colons in value string", function () {
|
|
76
|
+
var data = "key1:value1:extra:extra,key2:value2";
|
|
77
|
+
var result = parseKeyValueList(data);
|
|
78
|
+
expect(result).toEqual({
|
|
79
|
+
key1: "value1:extra:extra",
|
|
80
|
+
key2: "value2"
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
it("returns empty object for empty string", function () {
|
|
84
|
+
var data = "";
|
|
85
|
+
var result = parseKeyValueList(data);
|
|
86
|
+
expect(result).toEqual({});
|
|
87
|
+
});
|
|
88
|
+
it("parses example viewer channel settings", function () {
|
|
89
|
+
var data = "col:FF0000,clz:1,cza:0.5,isa:0.75,ven:1,sen:1,isv:128,lut:autoij:";
|
|
90
|
+
var result = parseKeyValueList(data);
|
|
91
|
+
expect(result).toEqual({
|
|
92
|
+
col: "FF0000",
|
|
93
|
+
clz: "1",
|
|
94
|
+
cza: "0.5",
|
|
95
|
+
isa: "0.75",
|
|
96
|
+
ven: "1",
|
|
97
|
+
sen: "1",
|
|
98
|
+
isv: "128",
|
|
99
|
+
lut: "autoij:"
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
it("removes trailing and leading whitespace", function () {
|
|
103
|
+
var data = " key1 : value1 , key2 : value2 , key3: value 3";
|
|
104
|
+
var result = parseKeyValueList(data);
|
|
105
|
+
expect(result).toEqual({
|
|
106
|
+
key1: "value1",
|
|
107
|
+
key2: "value2",
|
|
108
|
+
key3: "value 3"
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
describe("parseHexColorAsColorArray", function () {
|
|
113
|
+
it("parses hex values", function () {
|
|
114
|
+
expect(parseHexColorAsColorArray("000000")).toEqual([0, 0, 0]);
|
|
115
|
+
expect(parseHexColorAsColorArray("FFFFFF")).toEqual([255, 255, 255]);
|
|
116
|
+
expect(parseHexColorAsColorArray("ff0000")).toEqual([255, 0, 0]);
|
|
117
|
+
expect(parseHexColorAsColorArray("123456")).toEqual([18, 52, 86]);
|
|
118
|
+
expect(parseHexColorAsColorArray("7890ab")).toEqual([120, 144, 171]);
|
|
119
|
+
expect(parseHexColorAsColorArray("cdefef")).toEqual([205, 239, 239]);
|
|
120
|
+
expect(parseHexColorAsColorArray("ABCDEF")).toEqual([171, 205, 239]);
|
|
121
|
+
});
|
|
122
|
+
it("ignores unrecognized formats", function () {
|
|
123
|
+
expect(parseHexColorAsColorArray("f")).toBeUndefined();
|
|
124
|
+
expect(parseHexColorAsColorArray("fff")).toBeUndefined();
|
|
125
|
+
expect(parseHexColorAsColorArray("fffffff")).toBeUndefined();
|
|
126
|
+
expect(parseHexColorAsColorArray("hjklmn")).toBeUndefined();
|
|
127
|
+
});
|
|
128
|
+
it("parses the '1' code as white", function () {
|
|
129
|
+
expect(parseHexColorAsColorArray("1")).toEqual([255, 255, 255]);
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
describe("parseStringEnum", function () {
|
|
133
|
+
var TestEnum = /*#__PURE__*/function (TestEnum) {
|
|
134
|
+
TestEnum["SOME_VALUE"] = "some_value";
|
|
135
|
+
TestEnum["ANOTHER_VALUE"] = "another_value";
|
|
136
|
+
return TestEnum;
|
|
137
|
+
}({});
|
|
138
|
+
it("recognizes enum values", function () {
|
|
139
|
+
expect(parseStringEnum("some_value", TestEnum)).toEqual(TestEnum.SOME_VALUE);
|
|
140
|
+
expect(parseStringEnum("another_value", TestEnum)).toEqual(TestEnum.ANOTHER_VALUE);
|
|
141
|
+
});
|
|
142
|
+
it("returns default values for unrecognized enum values", function () {
|
|
143
|
+
expect(parseStringEnum("unexpected", TestEnum, undefined)).toEqual(undefined);
|
|
144
|
+
expect(parseStringEnum("unexpected", TestEnum, TestEnum.SOME_VALUE)).toEqual(TestEnum.SOME_VALUE);
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
describe("parseStringInt", function () {
|
|
148
|
+
it("parses int and undefined values", function () {
|
|
149
|
+
expect(parseStringInt("0", 0, 1000)).toEqual(0);
|
|
150
|
+
expect(parseStringInt("1", 0, 1000)).toEqual(1);
|
|
151
|
+
expect(parseStringInt("100", 0, 1000)).toEqual(100);
|
|
152
|
+
expect(parseStringInt("255", 0, 1000)).toEqual(255);
|
|
153
|
+
expect(parseStringInt("-1", -1000, 1000)).toEqual(-1);
|
|
154
|
+
});
|
|
155
|
+
it("returns undefined for undefined and NaN values", function () {
|
|
156
|
+
expect(parseStringInt("bad", -1000, 1000)).toEqual(undefined);
|
|
157
|
+
expect(parseStringInt("NaN", -1000, 1000)).toEqual(undefined);
|
|
158
|
+
expect(parseStringInt(undefined, -1000, 1000)).toEqual(undefined);
|
|
159
|
+
});
|
|
160
|
+
it("casts float values to integers", function () {
|
|
161
|
+
expect(parseStringInt("0.5", 0, 1000)).toEqual(0);
|
|
162
|
+
expect(parseStringInt("99.5", 0, 1000)).toEqual(99);
|
|
163
|
+
expect(parseStringInt("-10.5", -1000, 1000)).toEqual(-10);
|
|
164
|
+
});
|
|
165
|
+
it("applies clamping", function () {
|
|
166
|
+
expect(parseStringInt("0", 0, 255)).toEqual(0);
|
|
167
|
+
expect(parseStringInt("-1", 0, 255)).toEqual(0);
|
|
168
|
+
expect(parseStringInt("128", 0, 255)).toEqual(128);
|
|
169
|
+
expect(parseStringInt("255", 0, 255)).toEqual(255);
|
|
170
|
+
expect(parseStringInt("256", 0, 255)).toEqual(255);
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
describe("parseStringFloat", function () {
|
|
174
|
+
it("parses strings to float values", function () {
|
|
175
|
+
expect(parseStringFloat("0", -1000, 1000)).toEqual(0);
|
|
176
|
+
expect(parseStringFloat("1.0", -1000, 1000)).toEqual(1.0);
|
|
177
|
+
expect(parseStringFloat("0.5", -1000, 1000)).toEqual(0.5);
|
|
178
|
+
expect(parseStringFloat("128.5", -1000, 1000)).toEqual(128.5);
|
|
179
|
+
expect(parseStringFloat("495.344", -1000, 1000)).toEqual(495.344);
|
|
180
|
+
expect(parseStringFloat("-1", -1000, 1000)).toEqual(-1);
|
|
181
|
+
});
|
|
182
|
+
it("returns undefined for NaN or undefined values", function () {
|
|
183
|
+
expect(parseStringFloat("bad", -1000, 1000)).toEqual(undefined);
|
|
184
|
+
expect(parseStringFloat("NaN", -1000, 1000)).toEqual(undefined);
|
|
185
|
+
expect(parseStringFloat(undefined, -1000, 1000)).toEqual(undefined);
|
|
186
|
+
});
|
|
187
|
+
it("applies clamping", function () {
|
|
188
|
+
expect(parseStringFloat("0.5", 0, 1.0)).toEqual(0.5);
|
|
189
|
+
expect(parseStringFloat("1.0", 0, 1.0)).toEqual(1.0);
|
|
190
|
+
expect(parseStringFloat("1.1", 0, 1.0)).toEqual(1.0);
|
|
191
|
+
expect(parseStringFloat("0", 0, 1.0)).toEqual(0);
|
|
192
|
+
expect(parseStringFloat("-0.1", 0, 1.0)).toEqual(0);
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
//// DESERIALIZE STATE ////////////////////////////////////
|
|
197
|
+
|
|
198
|
+
// Note that the serialization + deserialization are NOT direct inverses.
|
|
199
|
+
// Serializing converts a ChannelState object to a ViewerChannelSettingParams object,
|
|
200
|
+
// deserializing converts a ViewerChannelSettingParams object to a **ViewerChannelSetting** object.
|
|
201
|
+
|
|
202
|
+
// ChannelStates are per-channel and are used internally, while ViewerChannelSettings are
|
|
203
|
+
// input into the viewer and support grouping/matching to multiple channels.
|
|
204
|
+
// TODO: refactor these to all be the same state?
|
|
205
|
+
|
|
206
|
+
describe("deserializeViewerChannelSetting", function () {
|
|
207
|
+
it("returns default settings for empty objects", function () {
|
|
208
|
+
var data = {};
|
|
209
|
+
var result = deserializeViewerChannelSetting(0, data);
|
|
210
|
+
expect(result).toEqual(DEFAULT_TEST_VIEWER_CHANNEL_SETTING);
|
|
211
|
+
});
|
|
212
|
+
it("ignores unexpected keys", function () {
|
|
213
|
+
var data = {
|
|
214
|
+
badKey: "badValue",
|
|
215
|
+
ven: "1",
|
|
216
|
+
sen: "1"
|
|
217
|
+
};
|
|
218
|
+
var result = deserializeViewerChannelSetting(0, data);
|
|
219
|
+
expect(result).toEqual(_objectSpread(_objectSpread({}, DEFAULT_TEST_VIEWER_CHANNEL_SETTING), {}, {
|
|
220
|
+
enabled: true,
|
|
221
|
+
surfaceEnabled: true
|
|
222
|
+
}));
|
|
223
|
+
});
|
|
224
|
+
it("parses settings correctly", function () {
|
|
225
|
+
var data = {
|
|
226
|
+
col: "FF0000",
|
|
227
|
+
clz: "1",
|
|
228
|
+
cza: "0.5",
|
|
229
|
+
isa: "0.75",
|
|
230
|
+
ven: "1",
|
|
231
|
+
sen: "1",
|
|
232
|
+
isv: "128",
|
|
233
|
+
lut: "0:255"
|
|
234
|
+
};
|
|
235
|
+
expect(deserializeViewerChannelSetting(0, data)).toEqual({
|
|
236
|
+
match: 0,
|
|
237
|
+
color: "FF0000",
|
|
238
|
+
enabled: true,
|
|
239
|
+
surfaceEnabled: true,
|
|
240
|
+
isovalue: 128,
|
|
241
|
+
surfaceOpacity: 0.75,
|
|
242
|
+
colorizeEnabled: true,
|
|
243
|
+
colorizeAlpha: 0.5,
|
|
244
|
+
intensity: {
|
|
245
|
+
lut: ["0", "255"]
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
it("handles expected lut formatting", function () {
|
|
250
|
+
var luts = [["autoij:0", ["autoij", "0"]], ["0:autoij", ["0", "autoij"]], [":autoij", ["", "autoij"]], ["autoij:", ["autoij", ""]], ["0:255", ["0", "255"]], ["0.5:1.0", ["0.5", "1.0"]], ["0.50:1.00", ["0.50", "1.00"]], ["m99:m100", ["m99", "m100"]], ["p10:p90", ["p10", "p90"]], ["p10: p90", ["p10", "p90"]] // handle spaces
|
|
251
|
+
];
|
|
252
|
+
for (var _i = 0, _luts = luts; _i < _luts.length; _i++) {
|
|
253
|
+
var _result$intensity;
|
|
254
|
+
var _luts$_i = _slicedToArray(_luts[_i], 2),
|
|
255
|
+
encodedLut = _luts$_i[0],
|
|
256
|
+
decodedLut = _luts$_i[1];
|
|
257
|
+
var data = {
|
|
258
|
+
lut: encodedLut
|
|
259
|
+
};
|
|
260
|
+
var result = deserializeViewerChannelSetting(0, data);
|
|
261
|
+
expect((_result$intensity = result.intensity) === null || _result$intensity === void 0 ? void 0 : _result$intensity.lut).toEqual(decodedLut);
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
it("ignores unexpected lut formats", function () {
|
|
265
|
+
var luts = ["!:0", "0:9:93", "255", ""];
|
|
266
|
+
for (var _i2 = 0, _luts2 = luts; _i2 < _luts2.length; _i2++) {
|
|
267
|
+
var lut = _luts2[_i2];
|
|
268
|
+
var data = {
|
|
269
|
+
lut: lut
|
|
270
|
+
};
|
|
271
|
+
var result = deserializeViewerChannelSetting(0, data);
|
|
272
|
+
expect(result.lut).toBeUndefined();
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
it("handles hex color formats", function () {
|
|
276
|
+
var colors = ["000000", "FFFFFF", "ffffff", "012345", "6789AB", "CDEF01", "abcdef"];
|
|
277
|
+
for (var _i3 = 0, _colors = colors; _i3 < _colors.length; _i3++) {
|
|
278
|
+
var color = _colors[_i3];
|
|
279
|
+
var data = {
|
|
280
|
+
col: color
|
|
281
|
+
};
|
|
282
|
+
var result = deserializeViewerChannelSetting(0, data);
|
|
283
|
+
expect(result.color).toEqual(color);
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
it("ignores bad color formats", function () {
|
|
287
|
+
var badColors = ["f", "ff00", "red", "rgb(255,0,0)"];
|
|
288
|
+
for (var _i4 = 0, _badColors = badColors; _i4 < _badColors.length; _i4++) {
|
|
289
|
+
var color = _badColors[_i4];
|
|
290
|
+
var data = {
|
|
291
|
+
col: color
|
|
292
|
+
};
|
|
293
|
+
var result = deserializeViewerChannelSetting(0, data);
|
|
294
|
+
expect(result.color).toBeUndefined();
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
it("ignores bad float data", function () {
|
|
298
|
+
var data = {
|
|
299
|
+
cza: "NaN",
|
|
300
|
+
isa: "bad",
|
|
301
|
+
isv: "f8"
|
|
302
|
+
};
|
|
303
|
+
var result = deserializeViewerChannelSetting(0, data);
|
|
304
|
+
expect(result.colorizeAlpha).toBeUndefined();
|
|
305
|
+
expect(result.surfaceOpacity).toBeUndefined();
|
|
306
|
+
expect(result.isovalue).toBeUndefined();
|
|
307
|
+
});
|
|
308
|
+
});
|
|
309
|
+
describe("deserializeViewerState", function () {
|
|
310
|
+
it("returns an empty object for empty input", function () {
|
|
311
|
+
expect(deserializeViewerState({})).toEqual({});
|
|
312
|
+
});
|
|
313
|
+
it("deserializes the default viewer settings", function () {
|
|
314
|
+
var params = SERIALIZED_DEFAULT_TEST_VIEWER_STATE;
|
|
315
|
+
expect(deserializeViewerState(params)).toEqual(DEFAULT_TEST_VIEWER_STATE);
|
|
316
|
+
});
|
|
317
|
+
it("deserializes custom viewer settings", function () {
|
|
318
|
+
var params = SERIALIZED_CUSTOM_TEST_VIEWER_STATE;
|
|
319
|
+
expect(deserializeViewerState(params)).toEqual(CUSTOM_TEST_VIEWER_STATE);
|
|
320
|
+
});
|
|
321
|
+
it("handles all ViewMode values", function () {
|
|
322
|
+
var viewModes = Object.values(ViewMode);
|
|
323
|
+
for (var _i5 = 0, _viewModes = viewModes; _i5 < _viewModes.length; _i5++) {
|
|
324
|
+
var viewMode = _viewModes[_i5];
|
|
325
|
+
var state = _objectSpread(_objectSpread({}, DEFAULT_TEST_VIEWER_STATE), {}, {
|
|
326
|
+
viewMode: viewMode
|
|
327
|
+
});
|
|
328
|
+
expect(deserializeViewerState(serializeViewerState(state, false)).viewMode).toEqual(viewMode);
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
it("handles all RenderMode values", function () {
|
|
332
|
+
var renderModes = Object.values(RenderMode);
|
|
333
|
+
for (var _i6 = 0, _renderModes = renderModes; _i6 < _renderModes.length; _i6++) {
|
|
334
|
+
var renderMode = _renderModes[_i6];
|
|
335
|
+
var state = _objectSpread(_objectSpread({}, DEFAULT_TEST_VIEWER_STATE), {}, {
|
|
336
|
+
renderMode: renderMode
|
|
337
|
+
});
|
|
338
|
+
expect(deserializeViewerState(serializeViewerState(state, false)).renderMode).toEqual(renderMode);
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
it("deserializes partial camera settings", function () {
|
|
342
|
+
var state = {
|
|
343
|
+
cameraState: {
|
|
344
|
+
position: [1.0, -1.4, 45],
|
|
345
|
+
up: [0, 1, 0],
|
|
346
|
+
fov: 43.5
|
|
347
|
+
}
|
|
348
|
+
};
|
|
349
|
+
var serializedState = "pos:1:-1.4:45,up:0:1:0,fov:43.5";
|
|
350
|
+
expect(deserializeViewerState({
|
|
351
|
+
cam: serializedState
|
|
352
|
+
})).toEqual(state);
|
|
353
|
+
});
|
|
354
|
+
});
|
|
355
|
+
var DEFAULT_CONTROL_POINTS = [{
|
|
356
|
+
x: -10,
|
|
357
|
+
opacity: 0,
|
|
358
|
+
color: [0, 0, 0]
|
|
359
|
+
}, {
|
|
360
|
+
x: 50,
|
|
361
|
+
opacity: 0,
|
|
362
|
+
color: [0, 0, 0]
|
|
363
|
+
}, {
|
|
364
|
+
x: 100,
|
|
365
|
+
opacity: 0.3,
|
|
366
|
+
color: [0, 16, 255]
|
|
367
|
+
}, {
|
|
368
|
+
x: 140,
|
|
369
|
+
opacity: 0.8,
|
|
370
|
+
color: [0, 255, 255]
|
|
371
|
+
}, {
|
|
372
|
+
x: 260,
|
|
373
|
+
opacity: 1,
|
|
374
|
+
color: [0, 255, 180]
|
|
375
|
+
}];
|
|
376
|
+
describe("legacy control points", function () {
|
|
377
|
+
it("parses comma-separated control points", function () {
|
|
378
|
+
var result = deserializeViewerChannelSetting(0, {
|
|
379
|
+
cps: "-10:0:000000,50:0:000000,100:0.3:0010ff,140:0.8:00ffff,260:1:00ffb4"
|
|
380
|
+
});
|
|
381
|
+
expect(result.controlPoints).toEqual(DEFAULT_CONTROL_POINTS);
|
|
382
|
+
});
|
|
383
|
+
it("parses colon-separated control points", function () {
|
|
384
|
+
var result = deserializeViewerChannelSetting(0, {
|
|
385
|
+
cps: "-10:0:000000:50:0:000000:100:0.3:0010ff:140:0.8:00ffff:260:1:00ffb4"
|
|
386
|
+
});
|
|
387
|
+
expect(result.controlPoints).toEqual(DEFAULT_CONTROL_POINTS);
|
|
388
|
+
});
|
|
389
|
+
it("replaces '1' color strings with default color #ffffff", function () {
|
|
390
|
+
var result = deserializeViewerChannelSetting(0, {
|
|
391
|
+
cps: "0:0:1:50:1:1"
|
|
392
|
+
});
|
|
393
|
+
expect(result.controlPoints).toEqual([{
|
|
394
|
+
x: 0,
|
|
395
|
+
opacity: 0,
|
|
396
|
+
color: [255, 255, 255]
|
|
397
|
+
}, {
|
|
398
|
+
x: 50,
|
|
399
|
+
opacity: 1,
|
|
400
|
+
color: [255, 255, 255]
|
|
401
|
+
}]);
|
|
402
|
+
});
|
|
403
|
+
});
|
|
404
|
+
it("parses comma-separated control points", function () {
|
|
405
|
+
var _result$intensity2;
|
|
406
|
+
var result = deserializeViewerChannelSetting(0, {
|
|
407
|
+
cpt: "-10:0:000000,50:0:000000,100:0.3:0010ff,140:0.8:00ffff,260:1:00ffb4"
|
|
408
|
+
});
|
|
409
|
+
expect((_result$intensity2 = result.intensity) === null || _result$intensity2 === void 0 ? void 0 : _result$intensity2.controlPoints).toEqual(DEFAULT_CONTROL_POINTS);
|
|
410
|
+
});
|
|
411
|
+
it("parses colon-separated control points", function () {
|
|
412
|
+
var _result$intensity3;
|
|
413
|
+
var result = deserializeViewerChannelSetting(0, {
|
|
414
|
+
cpt: "-10:0:000000:50:0:000000:100:0.3:0010ff:140:0.8:00ffff:260:1:00ffb4"
|
|
415
|
+
});
|
|
416
|
+
expect((_result$intensity3 = result.intensity) === null || _result$intensity3 === void 0 ? void 0 : _result$intensity3.controlPoints).toEqual(DEFAULT_CONTROL_POINTS);
|
|
417
|
+
});
|
|
418
|
+
it("replaces '1' color strings with default color #ffffff", function () {
|
|
419
|
+
var _result$intensity4;
|
|
420
|
+
var result = deserializeViewerChannelSetting(0, {
|
|
421
|
+
cpt: "0:0:1:50:1:1"
|
|
422
|
+
});
|
|
423
|
+
expect((_result$intensity4 = result.intensity) === null || _result$intensity4 === void 0 ? void 0 : _result$intensity4.controlPoints).toEqual([{
|
|
424
|
+
x: 0,
|
|
425
|
+
opacity: 0,
|
|
426
|
+
color: [255, 255, 255]
|
|
427
|
+
}, {
|
|
428
|
+
x: 50,
|
|
429
|
+
opacity: 1,
|
|
430
|
+
color: [255, 255, 255]
|
|
431
|
+
}]);
|
|
432
|
+
});
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
2
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
3
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
4
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
5
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
6
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
7
|
+
import { getDefaultCameraState } from "../../shared/constants";
|
|
8
|
+
import { serializeCameraState, serializeViewerChannelSetting, serializeViewerState } from "../serialize";
|
|
9
|
+
import { CUSTOM_TEST_VIEWER_STATE, DEFAULT_TEST_CHANNEL_STATE, DEFAULT_TEST_VIEWER_STATE, SERIALIZED_CUSTOM_TEST_VIEWER_STATE, SERIALIZED_DEFAULT_TEST_CHANNEL_STATE, SERIALIZED_DEFAULT_TEST_VIEWER_STATE } from "./test_data";
|
|
10
|
+
describe("serializeViewerChannelSetting", function () {
|
|
11
|
+
it("serializes channel settings", function () {
|
|
12
|
+
expect(serializeViewerChannelSetting(DEFAULT_TEST_CHANNEL_STATE, false)).toEqual(SERIALIZED_DEFAULT_TEST_CHANNEL_STATE);
|
|
13
|
+
});
|
|
14
|
+
it("serializes custom channel settings", function () {
|
|
15
|
+
var customChannelState = {
|
|
16
|
+
name: "a",
|
|
17
|
+
displayName: "a",
|
|
18
|
+
color: [3, 255, 157],
|
|
19
|
+
volumeEnabled: false,
|
|
20
|
+
isosurfaceEnabled: false,
|
|
21
|
+
isovalue: 0,
|
|
22
|
+
opacity: 0.54,
|
|
23
|
+
colorizeEnabled: false,
|
|
24
|
+
colorizeAlpha: 1.0,
|
|
25
|
+
useControlPoints: false,
|
|
26
|
+
controlPoints: [],
|
|
27
|
+
ramp: [0, 255],
|
|
28
|
+
// TODO: the settings below are not serialized. should they be? (see #384)
|
|
29
|
+
plotMin: 0,
|
|
30
|
+
plotMax: 255,
|
|
31
|
+
keepIntensityRange: false
|
|
32
|
+
};
|
|
33
|
+
var serializedCustomChannelState = {
|
|
34
|
+
col: "03ff9d",
|
|
35
|
+
ven: "0",
|
|
36
|
+
sen: "0",
|
|
37
|
+
isv: "0",
|
|
38
|
+
isa: "0.54",
|
|
39
|
+
clz: "0",
|
|
40
|
+
cza: "1",
|
|
41
|
+
cpe: "0",
|
|
42
|
+
cpt: "",
|
|
43
|
+
ram: "0:255",
|
|
44
|
+
pin: "0"
|
|
45
|
+
};
|
|
46
|
+
expect(serializeViewerChannelSetting(customChannelState, false)).toEqual(serializedCustomChannelState);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
describe("serializeViewerState", function () {
|
|
50
|
+
it("serializes the default viewer settings", function () {
|
|
51
|
+
expect(serializeViewerState(DEFAULT_TEST_VIEWER_STATE, false)).toEqual(SERIALIZED_DEFAULT_TEST_VIEWER_STATE);
|
|
52
|
+
});
|
|
53
|
+
it("serializes custom viewer settings", function () {
|
|
54
|
+
expect(serializeViewerState(CUSTOM_TEST_VIEWER_STATE, false)).toEqual(SERIALIZED_CUSTOM_TEST_VIEWER_STATE);
|
|
55
|
+
});
|
|
56
|
+
it("shortens long numbers in the slice and region parameters", function () {
|
|
57
|
+
// Floats should be rounded to 7 significant digits or less
|
|
58
|
+
var state = {
|
|
59
|
+
region: {
|
|
60
|
+
x: [0.4566666666, 0.8667332],
|
|
61
|
+
y: [0.49999999, 0.8999999],
|
|
62
|
+
z: [0.3000000001, 0.16467883]
|
|
63
|
+
},
|
|
64
|
+
slice: {
|
|
65
|
+
x: 0.41111186,
|
|
66
|
+
y: 0.49999999,
|
|
67
|
+
z: 0.677402
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
var serializedState = serializeViewerState(state, true);
|
|
71
|
+
expect(serializedState.reg).toEqual("0.4566667:0.8667332,0.5:0.8999999,0.3:0.1646788");
|
|
72
|
+
expect(serializedState.slice).toEqual("0.4111119,0.5,0.677402");
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
describe("Camera state", function () {
|
|
76
|
+
it("uses default camera state when choosing elements to exclude/ignore", function () {
|
|
77
|
+
var cameraState = _objectSpread({}, getDefaultCameraState());
|
|
78
|
+
// No changes from default
|
|
79
|
+
expect(serializeCameraState(cameraState, true)).toEqual(undefined);
|
|
80
|
+
cameraState = _objectSpread(_objectSpread({}, cameraState), {}, {
|
|
81
|
+
position: [1, 2, 3]
|
|
82
|
+
});
|
|
83
|
+
expect(serializeCameraState(cameraState, true)).toEqual("pos:1:2:3");
|
|
84
|
+
});
|
|
85
|
+
it("default camera state has not been changed", function () {
|
|
86
|
+
// The default camera state should NOT change unless backwards compatibility
|
|
87
|
+
// is added to ensure old links still maintain the same camera orientation;
|
|
88
|
+
// otherwise, cameras will appear in the new default orientation unexpectedly.
|
|
89
|
+
expect(getDefaultCameraState()).toEqual({
|
|
90
|
+
position: [0, 0, 5],
|
|
91
|
+
target: [0, 0, 0],
|
|
92
|
+
up: [0, 1, 0],
|
|
93
|
+
fov: 20,
|
|
94
|
+
orthoScale: 0.5
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
});
|