@tetacom/svg-charts 1.2.3 → 1.2.4
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/chart/chart/chart.component.d.ts +2 -1
- package/chart/chart-container/chart-container.component.d.ts +3 -5
- package/chart/chart-container/series/linear-series-base.d.ts +1 -1
- package/chart/chart-container/series/scatter-series/scatter-series.component.d.ts +0 -1
- package/chart/chart-container/x-axis/x-axis.component.d.ts +2 -4
- package/chart/core/axis/axis.d.ts +3 -0
- package/chart/service/chart.service.d.ts +4 -0
- package/chart/service/scale.service.d.ts +2 -0
- package/esm2020/chart/chart/chart.component.mjs +10 -2
- package/esm2020/chart/chart-container/annotation/annotation.component.mjs +3 -3
- package/esm2020/chart/chart-container/chart-container.component.mjs +10 -12
- package/esm2020/chart/chart-container/gridlines/gridlines.component.mjs +7 -7
- package/esm2020/chart/chart-container/series/area-series/area-series.component.mjs +5 -5
- package/esm2020/chart/chart-container/series/bar/bar-series.component.mjs +5 -5
- package/esm2020/chart/chart-container/series/block-area-series/block-area-series.component.mjs +3 -3
- package/esm2020/chart/chart-container/series/block-series/block-series.component.mjs +3 -3
- package/esm2020/chart/chart-container/series/linear-series-base.mjs +19 -21
- package/esm2020/chart/chart-container/series/scatter-series/scatter-series.component.mjs +3 -3
- package/esm2020/chart/chart-container/x-axis/x-axis.component.mjs +3 -27
- package/esm2020/chart/chart-container/y-axis/y-axis.component.mjs +3 -3
- package/esm2020/chart/core/axis/axis.mjs +7 -1
- package/esm2020/chart/default/default-axis-config.mjs +2 -2
- package/esm2020/chart/directives/zoomable.directive.mjs +4 -3
- package/esm2020/chart/service/brush.service.mjs +16 -13
- package/esm2020/chart/service/chart.service.mjs +6 -1
- package/esm2020/chart/service/scale.service.mjs +134 -1
- package/esm2020/chart/service/zoom.service.mjs +2 -2
- package/fesm2015/tetacom-svg-charts.mjs +233 -99
- package/fesm2015/tetacom-svg-charts.mjs.map +1 -1
- package/fesm2020/tetacom-svg-charts.mjs +225 -98
- package/fesm2020/tetacom-svg-charts.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -7,9 +7,9 @@ import * as d3 from 'd3';
|
|
|
7
7
|
import { zoomIdentity } from 'd3';
|
|
8
8
|
import objectHash from 'object-hash';
|
|
9
9
|
import { maxIndex } from 'd3-array';
|
|
10
|
+
import { debounceTime, tap as tap$1 } from 'rxjs/operators';
|
|
10
11
|
import { tetaZoneFull } from '@tetacom/ng-components';
|
|
11
12
|
import * as i3 from '@angular/platform-browser';
|
|
12
|
-
import { tap as tap$1, debounceTime } from 'rxjs/operators';
|
|
13
13
|
|
|
14
14
|
var ZoomType;
|
|
15
15
|
(function (ZoomType) {
|
|
@@ -94,7 +94,7 @@ const defaultAxisConfig = {
|
|
|
94
94
|
scaleType: {
|
|
95
95
|
type: ScaleType.linear,
|
|
96
96
|
},
|
|
97
|
-
niceTicks:
|
|
97
|
+
niceTicks: false,
|
|
98
98
|
};
|
|
99
99
|
|
|
100
100
|
var SeriesType;
|
|
@@ -148,6 +148,7 @@ class ChartService {
|
|
|
148
148
|
this.chartContextMenu$ = new Subject();
|
|
149
149
|
this.annotationEvent$ = new Subject();
|
|
150
150
|
this.annotationMove$ = new Subject();
|
|
151
|
+
this.zoomInstance$ = new Subject();
|
|
151
152
|
this.id = of((Date.now() + Math.random()).toString(36));
|
|
152
153
|
this.config = this.config$.asObservable().pipe(withLatestFrom(this.id), map(this.setDefaults), map(this.setPreparationData), map(this.restoreLocalStorage), shareReplay({
|
|
153
154
|
bufferSize: 1,
|
|
@@ -174,6 +175,7 @@ class ChartService {
|
|
|
174
175
|
this.plotBandContextMenu = this.plotBandEvent$
|
|
175
176
|
.asObservable()
|
|
176
177
|
.pipe(filter((_) => _?.event?.type === 'contextmenu'));
|
|
178
|
+
this.zoomInstance = this.zoomInstance$.asObservable();
|
|
177
179
|
}
|
|
178
180
|
setConfig(config) {
|
|
179
181
|
this.clearTooltips();
|
|
@@ -240,6 +242,9 @@ class ChartService {
|
|
|
240
242
|
emitChartContextMenu(event) {
|
|
241
243
|
this.chartContextMenu$.next(event);
|
|
242
244
|
}
|
|
245
|
+
emitZoomInstance(event) {
|
|
246
|
+
this.zoomInstance$.next(event);
|
|
247
|
+
}
|
|
243
248
|
saveCookie(config) {
|
|
244
249
|
if (!config.name)
|
|
245
250
|
return;
|
|
@@ -361,7 +366,7 @@ class ZoomService {
|
|
|
361
366
|
this.scaleHashMap = new Map();
|
|
362
367
|
this.elementHashMap = new Map();
|
|
363
368
|
this.zoomHashMap = new Map();
|
|
364
|
-
this.zoomed$ = new BehaviorSubject(
|
|
369
|
+
this.zoomed$ = new BehaviorSubject({});
|
|
365
370
|
this.zoomed = this.zoomed$.asObservable().pipe(shareReplay({
|
|
366
371
|
bufferSize: 1,
|
|
367
372
|
refCount: true
|
|
@@ -567,6 +572,9 @@ class Axis {
|
|
|
567
572
|
setOriginDomain(domain) {
|
|
568
573
|
this._originDomain = domain;
|
|
569
574
|
}
|
|
575
|
+
setScale(scale) {
|
|
576
|
+
this._scale = scale;
|
|
577
|
+
}
|
|
570
578
|
setSelfSize() {
|
|
571
579
|
this._selfSize = new AxisSizeBuilder().build(this);
|
|
572
580
|
}
|
|
@@ -579,6 +587,9 @@ class Axis {
|
|
|
579
587
|
: this.chartConfig.yAxis[this.index];
|
|
580
588
|
this._options = options;
|
|
581
589
|
}
|
|
590
|
+
get scale() {
|
|
591
|
+
return this._scale;
|
|
592
|
+
}
|
|
582
593
|
get extremes() {
|
|
583
594
|
return this._extremes;
|
|
584
595
|
}
|
|
@@ -706,6 +717,139 @@ class ScaleService {
|
|
|
706
717
|
bufferSize: 1,
|
|
707
718
|
refCount: true,
|
|
708
719
|
}));
|
|
720
|
+
this.xMap = combineLatest([
|
|
721
|
+
this.chartService.size,
|
|
722
|
+
this.chartService.config,
|
|
723
|
+
this.zoomService.zoomed,
|
|
724
|
+
]).pipe(map((data) => {
|
|
725
|
+
const [size, config, zoom] = data;
|
|
726
|
+
const xAxisMap = new Map();
|
|
727
|
+
const yAxisMap = new Map();
|
|
728
|
+
config.yAxis.map((_, index) => {
|
|
729
|
+
yAxisMap.set(index, Axis.createAxis(AxisOrientation.y, config, index));
|
|
730
|
+
});
|
|
731
|
+
config.xAxis.map((_, index) => {
|
|
732
|
+
xAxisMap.set(index, Axis.createAxis(AxisOrientation.x, config, index));
|
|
733
|
+
});
|
|
734
|
+
const left = Array.from(yAxisMap.values())
|
|
735
|
+
.filter((_) => _.options?.visible && _.options?.opposite)
|
|
736
|
+
.reduce((acc, cur) => acc + cur.selfSize, 0);
|
|
737
|
+
const right = Array.from(yAxisMap.values())
|
|
738
|
+
.filter((_) => _.options?.visible && _.options?.opposite !== true)
|
|
739
|
+
.reduce((acc, cur) => acc + cur.selfSize, 0);
|
|
740
|
+
const finalWidth = (size.width || 0) - left - right;
|
|
741
|
+
xAxisMap.forEach((axis) => {
|
|
742
|
+
let domain = axis.extremes;
|
|
743
|
+
if (axis?.options.inverted) {
|
|
744
|
+
domain = [...axis.extremes].reverse();
|
|
745
|
+
}
|
|
746
|
+
let scale = this.scaleMapping
|
|
747
|
+
.get(axis.options.scaleType.type)()
|
|
748
|
+
.domain(domain)
|
|
749
|
+
.range([0, finalWidth - config.bounds.right]);
|
|
750
|
+
if (axis.options.niceTicks) {
|
|
751
|
+
scale.nice();
|
|
752
|
+
}
|
|
753
|
+
if (axis.options.scaleType.type === ScaleType.log) {
|
|
754
|
+
scale.base(axis.options.scaleType.base);
|
|
755
|
+
}
|
|
756
|
+
axis.setScale(scale);
|
|
757
|
+
axis.setOriginDomain(scale.domain());
|
|
758
|
+
const hasCache = this.transformCacheX.has(axis.index);
|
|
759
|
+
const shouldRestore = zoom?.target?.orientation !== AxisOrientation.x ||
|
|
760
|
+
zoom.target?.index !== axis.index;
|
|
761
|
+
if (hasCache && shouldRestore) {
|
|
762
|
+
const restoredTransform = this.transformCacheX.get(axis.index);
|
|
763
|
+
axis.setScale(restoredTransform.rescaleX(scale));
|
|
764
|
+
}
|
|
765
|
+
});
|
|
766
|
+
if (zoom) {
|
|
767
|
+
const event = zoom.event;
|
|
768
|
+
if (zoom.target?.orientation === AxisOrientation.x) {
|
|
769
|
+
if (xAxisMap.has(zoom.target.index)) {
|
|
770
|
+
const x = xAxisMap.get(zoom.target.index);
|
|
771
|
+
const rescaled = event.transform.rescaleX(x.scale);
|
|
772
|
+
x.setScale(rescaled);
|
|
773
|
+
const axis = xAxisMap.get(zoom.target.index);
|
|
774
|
+
this.transformCacheX.set(axis.index, event.transform);
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
return xAxisMap;
|
|
779
|
+
}), shareReplay({
|
|
780
|
+
bufferSize: 1,
|
|
781
|
+
refCount: true,
|
|
782
|
+
}));
|
|
783
|
+
this.yMap = combineLatest([
|
|
784
|
+
this.chartService.size,
|
|
785
|
+
this.chartService.config,
|
|
786
|
+
this.zoomService.zoomed,
|
|
787
|
+
]).pipe(map((data) => {
|
|
788
|
+
const [size, config, zoom] = data;
|
|
789
|
+
const xAxisMap = new Map();
|
|
790
|
+
const yAxisMap = new Map();
|
|
791
|
+
config.yAxis.map((_, index) => {
|
|
792
|
+
yAxisMap.set(index, Axis.createAxis(AxisOrientation.y, config, index));
|
|
793
|
+
});
|
|
794
|
+
config.xAxis.map((_, index) => {
|
|
795
|
+
xAxisMap.set(index, Axis.createAxis(AxisOrientation.x, config, index));
|
|
796
|
+
});
|
|
797
|
+
const top = Array.from(xAxisMap.values())
|
|
798
|
+
.filter((_) => _.options?.visible && _.options?.opposite)
|
|
799
|
+
.reduce((acc, cur) => acc + cur.selfSize, 0);
|
|
800
|
+
const bottom = Array.from(xAxisMap.values())
|
|
801
|
+
.filter((_) => _.options?.visible && _.options?.opposite !== true)
|
|
802
|
+
.reduce((acc, cur) => acc + cur.selfSize, 0);
|
|
803
|
+
const finalHeight = (size.height || 0) -
|
|
804
|
+
top -
|
|
805
|
+
bottom -
|
|
806
|
+
config?.bounds?.top -
|
|
807
|
+
config.bounds?.bottom;
|
|
808
|
+
yAxisMap.forEach((axis) => {
|
|
809
|
+
let domain = axis.extremes;
|
|
810
|
+
if (axis.orientation === AxisOrientation.y) {
|
|
811
|
+
domain = [...axis.extremes].reverse();
|
|
812
|
+
}
|
|
813
|
+
if (axis?.options.inverted) {
|
|
814
|
+
domain = domain.reverse();
|
|
815
|
+
}
|
|
816
|
+
const scale = this.scaleMapping
|
|
817
|
+
.get(axis.options.scaleType.type)()
|
|
818
|
+
.domain(domain)
|
|
819
|
+
.range([config.bounds.top, finalHeight]);
|
|
820
|
+
if (axis.options.niceTicks) {
|
|
821
|
+
scale.nice();
|
|
822
|
+
}
|
|
823
|
+
if (axis.options.scaleType.type === ScaleType.log) {
|
|
824
|
+
scale.base(axis.options.scaleType.base);
|
|
825
|
+
}
|
|
826
|
+
axis.setScale(scale);
|
|
827
|
+
axis.setOriginDomain(scale.domain());
|
|
828
|
+
const hasCache = this.transformCacheY.has(axis.index);
|
|
829
|
+
const shouldRestore = zoom?.target?.orientation !== AxisOrientation.y ||
|
|
830
|
+
zoom.target?.index !== axis.index;
|
|
831
|
+
if (hasCache && shouldRestore) {
|
|
832
|
+
const restoredTransform = this.transformCacheY.get(axis.index);
|
|
833
|
+
axis.setScale(restoredTransform.rescaleY(scale));
|
|
834
|
+
}
|
|
835
|
+
});
|
|
836
|
+
if (zoom) {
|
|
837
|
+
const event = zoom.event;
|
|
838
|
+
if (zoom.target?.orientation === AxisOrientation.y) {
|
|
839
|
+
if (yAxisMap.has(zoom.target.index)) {
|
|
840
|
+
const y = yAxisMap.get(zoom.target.index);
|
|
841
|
+
const rescaled = event.transform.rescaleY(y.scale);
|
|
842
|
+
y.setScale(rescaled);
|
|
843
|
+
const axis = yAxisMap.get(zoom.target.index);
|
|
844
|
+
this.transformCacheY.set(axis.index, event.transform);
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
return yAxisMap;
|
|
849
|
+
}), shareReplay({
|
|
850
|
+
bufferSize: 1,
|
|
851
|
+
refCount: true,
|
|
852
|
+
}));
|
|
709
853
|
this.yScaleMap = combineLatest([
|
|
710
854
|
this.chartService.size,
|
|
711
855
|
this.chartService.config,
|
|
@@ -956,20 +1100,22 @@ class BrushService {
|
|
|
956
1100
|
brushScale(domain[0]),
|
|
957
1101
|
brushScale(domain[1]),
|
|
958
1102
|
]);
|
|
959
|
-
if (m.message.event.type === 'end') {
|
|
960
|
-
const brushMessage = new BrushMessage({
|
|
961
|
-
event: null,
|
|
962
|
-
selection: domain,
|
|
963
|
-
brushType: config?.brush?.type ?? BrushType.x,
|
|
964
|
-
brushScale,
|
|
965
|
-
});
|
|
966
|
-
this.broadcastService.broadcastBrush({
|
|
967
|
-
channel: config?.zoom?.syncChannel,
|
|
968
|
-
message: brushMessage,
|
|
969
|
-
});
|
|
970
|
-
}
|
|
971
1103
|
this.selection = domain;
|
|
972
1104
|
}
|
|
1105
|
+
}), debounceTime(30), tap((m) => {
|
|
1106
|
+
const { message: { domain }, } = m;
|
|
1107
|
+
if (m.message.event.type === 'zoom') {
|
|
1108
|
+
const brushMessage = new BrushMessage({
|
|
1109
|
+
event: null,
|
|
1110
|
+
selection: domain,
|
|
1111
|
+
brushType: config?.brush?.type ?? BrushType.x,
|
|
1112
|
+
brushScale,
|
|
1113
|
+
});
|
|
1114
|
+
this.broadcastService.broadcastBrush({
|
|
1115
|
+
channel: config?.zoom?.syncChannel,
|
|
1116
|
+
message: brushMessage,
|
|
1117
|
+
});
|
|
1118
|
+
}
|
|
973
1119
|
}))
|
|
974
1120
|
.subscribe();
|
|
975
1121
|
}
|
|
@@ -1067,17 +1213,17 @@ class LinearSeriesBase extends SeriesBaseComponent {
|
|
|
1067
1213
|
};
|
|
1068
1214
|
this.defaultClipPointsMapping.set(ClipPointsDirection.x, filterX);
|
|
1069
1215
|
this.defaultClipPointsMapping.set(ClipPointsDirection.y, filterY);
|
|
1070
|
-
this.transform = this.svc.pointerMove.pipe(withLatestFrom(this.scaleService.
|
|
1216
|
+
this.transform = this.svc.pointerMove.pipe(withLatestFrom(this.scaleService.xMap, this.scaleService.yMap), map((data) => {
|
|
1071
1217
|
const [event, x, y] = data;
|
|
1072
|
-
return this.getTransform(event, x, y);
|
|
1218
|
+
return this.getTransform(event, x.get(this.series.xAxisIndex).scale, y.get(this.series.yAxisIndex).scale);
|
|
1073
1219
|
}), tap(() => setTimeout(() => this.cdr.detectChanges())));
|
|
1074
1220
|
this.path = combineLatest([
|
|
1075
|
-
this.scaleService.
|
|
1076
|
-
this.scaleService.
|
|
1221
|
+
this.scaleService.xMap,
|
|
1222
|
+
this.scaleService.yMap,
|
|
1077
1223
|
]).pipe(map((data) => {
|
|
1078
1224
|
const [x, y] = data;
|
|
1079
|
-
this.x = x.get(this.series.xAxisIndex);
|
|
1080
|
-
this.y = y.get(this.series.yAxisIndex);
|
|
1225
|
+
this.x = x.get(this.series.xAxisIndex).scale;
|
|
1226
|
+
this.y = y.get(this.series.yAxisIndex).scale;
|
|
1081
1227
|
const filter = this.defaultClipPointsMapping.get(this.series.clipPointsDirection);
|
|
1082
1228
|
const line = d3
|
|
1083
1229
|
.line()
|
|
@@ -1160,8 +1306,6 @@ class LinearSeriesBase extends SeriesBaseComponent {
|
|
|
1160
1306
|
return null;
|
|
1161
1307
|
}
|
|
1162
1308
|
const mouse = [event?.offsetX, event?.offsetY];
|
|
1163
|
-
const foundX = scaleX.get(this.series.xAxisIndex);
|
|
1164
|
-
const foundY = scaleY.get(this.series.yAxisIndex);
|
|
1165
1309
|
const tooltipTracking = this.config?.tooltip?.tracking;
|
|
1166
1310
|
const lineIntersection = (p0_x, p0_y, p1_x, p1_y, p2_x, p2_y, p3_x, p3_y) => {
|
|
1167
1311
|
const rV = {};
|
|
@@ -1187,18 +1331,18 @@ class LinearSeriesBase extends SeriesBaseComponent {
|
|
|
1187
1331
|
if (tooltipTracking === TooltipTracking.x) {
|
|
1188
1332
|
const bisect = d3.bisector((_) => _.x).right;
|
|
1189
1333
|
const pointer = mouse[0];
|
|
1190
|
-
let x0 =
|
|
1334
|
+
let x0 = scaleX.invert(pointer);
|
|
1191
1335
|
if (x0 instanceof Date) {
|
|
1192
1336
|
x0 = x0.getTime();
|
|
1193
1337
|
}
|
|
1194
1338
|
const rightId = bisect(this.series.data, x0);
|
|
1195
|
-
const range =
|
|
1196
|
-
const intersect = lineIntersection(pointer, range[0], pointer, range[1],
|
|
1197
|
-
const x =
|
|
1198
|
-
const y =
|
|
1339
|
+
const range = scaleY.range();
|
|
1340
|
+
const intersect = lineIntersection(pointer, range[0], pointer, range[1], scaleX(this.series.data[rightId - 1]?.x), scaleY(this.series.data[rightId - 1]?.y), scaleX(this.series.data[rightId]?.x), scaleY(this.series.data[rightId]?.y));
|
|
1341
|
+
const x = scaleX.invert(intersect.x);
|
|
1342
|
+
const y = scaleY.invert(intersect.y);
|
|
1199
1343
|
if (x !== null && x !== undefined && !isNaN(x) && y !== null && y !== undefined && !isNaN(y)) {
|
|
1200
1344
|
this.svc.setTooltip({
|
|
1201
|
-
point: { x:
|
|
1345
|
+
point: { x: scaleX.invert(intersect.x), y: scaleY.invert(intersect.y) },
|
|
1202
1346
|
series: this.series,
|
|
1203
1347
|
});
|
|
1204
1348
|
}
|
|
@@ -1215,18 +1359,18 @@ class LinearSeriesBase extends SeriesBaseComponent {
|
|
|
1215
1359
|
}
|
|
1216
1360
|
if (tooltipTracking === TooltipTracking.y) {
|
|
1217
1361
|
const bisect = d3.bisector((_) => _.y).right;
|
|
1218
|
-
let y0 =
|
|
1362
|
+
let y0 = scaleY.invert(mouse[1]);
|
|
1219
1363
|
if (y0 instanceof Date) {
|
|
1220
1364
|
y0 = y0.getTime();
|
|
1221
1365
|
}
|
|
1222
1366
|
const rightId = bisect(this.series.data, y0);
|
|
1223
|
-
const range =
|
|
1224
|
-
const intersect = lineIntersection(range[0], mouse[1], range[1], mouse[1],
|
|
1225
|
-
const x =
|
|
1226
|
-
const y =
|
|
1367
|
+
const range = scaleX.range();
|
|
1368
|
+
const intersect = lineIntersection(range[0], mouse[1], range[1], mouse[1], scaleX(this.series.data[rightId - 1]?.x), scaleY(this.series.data[rightId - 1]?.y), scaleX(this.series.data[rightId]?.x), scaleY(this.series.data[rightId]?.y));
|
|
1369
|
+
const x = scaleX.invert(intersect.x);
|
|
1370
|
+
const y = scaleY.invert(intersect.y);
|
|
1227
1371
|
if (x !== null && x !== undefined && !isNaN(x) && y !== null && y !== undefined && !isNaN(y)) {
|
|
1228
1372
|
this.svc.setTooltip({
|
|
1229
|
-
point: { x:
|
|
1373
|
+
point: { x: scaleX.invert(intersect.x), y: scaleY.invert(intersect.y) },
|
|
1230
1374
|
series: this.series,
|
|
1231
1375
|
});
|
|
1232
1376
|
}
|
|
@@ -1284,8 +1428,8 @@ class BarSeriesComponent extends SeriesBaseComponent {
|
|
|
1284
1428
|
const count = _.series.filter((_) => _.type === SeriesType.bar && _.xAxisIndex === this.series.xAxisIndex);
|
|
1285
1429
|
return count.length;
|
|
1286
1430
|
}));
|
|
1287
|
-
this.x1 = this.scaleService.
|
|
1288
|
-
const x = _.get(this.series.xAxisIndex);
|
|
1431
|
+
this.x1 = this.scaleService.xMap.pipe(map((_) => {
|
|
1432
|
+
const x = _.get(this.series.xAxisIndex).scale;
|
|
1289
1433
|
const range = x.range();
|
|
1290
1434
|
const domain = this.series.data.map((_) => _.x);
|
|
1291
1435
|
return d3
|
|
@@ -1294,8 +1438,8 @@ class BarSeriesComponent extends SeriesBaseComponent {
|
|
|
1294
1438
|
.domain(domain)
|
|
1295
1439
|
.padding(0.1);
|
|
1296
1440
|
}));
|
|
1297
|
-
this.x = this.scaleService.
|
|
1298
|
-
this.y = this.scaleService.
|
|
1441
|
+
this.x = this.scaleService.xMap.pipe(map((_) => _.get(this.series.xAxisIndex).scale));
|
|
1442
|
+
this.y = this.scaleService.yMap.pipe(map((_) => _.get(this.series.yAxisIndex).scale));
|
|
1299
1443
|
}
|
|
1300
1444
|
mouseenter(point) {
|
|
1301
1445
|
this.svc.setTooltip({
|
|
@@ -1328,8 +1472,8 @@ class ScatterSeriesComponent extends SeriesBaseComponent {
|
|
|
1328
1472
|
this.element = element;
|
|
1329
1473
|
}
|
|
1330
1474
|
ngOnInit() {
|
|
1331
|
-
this.x = this.scaleService.
|
|
1332
|
-
this.y = this.scaleService.
|
|
1475
|
+
this.x = this.scaleService.xMap.pipe(map(_ => _.get(this.series.xAxisIndex).scale));
|
|
1476
|
+
this.y = this.scaleService.yMap.pipe(map(_ => _.get(this.series.yAxisIndex).scale));
|
|
1333
1477
|
}
|
|
1334
1478
|
ngAfterViewInit() {
|
|
1335
1479
|
}
|
|
@@ -1367,8 +1511,8 @@ class BlockSeriesComponent extends SeriesBaseComponent {
|
|
|
1367
1511
|
}
|
|
1368
1512
|
ngOnInit() {
|
|
1369
1513
|
const defaultVisiblePixels = 0;
|
|
1370
|
-
this.x = this.scaleService.
|
|
1371
|
-
this.y = this.scaleService.
|
|
1514
|
+
this.x = this.scaleService.xMap.pipe(map((_) => _.get(this.series.xAxisIndex).scale));
|
|
1515
|
+
this.y = this.scaleService.yMap.pipe(map((_) => _.get(this.series.yAxisIndex).scale));
|
|
1372
1516
|
this.displayPoints = this.y.pipe(map((y) => {
|
|
1373
1517
|
return this.series.data.filter((point, index, arr) => {
|
|
1374
1518
|
const [min, max] = y.domain();
|
|
@@ -1419,8 +1563,8 @@ class BlockAreaSeriesComponent extends SeriesBaseComponent {
|
|
|
1419
1563
|
}
|
|
1420
1564
|
ngOnInit() {
|
|
1421
1565
|
const defaultVisiblePixels = 0;
|
|
1422
|
-
this.x = this.scaleService.
|
|
1423
|
-
this.y = this.scaleService.
|
|
1566
|
+
this.x = this.scaleService.xMap.pipe(map((_) => _.get(this.series.xAxisIndex).scale));
|
|
1567
|
+
this.y = this.scaleService.yMap.pipe(map((_) => _.get(this.series.yAxisIndex).scale));
|
|
1424
1568
|
this.displayPoints = this.y.pipe(map((y) => {
|
|
1425
1569
|
return this.series.data.filter((point, index, arr) => {
|
|
1426
1570
|
const [min, max] = y.domain();
|
|
@@ -1472,12 +1616,12 @@ class AreaSeriesComponent extends LinearSeriesBase {
|
|
|
1472
1616
|
ngOnInit() {
|
|
1473
1617
|
super.ngOnInit();
|
|
1474
1618
|
this.areaPath = combineLatest([
|
|
1475
|
-
this.scaleService.
|
|
1476
|
-
this.scaleService.
|
|
1619
|
+
this.scaleService.xMap,
|
|
1620
|
+
this.scaleService.yMap,
|
|
1477
1621
|
]).pipe(map((data) => {
|
|
1478
1622
|
const [x, y] = data;
|
|
1479
|
-
this.x = x.get(this.series.xAxisIndex);
|
|
1480
|
-
this.y = y.get(this.series.yAxisIndex);
|
|
1623
|
+
this.x = x.get(this.series.xAxisIndex).scale;
|
|
1624
|
+
this.y = y.get(this.series.yAxisIndex).scale;
|
|
1481
1625
|
const area = d3
|
|
1482
1626
|
.area()
|
|
1483
1627
|
.defined((point) => point.x !== null &&
|
|
@@ -1567,16 +1711,16 @@ class GridlinesComponent {
|
|
|
1567
1711
|
this.svc = svc;
|
|
1568
1712
|
this.chartService = chartService;
|
|
1569
1713
|
this.config = this.chartService.config;
|
|
1570
|
-
this.tickYValues = this.svc.
|
|
1714
|
+
this.tickYValues = this.svc.yMap.pipe(map((_) => {
|
|
1571
1715
|
const ratio = this.size.height / 40;
|
|
1572
|
-
return _.get(0).ticks(ratio);
|
|
1716
|
+
return _.get(0).scale.ticks(ratio);
|
|
1573
1717
|
}));
|
|
1574
|
-
this.tickXValues = this.svc.
|
|
1718
|
+
this.tickXValues = this.svc.xMap.pipe(map((_) => {
|
|
1575
1719
|
const ratio = this.size.width / 40;
|
|
1576
|
-
return _.get(0).ticks(ratio);
|
|
1720
|
+
return _.get(0).scale.ticks(ratio);
|
|
1577
1721
|
}));
|
|
1578
|
-
this.y = this.svc.
|
|
1579
|
-
this.x = this.svc.
|
|
1722
|
+
this.y = this.svc.yMap.pipe(map((_) => _.get(0).scale));
|
|
1723
|
+
this.x = this.svc.xMap.pipe(map((_) => _.get(0).scale));
|
|
1580
1724
|
}
|
|
1581
1725
|
ngAfterViewInit() {
|
|
1582
1726
|
}
|
|
@@ -1594,8 +1738,8 @@ class XAxisComponent {
|
|
|
1594
1738
|
constructor(scaleService) {
|
|
1595
1739
|
this.scaleService = scaleService;
|
|
1596
1740
|
this._alive = true;
|
|
1597
|
-
this.x = this.scaleService.
|
|
1598
|
-
return _.get(this.axis.index);
|
|
1741
|
+
this.x = this.scaleService.xMap.pipe(map((_) => {
|
|
1742
|
+
return _.get(this.axis.index)?.scale;
|
|
1599
1743
|
}));
|
|
1600
1744
|
}
|
|
1601
1745
|
getLabelTransform() {
|
|
@@ -1605,30 +1749,6 @@ class XAxisComponent {
|
|
|
1605
1749
|
ngOnDestroy() {
|
|
1606
1750
|
this._alive = false;
|
|
1607
1751
|
}
|
|
1608
|
-
ngAfterViewInit() {
|
|
1609
|
-
// this.draw();
|
|
1610
|
-
}
|
|
1611
|
-
draw() {
|
|
1612
|
-
// if (!this.node || !this.axis) {
|
|
1613
|
-
// return;
|
|
1614
|
-
// }
|
|
1615
|
-
//
|
|
1616
|
-
// const axis = this.axis.options.opposite
|
|
1617
|
-
// ? d3
|
|
1618
|
-
// .axisTop(this.scale)
|
|
1619
|
-
// .tickFormat(
|
|
1620
|
-
// this.axis.options.tickFormat ?? this.axis.defaultFormatter()
|
|
1621
|
-
// )
|
|
1622
|
-
// : d3
|
|
1623
|
-
// .axisBottom(this.scale)
|
|
1624
|
-
// .tickFormat(
|
|
1625
|
-
// this.axis.options.tickFormat ?? this.axis.defaultFormatter()
|
|
1626
|
-
// );
|
|
1627
|
-
//
|
|
1628
|
-
// d3.select(this.node.nativeElement)
|
|
1629
|
-
// .call(axis)
|
|
1630
|
-
// .call((_) => _.select('.domain').remove());
|
|
1631
|
-
}
|
|
1632
1752
|
}
|
|
1633
1753
|
XAxisComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: XAxisComponent, deps: [{ token: ScaleService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1634
1754
|
XAxisComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.2", type: XAxisComponent, selector: "[teta-x-axis]", inputs: { axis: "axis", size: "size" }, ngImport: i0, template: "<ng-container *ngIf=\"x | async as scale\">\n <svg:g text-anchor=\"middle\" *ngFor=\"let tick of scale.ticks()\" [attr.transform]=\"'translate('+ scale(tick) +', 0)'\">\n <text fill=\"var(--color-text-70)\" [attr.dy]=\"axis.options.opposite ? '-0.71em' : '0.71em'\" [attr.y]=\"axis.options.opposite ? 0 : 9\">{{ this.axis.options.tickFormat ? this.axis.options.tickFormat(tick) : this.axis.defaultFormatter()(tick) }}</text>\n <line stroke=\"var(--color-text-30)\" [attr.y2]=\"axis.options.opposite ? -6 : 6\"></line>\n </svg:g>\n\n <svg:g class=\"label-axis font-caption\" [attr.transform]=\"getLabelTransform()\">\n <text fill=\"var(--color-text-70)\" text-anchor=\"middle\" dominant-baseline=\"middle\">{{ axis.options.title }}</text>\n </svg:g>\n</ng-container>\n\n", styles: [":host .tick{stroke:var(--color-text-20)}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
@@ -1645,8 +1765,8 @@ class YAxisComponent {
|
|
|
1645
1765
|
constructor(scaleService) {
|
|
1646
1766
|
this.scaleService = scaleService;
|
|
1647
1767
|
this._alive = true;
|
|
1648
|
-
this.y = this.scaleService.
|
|
1649
|
-
return _.get(this.axis.index);
|
|
1768
|
+
this.y = this.scaleService.yMap.pipe(map((_) => {
|
|
1769
|
+
return _.get(this.axis.index)?.scale;
|
|
1650
1770
|
}));
|
|
1651
1771
|
}
|
|
1652
1772
|
ngOnInit() { }
|
|
@@ -2069,6 +2189,7 @@ class ZoomableDirective {
|
|
|
2069
2189
|
this.zoom.scaleExtent([maxZoom, minZoom]);
|
|
2070
2190
|
this.zoom.on('zoom end', this.zoomed);
|
|
2071
2191
|
this._element.call(this.zoom).on('dblclick.zoom', null); // Disable dbclick zoom
|
|
2192
|
+
this.chartService.emitZoomInstance(this.zoomService);
|
|
2072
2193
|
if (this.config?.zoom?.zoomBehavior === ZoomBehaviorType.wheel) {
|
|
2073
2194
|
this.runWheelZoom();
|
|
2074
2195
|
}
|
|
@@ -2121,7 +2242,7 @@ class ZoomableDirective {
|
|
|
2121
2242
|
.pipe(combineLatestWith(this.chartService.size), takeWhile((_) => this.alive), filter((data) => {
|
|
2122
2243
|
const [m] = data;
|
|
2123
2244
|
return Boolean(m.message.selection);
|
|
2124
|
-
}),
|
|
2245
|
+
}), tap$1((data) => {
|
|
2125
2246
|
const [m] = data;
|
|
2126
2247
|
const currentTransform = d3.zoomTransform(this._element.node());
|
|
2127
2248
|
if (!m.message.event &&
|
|
@@ -2300,8 +2421,8 @@ class AnnotationComponent {
|
|
|
2300
2421
|
this.scaleService = scaleService;
|
|
2301
2422
|
this.cdr = cdr;
|
|
2302
2423
|
this.chartService = chartService;
|
|
2303
|
-
this.x = this.scaleService.
|
|
2304
|
-
this.y = this.scaleService.
|
|
2424
|
+
this.x = this.scaleService.xMap.pipe(map((_) => _.get(this.annotation.xAxisIndex ?? 0).scale));
|
|
2425
|
+
this.y = this.scaleService.yMap.pipe(map((_) => _.get(this.annotation.yAxisIndex ?? 0).scale));
|
|
2305
2426
|
this.drag = d3.drag();
|
|
2306
2427
|
}
|
|
2307
2428
|
set annotation(annotation) {
|
|
@@ -2415,27 +2536,25 @@ class ChartContainerComponent {
|
|
|
2415
2536
|
this.sumSize = (acc, curr) => acc + curr.selfSize;
|
|
2416
2537
|
this.config = this._svc.config;
|
|
2417
2538
|
this.size = this._svc.size;
|
|
2418
|
-
this.
|
|
2419
|
-
this.xAxisMap = this._scaleService.xAxisMap;
|
|
2420
|
-
this.yScaleMap = this._scaleService.yScaleMap.pipe(observeOn(animationFrameScheduler, 10), tetaZoneFull(this._zone), shareReplay({
|
|
2539
|
+
this.yMap = this._scaleService.yMap.pipe(observeOn(animationFrameScheduler), tetaZoneFull(this._zone), shareReplay({
|
|
2421
2540
|
bufferSize: 1,
|
|
2422
2541
|
refCount: true,
|
|
2423
2542
|
}));
|
|
2424
|
-
this.
|
|
2543
|
+
this.xMap = this._scaleService.xMap.pipe(observeOn(animationFrameScheduler), tetaZoneFull(this._zone), shareReplay({
|
|
2425
2544
|
bufferSize: 1,
|
|
2426
2545
|
refCount: true,
|
|
2427
2546
|
}));
|
|
2428
2547
|
this.brushScale = combineLatest([
|
|
2429
|
-
this._scaleService.
|
|
2430
|
-
this._scaleService.
|
|
2548
|
+
this._scaleService.xMap,
|
|
2549
|
+
this._scaleService.yMap,
|
|
2431
2550
|
]).pipe(withLatestFrom(this.config), map((data) => {
|
|
2432
2551
|
const [[x, y], config] = data;
|
|
2433
|
-
return config.brush?.type === BrushType.x || config?.zoom?.type === ZoomType.x ? x.get(0) : y.get(0);
|
|
2552
|
+
return config.brush?.type === BrushType.x || config?.zoom?.type === ZoomType.x ? x.get(0).scale : y.get(0).scale;
|
|
2434
2553
|
}), shareReplay({
|
|
2435
2554
|
bufferSize: 1,
|
|
2436
2555
|
refCount: true,
|
|
2437
2556
|
}));
|
|
2438
|
-
this.visibleRect = this.size.pipe(combineLatestWith(this.
|
|
2557
|
+
this.visibleRect = this.size.pipe(combineLatestWith(this.xMap, this.yMap)).pipe(withLatestFrom(this.config), map((data) => {
|
|
2439
2558
|
const [[size, x, y], config] = data;
|
|
2440
2559
|
const yAxesArray = [...y.values()];
|
|
2441
2560
|
const xAxesArray = [...x.values()];
|
|
@@ -2490,7 +2609,7 @@ class ChartContainerComponent {
|
|
|
2490
2609
|
this._observer.disconnect();
|
|
2491
2610
|
}
|
|
2492
2611
|
getTranslate(axis, size) {
|
|
2493
|
-
return combineLatest([this.
|
|
2612
|
+
return combineLatest([this.xMap, this.yMap]).pipe(withLatestFrom(this.config), map((data) => {
|
|
2494
2613
|
const [[x, y], config] = data;
|
|
2495
2614
|
const xAxesArray = [...x.values()];
|
|
2496
2615
|
const yAxesArray = [...y.values()];
|
|
@@ -2556,10 +2675,10 @@ class ChartContainerComponent {
|
|
|
2556
2675
|
}
|
|
2557
2676
|
}
|
|
2558
2677
|
ChartContainerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ChartContainerComponent, deps: [{ token: ChartService }, { token: i0.ChangeDetectorRef }, { token: ScaleService }, { token: ZoomService }, { token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
|
|
2559
|
-
ChartContainerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.2", type: ChartContainerComponent, selector: "teta-chart-container", ngImport: i0, template: "<ng-container *ngIf=\"{\n size: size | async,\n config: config | async,\n
|
|
2678
|
+
ChartContainerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.2", type: ChartContainerComponent, selector: "teta-chart-container", ngImport: i0, template: "<ng-container *ngIf=\"{\n size: size | async,\n config: config | async,\n yMap: yMap | async,\n xMap: xMap | async,\n visibleRect: visibleRect | async,\n brushScale: brushScale | async\n} as data\" xmlns:svg=\"http://www.w3.org/1999/html\">\n <teta-tooltip *ngIf=\"data.config?.tooltip?.enable\"\n [size]=\"data.size\"\n [config]=\"data.config\"></teta-tooltip>\n <ng-container *ngIf=\"data.visibleRect?.width > 0 && data.visibleRect?.height > 0 && data.xMap.size === data.config?.xAxis?.length && data.yMap.size === data.config?.yAxis?.length\">\n <svg height=\"100%\" width=\"100%\" class=\"position-absolute\">\n <g class=\"y-axis-container\">\n <ng-container *ngFor=\"let item of data.yMap | keyvalue; trackBy: identify\">\n <ng-container *ngIf=\"item.value.options.visible\">\n <g\n teta-y-axis\n [axis]=\"item.value\"\n [size]=\"data.visibleRect\"\n [attr.transform]=\"getTranslate(item.value, data.size) | async\"></g>\n <rect\n tetaZoomable\n fill-opacity=\"0\"\n [brushScale]=\"data.brushScale\"\n [scale]=\"data.yMap.get(item.key).scale\"\n [axis]=\"item.value\"\n [config]=\"data.config\"\n [size]=\"data.visibleRect\"\n [attr.x]=\"item.value.options.opposite ? 0 : -item.value.selfSize\"\n [attr.y]=\"0\"\n [attr.height]=\"data.visibleRect.height\"\n [attr.width]=\"item.value.selfSize\"\n [attr.transform]=\"getTranslate(item.value, data.size) | async\"></rect>\n </ng-container>\n\n </ng-container>\n </g>\n <g class=\"x-axis-container\">\n <ng-container *ngFor=\"let item of data.xMap | keyvalue; trackBy: identify\">\n <ng-container *ngIf=\"item.value.options.visible && data.xMap.size === data.config?.xAxis?.length && data.yMap.size === data.config?.yAxis?.length\">\n <g\n teta-x-axis\n [axis]=\"item.value\"\n [size]=\"data.visibleRect\"\n [attr.transform]=\"getTranslate(item.value, data.size) | async\"></g>\n <rect\n tetaZoomable\n fill-opacity=\"0\"\n [brushScale]=\"data.brushScale\"\n [scale]=\"data.xMap.get(item.key).scale\"\n [axis]=\"item.value\"\n [config]=\"data.config\"\n [size]=\"data.visibleRect\"\n [attr.x]=\"0\"\n [attr.y]=\"item.value.options.opposite ? -item.value.selfSize : 0\"\n [attr.width]=\"data.visibleRect.width\"\n [attr.height]=\"item.value.selfSize\"\n [attr.transform]=\"getTranslate(item.value, data.size) | async\"></rect>\n </ng-container>\n </ng-container>\n </g>\n </svg>\n </ng-container>\n <ng-container *ngIf=\"data.visibleRect?.width > 0 && data.visibleRect?.height > 0 && data.xMap.size === data.config?.xAxis?.length && data.yMap.size === data.config?.yAxis?.length\">\n <svg\n tetaBrushable\n tetaZoomable\n class=\"position-absolute\"\n [size]=\"data.visibleRect\"\n [brushScale]=\"data.brushScale\"\n [scale]=\"data.brushScale\"\n [config]=\"data.config\"\n [axis]=\"data.config?.zoom?.type === zoomType.x ? data.xMap.get(0) : data.yMap.get(0)\"\n [attr.width]=\"data.visibleRect.width\"\n [attr.height]=\"data.visibleRect.height\"\n [attr.viewBox]=\"'0 0 ' + data.visibleRect.width + ' ' + data.visibleRect.height\"\n [style.transform]=\"'translate('+ data.visibleRect.x +'px, '+ data.visibleRect.y +'px)'\"\n (contextmenu)=\"contextMenu($event, data.xMap, data.yMap)\"\n (click)=\"click($event, data.xMap, data.yMap)\"\n (mouseleave)=\"mouseLeave($event)\"\n (mousemove)=\"mouseMove($event)\">\n\n <g class=\"gridlines\"\n teta-gridlines\n *ngIf=\"data.config.gridLines?.enable !== false\"\n [size]=\"data.size\"></g>\n\n <g class=\"x-axis-plotband-container\">\n <ng-container *ngFor=\"let axis of data.config.xAxis; let i = index\">\n <g teta-plot-band *ngFor=\"let plotBand of axis.plotBands\"\n [plotBand]=\"plotBand\"\n [scale]=\"data.xMap.get(i).scale\"\n [size]=\"data.size\"\n [axis]=\"data.xMap.get(i)\"></g>\n </ng-container>\n </g>\n <g class=\"y-axis-plotband-container\">\n <ng-container *ngFor=\"let axis of data.config.yAxis; let i = index\">\n <g teta-plot-band *ngFor=\"let plotBand of axis.plotBands\"\n [plotBand]=\"plotBand\"\n [scale]=\"data.yMap.get(i).scale\"\n [size]=\"data.size\"\n [axis]=\"data.yMap.get(i)\"></g>\n </ng-container>\n </g>\n <g class=\"x-axis-plotline-container\">\n <ng-container *ngFor=\"let axis of data.config.xAxis; let i = index\">\n <g teta-plot-line *ngFor=\"let plotLine of axis.plotLines\"\n [plotLine]=\"plotLine\"\n [scale]=\"data.xMap.get(i).scale\"\n [size]=\"data.size\"\n [axis]=\"data.xMap.get(i)\"></g>\n </ng-container>\n </g>\n <g class=\"y-axis-plotline-container\">\n <ng-container *ngFor=\"let axis of data.config.yAxis; let i = index\">\n <g teta-plot-line *ngFor=\"let plotLine of axis.plotLines\"\n [plotLine]=\"plotLine\"\n [scale]=\"data.yMap.get(i).scale\"\n [size]=\"data.size\"\n [axis]=\"data.yMap.get(i)\"></g>\n </ng-container>\n </g>\n <g class=\"series-container\">\n <ng-container *ngFor=\"let series of data.config.series\">\n <g teta-series-host\n *ngIf=\"series.visible\"\n [config]=\"data.config\"\n [series]=\"series\"></g>\n </ng-container>\n </g>\n <g class=\"annotations\">\n <g teta-annotation\n *ngFor=\"let annotation of data.config.annotations\"\n [annotation]=\"annotation\"></g>\n </g>\n <g class=\"crosshair\" *ngIf=\"data.config.tooltip?.showCrosshair\">\n <g teta-crosshair [size]=\"data.visibleRect\"></g>\n </g>\n </svg>\n\n </ng-container>\n</ng-container>\n", styles: [":host{display:flex;flex-direction:column;flex-grow:1;min-width:0;min-height:0}:host .zoomable:hover{cursor:grab}:host .zoomable:active{cursor:grabbing}:host .crosshair{cursor:crosshair}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: SeriesHostComponent, selector: "[teta-series-host]", inputs: ["config", "series"] }, { kind: "component", type: GridlinesComponent, selector: "[teta-gridlines]", inputs: ["size"] }, { kind: "component", type: XAxisComponent, selector: "[teta-x-axis]", inputs: ["axis", "size"] }, { kind: "component", type: YAxisComponent, selector: "[teta-y-axis]", inputs: ["axis", "size"] }, { kind: "component", type: PlotlineComponent, selector: "[teta-plot-line]", inputs: ["plotLine", "size", "axis", "scale"] }, { kind: "component", type: PlotBandComponent, selector: "[teta-plot-band]", inputs: ["plotBand", "axis", "scale", "size"] }, { kind: "component", type: TooltipComponent, selector: "teta-tooltip", inputs: ["size", "config"] }, { kind: "directive", type: ZoomableDirective, selector: "[tetaZoomable]", inputs: ["config", "axis", "size", "brushScale", "scale"] }, { kind: "directive", type: BrushableDirective, selector: "[tetaBrushable]", inputs: ["config", "brushScale"] }, { kind: "component", type: AnnotationComponent, selector: "[teta-annotation]", inputs: ["annotation"] }, { kind: "component", type: CrosshairComponent, selector: "[teta-crosshair]", inputs: ["size"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i4.KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2560
2679
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ChartContainerComponent, decorators: [{
|
|
2561
2680
|
type: Component,
|
|
2562
|
-
args: [{ selector: 'teta-chart-container', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"{\n size: size | async,\n config: config | async,\n
|
|
2681
|
+
args: [{ selector: 'teta-chart-container', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"{\n size: size | async,\n config: config | async,\n yMap: yMap | async,\n xMap: xMap | async,\n visibleRect: visibleRect | async,\n brushScale: brushScale | async\n} as data\" xmlns:svg=\"http://www.w3.org/1999/html\">\n <teta-tooltip *ngIf=\"data.config?.tooltip?.enable\"\n [size]=\"data.size\"\n [config]=\"data.config\"></teta-tooltip>\n <ng-container *ngIf=\"data.visibleRect?.width > 0 && data.visibleRect?.height > 0 && data.xMap.size === data.config?.xAxis?.length && data.yMap.size === data.config?.yAxis?.length\">\n <svg height=\"100%\" width=\"100%\" class=\"position-absolute\">\n <g class=\"y-axis-container\">\n <ng-container *ngFor=\"let item of data.yMap | keyvalue; trackBy: identify\">\n <ng-container *ngIf=\"item.value.options.visible\">\n <g\n teta-y-axis\n [axis]=\"item.value\"\n [size]=\"data.visibleRect\"\n [attr.transform]=\"getTranslate(item.value, data.size) | async\"></g>\n <rect\n tetaZoomable\n fill-opacity=\"0\"\n [brushScale]=\"data.brushScale\"\n [scale]=\"data.yMap.get(item.key).scale\"\n [axis]=\"item.value\"\n [config]=\"data.config\"\n [size]=\"data.visibleRect\"\n [attr.x]=\"item.value.options.opposite ? 0 : -item.value.selfSize\"\n [attr.y]=\"0\"\n [attr.height]=\"data.visibleRect.height\"\n [attr.width]=\"item.value.selfSize\"\n [attr.transform]=\"getTranslate(item.value, data.size) | async\"></rect>\n </ng-container>\n\n </ng-container>\n </g>\n <g class=\"x-axis-container\">\n <ng-container *ngFor=\"let item of data.xMap | keyvalue; trackBy: identify\">\n <ng-container *ngIf=\"item.value.options.visible && data.xMap.size === data.config?.xAxis?.length && data.yMap.size === data.config?.yAxis?.length\">\n <g\n teta-x-axis\n [axis]=\"item.value\"\n [size]=\"data.visibleRect\"\n [attr.transform]=\"getTranslate(item.value, data.size) | async\"></g>\n <rect\n tetaZoomable\n fill-opacity=\"0\"\n [brushScale]=\"data.brushScale\"\n [scale]=\"data.xMap.get(item.key).scale\"\n [axis]=\"item.value\"\n [config]=\"data.config\"\n [size]=\"data.visibleRect\"\n [attr.x]=\"0\"\n [attr.y]=\"item.value.options.opposite ? -item.value.selfSize : 0\"\n [attr.width]=\"data.visibleRect.width\"\n [attr.height]=\"item.value.selfSize\"\n [attr.transform]=\"getTranslate(item.value, data.size) | async\"></rect>\n </ng-container>\n </ng-container>\n </g>\n </svg>\n </ng-container>\n <ng-container *ngIf=\"data.visibleRect?.width > 0 && data.visibleRect?.height > 0 && data.xMap.size === data.config?.xAxis?.length && data.yMap.size === data.config?.yAxis?.length\">\n <svg\n tetaBrushable\n tetaZoomable\n class=\"position-absolute\"\n [size]=\"data.visibleRect\"\n [brushScale]=\"data.brushScale\"\n [scale]=\"data.brushScale\"\n [config]=\"data.config\"\n [axis]=\"data.config?.zoom?.type === zoomType.x ? data.xMap.get(0) : data.yMap.get(0)\"\n [attr.width]=\"data.visibleRect.width\"\n [attr.height]=\"data.visibleRect.height\"\n [attr.viewBox]=\"'0 0 ' + data.visibleRect.width + ' ' + data.visibleRect.height\"\n [style.transform]=\"'translate('+ data.visibleRect.x +'px, '+ data.visibleRect.y +'px)'\"\n (contextmenu)=\"contextMenu($event, data.xMap, data.yMap)\"\n (click)=\"click($event, data.xMap, data.yMap)\"\n (mouseleave)=\"mouseLeave($event)\"\n (mousemove)=\"mouseMove($event)\">\n\n <g class=\"gridlines\"\n teta-gridlines\n *ngIf=\"data.config.gridLines?.enable !== false\"\n [size]=\"data.size\"></g>\n\n <g class=\"x-axis-plotband-container\">\n <ng-container *ngFor=\"let axis of data.config.xAxis; let i = index\">\n <g teta-plot-band *ngFor=\"let plotBand of axis.plotBands\"\n [plotBand]=\"plotBand\"\n [scale]=\"data.xMap.get(i).scale\"\n [size]=\"data.size\"\n [axis]=\"data.xMap.get(i)\"></g>\n </ng-container>\n </g>\n <g class=\"y-axis-plotband-container\">\n <ng-container *ngFor=\"let axis of data.config.yAxis; let i = index\">\n <g teta-plot-band *ngFor=\"let plotBand of axis.plotBands\"\n [plotBand]=\"plotBand\"\n [scale]=\"data.yMap.get(i).scale\"\n [size]=\"data.size\"\n [axis]=\"data.yMap.get(i)\"></g>\n </ng-container>\n </g>\n <g class=\"x-axis-plotline-container\">\n <ng-container *ngFor=\"let axis of data.config.xAxis; let i = index\">\n <g teta-plot-line *ngFor=\"let plotLine of axis.plotLines\"\n [plotLine]=\"plotLine\"\n [scale]=\"data.xMap.get(i).scale\"\n [size]=\"data.size\"\n [axis]=\"data.xMap.get(i)\"></g>\n </ng-container>\n </g>\n <g class=\"y-axis-plotline-container\">\n <ng-container *ngFor=\"let axis of data.config.yAxis; let i = index\">\n <g teta-plot-line *ngFor=\"let plotLine of axis.plotLines\"\n [plotLine]=\"plotLine\"\n [scale]=\"data.yMap.get(i).scale\"\n [size]=\"data.size\"\n [axis]=\"data.yMap.get(i)\"></g>\n </ng-container>\n </g>\n <g class=\"series-container\">\n <ng-container *ngFor=\"let series of data.config.series\">\n <g teta-series-host\n *ngIf=\"series.visible\"\n [config]=\"data.config\"\n [series]=\"series\"></g>\n </ng-container>\n </g>\n <g class=\"annotations\">\n <g teta-annotation\n *ngFor=\"let annotation of data.config.annotations\"\n [annotation]=\"annotation\"></g>\n </g>\n <g class=\"crosshair\" *ngIf=\"data.config.tooltip?.showCrosshair\">\n <g teta-crosshair [size]=\"data.visibleRect\"></g>\n </g>\n </svg>\n\n </ng-container>\n</ng-container>\n", styles: [":host{display:flex;flex-direction:column;flex-grow:1;min-width:0;min-height:0}:host .zoomable:hover{cursor:grab}:host .zoomable:active{cursor:grabbing}:host .crosshair{cursor:crosshair}\n"] }]
|
|
2563
2682
|
}], ctorParameters: function () { return [{ type: ChartService }, { type: i0.ChangeDetectorRef }, { type: ScaleService }, { type: ZoomService }, { type: i0.ElementRef }, { type: i0.NgZone }]; } });
|
|
2564
2683
|
|
|
2565
2684
|
class LegendComponent {
|
|
@@ -2609,6 +2728,7 @@ class ChartComponent {
|
|
|
2609
2728
|
this.annotationContextMenu = new EventEmitter();
|
|
2610
2729
|
this.annotationClick = new EventEmitter();
|
|
2611
2730
|
this.annotationMove = new EventEmitter();
|
|
2731
|
+
this.zoomServiceInstance = new EventEmitter();
|
|
2612
2732
|
this._alive = true;
|
|
2613
2733
|
this.svcConfig = this.chartService.config;
|
|
2614
2734
|
this.hasSeriesData = this.svcConfig.pipe(map((_) => _.series?.length > 0 && _.series?.some((_) => _.data?.length > 0)));
|
|
@@ -2689,6 +2809,11 @@ class ChartComponent {
|
|
|
2689
2809
|
.subscribe((_) => {
|
|
2690
2810
|
this.annotationMove.emit(_);
|
|
2691
2811
|
});
|
|
2812
|
+
this.chartService.zoomInstance
|
|
2813
|
+
.pipe(takeWhile(() => this._alive))
|
|
2814
|
+
.subscribe((_) => {
|
|
2815
|
+
this.zoomServiceInstance.emit(_);
|
|
2816
|
+
});
|
|
2692
2817
|
}
|
|
2693
2818
|
ngAfterViewInit() {
|
|
2694
2819
|
}
|
|
@@ -2700,7 +2825,7 @@ class ChartComponent {
|
|
|
2700
2825
|
}
|
|
2701
2826
|
}
|
|
2702
2827
|
ChartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ChartComponent, deps: [{ token: ChartService }, { token: ZoomService }, { token: ScaleService }], target: i0.ɵɵFactoryTarget.Component });
|
|
2703
|
-
ChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.2", type: ChartComponent, selector: "teta-svg-chart", inputs: { config: "config" }, outputs: { pointerMove: "pointerMove", plotBandsMove: "plotBandsMove", plotBandClick: "plotBandClick", plotBandContextMenu: "plotBandContextMenu", plotLinesMove: "plotLinesMove", pointMove: "pointMove", chartClick: "chartClick", chartContextMenu: "chartContextMenu", annotationContextMenu: "annotationContextMenu", annotationClick: "annotationClick", annotationMove: "annotationMove" }, providers: [ChartService, ZoomService, ScaleService, BrushService], usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"{\n hasSeriesData: hasSeriesData | async,\n svcConfig: svcConfig | async\n} as data\">\n <ng-container *ngIf=\"data.hasSeriesData === true else noData\">\n <div class=\"column column_auto\">\n <teta-chart-container class=\"chart-container position-relative\"></teta-chart-container>\n </div>\n <teta-legend *ngIf=\"data.svcConfig.legend?.enable === true\" [series]=\"data.svcConfig.series\"></teta-legend>\n </ng-container>\n</ng-container>\n<ng-template #noData>\n <div class=\"column column_auto align-center justify-content-center\">\n <span class=\"font-body-3 color-text-40\">\u0414\u0430\u043D\u043D\u044B\u0435 \u043E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044E\u0442</span>\n </div>\n</ng-template>\n", styles: [":host{position:relative;display:flex;flex-direction:column;height:100%;width:100%}\n"], dependencies: [{ kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ChartContainerComponent, selector: "teta-chart-container" }, { kind: "component", type: LegendComponent, selector: "teta-legend", inputs: ["series"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2828
|
+
ChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.2", type: ChartComponent, selector: "teta-svg-chart", inputs: { config: "config" }, outputs: { pointerMove: "pointerMove", plotBandsMove: "plotBandsMove", plotBandClick: "plotBandClick", plotBandContextMenu: "plotBandContextMenu", plotLinesMove: "plotLinesMove", pointMove: "pointMove", chartClick: "chartClick", chartContextMenu: "chartContextMenu", annotationContextMenu: "annotationContextMenu", annotationClick: "annotationClick", annotationMove: "annotationMove", zoomServiceInstance: "zoomServiceInstance" }, providers: [ChartService, ZoomService, ScaleService, BrushService], usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"{\n hasSeriesData: hasSeriesData | async,\n svcConfig: svcConfig | async\n} as data\">\n <ng-container *ngIf=\"data.hasSeriesData === true else noData\">\n <div class=\"column column_auto\">\n <teta-chart-container class=\"chart-container position-relative\"></teta-chart-container>\n </div>\n <teta-legend *ngIf=\"data.svcConfig.legend?.enable === true\" [series]=\"data.svcConfig.series\"></teta-legend>\n </ng-container>\n</ng-container>\n<ng-template #noData>\n <div class=\"column column_auto align-center justify-content-center\">\n <span class=\"font-body-3 color-text-40\">\u0414\u0430\u043D\u043D\u044B\u0435 \u043E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044E\u0442</span>\n </div>\n</ng-template>\n", styles: [":host{position:relative;display:flex;flex-direction:column;height:100%;width:100%}\n"], dependencies: [{ kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ChartContainerComponent, selector: "teta-chart-container" }, { kind: "component", type: LegendComponent, selector: "teta-legend", inputs: ["series"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2704
2829
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: ChartComponent, decorators: [{
|
|
2705
2830
|
type: Component,
|
|
2706
2831
|
args: [{ selector: 'teta-svg-chart', providers: [ChartService, ZoomService, ScaleService, BrushService], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"{\n hasSeriesData: hasSeriesData | async,\n svcConfig: svcConfig | async\n} as data\">\n <ng-container *ngIf=\"data.hasSeriesData === true else noData\">\n <div class=\"column column_auto\">\n <teta-chart-container class=\"chart-container position-relative\"></teta-chart-container>\n </div>\n <teta-legend *ngIf=\"data.svcConfig.legend?.enable === true\" [series]=\"data.svcConfig.series\"></teta-legend>\n </ng-container>\n</ng-container>\n<ng-template #noData>\n <div class=\"column column_auto align-center justify-content-center\">\n <span class=\"font-body-3 color-text-40\">\u0414\u0430\u043D\u043D\u044B\u0435 \u043E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044E\u0442</span>\n </div>\n</ng-template>\n", styles: [":host{position:relative;display:flex;flex-direction:column;height:100%;width:100%}\n"] }]
|
|
@@ -2726,6 +2851,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImpor
|
|
|
2726
2851
|
type: Output
|
|
2727
2852
|
}], annotationMove: [{
|
|
2728
2853
|
type: Output
|
|
2854
|
+
}], zoomServiceInstance: [{
|
|
2855
|
+
type: Output
|
|
2729
2856
|
}], config: [{
|
|
2730
2857
|
type: Input
|
|
2731
2858
|
}] } });
|