@alisaitteke/seatmap-canvas 2.0.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 (79) hide show
  1. package/.eslintrc.json +15 -0
  2. package/.github/FUNDING.yml +4 -0
  3. package/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
  4. package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  5. package/.github/workflows/codeql-analysis.yml +29 -0
  6. package/.github/workflows/npm-publish-packages.yml +35 -0
  7. package/.github/workflows/webpack.yml +22 -0
  8. package/AUTHORS +3 -0
  9. package/LICENSE +21 -0
  10. package/README.md +160 -0
  11. package/SECURITY.md +21 -0
  12. package/_config.yml +1 -0
  13. package/assets/banner_ui.png +0 -0
  14. package/assets/bn.jpg +0 -0
  15. package/assets/logo.jpg +0 -0
  16. package/assets/logo_small.jpg +0 -0
  17. package/assets/zoom_out.svg +11 -0
  18. package/examples/basic/bootstrap.min.css +7 -0
  19. package/examples/basic/index.html +201 -0
  20. package/examples/basic/jquery.min.js +2 -0
  21. package/examples/data/data.json +70007 -0
  22. package/examples/data/small.json +1307 -0
  23. package/examples/data/tiny.json +119 -0
  24. package/examples/old/index.html +262 -0
  25. package/package.json +59 -0
  26. package/src/lib/canvas.index.ts +122 -0
  27. package/src/lib/config.ts +11 -0
  28. package/src/lib/decorators/dom.ts +40 -0
  29. package/src/lib/decorators/index.ts +6 -0
  30. package/src/lib/dev.tools.ts +18 -0
  31. package/src/lib/enums/global.ts +67 -0
  32. package/src/lib/models/block.model.ts +170 -0
  33. package/src/lib/models/coordinate.model.ts +43 -0
  34. package/src/lib/models/data.model.ts +105 -0
  35. package/src/lib/models/defaults.model.ts +125 -0
  36. package/src/lib/models/global.model.ts +24 -0
  37. package/src/lib/models/label.model.ts +58 -0
  38. package/src/lib/models/legend.model.ts +56 -0
  39. package/src/lib/models/model.base.ts +32 -0
  40. package/src/lib/models/seat.model.ts +182 -0
  41. package/src/lib/svg/event.manager.ts +56 -0
  42. package/src/lib/svg/legend/legend.circle.ts +28 -0
  43. package/src/lib/svg/legend/legend.item.ts +50 -0
  44. package/src/lib/svg/legend/legend.title.ts +27 -0
  45. package/src/lib/svg/legend.ts +55 -0
  46. package/src/lib/svg/stage/blocks/block-item/block-item.bounds.ts +51 -0
  47. package/src/lib/svg/stage/blocks/block-item/block-item.index.ts +173 -0
  48. package/src/lib/svg/stage/blocks/block-item/block-item.info.index.ts +38 -0
  49. package/src/lib/svg/stage/blocks/block-item/block-item.labels.index.ts +41 -0
  50. package/src/lib/svg/stage/blocks/block-item/block-item.mask.ts +67 -0
  51. package/src/lib/svg/stage/blocks/block-item/block-item.seats.index.ts +81 -0
  52. package/src/lib/svg/stage/blocks/block-item/bound/bound-item.index.ts +43 -0
  53. package/src/lib/svg/stage/blocks/block-item/info/title.ts +30 -0
  54. package/src/lib/svg/stage/blocks/block-item/label/label-item.circle.ts +27 -0
  55. package/src/lib/svg/stage/blocks/block-item/label/label-item.index.ts +46 -0
  56. package/src/lib/svg/stage/blocks/block-item/label/label-item.title.ts +27 -0
  57. package/src/lib/svg/stage/blocks/block-item/seat/seat-item.check.ts +45 -0
  58. package/src/lib/svg/stage/blocks/block-item/seat/seat-item.circle.ts +30 -0
  59. package/src/lib/svg/stage/blocks/block-item/seat/seat-item.index.ts +159 -0
  60. package/src/lib/svg/stage/blocks/block-item/seat/seat-item.title.ts +27 -0
  61. package/src/lib/svg/stage/blocks/blocks.index.ts +68 -0
  62. package/src/lib/svg/stage/blocks.search-circle.ts +86 -0
  63. package/src/lib/svg/stage/multi-select/rect.ts +36 -0
  64. package/src/lib/svg/stage/multi-select.ts +107 -0
  65. package/src/lib/svg/stage/search-circle/circle.ts +37 -0
  66. package/src/lib/svg/stage/stage.index.ts +41 -0
  67. package/src/lib/svg/svg.base.ts +217 -0
  68. package/src/lib/svg/svg.index.ts +76 -0
  69. package/src/lib/svg/tooltip/rect.ts +66 -0
  70. package/src/lib/svg/tooltip/title.ts +57 -0
  71. package/src/lib/svg/tooltip.ts +92 -0
  72. package/src/lib/svg/zoom-out.bg.ts +35 -0
  73. package/src/lib/svg/zoom.manager.ts +440 -0
  74. package/src/lib/window.manager.ts +40 -0
  75. package/src/scss/lib.scss +10 -0
  76. package/src/scss/style.scss +221 -0
  77. package/tsconfig.json +28 -0
  78. package/webpack.environments/development.js +58 -0
  79. package/webpack.environments/production.js +52 -0
@@ -0,0 +1,57 @@
1
+ /*
2
+ * $project.fileName
3
+ * https://github.com/seatmap/canvas Copyright 2018 Ali Sait TEKE
4
+ */
5
+
6
+
7
+ import {dom} from "../../decorators";
8
+ import SvgBase from "../svg.base";
9
+ import Tooltip from "../tooltip";
10
+
11
+ @dom({
12
+ tag: "text",
13
+ class: "tooltip-title",
14
+ autoGenerate: false
15
+ })
16
+ export default class TooltipTitle extends SvgBase {
17
+
18
+ private _title: Array<string>;
19
+
20
+ constructor(public parent: Tooltip) {
21
+ super(parent);
22
+ this.attr("x", 6);
23
+ this.attr("y", 21);
24
+ this.attr("fill", this.global.config.tooltip_style.color);
25
+ return this;
26
+ }
27
+
28
+ update(): this {
29
+ this.updateChilds();
30
+ return this;
31
+ }
32
+
33
+ afterGenerate() {
34
+
35
+ this.node.style("pointer-events", "none");
36
+ this.node.style("font-size", "12px");
37
+ }
38
+
39
+ generateTitle() {
40
+ this.node.selectAll("tspan").remove()
41
+ .data(this.title).enter()
42
+ .append("tspan")
43
+ .text((item: string) => item)
44
+ .attr("x", 6)
45
+ .attr("y", (line: any, index: number) => (index * 16) + 16);
46
+ }
47
+
48
+
49
+ get title(): Array<string> {
50
+ return this._title;
51
+ }
52
+
53
+ set title(value: Array<string>) {
54
+ this._title = value;
55
+ //this.generateTitle();
56
+ }
57
+ }
@@ -0,0 +1,92 @@
1
+ /*
2
+ * $project.fileName
3
+ * https://github.com/seatmap/canvas Copyright 2018 Ali Sait TEKE
4
+ */
5
+
6
+
7
+ import {dom} from "../decorators";
8
+ import SvgBase from "./svg.base";
9
+
10
+ import TooltipRect from "./tooltip/rect";
11
+ import {EventType, ZoomLevel} from "../enums/global";
12
+
13
+
14
+ import Svg from "./svg.index";
15
+ import {SeatItem} from "./stage/blocks/block-item/seat/seat-item.index";
16
+
17
+ import {mouse as d3Mouse} from 'd3-selection'
18
+ import TooltipTitle from "./tooltip/title";
19
+
20
+ @dom({
21
+ tag: "g",
22
+ class: "seatmap-tooltip",
23
+ autoGenerate: false
24
+ })
25
+ export default class Tooltip extends SvgBase {
26
+
27
+
28
+ public rect: TooltipRect;
29
+ public title: TooltipTitle;
30
+
31
+ public activeSeat: SeatItem;
32
+
33
+ constructor(public parent: Svg) {
34
+ super(parent);
35
+ this.attr("transform", "translate(0,0)");
36
+ this.attr("opacity", 0);
37
+
38
+ this.activeSeat = null;
39
+
40
+
41
+ this.global.eventManager.addEventListener([EventType.MOUSEMOVE_SEAT], (seat: SeatItem) => {
42
+ if (this.global.multi_select) return;
43
+ if (this.activeSeat !== seat) {
44
+ this.activeSeat = seat;
45
+ this.setTitle(seat.item.title.split("\n"));
46
+ this.title.generateTitle();
47
+ }
48
+ });
49
+ this.global.eventManager.addEventListener([EventType.MOUSEOUT_SEAT], (seat: SeatItem) => {
50
+ this.node.attr("opacity", 0);
51
+ this.activeSeat = null;
52
+ this.title.title = [];
53
+ this.title.generateTitle();
54
+ });
55
+ this.global.eventManager.addEventListener([EventType.TOUCHSTART_BLOCK], (seat: SeatItem) => {
56
+ this.node.attr("opacity", 0);
57
+ });
58
+ return this;
59
+ }
60
+
61
+ public setTitle(title: Array<string>): this {
62
+ this.title.title = title;
63
+ return this;
64
+ }
65
+
66
+ update(): this {
67
+ this.rect = new TooltipRect(this).addTo(this);
68
+ this.title = new TooltipTitle(this).addTo(this);
69
+
70
+
71
+ this.updateChilds();
72
+ return this;
73
+ }
74
+
75
+ afterGenerate() {
76
+
77
+ let _self = this;
78
+
79
+ this.parent.node.on("mousemove.seat", function () {
80
+ if (_self.global.multi_select) return;
81
+ if (_self.global.zoomManager.zoomLevel === ZoomLevel.SEAT && _self.activeSeat !== null) {
82
+ let cor = d3Mouse(this);
83
+
84
+ let x = cor[0] - (_self.global.config.tooltip_style.width / 2);
85
+ let y = cor[1] - (_self.global.config.tooltip_style.height + (_self.global.config.seat_style.radius) + 2);
86
+ _self.node.attr("transform", "translate(" + [x, y] + ")").attr("opacity", 1);
87
+ } else {
88
+ _self.node.attr("opacity", 0);
89
+ }
90
+ })
91
+ }
92
+ }
@@ -0,0 +1,35 @@
1
+ /*
2
+ * $project.fileName
3
+ * https://github.com/seatmap/canvas Copyright 2018 Ali Sait TEKE
4
+ */
5
+
6
+
7
+ import {dom} from "../decorators";
8
+ import SvgBase from "./svg.base";
9
+ import Svg from "./svg.index";
10
+ import {EventType} from "../enums/global";
11
+
12
+ @dom({
13
+ tag: "rect",
14
+ class: "zoom-out-bg",
15
+ autoGenerate: false
16
+ })
17
+ export default class ZoomOutBg extends SvgBase {
18
+
19
+ constructor(public parent: Svg) {
20
+ super(parent);
21
+ this.global.eventManager.addEventListener(EventType.RESIZE_WINDOW, (win: any) => {
22
+
23
+ this.node
24
+ .attr("width", win.width)
25
+ .attr("height", win.height)
26
+ .on("click.zoomout", () => {
27
+ this.global.eventManager.dispatch(EventType.CLICK_ZOOMOUT, this);
28
+ });
29
+ })
30
+ }
31
+
32
+ update() {
33
+
34
+ }
35
+ }
@@ -0,0 +1,440 @@
1
+ /*
2
+ * $project.fileName
3
+ * https://github.com/seatmap/canvas Copyright 2018 Ali Sait TEKE
4
+ */
5
+
6
+ import {mouse as d3Mouse, event as d3Event} from 'd3-selection'
7
+ import {zoom as d3Zoom} from 'd3-zoom'
8
+
9
+
10
+ import {SeatMapCanvas} from "../canvas.index";
11
+ import {EventType, ZoomLevel} from "../enums/global";
12
+ import SeatModel from "../models/seat.model";
13
+ import BlockModel from "../models/block.model";
14
+ import LabelModel from "../models/label.model";
15
+
16
+ interface ZoomCoordinate {
17
+ x: number,
18
+ y: number,
19
+ k: number
20
+ }
21
+
22
+ export interface ZoomLevelObject {
23
+ level: string,
24
+ values: {
25
+ x: number,
26
+ y: number,
27
+ k: number
28
+ }
29
+ }
30
+
31
+ export default class ZoomManager {
32
+
33
+ public zoomTypes: any = {
34
+ normal: null,
35
+ animated: null,
36
+ fastAnimated: null
37
+ };
38
+
39
+ public scale: any = {
40
+ x: null,
41
+ y: null,
42
+ k: null
43
+ };
44
+
45
+ private zoomLevels: any = {
46
+ VENUE: null,
47
+ BLOCK: null,
48
+ SEAT: null
49
+ };
50
+
51
+ public activeBlocks: Array<any>;
52
+ public minZoom: number = null;
53
+ private _zoomLevel: ZoomLevel;
54
+
55
+
56
+ constructor(private _self: SeatMapCanvas) {
57
+
58
+ this.activeBlocks = [];
59
+ this.zoomLevel = ZoomLevel.VENUE;
60
+
61
+ this.dispatchZoomEvent();
62
+ }
63
+
64
+ public init() {
65
+
66
+ this.calculateZoomLevels();
67
+ this.zoomInit();
68
+ // this._self.eventManager.addEventListener(EventType.UPDATE_BLOCK, (blocks: Array<BlockModel>) => {
69
+ // this.calculateZoomLevels(blocks);
70
+ // })
71
+
72
+ this._self.eventManager.addEventListener(EventType.KEYDOWN_SVG, (e: any) => {
73
+ if (e.which == 17 || e.which === 91) {
74
+ this._self.eventManager.dispatch(EventType.MULTI_SELECT_ENABLE, e);
75
+ d3Event.preventDefault();
76
+ this.zoomDisable();
77
+ }
78
+ });
79
+ this._self.eventManager.addEventListener(EventType.KEYUP_SVG, (e: any) => {
80
+ this._self.eventManager.dispatch(EventType.MULTI_SELECT_DISABLE, e);
81
+ d3Event.preventDefault();
82
+ this.zoomEnable();
83
+ });
84
+
85
+ }
86
+
87
+ zoomInit() {
88
+ this.zoomTypes.normal = d3Zoom()
89
+ .scaleExtent([this._self.config.min_zoom, this._self.config.max_zoom])
90
+ .on("end", this.zoomEnd(this))
91
+ .on("zoom", this.zoomHand(this));
92
+
93
+ this.zoomTypes.animated = d3Zoom()
94
+ .scaleExtent([this._self.config.min_zoom, this._self.config.max_zoom])
95
+ .on("end", this.animatedZoomEnd(this))
96
+ .on("zoom", this.zoomHandAnimated(this));
97
+
98
+ this.zoomTypes.fastAnimated = d3Zoom()
99
+ .scaleExtent([this._self.config.min_zoom, this._self.config.max_zoom])
100
+ .on("end", this.animatedFastZoomEnd(this))
101
+ .on("zoom", this.zoomHandFastAnimated(this));
102
+
103
+ this._self.svg.node.call(this.zoomTypes.normal);
104
+ }
105
+
106
+ zoomEnd(_self: this): any {
107
+ return function () {
108
+ let x = d3Event.transform.x;
109
+ let y = d3Event.transform.y;
110
+ let k = d3Event.transform.k;
111
+ _self._self.svg.stage.node.interrupt().attr("transform", "translate(" + x + "," + y + ")scale(" + k + ")");
112
+ _self.calculateActiveBlocks();
113
+ _self.calculateZoomLevel(k);
114
+ _self.canvasScopeHandler();
115
+ }
116
+ }
117
+
118
+ animatedZoomEnd(_self: this): any {
119
+ return function () {
120
+ let x = d3Event.transform.x;
121
+ let y = d3Event.transform.y;
122
+ let k = d3Event.transform.k;
123
+ _self._self.svg.stage.node.interrupt().transition().duration(_self._self.config.animation_speed).attr("transform", "translate(" + x + "," + y + ")scale(" + k + ")");
124
+ _self.calculateActiveBlocks();
125
+ _self.calculateZoomLevel(k);
126
+ }
127
+ }
128
+
129
+ animatedFastZoomEnd(_self: this): any {
130
+ return function () {
131
+ let x = d3Event.transform.x;
132
+ let y = d3Event.transform.y;
133
+ let k = d3Event.transform.k;
134
+ _self._self.svg.stage.node.interrupt().transition().duration(_self._self.config.animation_speed / 2).attr("transform", "translate(" + x + "," + y + ")scale(" + k + ")");
135
+ _self.calculateActiveBlocks();
136
+ _self.calculateZoomLevel(k);
137
+ }
138
+ }
139
+
140
+ zoomHand(_self: this): any {
141
+ return function () {
142
+ let x = d3Event.transform.x;
143
+ let y = d3Event.transform.y;
144
+ let k = d3Event.transform.k;
145
+ _self._self.svg.stage.node.interrupt().attr("transform", "translate(" + x + "," + y + ")scale(" + k + ")");
146
+ _self.calculateZoomLevel(k);
147
+ }
148
+ }
149
+
150
+ zoomHandAnimated(_self: this): any {
151
+ return function () {
152
+ let x = d3Event.transform.x;
153
+ let y = d3Event.transform.y;
154
+ let k = d3Event.transform.k;
155
+
156
+ _self._self.svg.stage.node.interrupt().transition().duration(_self._self.config.animation_speed).attr("transform", "translate(" + x + "," + y + ")scale(" + k + ")");
157
+ //_self.calculateZoomLevel(k);
158
+ }
159
+ }
160
+
161
+ zoomHandFastAnimated(_self: this): any {
162
+ return function () {
163
+ let x = d3Event.transform.x;
164
+ let y = d3Event.transform.y;
165
+ let k = d3Event.transform.k;
166
+
167
+ _self._self.svg.stage.node.interrupt().transition().duration(_self._self.config.animation_speed / 2).attr("transform", "translate(" + x + "," + y + ")scale(" + k + ")");
168
+ //_self.calculateZoomLevel(k);
169
+ }
170
+ }
171
+
172
+ calculateZoomLevel(k: number) {
173
+ let _levels = {
174
+ seat: this._self.config.max_zoom - 0.2,
175
+ block: this.zoomLevels.BLOCK.k,
176
+ venue: this.zoomLevels.VENUE.k
177
+ };
178
+
179
+ let _zoomLevel = null;
180
+
181
+ let blocks_count = this._self.data.getBlocks().length;
182
+
183
+ if (k >= _levels.seat) {
184
+ _zoomLevel = ZoomLevel.SEAT;
185
+
186
+ } else if (k >= _levels.block) {
187
+ _zoomLevel = ZoomLevel.BLOCK;
188
+
189
+ } else if (k >= _levels.venue && blocks_count > 1) {
190
+ _zoomLevel = ZoomLevel.VENUE;
191
+ }
192
+
193
+ if (_zoomLevel !== this.zoomLevel) {
194
+ this.zoomLevel = _zoomLevel;
195
+ this.dispatchZoomEvent();
196
+ }
197
+ }
198
+
199
+ canvasScopeHandler() {
200
+ if (this._self.config.canvas_stageout_control === false) return;
201
+ let _blocks_values = this._self.svg.stage.blocks.node.node().getBoundingClientRect();
202
+ let _svg_values = this._self.svg.node.node().getBoundingClientRect();
203
+
204
+ if (this.zoomLevel === ZoomLevel.VENUE ||
205
+ (this.zoomLevel === ZoomLevel.BLOCK && this._self.data.getBlocks().length === 1) ||
206
+ (this.zoomLevel == ZoomLevel.SEAT && this.zoomLevels.BLOCK && this.zoomLevels.BLOCK.k === this._self.config.max_zoom)) {
207
+
208
+ if (_blocks_values.left < _svg_values.left ||
209
+ _blocks_values.top < _svg_values.top ||
210
+ _blocks_values.right > _svg_values.right ||
211
+ _blocks_values.bottom > _svg_values.bottom) {
212
+ this.zoomToVenue(true, true);
213
+ }
214
+ }
215
+ }
216
+
217
+ public calculateZoomLevels(blocks: Array<BlockModel> = this._self.data.getBlocks()): this {
218
+
219
+ let _wm = this._self.windowManager;
220
+ let _stage = _wm.stage;
221
+
222
+ blocks.map((block: BlockModel) => {
223
+
224
+ block.seats.map((seat: SeatModel) => {
225
+ if (seat.x < block.x) block.x = seat.x;
226
+ if (seat.y < block.y) block.y = seat.y;
227
+
228
+ if (seat.x > _stage.width) _stage.width = seat.x;
229
+ if (seat.y > _stage.height) _stage.height = seat.y;
230
+
231
+ //this.total_seat_count++;
232
+ });
233
+
234
+ block.labels.map((label: LabelModel) => {
235
+ if (label.x < block.x) block.x = label.x;
236
+ if (label.y < block.y) block.y = label.y;
237
+
238
+ if (label.x > _stage.width) _stage.width = label.x;
239
+ if (label.y > _stage.height) _stage.height = label.y;
240
+ });
241
+
242
+ });
243
+
244
+ this.scale.x = (_wm.width / _stage.width) - ((_wm.width / _stage.width) / 5);
245
+ this.scale.y = (_wm.height / _stage.height) - ((_wm.height / _stage.height) / 5);
246
+ this.scale.k = (this.scale.x < this.scale.y) ? this.scale.x : this.scale.y;
247
+ this.minZoom = this.scale.k < 1 ? this.scale.k : 1;
248
+
249
+ this.scale.k = this.scale.k > this._self.config.max_zoom ? this._self.config.max_zoom : this.scale.k;
250
+
251
+
252
+ let x = _stage.width / 2;
253
+ let y = _stage.height / 2;
254
+ this.zoomLevels.VENUE = {
255
+ x: x,
256
+ y: y,
257
+ k: this.scale.k - 0.1
258
+ };
259
+
260
+
261
+ if (this._self.data.getBlocks().length === 1 && this.zoomLevels.BLOCK) {
262
+ this.zoomLevels.VENUE = this.zoomLevels.BLOCK;
263
+ }
264
+
265
+ return this;
266
+ }
267
+
268
+ public calculateActiveBlocks(blocks: Array<BlockModel> = this._self.data.getBlocks()): Array<BlockModel> {
269
+ this.activeBlocks = [];
270
+
271
+
272
+ blocks.map((block: BlockModel) => {
273
+ let _block_item = this._self.svg.stage.blocks.getBlock(block.id);
274
+
275
+
276
+ let bound = _block_item.node.node().getBoundingClientRect();
277
+ let bbox = _block_item.node.node().getBBox();
278
+
279
+ block.bbox = bbox;
280
+
281
+ let x = (this._self.windowManager.width / bbox.width) - ((this._self.windowManager.width / bbox.width) / 3);
282
+ let y = (this._self.windowManager.height / bbox.height) - ((this._self.windowManager.height / bbox.height) / 3);
283
+ let k = (x < y) ? x : y;
284
+
285
+ x += bbox.x + (bbox.width / 2);
286
+ y += bbox.y + (bbox.height / 2);
287
+
288
+ k = k > this._self.config.max_zoom ? this._self.config.max_zoom : k;
289
+
290
+ block.zoom_bbox = {
291
+ x: x,
292
+ y: y,
293
+ k: k
294
+ };
295
+
296
+
297
+ let x_overlap = Math.max(0, Math.min(this._self.windowManager.width, bound.right) - Math.max(0, bound.left));
298
+ let y_overlap = Math.max(0, Math.min(this._self.windowManager.height, bound.bottom) - Math.max(0, bound.top));
299
+ let overlapArea = (x_overlap * y_overlap);
300
+ let allOverlapArea = this._self.windowManager.width * this._self.windowManager.height;
301
+ let ratio: number = (overlapArea * 100) / allOverlapArea;
302
+
303
+ if (overlapArea > 0) {
304
+ this.activeBlocks.push({
305
+ block: _block_item,
306
+ ratio: Number(ratio.toFixed(2))
307
+ });
308
+ }
309
+ });
310
+
311
+ this.activeBlocks = this.activeBlocks.sort((a, b) => b.ratio - a.ratio);
312
+ if (this.activeBlocks.length) {
313
+ let _activeBlock: BlockModel = this.activeBlocks[0].block.item;
314
+ this.zoomLevels.BLOCK = _activeBlock.zoom_bbox;
315
+ }
316
+
317
+ return this.activeBlocks;
318
+ }
319
+
320
+ public zoomToSelection(animation: boolean = true) {
321
+
322
+ let cor = d3Mouse(this._self.svg.stage.blocks.node.node());
323
+ let x = cor[0];
324
+ let y = cor[1];
325
+ let k = this._self.config.max_zoom;
326
+
327
+ this.zoomLevels.SEAT = {
328
+ x: x,
329
+ y: y,
330
+ k: k
331
+ };
332
+
333
+ if (animation) {
334
+ this._self.svg.node.interrupt().call(this.zoomTypes.animated.translateTo, x, y).call(this.zoomTypes.animated.scaleTo, k);
335
+ } else {
336
+ this._self.svg.node.interrupt().call(this.zoomTypes.normal.translateTo, x, y).call(this.zoomTypes.normal.scaleTo, k);
337
+ }
338
+ this.zoomLevel = ZoomLevel.SEAT;
339
+ this.dispatchZoomEvent();
340
+
341
+ }
342
+
343
+ public zoomToBlock(id: string | number, animation: boolean = true, fastAnimated: boolean = false) {
344
+ let _block = this._self.data.getBlocks().find((block: BlockModel) => block.id === id);
345
+
346
+
347
+ if (_block) {
348
+ if (animation) {
349
+ if (fastAnimated) {
350
+ this._self.svg.node.interrupt().call(this.zoomTypes.fastAnimated.translateTo, _block.zoom_bbox.x, _block.zoom_bbox.y).call(this.zoomTypes.fastAnimated.scaleTo, _block.zoom_bbox.k);
351
+ } else {
352
+ this._self.svg.node.interrupt().call(this.zoomTypes.animated.translateTo, _block.zoom_bbox.x, _block.zoom_bbox.y).call(this.zoomTypes.animated.scaleTo, _block.zoom_bbox.k);
353
+ }
354
+ } else {
355
+ this._self.svg.node.interrupt().call(this.zoomTypes.normal.translateTo, _block.zoom_bbox.x, _block.zoom_bbox.y).call(this.zoomTypes.normal.scaleTo, _block.zoom_bbox.k);
356
+ }
357
+
358
+ // let gap = 0.2;
359
+
360
+ // if (_block.zoom_bbox.k > this._self.config.max_zoom + gap || _block.zoom_bbox.k < this._self.config.max_zoom - gap) {
361
+ if (_block.zoom_bbox.k === this._self.config.max_zoom) {
362
+ this.zoomLevel = ZoomLevel.SEAT;
363
+ } else {
364
+ this.zoomLevel = ZoomLevel.BLOCK;
365
+ }
366
+
367
+ this.dispatchZoomEvent();
368
+ }
369
+ }
370
+
371
+ public zoomToVenue(animation: boolean = true, fastAnimated: boolean = false) {
372
+
373
+ let x = this.zoomLevels.VENUE.x;
374
+ let y = this.zoomLevels.VENUE.y;
375
+ let k = this.zoomLevels.VENUE.k;
376
+
377
+ this._self.config.min_zoom = k;
378
+ this.zoomInit();
379
+
380
+
381
+ // single mode
382
+ if (this._self.data.getBlocks().length === 1) {
383
+ let _block = this._self.data.getBlocks()[0];
384
+ this.zoomToBlock(_block.id, animation, fastAnimated);
385
+ return;
386
+ }
387
+
388
+
389
+ if (x && y && k) {
390
+ if (animation) {
391
+ if (fastAnimated) {
392
+ this._self.svg.node.interrupt().call(this.zoomTypes.fastAnimated.translateTo, x, y).call(this.zoomTypes.fastAnimated.scaleTo, k);
393
+ } else {
394
+ this._self.svg.node.interrupt().call(this.zoomTypes.animated.translateTo, x, y).call(this.zoomTypes.animated.scaleTo, k);
395
+ }
396
+
397
+ } else {
398
+ this._self.svg.node.interrupt().call(this.zoomTypes.normal.translateTo, x, y).call(this.zoomTypes.normal.scaleTo, k);
399
+ }
400
+ this.zoomLevel = ZoomLevel.VENUE;
401
+ this.dispatchZoomEvent();
402
+ }
403
+
404
+ }
405
+
406
+
407
+ get zoomLevel(): ZoomLevel {
408
+ return this._zoomLevel;
409
+ }
410
+
411
+ set zoomLevel(value: ZoomLevel) {
412
+ this._zoomLevel = value;
413
+ }
414
+
415
+ public zoomEnable(): this {
416
+ this._self.svg.node.call(this.zoomTypes.normal);
417
+ //this._self.svg.node.on('.zoom', null);
418
+ return this;
419
+ }
420
+
421
+ public zoomDisable(): this {
422
+ this._self.svg.node.on('.zoom', null);
423
+ return this;
424
+ }
425
+
426
+ public getZoomLevelValues(level: ZoomLevel) {
427
+ return this.zoomLevels[level];
428
+ }
429
+
430
+ public getActiveZoom() {
431
+ return this.zoomLevels[this._zoomLevel];
432
+ }
433
+
434
+ private dispatchZoomEvent() {
435
+ this._self.eventManager.dispatch(EventType.ZOOM_LEVEL_CHANGE, {
436
+ level: this._zoomLevel,
437
+ values: this.getZoomLevelValues(this._zoomLevel)
438
+ });
439
+ }
440
+ }
@@ -0,0 +1,40 @@
1
+ /*
2
+ * Seatmap-canvas
3
+ * https://github.com/seatmap/canvas Copyright 2022 Ali Sait TEKE
4
+ */
5
+ import {select as d3Select} from 'd3-selection'
6
+
7
+ import {SeatMapCanvas} from "./canvas.index";
8
+ import {EventType} from "./enums/global";
9
+
10
+ declare var window: any;
11
+
12
+ export default class WindowManager {
13
+
14
+ public width: number = null;
15
+ public height: number = null;
16
+
17
+ public stage: any = {
18
+ width: null,
19
+ height: null
20
+ };
21
+
22
+
23
+ constructor(public parent: SeatMapCanvas) {
24
+ d3Select(window).on("resize.svg", () => {
25
+ this.resizeHandler();
26
+
27
+ });
28
+
29
+ }
30
+
31
+ resizeHandler(): this {
32
+ let _node = d3Select(this.parent.container_selector).node().getBoundingClientRect();
33
+ this.width = _node.width;
34
+ this.height = _node.height;
35
+ this.parent.svg.node.attr("width", _node.width);
36
+ this.parent.svg.node.attr("height", _node.height);
37
+ this.parent.global.eventManager.dispatch(EventType.RESIZE_WINDOW, _node);
38
+ return this;
39
+ }
40
+ }
@@ -0,0 +1,10 @@
1
+ @mixin stroke-width($param: 4) {
2
+ stroke-width: #{$param}px;
3
+ }
4
+
5
+ @mixin trans($duration:0.5s,$delay:0.2s) {
6
+ transition-property: opacity;
7
+ transition-duration: $duration;
8
+ transition-delay: $delay;
9
+ transition-timing-function: ease-in-out;
10
+ }