@operato/scene-scichart 9.0.0-beta.24 → 9.0.0-beta.26
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/dist/charts/ox-scichart-multiple.js +10 -2
- package/dist/charts/ox-scichart-multiple.js.map +1 -1
- package/dist/charts/ox-scichart.js +24 -5
- package/dist/charts/ox-scichart.js.map +1 -1
- package/dist/charts/scichart-builder.d.ts +8 -0
- package/dist/charts/scichart-builder.js +427 -81
- package/dist/charts/scichart-builder.js.map +1 -1
- package/dist/scichart-multiple-timeseries.js +7 -5
- package/dist/scichart-multiple-timeseries.js.map +1 -1
- package/dist/scichart-timeseries.js +4 -3
- package/dist/scichart-timeseries.js.map +1 -1
- package/package.json +2 -2
@@ -211,7 +211,7 @@ export async function buildSciChart(config, container, { fontSize = 14, fontFami
|
|
211
211
|
var { theme, tooltip = true, animation = true, legend = {
|
212
212
|
display: true,
|
213
213
|
position: 'top'
|
214
|
-
}, scales: fromScales, xGridLine = false, yGridLine = false, y2ndGridLine = false, stacked = false, multiAxis = false
|
214
|
+
}, scales: fromScales, xGridLine = false, yGridLine = false, y2ndGridLine = false, stacked = false, multiAxis = false } = options || {};
|
215
215
|
var baseColor = getBaseColorFromTheme(theme);
|
216
216
|
if (theme === 'auto') {
|
217
217
|
theme = getThemeFromBrowser();
|
@@ -250,9 +250,31 @@ export async function buildSciChart(config, container, { fontSize = 14, fontFami
|
|
250
250
|
showAxisLabel: true /* show x-axis label for cursor */,
|
251
251
|
modifierGroup: grouped,
|
252
252
|
tooltipDataTemplate: (seriesInfo) => {
|
253
|
+
var _a, _b;
|
253
254
|
const valuesWithLabels = [];
|
254
255
|
const xySeriesInfo = seriesInfo;
|
255
|
-
|
256
|
+
let formattedValue = xySeriesInfo.yValue;
|
257
|
+
// 시리즈 이름으로 인덱스 찾기
|
258
|
+
const datasetIdx = datasets.findIndex(ds => ds.label === xySeriesInfo.seriesName);
|
259
|
+
const thisDataset = datasets[datasetIdx >= 0 ? datasetIdx : index];
|
260
|
+
const valueFormat = (thisDataset === null || thisDataset === void 0 ? void 0 : thisDataset.valueFormat) || '0.##';
|
261
|
+
if (typeof formattedValue === 'number') {
|
262
|
+
// prefix, numberFormat, suffix 분리
|
263
|
+
const match = valueFormat.match(/^(.*?)([#,0.]+)(.*?)$/);
|
264
|
+
const prefix = match ? match[1] : '';
|
265
|
+
const numberFormat = match ? match[2] : valueFormat;
|
266
|
+
const suffix = match ? match[3] : '';
|
267
|
+
const decimalPart = (_a = numberFormat.split('.')[1]) === null || _a === void 0 ? void 0 : _a.replace(/[^#0]/g, '');
|
268
|
+
let minFrac = decimalPart ? decimalPart.length : 0;
|
269
|
+
let maxFrac = ((_b = numberFormat.split('.')[1]) === null || _b === void 0 ? void 0 : _b.length) || 2;
|
270
|
+
const formattedNumber = new Intl.NumberFormat(undefined, {
|
271
|
+
minimumFractionDigits: minFrac,
|
272
|
+
maximumFractionDigits: maxFrac,
|
273
|
+
useGrouping: numberFormat.includes(',')
|
274
|
+
}).format(formattedValue);
|
275
|
+
formattedValue = `${prefix}${formattedNumber}${suffix}`;
|
276
|
+
}
|
277
|
+
valuesWithLabels.push(formattedValue);
|
256
278
|
return valuesWithLabels;
|
257
279
|
}
|
258
280
|
});
|
@@ -278,85 +300,6 @@ export async function buildSciChart(config, container, { fontSize = 14, fontFami
|
|
278
300
|
sciChartSurface.renderableSeries.add(stackedMountainCollection);
|
279
301
|
}
|
280
302
|
}
|
281
|
-
if (annotations) {
|
282
|
-
annotations.forEach(annotation => {
|
283
|
-
let sciAnnotation;
|
284
|
-
let horizontalAnchorPoint = annotation.horizontalAnchorPoint == 'Right'
|
285
|
-
? EHorizontalAnchorPoint.Right
|
286
|
-
: annotation.horizontalAnchorPoint == 'Left'
|
287
|
-
? EHorizontalAnchorPoint.Left
|
288
|
-
: EHorizontalAnchorPoint.Center;
|
289
|
-
let verticalAnchorPoint = annotation.verticalAnchorPoint == 'Top'
|
290
|
-
? EVerticalAnchorPoint.Top
|
291
|
-
: annotation.verticalAnchorPoint == 'Bottom'
|
292
|
-
? EVerticalAnchorPoint.Bottom
|
293
|
-
: EVerticalAnchorPoint.Center;
|
294
|
-
switch (annotation.type) {
|
295
|
-
case 'text':
|
296
|
-
sciAnnotation = new TextAnnotation({
|
297
|
-
x1: annotation.x1,
|
298
|
-
y1: annotation.y1,
|
299
|
-
text: annotation.text,
|
300
|
-
horizontalAnchorPoint,
|
301
|
-
verticalAnchorPoint,
|
302
|
-
fontSize: annotation.fontSize,
|
303
|
-
fontFamily: annotation.fontFamily,
|
304
|
-
textColor: convertColor(annotation.stroke, fontColor),
|
305
|
-
xCoordinateMode: (annotation.xCoordinateMode || ECoordinateMode.DataValue),
|
306
|
-
yCoordinateMode: (annotation.yCoordinateMode || ECoordinateMode.DataValue)
|
307
|
-
});
|
308
|
-
break;
|
309
|
-
case 'line':
|
310
|
-
sciAnnotation = new LineAnnotation({
|
311
|
-
x1: annotation.x1,
|
312
|
-
y1: annotation.y1,
|
313
|
-
x2: annotation.x2,
|
314
|
-
y2: annotation.y2,
|
315
|
-
stroke: convertColor(annotation.stroke, '#FF0000'),
|
316
|
-
strokeThickness: annotation.strokeThickness,
|
317
|
-
xCoordinateMode: (annotation.xCoordinateMode || ECoordinateMode.DataValue),
|
318
|
-
yCoordinateMode: (annotation.yCoordinateMode || ECoordinateMode.DataValue)
|
319
|
-
});
|
320
|
-
break;
|
321
|
-
case 'box':
|
322
|
-
sciAnnotation = new BoxAnnotation({
|
323
|
-
x1: annotation.x1,
|
324
|
-
y1: annotation.y1,
|
325
|
-
x2: annotation.x2,
|
326
|
-
y2: annotation.y2,
|
327
|
-
fill: convertColor(annotation.fill, '#FF0000'),
|
328
|
-
stroke: convertColor(annotation.stroke, '#FF0000'),
|
329
|
-
strokeThickness: annotation.strokeThickness,
|
330
|
-
xCoordinateMode: (annotation.xCoordinateMode || ECoordinateMode.DataValue),
|
331
|
-
yCoordinateMode: (annotation.yCoordinateMode || ECoordinateMode.DataValue)
|
332
|
-
});
|
333
|
-
break;
|
334
|
-
case 'horizontalLine':
|
335
|
-
sciAnnotation = new HorizontalLineAnnotation({
|
336
|
-
y1: annotation.y1,
|
337
|
-
stroke: convertColor(annotation.stroke, '#FF0000'),
|
338
|
-
strokeThickness: annotation.strokeThickness,
|
339
|
-
xCoordinateMode: (annotation.xCoordinateMode || ECoordinateMode.DataValue),
|
340
|
-
yCoordinateMode: (annotation.yCoordinateMode || ECoordinateMode.DataValue)
|
341
|
-
});
|
342
|
-
break;
|
343
|
-
case 'verticalLine':
|
344
|
-
sciAnnotation = new VerticalLineAnnotation({
|
345
|
-
x1: annotation.x1,
|
346
|
-
stroke: convertColor(annotation.stroke, '#FF0000'),
|
347
|
-
strokeThickness: annotation.strokeThickness,
|
348
|
-
xCoordinateMode: (annotation.xCoordinateMode || ECoordinateMode.DataValue),
|
349
|
-
yCoordinateMode: (annotation.yCoordinateMode || ECoordinateMode.DataValue)
|
350
|
-
});
|
351
|
-
break;
|
352
|
-
default:
|
353
|
-
break;
|
354
|
-
}
|
355
|
-
if (sciAnnotation) {
|
356
|
-
sciChartSurface.annotations.add(sciAnnotation);
|
357
|
-
}
|
358
|
-
});
|
359
|
-
}
|
360
303
|
sciChartSurface.chartModifiers.add(new RubberBandXyZoomModifier({ executeOn: EExecuteOn.MouseRightButton, modifierGroup: grouped }),
|
361
304
|
// new ZoomPanModifier({ xyDirection: EXyDirection.XDirection }),
|
362
305
|
new ZoomPanModifier({ xyDirection: EXyDirection.XDirection }), new MouseWheelZoomModifier({ xyDirection: EXyDirection.XDirection }), new ZoomExtentsModifier(), new XAxisDragModifier(), new YAxisDragModifier());
|
@@ -458,4 +401,407 @@ function getDefaultYAxis(wasmContext, sciChartSurface) {
|
|
458
401
|
});
|
459
402
|
sciChartSurface.yAxes.add(yAxis);
|
460
403
|
}
|
404
|
+
// Helper 함수 - verticalAnchorPoint에 따라 적절한 y1 값을 반환
|
405
|
+
function getYPositionByAnchor(anchor) {
|
406
|
+
if (anchor === EVerticalAnchorPoint.Top) {
|
407
|
+
return 0.05; // 상단에서 5% 위치
|
408
|
+
}
|
409
|
+
else if (anchor === EVerticalAnchorPoint.Center) {
|
410
|
+
return 0.5; // 중앙
|
411
|
+
}
|
412
|
+
else if (anchor === EVerticalAnchorPoint.Bottom) {
|
413
|
+
return 0.95; // 차트 맨 아래
|
414
|
+
}
|
415
|
+
// 기본값 (Bottom이거나 값이 없는 경우)
|
416
|
+
return 0.95; // 바닥에서 5% 위치
|
417
|
+
}
|
418
|
+
// Helper 함수 - verticalAnchorPoint에 따라 적절한 좌표 모드 반환
|
419
|
+
function getYCoordModeByAnchor(anchor) {
|
420
|
+
// verticalAnchorPoint 값과 상관없이 상대 좌표 사용
|
421
|
+
return ECoordinateMode.Relative;
|
422
|
+
}
|
423
|
+
export function updateAnnotations(sciChartSurface, annotations = [], fromData, rawData = [], fontFamily, fontColor) {
|
424
|
+
sciChartSurface.annotations.clear();
|
425
|
+
if (annotations) {
|
426
|
+
annotations.forEach(annotation => {
|
427
|
+
let sciAnnotation;
|
428
|
+
let horizontalAnchorPoint = annotation.horizontalAnchorPoint == 'Right'
|
429
|
+
? EHorizontalAnchorPoint.Right
|
430
|
+
: annotation.horizontalAnchorPoint == 'Left'
|
431
|
+
? EHorizontalAnchorPoint.Left
|
432
|
+
: EHorizontalAnchorPoint.Center;
|
433
|
+
let verticalAnchorPoint = annotation.verticalAnchorPoint == 'Top'
|
434
|
+
? EVerticalAnchorPoint.Top
|
435
|
+
: annotation.verticalAnchorPoint == 'Bottom'
|
436
|
+
? EVerticalAnchorPoint.Bottom
|
437
|
+
: EVerticalAnchorPoint.Center;
|
438
|
+
// dataKey가 있는 경우 데이터와 연동
|
439
|
+
if (annotation.dataKey && rawData && rawData.length > 0) {
|
440
|
+
const attrX = (fromData === null || fromData === void 0 ? void 0 : fromData.labelDataKey) || ''; // X축 데이터 키 가져오기
|
441
|
+
if (annotation.type === 'verticalLine') {
|
442
|
+
// 수직 라인: falsy => truthy 변화 지점에만 표시
|
443
|
+
let prevValue = undefined;
|
444
|
+
for (let i = 0; i < rawData.length; i++) {
|
445
|
+
// 원본 데이터에서 직접 값 가져오기
|
446
|
+
const currentValue = rawData[i][annotation.dataKey];
|
447
|
+
const isChanged = prevValue !== currentValue;
|
448
|
+
const isTruthy = !!currentValue || annotation.text;
|
449
|
+
if (isTruthy && isChanged) {
|
450
|
+
// falsy에서 truthy로 변화한 지점
|
451
|
+
// X 값은 인덱스나 타임스탬프 사용
|
452
|
+
const xValue = attrX ? new Date(rawData[i][attrX]).getTime() / 1000 : i;
|
453
|
+
// 수직선 추가
|
454
|
+
const sciVerticalLine = new VerticalLineAnnotation({
|
455
|
+
x1: xValue,
|
456
|
+
stroke: convertColor(annotation.stroke, '#FF0000'),
|
457
|
+
strokeThickness: annotation.strokeThickness,
|
458
|
+
xCoordinateMode: (annotation.xCoordinateMode || ECoordinateMode.DataValue),
|
459
|
+
yCoordinateMode: (annotation.yCoordinateMode || ECoordinateMode.DataValue)
|
460
|
+
});
|
461
|
+
sciChartSurface.annotations.add(sciVerticalLine);
|
462
|
+
// 텍스트 레이블 추가
|
463
|
+
// if (annotation.text !== undefined || currentValue !== undefined) {
|
464
|
+
// 표시할 텍스트 결정
|
465
|
+
const labelText = currentValue ? String(currentValue) : annotation.text;
|
466
|
+
// 텍스트 주석 추가 (수직선 상단에)
|
467
|
+
const sciTextAnnotation = new TextAnnotation({
|
468
|
+
// 동일한 X 위치 사용
|
469
|
+
x1: xValue,
|
470
|
+
// verticalAnchorPoint에 따라 Y 위치 결정
|
471
|
+
y1: getYPositionByAnchor(annotation.verticalAnchorPoint),
|
472
|
+
text: labelText,
|
473
|
+
// 가운데 정렬
|
474
|
+
horizontalAnchorPoint: (annotation.horizontalAnchorPoint ||
|
475
|
+
EHorizontalAnchorPoint.Center),
|
476
|
+
// 텍스트의 하단이 y1에 위치
|
477
|
+
verticalAnchorPoint: (annotation.verticalAnchorPoint ||
|
478
|
+
EVerticalAnchorPoint.Bottom),
|
479
|
+
fontFamily: annotation.fontFamily || fontFamily,
|
480
|
+
fontSize: annotation.fontSize || 14,
|
481
|
+
textColor: convertColor(annotation.stroke, '#FF0000'),
|
482
|
+
background: 'rgba(255, 255, 255, 0.7)', // 텍스트 배경 추가
|
483
|
+
padding: { left: 5, top: 5, right: 5, bottom: 5 }, // 패딩 추가
|
484
|
+
xCoordinateMode: ECoordinateMode.DataValue,
|
485
|
+
// verticalAnchorPoint에 따라 좌표 모드 결정
|
486
|
+
yCoordinateMode: getYCoordModeByAnchor(annotation.verticalAnchorPoint)
|
487
|
+
});
|
488
|
+
sciChartSurface.annotations.add(sciTextAnnotation);
|
489
|
+
// }
|
490
|
+
}
|
491
|
+
prevValue = currentValue;
|
492
|
+
}
|
493
|
+
// 기본 annotation 처리 건너뛰기
|
494
|
+
return;
|
495
|
+
}
|
496
|
+
else if (annotation.type === 'text') {
|
497
|
+
// 텍스트: 해당 값을 그대로 출력
|
498
|
+
for (let i = 0; i < rawData.length; i++) {
|
499
|
+
// 원본 데이터에서 직접 값 가져오기
|
500
|
+
const value = rawData[i][annotation.dataKey];
|
501
|
+
// null이나 undefined가 아닌 값만 표시
|
502
|
+
if (value !== undefined && value !== null) {
|
503
|
+
// X 값은 인덱스나 타임스탬프 사용
|
504
|
+
const xValue = attrX ? new Date(rawData[i][attrX]).getTime() / 1000 : i;
|
505
|
+
const sciTextAnnotation = new TextAnnotation({
|
506
|
+
x1: xValue,
|
507
|
+
y1: value,
|
508
|
+
text: String(value),
|
509
|
+
horizontalAnchorPoint,
|
510
|
+
verticalAnchorPoint,
|
511
|
+
fontSize: annotation.fontSize,
|
512
|
+
fontFamily: annotation.fontFamily,
|
513
|
+
textColor: convertColor(annotation.stroke, fontColor),
|
514
|
+
xCoordinateMode: (annotation.xCoordinateMode || ECoordinateMode.DataValue),
|
515
|
+
yCoordinateMode: (annotation.yCoordinateMode || ECoordinateMode.DataValue)
|
516
|
+
});
|
517
|
+
sciChartSurface.annotations.add(sciTextAnnotation);
|
518
|
+
}
|
519
|
+
}
|
520
|
+
// 기본 annotation 처리 건너뛰기
|
521
|
+
return;
|
522
|
+
}
|
523
|
+
else {
|
524
|
+
// 다른 타입의 annotation은 원래 로직으로 처리
|
525
|
+
// 원본 데이터에서 값 추출
|
526
|
+
const dataValues = rawData.map(item => item[annotation.dataKey]).filter(v => v !== undefined);
|
527
|
+
if (dataValues.length > 0) {
|
528
|
+
// annotation 타입에 따라 데이터 값을 적용
|
529
|
+
if (annotation.type === 'horizontalLine') {
|
530
|
+
annotation.y1 = dataValues[0];
|
531
|
+
}
|
532
|
+
else if (annotation.type === 'line' || annotation.type === 'box') {
|
533
|
+
// 데이터 값이 최소 한 개 이상인 경우에만 적용
|
534
|
+
if (annotation.yCoordinateMode === 'DataValue') {
|
535
|
+
annotation.y1 = dataValues[0];
|
536
|
+
}
|
537
|
+
if (annotation.xCoordinateMode === 'DataValue' && !annotation.x1) {
|
538
|
+
annotation.x1 = 0;
|
539
|
+
}
|
540
|
+
// 두 번째 지점이 필요한 경우 (line, box)
|
541
|
+
if (dataValues.length > 1) {
|
542
|
+
if (annotation.yCoordinateMode === 'DataValue') {
|
543
|
+
annotation.y2 = dataValues[dataValues.length - 1];
|
544
|
+
}
|
545
|
+
if (annotation.xCoordinateMode === 'DataValue' && !annotation.x2) {
|
546
|
+
annotation.x2 = dataValues.length - 1;
|
547
|
+
}
|
548
|
+
}
|
549
|
+
}
|
550
|
+
}
|
551
|
+
}
|
552
|
+
}
|
553
|
+
else {
|
554
|
+
// 기본 annotation 생성 (dataKey가 없거나 rawData가 없는 경우)
|
555
|
+
switch (annotation.type) {
|
556
|
+
case 'text':
|
557
|
+
sciAnnotation = new TextAnnotation({
|
558
|
+
x1: annotation.x1,
|
559
|
+
y1: annotation.y1,
|
560
|
+
text: annotation.text,
|
561
|
+
horizontalAnchorPoint,
|
562
|
+
verticalAnchorPoint,
|
563
|
+
fontSize: annotation.fontSize,
|
564
|
+
fontFamily: annotation.fontFamily,
|
565
|
+
textColor: convertColor(annotation.stroke, fontColor),
|
566
|
+
xCoordinateMode: (annotation.xCoordinateMode || ECoordinateMode.DataValue),
|
567
|
+
yCoordinateMode: (annotation.yCoordinateMode || ECoordinateMode.DataValue)
|
568
|
+
});
|
569
|
+
break;
|
570
|
+
case 'line':
|
571
|
+
sciAnnotation = new LineAnnotation({
|
572
|
+
x1: annotation.x1,
|
573
|
+
y1: annotation.y1,
|
574
|
+
x2: annotation.x2,
|
575
|
+
y2: annotation.y2,
|
576
|
+
stroke: convertColor(annotation.stroke, '#FF0000'),
|
577
|
+
strokeThickness: annotation.strokeThickness,
|
578
|
+
xCoordinateMode: (annotation.xCoordinateMode || ECoordinateMode.DataValue),
|
579
|
+
yCoordinateMode: (annotation.yCoordinateMode || ECoordinateMode.DataValue)
|
580
|
+
});
|
581
|
+
break;
|
582
|
+
case 'box':
|
583
|
+
sciAnnotation = new BoxAnnotation({
|
584
|
+
x1: annotation.x1,
|
585
|
+
y1: annotation.y1,
|
586
|
+
x2: annotation.x2,
|
587
|
+
y2: annotation.y2,
|
588
|
+
fill: convertColor(annotation.fill, '#FF0000'),
|
589
|
+
stroke: convertColor(annotation.stroke, '#FF0000'),
|
590
|
+
strokeThickness: annotation.strokeThickness,
|
591
|
+
xCoordinateMode: (annotation.xCoordinateMode || ECoordinateMode.DataValue),
|
592
|
+
yCoordinateMode: (annotation.yCoordinateMode || ECoordinateMode.DataValue)
|
593
|
+
});
|
594
|
+
break;
|
595
|
+
case 'horizontalLine':
|
596
|
+
sciAnnotation = new HorizontalLineAnnotation({
|
597
|
+
y1: annotation.y1,
|
598
|
+
stroke: convertColor(annotation.stroke, '#FF0000'),
|
599
|
+
strokeThickness: annotation.strokeThickness,
|
600
|
+
xCoordinateMode: (annotation.xCoordinateMode || ECoordinateMode.DataValue),
|
601
|
+
yCoordinateMode: (annotation.yCoordinateMode || ECoordinateMode.DataValue)
|
602
|
+
});
|
603
|
+
break;
|
604
|
+
case 'verticalLine':
|
605
|
+
sciAnnotation = new VerticalLineAnnotation({
|
606
|
+
x1: annotation.x1,
|
607
|
+
stroke: convertColor(annotation.stroke, '#FF0000'),
|
608
|
+
strokeThickness: annotation.strokeThickness,
|
609
|
+
xCoordinateMode: (annotation.xCoordinateMode || ECoordinateMode.DataValue),
|
610
|
+
yCoordinateMode: (annotation.yCoordinateMode || ECoordinateMode.DataValue)
|
611
|
+
});
|
612
|
+
// 텍스트가 있는 경우에만 텍스트 주석 추가
|
613
|
+
if (annotation.text) {
|
614
|
+
// 수직선을 먼저 추가
|
615
|
+
if (sciAnnotation) {
|
616
|
+
sciChartSurface.annotations.add(sciAnnotation);
|
617
|
+
}
|
618
|
+
// 텍스트 주석 생성
|
619
|
+
const textAnnotation = new TextAnnotation({
|
620
|
+
x1: annotation.x1,
|
621
|
+
y1: getYPositionByAnchor(annotation.verticalAnchorPoint),
|
622
|
+
text: annotation.text,
|
623
|
+
horizontalAnchorPoint: (annotation.horizontalAnchorPoint ||
|
624
|
+
EHorizontalAnchorPoint.Center),
|
625
|
+
verticalAnchorPoint: (annotation.verticalAnchorPoint ||
|
626
|
+
EVerticalAnchorPoint.Bottom),
|
627
|
+
fontFamily: annotation.fontFamily || fontFamily,
|
628
|
+
fontSize: annotation.fontSize || 14,
|
629
|
+
textColor: convertColor(annotation.stroke, '#FF0000'),
|
630
|
+
background: 'rgba(255, 255, 255, 0.7)', // 텍스트 배경 추가
|
631
|
+
padding: { left: 5, top: 5, right: 5, bottom: 5 }, // 패딩 추가
|
632
|
+
xCoordinateMode: (annotation.xCoordinateMode || ECoordinateMode.DataValue),
|
633
|
+
yCoordinateMode: getYCoordModeByAnchor(annotation.verticalAnchorPoint)
|
634
|
+
});
|
635
|
+
// 텍스트 주석 추가
|
636
|
+
sciChartSurface.annotations.add(textAnnotation);
|
637
|
+
sciAnnotation = null; // 이미 추가했으므로 아래에서 다시 추가하지 않도록 null로 설정
|
638
|
+
}
|
639
|
+
break;
|
640
|
+
default:
|
641
|
+
console.error('Unknown annotation type:', annotation.type);
|
642
|
+
break;
|
643
|
+
}
|
644
|
+
}
|
645
|
+
// switch (annotation.type) {
|
646
|
+
// case 'text':
|
647
|
+
// sciAnnotation = new TextAnnotation({
|
648
|
+
// x1: annotation.x1,
|
649
|
+
// y1: annotation.y1,
|
650
|
+
// text: annotation.text,
|
651
|
+
// horizontalAnchorPoint,
|
652
|
+
// verticalAnchorPoint,
|
653
|
+
// fontSize: annotation.fontSize,
|
654
|
+
// fontFamily: annotation.fontFamily,
|
655
|
+
// textColor: convertColor(annotation.stroke, fontColor),
|
656
|
+
// xCoordinateMode: (annotation.xCoordinateMode || ECoordinateMode.DataValue) as ECoordinateMode,
|
657
|
+
// yCoordinateMode: (annotation.yCoordinateMode || ECoordinateMode.DataValue) as ECoordinateMode
|
658
|
+
// })
|
659
|
+
// break
|
660
|
+
// case 'line':
|
661
|
+
// sciAnnotation = new LineAnnotation({
|
662
|
+
// x1: annotation.x1,
|
663
|
+
// y1: annotation.y1,
|
664
|
+
// x2: annotation.x2,
|
665
|
+
// y2: annotation.y2,
|
666
|
+
// stroke: convertColor(annotation.stroke, '#FF0000'),
|
667
|
+
// strokeThickness: annotation.strokeThickness,
|
668
|
+
// xCoordinateMode: (annotation.xCoordinateMode || ECoordinateMode.DataValue) as ECoordinateMode,
|
669
|
+
// yCoordinateMode: (annotation.yCoordinateMode || ECoordinateMode.DataValue) as ECoordinateMode
|
670
|
+
// })
|
671
|
+
// break
|
672
|
+
// case 'box':
|
673
|
+
// sciAnnotation = new BoxAnnotation({
|
674
|
+
// x1: annotation.x1,
|
675
|
+
// y1: annotation.y1,
|
676
|
+
// x2: annotation.x2,
|
677
|
+
// y2: annotation.y2,
|
678
|
+
// fill: convertColor(annotation.fill, '#FF0000'),
|
679
|
+
// stroke: convertColor(annotation.stroke, '#FF0000'),
|
680
|
+
// strokeThickness: annotation.strokeThickness,
|
681
|
+
// xCoordinateMode: (annotation.xCoordinateMode || ECoordinateMode.DataValue) as ECoordinateMode,
|
682
|
+
// yCoordinateMode: (annotation.yCoordinateMode || ECoordinateMode.DataValue) as ECoordinateMode
|
683
|
+
// })
|
684
|
+
// break
|
685
|
+
// case 'horizontalLine':
|
686
|
+
// sciAnnotation = new HorizontalLineAnnotation({
|
687
|
+
// y1: annotation.y1,
|
688
|
+
// stroke: convertColor(annotation.stroke, '#FF0000'),
|
689
|
+
// strokeThickness: annotation.strokeThickness,
|
690
|
+
// xCoordinateMode: (annotation.xCoordinateMode || ECoordinateMode.DataValue) as ECoordinateMode,
|
691
|
+
// yCoordinateMode: (annotation.yCoordinateMode || ECoordinateMode.DataValue) as ECoordinateMode
|
692
|
+
// })
|
693
|
+
// break
|
694
|
+
// case 'verticalLine':
|
695
|
+
// sciAnnotation = new VerticalLineAnnotation({
|
696
|
+
// x1: annotation.x1,
|
697
|
+
// stroke: convertColor(annotation.stroke, '#FF0000'),
|
698
|
+
// strokeThickness: annotation.strokeThickness,
|
699
|
+
// xCoordinateMode: (annotation.xCoordinateMode || ECoordinateMode.DataValue) as ECoordinateMode,
|
700
|
+
// yCoordinateMode: (annotation.yCoordinateMode || ECoordinateMode.DataValue) as ECoordinateMode
|
701
|
+
// })
|
702
|
+
// break
|
703
|
+
// default:
|
704
|
+
// break
|
705
|
+
// }
|
706
|
+
if (sciAnnotation) {
|
707
|
+
sciChartSurface.annotations.add(sciAnnotation);
|
708
|
+
}
|
709
|
+
});
|
710
|
+
}
|
711
|
+
}
|
712
|
+
/**
|
713
|
+
* 데이터 append 시, 값이 변경된 경우(이전 값과 다를 때)만 annotation을 추가하고,
|
714
|
+
* annotation의 텍스트는 변경된 값이 되도록 한다.
|
715
|
+
*/
|
716
|
+
export function addAnnotationsOnDataChange(sciChartSurface, annotations = [], fromData, prevData = [], appendum = [], fontFamily, fontColor) {
|
717
|
+
if (!annotations || !appendum || !appendum.length)
|
718
|
+
return;
|
719
|
+
const attrX = (fromData === null || fromData === void 0 ? void 0 : fromData.labelDataKey) || '';
|
720
|
+
annotations
|
721
|
+
.filter(annotation => annotation.dataKey && (annotation.type == 'text' || annotation.type == 'verticalLine'))
|
722
|
+
.forEach(annotation => {
|
723
|
+
if (!annotation.dataKey)
|
724
|
+
return;
|
725
|
+
let prevValue = prevData.length > 0 ? prevData[prevData.length - 1][annotation.dataKey] : undefined;
|
726
|
+
appendum.forEach((item, idx) => {
|
727
|
+
const currentValue = item[annotation.dataKey];
|
728
|
+
const isChanged = prevValue !== currentValue;
|
729
|
+
const isTruthy = !!currentValue || annotation.text;
|
730
|
+
if (isChanged && isTruthy) {
|
731
|
+
const xValue = attrX ? new Date(item[attrX]).getTime() / 1000 : prevData.length + idx;
|
732
|
+
// 수직선 annotation 추가
|
733
|
+
if (annotation.type === 'verticalLine') {
|
734
|
+
const sciVerticalLine = new VerticalLineAnnotation({
|
735
|
+
x1: xValue,
|
736
|
+
stroke: convertColor(annotation.stroke, '#FF0000'),
|
737
|
+
strokeThickness: annotation.strokeThickness,
|
738
|
+
xCoordinateMode: (annotation.xCoordinateMode || ECoordinateMode.DataValue),
|
739
|
+
yCoordinateMode: (annotation.yCoordinateMode || ECoordinateMode.DataValue)
|
740
|
+
});
|
741
|
+
sciChartSurface.annotations.add(sciVerticalLine);
|
742
|
+
// 텍스트 annotation 추가 (변경된 값이 텍스트)
|
743
|
+
const labelText = currentValue ? String(currentValue) : annotation.text;
|
744
|
+
const sciTextAnnotation = new TextAnnotation({
|
745
|
+
x1: xValue,
|
746
|
+
y1: getYPositionByAnchor(annotation.verticalAnchorPoint),
|
747
|
+
text: labelText,
|
748
|
+
horizontalAnchorPoint: (annotation.horizontalAnchorPoint ||
|
749
|
+
EHorizontalAnchorPoint.Center),
|
750
|
+
verticalAnchorPoint: (annotation.verticalAnchorPoint ||
|
751
|
+
EVerticalAnchorPoint.Bottom),
|
752
|
+
fontFamily: annotation.fontFamily || fontFamily,
|
753
|
+
fontSize: annotation.fontSize || 14,
|
754
|
+
textColor: convertColor(annotation.stroke, '#FF0000'),
|
755
|
+
background: 'rgba(255, 255, 255, 0.7)',
|
756
|
+
padding: { left: 5, top: 5, right: 5, bottom: 5 },
|
757
|
+
xCoordinateMode: ECoordinateMode.DataValue,
|
758
|
+
yCoordinateMode: getYCoordModeByAnchor(annotation.verticalAnchorPoint)
|
759
|
+
});
|
760
|
+
sciChartSurface.annotations.add(sciTextAnnotation);
|
761
|
+
}
|
762
|
+
// 텍스트 annotation 타입도 지원
|
763
|
+
if (annotation.type === 'text') {
|
764
|
+
const sciTextAnnotation = new TextAnnotation({
|
765
|
+
x1: xValue,
|
766
|
+
y1: currentValue,
|
767
|
+
text: String(currentValue),
|
768
|
+
horizontalAnchorPoint: (annotation.horizontalAnchorPoint ||
|
769
|
+
EHorizontalAnchorPoint.Center),
|
770
|
+
verticalAnchorPoint: (annotation.verticalAnchorPoint ||
|
771
|
+
EVerticalAnchorPoint.Bottom),
|
772
|
+
fontFamily: annotation.fontFamily || fontFamily,
|
773
|
+
fontSize: annotation.fontSize || 14,
|
774
|
+
textColor: convertColor(annotation.stroke, fontColor),
|
775
|
+
xCoordinateMode: (annotation.xCoordinateMode || ECoordinateMode.DataValue),
|
776
|
+
yCoordinateMode: (annotation.yCoordinateMode || ECoordinateMode.DataValue)
|
777
|
+
});
|
778
|
+
sciChartSurface.annotations.add(sciTextAnnotation);
|
779
|
+
}
|
780
|
+
}
|
781
|
+
prevValue = currentValue;
|
782
|
+
});
|
783
|
+
});
|
784
|
+
}
|
785
|
+
export function removeAnnotationsByData(sciChartSurface, removedData = [], fromData, annotations = []) {
|
786
|
+
if (!removedData || !removedData.length || !annotations.length)
|
787
|
+
return;
|
788
|
+
const attrX = (fromData === null || fromData === void 0 ? void 0 : fromData.labelDataKey) || '';
|
789
|
+
const removedXValues = removedData
|
790
|
+
.map(item => {
|
791
|
+
const xValue = attrX ? new Date(item[attrX]).getTime() / 1000 : undefined;
|
792
|
+
return isNaN(Number(xValue)) ? undefined : xValue;
|
793
|
+
})
|
794
|
+
.filter(x => x !== undefined);
|
795
|
+
if (!removedXValues.length)
|
796
|
+
return;
|
797
|
+
// annotation config 조건에 맞는 것만 삭제
|
798
|
+
annotations
|
799
|
+
.filter(annotation => annotation.dataKey && (annotation.type === 'text' || annotation.type === 'verticalLine'))
|
800
|
+
.forEach(() => {
|
801
|
+
sciChartSurface.annotations
|
802
|
+
.asArray()
|
803
|
+
.filter((a) => removedXValues.includes(a.x1))
|
804
|
+
.forEach((a) => sciChartSurface.annotations.remove(a));
|
805
|
+
});
|
806
|
+
}
|
461
807
|
//# sourceMappingURL=scichart-builder.js.map
|