@tetacom/svg-charts 1.0.1

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 (216) hide show
  1. package/.browserslistrc +16 -0
  2. package/README.md +24 -0
  3. package/dist/README.md +24 -0
  4. package/dist/chart/base/series-base.component.d.ts +22 -0
  5. package/dist/chart/chart/chart.component.d.ts +29 -0
  6. package/dist/chart/chart-container/chart-container.component.d.ts +42 -0
  7. package/dist/chart/chart-container/gridlines/gridlines.component.d.ts +23 -0
  8. package/dist/chart/chart-container/plotband/plotband.component.d.ts +33 -0
  9. package/dist/chart/chart-container/plotline/plotline.component.d.ts +30 -0
  10. package/dist/chart/chart-container/series/bar/bar-series.component.d.ts +25 -0
  11. package/dist/chart/chart-container/series/line/line-series.component.d.ts +28 -0
  12. package/dist/chart/chart-container/series-host/series-host.component.d.ts +20 -0
  13. package/dist/chart/chart-container/tooltip/tooltip.component.d.ts +29 -0
  14. package/dist/chart/chart-container/x-axis/x-axis.component.d.ts +23 -0
  15. package/dist/chart/chart-container/y-axis/y-axis.component.d.ts +24 -0
  16. package/dist/chart/chart.module.d.ts +22 -0
  17. package/dist/chart/core/axis/axis.d.ts +54 -0
  18. package/dist/chart/core/axis/builders/axis-size-builder.d.ts +8 -0
  19. package/dist/chart/core/axis/builders/extremes-builder.d.ts +7 -0
  20. package/dist/chart/core/axis/builders/public-api.d.ts +2 -0
  21. package/dist/chart/core/utils/generate-ticks.d.ts +1 -0
  22. package/dist/chart/core/utils/get-text-width.d.ts +1 -0
  23. package/dist/chart/core/utils/public-api.d.ts +2 -0
  24. package/dist/chart/directives/brushable.directive.d.ts +17 -0
  25. package/dist/chart/directives/zoomable.directive.d.ts +20 -0
  26. package/dist/chart/legend/legend.component.d.ts +14 -0
  27. package/dist/chart/model/axis-options.d.ts +17 -0
  28. package/dist/chart/model/base-point.d.ts +9 -0
  29. package/dist/chart/model/chart-bounds.d.ts +12 -0
  30. package/dist/chart/model/enum/axis-orientation.d.ts +4 -0
  31. package/dist/chart/model/enum/axis-type.d.ts +7 -0
  32. package/dist/chart/model/enum/brush-type.d.ts +5 -0
  33. package/dist/chart/model/enum/drag-point-type.d.ts +5 -0
  34. package/dist/chart/model/enum/series-type.d.ts +4 -0
  35. package/dist/chart/model/enum/tooltip-tracking.d.ts +4 -0
  36. package/dist/chart/model/enum/zoom-type.d.ts +5 -0
  37. package/dist/chart/model/i-broadcast-message.d.ts +5 -0
  38. package/dist/chart/model/i-builder.d.ts +3 -0
  39. package/dist/chart/model/i-chart-config.d.ts +32 -0
  40. package/dist/chart/model/i-chart-event.d.ts +4 -0
  41. package/dist/chart/model/i-display-tooltip.d.ts +6 -0
  42. package/dist/chart/model/i-point-move.d.ts +6 -0
  43. package/dist/chart/model/marker-options.d.ts +7 -0
  44. package/dist/chart/model/plotband.d.ts +31 -0
  45. package/dist/chart/model/plotline.d.ts +19 -0
  46. package/dist/chart/model/series.d.ts +17 -0
  47. package/dist/chart/model/svg-attributes.d.ts +14 -0
  48. package/dist/chart/model/tooltip-options.d.ts +8 -0
  49. package/dist/chart/service/axes.service.d.ts +11 -0
  50. package/dist/chart/service/broadcast.service.d.ts +11 -0
  51. package/dist/chart/service/brush.service.d.ts +17 -0
  52. package/dist/chart/service/chart.service.d.ts +38 -0
  53. package/dist/chart/service/scale.service.d.ts +14 -0
  54. package/dist/chart/service/zoom.service.d.ts +25 -0
  55. package/dist/esm2020/chart/base/series-base.component.mjs +34 -0
  56. package/dist/esm2020/chart/chart/chart.component.mjs +73 -0
  57. package/dist/esm2020/chart/chart-container/chart-container.component.mjs +151 -0
  58. package/dist/esm2020/chart/chart-container/gridlines/gridlines.component.mjs +41 -0
  59. package/dist/esm2020/chart/chart-container/plotband/plotband.component.mjs +139 -0
  60. package/dist/esm2020/chart/chart-container/plotline/plotline.component.mjs +79 -0
  61. package/dist/esm2020/chart/chart-container/series/bar/bar-series.component.mjs +48 -0
  62. package/dist/esm2020/chart/chart-container/series/line/line-series.component.mjs +148 -0
  63. package/dist/esm2020/chart/chart-container/series-host/series-host.component.mjs +59 -0
  64. package/dist/esm2020/chart/chart-container/tooltip/tooltip.component.mjs +81 -0
  65. package/dist/esm2020/chart/chart-container/x-axis/x-axis.component.mjs +56 -0
  66. package/dist/esm2020/chart/chart-container/y-axis/y-axis.component.mjs +63 -0
  67. package/dist/esm2020/chart/chart.module.mjs +62 -0
  68. package/dist/esm2020/chart/core/axis/axis.mjs +96 -0
  69. package/dist/esm2020/chart/core/axis/builders/axis-size-builder.mjs +24 -0
  70. package/dist/esm2020/chart/core/axis/builders/extremes-builder.mjs +32 -0
  71. package/dist/esm2020/chart/core/axis/builders/public-api.mjs +3 -0
  72. package/dist/esm2020/chart/core/utils/generate-ticks.mjs +11 -0
  73. package/dist/esm2020/chart/core/utils/get-text-width.mjs +6 -0
  74. package/dist/esm2020/chart/core/utils/public-api.mjs +3 -0
  75. package/dist/esm2020/chart/directives/brushable.directive.mjs +28 -0
  76. package/dist/esm2020/chart/directives/zoomable.directive.mjs +37 -0
  77. package/dist/esm2020/chart/legend/legend.component.mjs +30 -0
  78. package/dist/esm2020/chart/model/axis-options.mjs +2 -0
  79. package/dist/esm2020/chart/model/base-point.mjs +2 -0
  80. package/dist/esm2020/chart/model/chart-bounds.mjs +13 -0
  81. package/dist/esm2020/chart/model/enum/axis-orientation.mjs +6 -0
  82. package/dist/esm2020/chart/model/enum/axis-type.mjs +9 -0
  83. package/dist/esm2020/chart/model/enum/brush-type.mjs +7 -0
  84. package/dist/esm2020/chart/model/enum/drag-point-type.mjs +7 -0
  85. package/dist/esm2020/chart/model/enum/series-type.mjs +6 -0
  86. package/dist/esm2020/chart/model/enum/tooltip-tracking.mjs +6 -0
  87. package/dist/esm2020/chart/model/enum/zoom-type.mjs +7 -0
  88. package/dist/esm2020/chart/model/i-broadcast-message.mjs +2 -0
  89. package/dist/esm2020/chart/model/i-builder.mjs +2 -0
  90. package/dist/esm2020/chart/model/i-chart-config.mjs +2 -0
  91. package/dist/esm2020/chart/model/i-chart-event.mjs +2 -0
  92. package/dist/esm2020/chart/model/i-display-tooltip.mjs +2 -0
  93. package/dist/esm2020/chart/model/i-point-move.mjs +2 -0
  94. package/dist/esm2020/chart/model/marker-options.mjs +2 -0
  95. package/dist/esm2020/chart/model/plotband.mjs +16 -0
  96. package/dist/esm2020/chart/model/plotline.mjs +12 -0
  97. package/dist/esm2020/chart/model/series.mjs +2 -0
  98. package/dist/esm2020/chart/model/svg-attributes.mjs +2 -0
  99. package/dist/esm2020/chart/model/tooltip-options.mjs +2 -0
  100. package/dist/esm2020/chart/service/axes.service.mjs +29 -0
  101. package/dist/esm2020/chart/service/broadcast.service.mjs +25 -0
  102. package/dist/esm2020/chart/service/brush.service.mjs +67 -0
  103. package/dist/esm2020/chart/service/chart.service.mjs +76 -0
  104. package/dist/esm2020/chart/service/scale.service.mjs +64 -0
  105. package/dist/esm2020/chart/service/zoom.service.mjs +117 -0
  106. package/dist/esm2020/public-api.mjs +7 -0
  107. package/dist/esm2020/tetacom-svg-charts.mjs +5 -0
  108. package/dist/fesm2015/tetacom-svg-charts.mjs +1589 -0
  109. package/dist/fesm2015/tetacom-svg-charts.mjs.map +1 -0
  110. package/dist/fesm2020/tetacom-svg-charts.mjs +1575 -0
  111. package/dist/fesm2020/tetacom-svg-charts.mjs.map +1 -0
  112. package/dist/package.json +35 -0
  113. package/dist/public-api.d.ts +3 -0
  114. package/dist/tetacom-svg-charts.d.ts +5 -0
  115. package/karma.conf.js +44 -0
  116. package/ng-package.json +7 -0
  117. package/package.json +15 -0
  118. package/src/chart/Chart.stories.ts +397 -0
  119. package/src/chart/base/series-base.component.ts +41 -0
  120. package/src/chart/chart/chart.component.html +5 -0
  121. package/src/chart/chart/chart.component.scss +6 -0
  122. package/src/chart/chart/chart.component.spec.ts +25 -0
  123. package/src/chart/chart/chart.component.ts +97 -0
  124. package/src/chart/chart-container/chart-container.component.html +78 -0
  125. package/src/chart/chart-container/chart-container.component.scss +15 -0
  126. package/src/chart/chart-container/chart-container.component.spec.ts +25 -0
  127. package/src/chart/chart-container/chart-container.component.ts +242 -0
  128. package/src/chart/chart-container/gridlines/gridlines.component.html +7 -0
  129. package/src/chart/chart-container/gridlines/gridlines.component.scss +8 -0
  130. package/src/chart/chart-container/gridlines/gridlines.component.spec.ts +25 -0
  131. package/src/chart/chart-container/gridlines/gridlines.component.ts +55 -0
  132. package/src/chart/chart-container/plotband/plotband.component.html +58 -0
  133. package/src/chart/chart-container/plotband/plotband.component.scss +13 -0
  134. package/src/chart/chart-container/plotband/plotband.component.spec.ts +25 -0
  135. package/src/chart/chart-container/plotband/plotband.component.ts +206 -0
  136. package/src/chart/chart-container/plotline/plotline.component.html +22 -0
  137. package/src/chart/chart-container/plotline/plotline.component.scss +6 -0
  138. package/src/chart/chart-container/plotline/plotline.component.spec.ts +25 -0
  139. package/src/chart/chart-container/plotline/plotline.component.ts +113 -0
  140. package/src/chart/chart-container/series/bar/bar-series.component.html +3 -0
  141. package/src/chart/chart-container/series/bar/bar-series.component.scss +0 -0
  142. package/src/chart/chart-container/series/bar/bar-series.component.ts +71 -0
  143. package/src/chart/chart-container/series/line/line-series.component.html +38 -0
  144. package/src/chart/chart-container/series/line/line-series.component.scss +9 -0
  145. package/src/chart/chart-container/series/line/line-series.component.spec.ts +25 -0
  146. package/src/chart/chart-container/series/line/line-series.component.ts +245 -0
  147. package/src/chart/chart-container/series-host/series-host.component.ts +80 -0
  148. package/src/chart/chart-container/tooltip/tooltip.component.html +14 -0
  149. package/src/chart/chart-container/tooltip/tooltip.component.scss +7 -0
  150. package/src/chart/chart-container/tooltip/tooltip.component.spec.ts +25 -0
  151. package/src/chart/chart-container/tooltip/tooltip.component.ts +134 -0
  152. package/src/chart/chart-container/x-axis/x-axis.component.html +1 -0
  153. package/src/chart/chart-container/x-axis/x-axis.component.scss +3 -0
  154. package/src/chart/chart-container/x-axis/x-axis.component.spec.ts +25 -0
  155. package/src/chart/chart-container/x-axis/x-axis.component.ts +80 -0
  156. package/src/chart/chart-container/y-axis/y-axis.component.html +4 -0
  157. package/src/chart/chart-container/y-axis/y-axis.component.scss +13 -0
  158. package/src/chart/chart-container/y-axis/y-axis.component.spec.ts +25 -0
  159. package/src/chart/chart-container/y-axis/y-axis.component.ts +90 -0
  160. package/src/chart/chart.module.ts +40 -0
  161. package/src/chart/core/axis/axis.ts +132 -0
  162. package/src/chart/core/axis/builders/axis-size-builder.ts +37 -0
  163. package/src/chart/core/axis/builders/extremes-builder.ts +45 -0
  164. package/src/chart/core/axis/builders/public-api.ts +2 -0
  165. package/src/chart/core/utils/generate-ticks.ts +14 -0
  166. package/src/chart/core/utils/get-text-width.ts +10 -0
  167. package/src/chart/core/utils/public-api.ts +2 -0
  168. package/src/chart/default/default-chart-config.ts +12 -0
  169. package/src/chart/directives/brushable.directive.ts +30 -0
  170. package/src/chart/directives/zoomable.directive.ts +31 -0
  171. package/src/chart/legend/legend.component.html +6 -0
  172. package/src/chart/legend/legend.component.scss +20 -0
  173. package/src/chart/legend/legend.component.spec.ts +25 -0
  174. package/src/chart/legend/legend.component.ts +35 -0
  175. package/src/chart/model/axis-options.ts +18 -0
  176. package/src/chart/model/base-point.ts +10 -0
  177. package/src/chart/model/chart-bounds.ts +18 -0
  178. package/src/chart/model/enum/axis-orientation.ts +4 -0
  179. package/src/chart/model/enum/axis-type.ts +7 -0
  180. package/src/chart/model/enum/brush-type.ts +5 -0
  181. package/src/chart/model/enum/drag-point-type.ts +5 -0
  182. package/src/chart/model/enum/public-api.ts +7 -0
  183. package/src/chart/model/enum/series-type.ts +4 -0
  184. package/src/chart/model/enum/tooltip-tracking.ts +4 -0
  185. package/src/chart/model/enum/zoom-type.ts +5 -0
  186. package/src/chart/model/i-broadcast-message.ts +5 -0
  187. package/src/chart/model/i-builder.ts +3 -0
  188. package/src/chart/model/i-chart-config.ts +33 -0
  189. package/src/chart/model/i-chart-event.ts +4 -0
  190. package/src/chart/model/i-display-tooltip.ts +7 -0
  191. package/src/chart/model/i-drag-event.ts +5 -0
  192. package/src/chart/model/i-point-move.ts +7 -0
  193. package/src/chart/model/marker-options.ts +8 -0
  194. package/src/chart/model/plotband.ts +45 -0
  195. package/src/chart/model/plotline.ts +29 -0
  196. package/src/chart/model/public-api.ts +0 -0
  197. package/src/chart/model/series.ts +18 -0
  198. package/src/chart/model/svg-attributes.ts +14 -0
  199. package/src/chart/model/tooltip-options.ts +37 -0
  200. package/src/chart/service/axes.service.spec.ts +16 -0
  201. package/src/chart/service/axes.service.ts +27 -0
  202. package/src/chart/service/broadcast.service.spec.ts +16 -0
  203. package/src/chart/service/broadcast.service.ts +24 -0
  204. package/src/chart/service/brush.service.spec.ts +16 -0
  205. package/src/chart/service/brush.service.ts +87 -0
  206. package/src/chart/service/chart.service.spec.ts +16 -0
  207. package/src/chart/service/chart.service.ts +100 -0
  208. package/src/chart/service/scale.service.spec.ts +16 -0
  209. package/src/chart/service/scale.service.ts +74 -0
  210. package/src/chart/service/zoom.service.spec.ts +16 -0
  211. package/src/chart/service/zoom.service.ts +153 -0
  212. package/src/public-api.ts +7 -0
  213. package/src/test.ts +27 -0
  214. package/tsconfig.lib.json +15 -0
  215. package/tsconfig.lib.prod.json +10 -0
  216. package/tsconfig.spec.json +17 -0
@@ -0,0 +1,242 @@
1
+ import {
2
+ AfterContentChecked,
3
+ AfterViewChecked,
4
+ ChangeDetectionStrategy,
5
+ ChangeDetectorRef,
6
+ Component,
7
+ ElementRef,
8
+ Input,
9
+ OnChanges,
10
+ OnInit,
11
+ SimpleChanges,
12
+ } from '@angular/core';
13
+ import { IChartConfig } from '../model/i-chart-config';
14
+ import { ChartService } from '../service/chart.service';
15
+ import { Observable, tap } from 'rxjs';
16
+ import { throttleTime } from 'rxjs/operators';
17
+ import { AxesService } from '../service/axes.service';
18
+ import { Axis } from '../core/axis/axis';
19
+ import { AxisOrientation } from '../model/enum/axis-orientation';
20
+
21
+ type Opposite = boolean;
22
+
23
+ @Component({
24
+ selector: 'teta-chart-container',
25
+ templateUrl: './chart-container.component.html',
26
+ styleUrls: ['./chart-container.component.scss'],
27
+ changeDetection: ChangeDetectionStrategy.OnPush,
28
+ })
29
+ export class ChartContainerComponent
30
+ implements OnInit, OnChanges, AfterViewChecked, AfterContentChecked
31
+ {
32
+ @Input() config: IChartConfig;
33
+
34
+ yAxes: Map<number, Axis>;
35
+ xAxes: Map<number, Axis>;
36
+ size: Observable<DOMRect>;
37
+
38
+ private _observer: ResizeObserver;
39
+ private uniqId: string;
40
+
41
+ private filterPositionMap = new Map<
42
+ Opposite,
43
+ (axis: Axis) => (_: Axis) => boolean
44
+ >()
45
+ .set(
46
+ true,
47
+ (axis) => (_: Axis) =>
48
+ _.options.opposite && _.options.visible && axis.index <= _.index
49
+ )
50
+ .set(
51
+ false,
52
+ (axis) => (_: Axis) =>
53
+ _.options.opposite !== true &&
54
+ _.options.visible &&
55
+ _.index <= axis.index
56
+ );
57
+
58
+ constructor(
59
+ private _svc: ChartService,
60
+ private _cdr: ChangeDetectorRef,
61
+ private _elementRef: ElementRef,
62
+ private _axesService: AxesService
63
+ ) {
64
+ this.size = this._svc.size.pipe(
65
+ throttleTime(100, undefined, { trailing: true }),
66
+ tap(() => {
67
+ setTimeout(() => {
68
+ this._cdr.detectChanges();
69
+ });
70
+ })
71
+ );
72
+
73
+ this.yAxes = this._axesService.yAxis;
74
+ this.xAxes = this._axesService.xAxis;
75
+
76
+ this.uniqId = (Date.now() + Math.random()).toString(36);
77
+ }
78
+
79
+ ngOnInit(): void {
80
+ this._observer = new ResizeObserver((entries: ResizeObserverEntry[]) => {
81
+ this._svc.setSize(entries[0].contentRect);
82
+ });
83
+ this._observer.observe(this._elementRef.nativeElement);
84
+
85
+ this._svc.init(this.config);
86
+ }
87
+
88
+ private sumSize = (acc, curr) => acc + curr.selfSize;
89
+
90
+ private oppositeFilter(axis?: Axis) {
91
+ return (_) =>
92
+ _.options.opposite && _.options.visible && axis.index <= _.index;
93
+ }
94
+
95
+ private nonOppositeFilter(axis?: Axis) {
96
+ return (_) =>
97
+ _.options.opposite !== true && _.options.visible && _.index <= axis.index;
98
+ }
99
+
100
+ getVisibleRect(size: DOMRect) {
101
+ const yAxesArray = [...this.yAxes.values()];
102
+ const xAxesArray = [...this.xAxes.values()];
103
+
104
+ const left = yAxesArray
105
+ .filter((_) => _.options.opposite !== true && _.options.visible)
106
+ .reduce(this.sumSize, 0);
107
+
108
+ const right = yAxesArray
109
+ .filter((_) => _.options.opposite && _.options.visible)
110
+ .reduce(this.sumSize, 0);
111
+
112
+ const bottom = xAxesArray
113
+ .filter((_) => _.options.opposite !== true && _.options.visible)
114
+ .reduce(this.sumSize, 0);
115
+
116
+ const top = xAxesArray
117
+ .filter((_) => _.options.opposite && _.options.visible)
118
+ .reduce(this.sumSize, 0);
119
+
120
+ const rect = {
121
+ left,
122
+ top,
123
+ width: size.width - left - right + 1,
124
+ height: size.height - top - bottom + 1,
125
+ };
126
+
127
+ return rect;
128
+ }
129
+
130
+ getYAxisTranslate(axis: Axis, size: DOMRect): string {
131
+ const yAxesArray = [...this.yAxes.values()];
132
+
133
+ const translateOpposite = yAxesArray
134
+ .filter(this.nonOppositeFilter(axis))
135
+ .reduce(this.sumSize, 0);
136
+
137
+ const translateNonOpposite = yAxesArray
138
+ .filter(this.oppositeFilter(axis))
139
+ .reduce(this.sumSize, 0);
140
+
141
+ return `translate(${
142
+ axis.options.opposite
143
+ ? size.width - translateNonOpposite
144
+ : translateOpposite
145
+ }, 0)`;
146
+ }
147
+
148
+ getXAxisTranslate(axis: Axis, size: DOMRect): string {
149
+ const xAxesArray = [...this.xAxes.values()];
150
+
151
+ const translateNonOpposite = xAxesArray
152
+ .filter(this.nonOppositeFilter(axis))
153
+ .reduce(this.sumSize, 0);
154
+
155
+ const translateOpposite = xAxesArray
156
+ .filter(this.oppositeFilter(axis))
157
+ .reduce(this.sumSize, 0);
158
+
159
+ return `translate(0, ${
160
+ axis.options.opposite
161
+ ? translateOpposite
162
+ : size.height - translateNonOpposite
163
+ })`;
164
+ }
165
+
166
+ getTranslate(axis?: Axis, size?: DOMRect): string {
167
+ const xAxesArray = [...this.xAxes.values()];
168
+ const yAxesArray = [...this.yAxes.values()];
169
+
170
+ const oppositeFilter = this.filterPositionMap.get(true);
171
+ const nonOppositeFilter = this.filterPositionMap.get(false);
172
+
173
+ const oppositeOffsetY = yAxesArray.filter(oppositeFilter(axis));
174
+ const nonOppositeOffsetY = yAxesArray.filter(nonOppositeFilter(axis));
175
+
176
+ const oppositeOffsetX = xAxesArray.filter(oppositeFilter(axis));
177
+ const nonOppositeOffsetX = xAxesArray.filter(nonOppositeFilter(axis));
178
+
179
+ const oppositeTranslateY = oppositeOffsetY.reduce(
180
+ (acc, curr) => acc + curr.selfSize,
181
+ 0
182
+ );
183
+ const nonOppisteTranslateY = nonOppositeOffsetY.reduce(
184
+ (acc, curr) => acc + curr.selfSize,
185
+ 0
186
+ );
187
+
188
+ const oppositeTranslateX = oppositeOffsetX.reduce(
189
+ (acc, curr) => acc + curr.selfSize,
190
+ 0
191
+ );
192
+
193
+ const nonOppisteTranslateX = nonOppositeOffsetX.reduce(
194
+ (acc, curr) => acc + curr.selfSize,
195
+ 0
196
+ );
197
+
198
+ const left = yAxesArray
199
+ .filter((_) => _.options.visible && _.options.opposite !== true)
200
+ .reduce((acc, curr) => acc + curr.selfSize, 0);
201
+
202
+ const top = xAxesArray
203
+ .filter((_) => _.options.visible && _.options.opposite === true)
204
+ .reduce((acc, curr) => acc + curr.selfSize, 0);
205
+
206
+ if (axis.orientation === AxisOrientation.x) {
207
+ return `translate(${left}, ${
208
+ axis.options.opposite
209
+ ? oppositeTranslateX
210
+ : size.height - nonOppisteTranslateX
211
+ })`;
212
+ }
213
+
214
+ if (axis.orientation === AxisOrientation.y) {
215
+ return `translate(${
216
+ axis.options.opposite
217
+ ? size.width - oppositeTranslateY
218
+ : nonOppisteTranslateY
219
+ }, ${top})`;
220
+ }
221
+
222
+ return 'translate(0, 0)';
223
+ }
224
+
225
+ mouseMove(event) {
226
+ this._svc.setPointerMove(event);
227
+ }
228
+
229
+ mouseLeave(event) {
230
+ this._svc.setPointerMove(event);
231
+ }
232
+
233
+ id(): string {
234
+ return this.uniqId;
235
+ }
236
+
237
+ ngAfterContentChecked(): void {}
238
+
239
+ ngAfterViewChecked(): void {}
240
+
241
+ ngOnChanges(changes: SimpleChanges): void {}
242
+ }
@@ -0,0 +1,7 @@
1
+ <ng-container *ngFor="let tick of tickYValues">
2
+ <svg:line [attr.x1]="0" stroke="red" [attr.y1]="y(tick)" [attr.x2]="size?.width" [attr.y2]="y(tick)"></svg:line>
3
+ </ng-container>
4
+
5
+ <ng-container *ngFor="let tick of tickXValues">
6
+ <svg:line [attr.x1]="x(tick)" stroke="red" [attr.y1]="0" [attr.x2]="x(tick)" [attr.y2]="size?.height"></svg:line>
7
+ </ng-container>
@@ -0,0 +1,8 @@
1
+ :host {
2
+ shape-rendering: crispEdges;
3
+ }
4
+
5
+ :host line {
6
+ stroke-dasharray: 1,4;
7
+ stroke: var(--color-text-20);
8
+ }
@@ -0,0 +1,25 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { GridlinesComponent } from './gridlines.component';
4
+
5
+ describe('GridlinesComponent', () => {
6
+ let component: GridlinesComponent;
7
+ let fixture: ComponentFixture<GridlinesComponent>;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ declarations: [ GridlinesComponent ]
12
+ })
13
+ .compileComponents();
14
+ });
15
+
16
+ beforeEach(() => {
17
+ fixture = TestBed.createComponent(GridlinesComponent);
18
+ component = fixture.componentInstance;
19
+ fixture.detectChanges();
20
+ });
21
+
22
+ it('should create', () => {
23
+ expect(component).toBeTruthy();
24
+ });
25
+ });
@@ -0,0 +1,55 @@
1
+ import {
2
+ AfterViewInit,
3
+ ChangeDetectorRef,
4
+ Component,
5
+ Input,
6
+ OnInit,
7
+ } from '@angular/core';
8
+ import { ScaleService } from '../../service/scale.service';
9
+ import { AxesService } from '../../service/axes.service';
10
+
11
+ import { merge, tap } from 'rxjs';
12
+ import { ChartService } from '../../service/chart.service';
13
+ import { ZoomService } from '../../service/zoom.service';
14
+
15
+ @Component({
16
+ selector: '[teta-gridlines]',
17
+ templateUrl: './gridlines.component.html',
18
+ styleUrls: ['./gridlines.component.scss'],
19
+ })
20
+ export class GridlinesComponent implements OnInit {
21
+ @Input() size: DOMRect;
22
+ tickYValues: number[];
23
+ tickXValues: number[];
24
+ y: any;
25
+ x: any;
26
+
27
+ constructor(
28
+ private scaleService: ScaleService,
29
+ private axesService: AxesService,
30
+ private chartService: ChartService,
31
+ private zoomService: ZoomService,
32
+ private cdr: ChangeDetectorRef
33
+ ) {
34
+ merge(this.chartService.size, this.zoomService.zoomed)
35
+ .pipe(
36
+ tap(() => {
37
+ this.draw();
38
+ this.cdr.detectChanges();
39
+ })
40
+ )
41
+ .subscribe();
42
+ }
43
+
44
+ draw() {
45
+ this.y = this.scaleService.yScales.get(0);
46
+ this.x = this.scaleService.xScales.get(0);
47
+
48
+ this.tickYValues = this.y.ticks();
49
+ this.tickXValues = this.x.ticks();
50
+ }
51
+
52
+ ngOnInit(): void {
53
+ this.draw();
54
+ }
55
+ }
@@ -0,0 +1,58 @@
1
+ <svg:rect class="plotband"
2
+ [attr.fill]="getFill(plotband)"
3
+ [attr.opacity]="plotband.style?.plotband?.opacity"
4
+ [attr.height]="axis.orientation === orientation.x ? height : bandSize"
5
+ [attr.width]="axis.orientation === orientation.x ? bandSize : width"
6
+ [attr.y]="axis.orientation === orientation.y ? to : null"
7
+ [attr.x]="axis.orientation === orientation.x ? from : null">
8
+ </svg:rect>
9
+
10
+ <svg:line class="display-grabber"
11
+ [attr.stroke]="plotband.style?.grabbers?.stroke || 'red'"
12
+ [attr.stroke-width]="plotband.style?.grabbers?.strokeWidth || 4"
13
+ [attr.stroke-dasharray]="plotband.style?.grabbers?.strokeDasharray"
14
+ [attr.x1]="axis.orientation === orientation.x ? from : 0"
15
+ [attr.x2]="axis.orientation === orientation.x ? from : width"
16
+ [attr.data-grabber]="'from'"
17
+ [attr.y1]="axis.orientation === orientation.x ? 0 : from"
18
+ [attr.y2]="axis.orientation === orientation.x ? height : from">
19
+ </svg:line>
20
+
21
+ <svg:line class="display-grabber"
22
+ [attr.stroke]="plotband.style?.grabbers?.stroke || 'red'"
23
+ [attr.stroke-width]="plotband.style?.grabbers?.strokeWidth || 4"
24
+ [attr.stroke-dasharray]="plotband.style?.grabbers?.strokeDasharray"
25
+ [attr.x1]="axis.orientation === orientation.x ? to : 0"
26
+ [attr.x2]="axis.orientation === orientation.x ? to : width"
27
+ [attr.data-grabber]="'to'"
28
+ [attr.y1]="axis.orientation === orientation.x ? 0 : to"
29
+ [attr.y2]="axis.orientation === orientation.x ? height : to">
30
+ </svg:line>
31
+
32
+ <svg:line class="grabber"
33
+ [class.x-grabber]="axis.orientation === orientation.x"
34
+ [class.y-grabber]="axis.orientation === orientation.y"
35
+ [attr.stroke]="'red'"
36
+ [attr.stroke-width]="8"
37
+ opacity="0"
38
+ [attr.x1]="axis.orientation === orientation.x ? from : 0"
39
+ [attr.x2]="axis.orientation === orientation.x ? from : width"
40
+ [attr.data-grabber]="'from'"
41
+ [attr.y1]="axis.orientation === orientation.x ? 0 : from"
42
+ [attr.y2]="axis.orientation === orientation.x ? height : from">
43
+ </svg:line>
44
+
45
+ <svg:line class="grabber"
46
+ [class.x-grabber]="axis.orientation === orientation.x"
47
+ [class.y-grabber]="axis.orientation === orientation.y"
48
+ [attr.stroke]="'red'"
49
+ [attr.stroke-width]="8"
50
+ opacity="0"
51
+ [attr.x1]="axis.orientation === orientation.x ? to : 0"
52
+ [attr.x2]="axis.orientation === orientation.x ? to : width"
53
+ [attr.data-grabber]="'to'"
54
+ [attr.y1]="axis.orientation === orientation.x ? 0 : to"
55
+ [attr.y2]="axis.orientation === orientation.x ? height : to">
56
+ </svg:line>
57
+
58
+
@@ -0,0 +1,13 @@
1
+ :host rect:hover {
2
+ cursor: grab;
3
+ }
4
+ :host rect:active {
5
+ cursor: grabbing;
6
+ }
7
+
8
+ :host .x-grabber {
9
+ cursor: col-resize;
10
+ }
11
+ :host .y-grabber {
12
+ cursor: row-resize;
13
+ }
@@ -0,0 +1,25 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { PlotbandComponent } from './plotband.component';
4
+
5
+ describe('PlotbandComponent', () => {
6
+ let component: PlotbandComponent;
7
+ let fixture: ComponentFixture<PlotbandComponent>;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ declarations: [ PlotbandComponent ]
12
+ })
13
+ .compileComponents();
14
+ });
15
+
16
+ beforeEach(() => {
17
+ fixture = TestBed.createComponent(PlotbandComponent);
18
+ component = fixture.componentInstance;
19
+ fixture.detectChanges();
20
+ });
21
+
22
+ it('should create', () => {
23
+ expect(component).toBeTruthy();
24
+ });
25
+ });
@@ -0,0 +1,206 @@
1
+ import {
2
+ ChangeDetectionStrategy,
3
+ ChangeDetectorRef,
4
+ Component,
5
+ ElementRef,
6
+ Input,
7
+ OnInit,
8
+ } from '@angular/core';
9
+
10
+ import * as d3 from 'd3';
11
+ import { Plotband } from '../../model/plotband';
12
+ import { ScaleService } from '../../service/scale.service';
13
+
14
+ import { Axis } from '../../core/axis/axis';
15
+ import { ZoomService } from '../../service/zoom.service';
16
+ import { AxisOrientation } from '../../model/enum/axis-orientation';
17
+ import { IChartEvent } from '../../model/i-chart-event';
18
+ import { ChartService } from '../../service/chart.service';
19
+
20
+ @Component({
21
+ selector: '[teta-plot-band]',
22
+ templateUrl: './plotband.component.html',
23
+ styleUrls: ['./plotband.component.scss'],
24
+ changeDetection: ChangeDetectionStrategy.OnPush,
25
+ })
26
+ export class PlotbandComponent implements OnInit {
27
+ @Input() plotband: Plotband;
28
+ @Input() axis: Axis;
29
+ @Input() size: DOMRect;
30
+ orientation = AxisOrientation;
31
+
32
+ private scale: any;
33
+ domain: number[];
34
+
35
+ constructor(
36
+ private scaleService: ScaleService,
37
+ private zoomService: ZoomService,
38
+ private chartService: ChartService,
39
+ private cdr: ChangeDetectorRef,
40
+ private element: ElementRef
41
+ ) {
42
+ this.zoomService.zoomed.subscribe(() => {
43
+ this.scale = this.scaleService[
44
+ this.axis.orientation === AxisOrientation.x ? 'xScales' : 'yScales'
45
+ ].get(this.axis.index);
46
+ this.cdr.detectChanges();
47
+ });
48
+ }
49
+
50
+ emit(event: IChartEvent<Plotband>) {
51
+ this.chartService.emitPlotband(event);
52
+ }
53
+
54
+ ngOnInit(): void {
55
+ this.scale = this.scaleService[
56
+ this.axis.orientation === AxisOrientation.x ? 'xScales' : 'yScales'
57
+ ].get(this.axis.index);
58
+
59
+ this.domain = this.scale.domain();
60
+
61
+ const plotbandElement = d3
62
+ .select(this.element.nativeElement)
63
+ .select('.plotband');
64
+
65
+ const grabElements = d3
66
+ .select(this.element.nativeElement)
67
+ .selectAll('.grabber');
68
+
69
+ const drag = d3
70
+ .drag()
71
+ .subject(() => {
72
+ if (this.axis.orientation === AxisOrientation.x) {
73
+ return { x: plotbandElement.attr('x') };
74
+ }
75
+
76
+ if (this.axis.orientation === AxisOrientation.y) {
77
+ return { y: plotbandElement.attr('y') };
78
+ }
79
+ })
80
+ .on(
81
+ 'start drag end',
82
+ (event: d3.D3DragEvent<any, Plotband, any>, d: Plotband) => {
83
+ requestAnimationFrame(() => {
84
+ let bandSize = parseFloat(
85
+ plotbandElement.attr(
86
+ this.axis.orientation === AxisOrientation.x ? 'width' : 'height'
87
+ )
88
+ );
89
+
90
+ d.to = this.scale.invert(
91
+ event[AxisOrientation[this.axis.orientation]] +
92
+ (this.axis.orientation === AxisOrientation.x ? bandSize : 0)
93
+ );
94
+
95
+ d.from = this.scale.invert(
96
+ event[AxisOrientation[this.axis.orientation]] +
97
+ (this.axis.orientation === AxisOrientation.y ? bandSize : 0)
98
+ );
99
+
100
+ this.emit({
101
+ event,
102
+ target: d,
103
+ });
104
+
105
+ this.cdr.detectChanges();
106
+ });
107
+ }
108
+ );
109
+
110
+ let grabberKey;
111
+
112
+ const resize = d3
113
+ .drag()
114
+ .on(
115
+ 'start drag end',
116
+ (event: d3.D3DragEvent<any, Plotband, any>, d: Plotband) => {
117
+ requestAnimationFrame(() => {
118
+ if (event?.type === 'start') {
119
+ const { grabber } = event?.sourceEvent?.target?.dataset;
120
+ grabberKey = grabber;
121
+ }
122
+
123
+ const min = Math.min(...this.domain);
124
+ const max = Math.max(...this.domain);
125
+
126
+ const minValue = d.min ?? min;
127
+ const maxValue = d.max ?? max;
128
+ d[grabberKey] = this.scale.invert(
129
+ event[AxisOrientation[this.axis.orientation]]
130
+ );
131
+
132
+ if (grabberKey === 'from') {
133
+ const borderMin = d.from <= minValue;
134
+
135
+ if (d.from >= d.to) {
136
+ d.from = d.to;
137
+ }
138
+
139
+ if (borderMin) {
140
+ d.from = minValue;
141
+ }
142
+ }
143
+
144
+ if (grabberKey === 'to') {
145
+ const borderMax = d.to >= maxValue;
146
+
147
+ if (borderMax) {
148
+ d.to = maxValue;
149
+ }
150
+
151
+ if (d.to <= d.from) {
152
+ d.to = d.from;
153
+ }
154
+ }
155
+
156
+ this.emit({
157
+ event,
158
+ target: d,
159
+ });
160
+
161
+ this.cdr.detectChanges();
162
+ });
163
+ }
164
+ );
165
+
166
+ plotbandElement.datum<Plotband>(this.plotband);
167
+ grabElements.datum<Plotband>(this.plotband);
168
+
169
+ if (this.plotband.draggable) {
170
+ plotbandElement.call(drag);
171
+ }
172
+
173
+ if (this.plotband.resizable) {
174
+ grabElements.call(resize);
175
+ }
176
+ }
177
+
178
+ get bandSize(): number {
179
+ return Math.abs(
180
+ this.scale(this.plotband.to) - this.scale(this.plotband.from)
181
+ );
182
+ }
183
+
184
+ get height(): number {
185
+ return this.size.height;
186
+ }
187
+
188
+ get width(): number {
189
+ return this.size.width;
190
+ }
191
+
192
+ get from(): number {
193
+ return this.scale(this.plotband.from);
194
+ }
195
+
196
+ get to(): number {
197
+ return this.scale(this.plotband.to);
198
+ }
199
+
200
+ getFill(d: Plotband): string {
201
+ if (d.style?.plotband?.patternImage) {
202
+ return `url(#${d.style.plotband?.patternImage})`;
203
+ }
204
+ return d.style.plotband?.fill;
205
+ }
206
+ }
@@ -0,0 +1,22 @@
1
+ <svg:line class="plotline"
2
+ [attr.stroke]="plotline.style?.stroke || 'red'"
3
+ [attr.stroke-width]="plotline.style?.strokeWidth || 4"
4
+ [attr.stroke-dasharray]="plotline.style?.strokeDasharray"
5
+ [attr.x1]="axis.orientation === orientation.x ? value : 0"
6
+ [attr.x2]="axis.orientation === orientation.x ? value : width"
7
+ [attr.y1]="axis.orientation === orientation.x ? 0 : value"
8
+ [attr.y2]="axis.orientation === orientation.x ? height : value">
9
+ </svg:line>
10
+
11
+ <svg:line class="grabber"
12
+
13
+ [class.x-grabber]="axis.orientation === orientation.x"
14
+ [class.y-grabber]="axis.orientation === orientation.y"
15
+ [attr.stroke]="'red'"
16
+ [attr.stroke-width]="8"
17
+ opacity="0"
18
+ [attr.x1]="axis.orientation === orientation.x ? value : 0"
19
+ [attr.x2]="axis.orientation === orientation.x ? value : width"
20
+ [attr.y1]="axis.orientation === orientation.x ? 0 : value"
21
+ [attr.y2]="axis.orientation === orientation.x ? height : value">
22
+ </svg:line>
@@ -0,0 +1,6 @@
1
+ :host .x-grabber {
2
+ cursor: col-resize;
3
+ }
4
+ :host .y-grabber {
5
+ cursor: row-resize;
6
+ }