axidio-styleguide-library1-v2 0.4.21 → 0.4.23
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.
|
@@ -3381,910 +3381,1029 @@ class GroupChartComponent extends ComponentUniqueId {
|
|
|
3381
3381
|
super();
|
|
3382
3382
|
this.clickEvent = new EventEmitter();
|
|
3383
3383
|
this.headerMenuclickEvent = new EventEmitter();
|
|
3384
|
+
this.chartConfiguration = {};
|
|
3384
3385
|
this.isHeaderVisible = true;
|
|
3385
|
-
this.
|
|
3386
|
+
this.isTopCaptionVisible = true;
|
|
3387
|
+
this.uniqueId = this.getUniqueId();
|
|
3386
3388
|
this.isTransparentBackground = false;
|
|
3387
|
-
this.
|
|
3388
|
-
this.
|
|
3389
|
+
this.isCC = false;
|
|
3390
|
+
this.isZoomedOut = true;
|
|
3391
|
+
this.CONSTANTS = {
|
|
3392
|
+
RIGHT_SVG_WIDTH: 60,
|
|
3393
|
+
LEFT_RIGHT_SPACES: 50,
|
|
3394
|
+
SHORT_TICK_LENGTH: 4,
|
|
3395
|
+
LONG_TICK_LENGTH: 16,
|
|
3396
|
+
SHORT_TICK_LENGTH_BG: 5,
|
|
3397
|
+
LONG_TICK_LENGTH_BG: 30,
|
|
3398
|
+
DESKTOP_BAR_WIDTH: 40, // Desktop bar width
|
|
3399
|
+
MOBILE_BAR_WIDTH: 25, // Mobile/Tablet bar width (reduced)
|
|
3400
|
+
BAR_GAP: 30, // Gap between bars (increased for better separation)
|
|
3401
|
+
ZOOM_THRESHOLD: 30,
|
|
3402
|
+
ZOOM_IN_THRESHOLD: 8,
|
|
3403
|
+
};
|
|
3389
3404
|
this.defaultConfiguration = {
|
|
3390
|
-
|
|
3391
|
-
"top": 30,
|
|
3392
|
-
"left": 110,
|
|
3393
|
-
"right": 40,
|
|
3394
|
-
"bottom": 50
|
|
3395
|
-
},
|
|
3396
|
-
labelFormatter: ChartHelper.defaultFormatter,
|
|
3405
|
+
margin: { top: 20, right: 20, bottom: 20, left: 40 },
|
|
3397
3406
|
svgHeight: 70,
|
|
3407
|
+
legendHeight: '10%',
|
|
3398
3408
|
numberOfYTicks: 5,
|
|
3399
|
-
|
|
3400
|
-
|
|
3409
|
+
labelFormatter: ChartHelper.defaultFormatter,
|
|
3410
|
+
xAxisLabelFomatter: ChartHelper.defaultFormatter,
|
|
3401
3411
|
yAxisLabelFomatter: ChartHelper.defaultFormatter,
|
|
3412
|
+
yLineAxisLabelFomatter: ChartHelper.defaultFormatter,
|
|
3402
3413
|
lineGraphColor: '#F6D283',
|
|
3403
3414
|
showLineChartAxis: true,
|
|
3404
|
-
|
|
3415
|
+
showLegend: false,
|
|
3416
|
+
forComparison: true,
|
|
3405
3417
|
headerMenuOptions: HeaderConfigHelper.headerConfig.headerMenuOptions,
|
|
3406
|
-
yAxisGrid:
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3418
|
+
yAxisGrid: false,
|
|
3419
|
+
// Optional configs with undefined defaults
|
|
3420
|
+
isHeaderVisible: undefined,
|
|
3421
|
+
isTransparentBackground: undefined,
|
|
3422
|
+
isTopCaptionVisible: undefined,
|
|
3423
|
+
isMultiChartGridLine: undefined,
|
|
3424
|
+
isFullScreen: undefined,
|
|
3425
|
+
customYscale: undefined,
|
|
3426
|
+
isXaxisLabelHidden: undefined,
|
|
3427
|
+
isYaxisLabelHidden: undefined,
|
|
3428
|
+
isYaxisHidden: undefined,
|
|
3429
|
+
isYaxisDashed: undefined,
|
|
3430
|
+
isXaxisColor: undefined,
|
|
3431
|
+
textFormatter: undefined,
|
|
3432
|
+
showTotalOnTop: undefined,
|
|
3433
|
+
backendFormatterHasPriority: undefined,
|
|
3434
|
+
showAngledLabels: undefined,
|
|
3435
|
+
isNoAlternateXaxisText: undefined,
|
|
3436
|
+
isXgridBetweenLabels: undefined,
|
|
3437
|
+
showXaxisTop: undefined,
|
|
3438
|
+
xAxisGrid: undefined,
|
|
3439
|
+
xLabelsOnSameLine: undefined,
|
|
3440
|
+
hideXaxisTick: undefined,
|
|
3441
|
+
isDrilldownChart: undefined,
|
|
3442
|
+
isTargetLine: undefined,
|
|
3443
|
+
displayTitleOnTop: undefined,
|
|
3444
|
+
isToggleVisible: undefined,
|
|
3445
|
+
isTitleHidden: undefined,
|
|
3417
3446
|
};
|
|
3418
|
-
this.uniqueId = this.getUniqueId();
|
|
3419
|
-
this.isZoomedOut = false;
|
|
3420
|
-
this.isDD1Open = false;
|
|
3421
|
-
this.isDD2Open = false;
|
|
3422
|
-
this.keepOrder = (a, b) => a;
|
|
3423
3447
|
}
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
|
|
3448
|
+
ngOnChanges() {
|
|
3449
|
+
this.removeExistingChart();
|
|
3450
|
+
this.initializeStackedChart();
|
|
3427
3451
|
}
|
|
3428
3452
|
onResized(event) {
|
|
3429
3453
|
setTimeout(() => {
|
|
3430
|
-
|
|
3431
|
-
this.
|
|
3454
|
+
this.removeExistingChart();
|
|
3455
|
+
this.initializeStackedChart();
|
|
3432
3456
|
}, 10);
|
|
3433
3457
|
}
|
|
3434
|
-
isZoomOutSelected(isZoomOut
|
|
3458
|
+
isZoomOutSelected(isZoomOut) {
|
|
3435
3459
|
this.isZoomedOut = isZoomOut;
|
|
3436
|
-
this.
|
|
3437
|
-
}
|
|
3438
|
-
handleZoominZoomoutClick({ isZoomOut, event }) {
|
|
3439
|
-
this.isZoomOutSelected(isZoomOut, event);
|
|
3440
|
-
}
|
|
3441
|
-
isLegendVisible() {
|
|
3442
|
-
return !!(this.chartData?.metaData?.colors &&
|
|
3443
|
-
Object.keys(this.chartData.metaData.colors).length > 1);
|
|
3460
|
+
this.ngOnChanges();
|
|
3444
3461
|
}
|
|
3445
|
-
|
|
3446
|
-
this.
|
|
3447
|
-
const chartContext = this.prepareChartData();
|
|
3448
|
-
const dimensions = this.calculateDimensions(chartContext);
|
|
3449
|
-
const scales = this.createScales(chartContext, dimensions);
|
|
3450
|
-
const svgElements = this.createSVGStructure(dimensions);
|
|
3451
|
-
this.renderAxes(svgElements, scales, chartContext, dimensions);
|
|
3452
|
-
this.renderBars(svgElements.svg, chartContext, scales, dimensions);
|
|
3453
|
-
this.renderLabels(svgElements, scales, chartContext, dimensions);
|
|
3454
|
-
this.renderTargetLine(svgElements, scales, chartContext, dimensions);
|
|
3455
|
-
this.renderLineGraph(svgElements.svg, chartContext, scales);
|
|
3462
|
+
removeExistingChart() {
|
|
3463
|
+
d3.select('#' + this.uniqueId).remove();
|
|
3456
3464
|
}
|
|
3457
3465
|
mergeConfigurations() {
|
|
3458
3466
|
for (const key in this.defaultConfiguration) {
|
|
3459
3467
|
this.chartConfiguration[key] = ChartHelper.getValueByConfigurationType(key, this.defaultConfiguration, this.customChartConfiguration);
|
|
3460
3468
|
}
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3469
|
+
}
|
|
3470
|
+
prepareMetaData(metaData) {
|
|
3471
|
+
if (!metaData.unit)
|
|
3472
|
+
metaData.unit = '';
|
|
3473
|
+
if (metaData.isCC)
|
|
3474
|
+
this.isCC = metaData.isCC;
|
|
3475
|
+
if (metaData.barWithoutClick?.length) {
|
|
3476
|
+
metaData.barWithoutClick = metaData.barWithoutClick.map(el => el.toLowerCase());
|
|
3466
3477
|
}
|
|
3467
|
-
|
|
3468
|
-
|
|
3478
|
+
else {
|
|
3479
|
+
metaData.barWithoutClick = [];
|
|
3469
3480
|
}
|
|
3481
|
+
return metaData;
|
|
3470
3482
|
}
|
|
3471
|
-
|
|
3472
|
-
const
|
|
3473
|
-
const
|
|
3474
|
-
const
|
|
3475
|
-
|
|
3476
|
-
|
|
3483
|
+
calculateDimensions(chartContainer, verticalContainer, margin, dataLength) {
|
|
3484
|
+
const containerWidth = chartContainer.node().getBoundingClientRect().width;
|
|
3485
|
+
const containerHeight = verticalContainer.node().getBoundingClientRect().height;
|
|
3486
|
+
const leftAxisWidth = 80;
|
|
3487
|
+
const rightAxisWidth = this.CONSTANTS.RIGHT_SVG_WIDTH;
|
|
3488
|
+
const availableWidth = containerWidth - leftAxisWidth - rightAxisWidth;
|
|
3489
|
+
let width = availableWidth;
|
|
3490
|
+
let height = containerHeight * (this.chartConfiguration.svgHeight / 100) - margin.top - margin.bottom;
|
|
3491
|
+
if (dataLength > this.CONSTANTS.ZOOM_THRESHOLD && this.isZoomedOut) {
|
|
3492
|
+
const minWidth = dataLength * 25;
|
|
3493
|
+
width = Math.max(width, minWidth);
|
|
3477
3494
|
}
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
metaData,
|
|
3481
|
-
lineData,
|
|
3482
|
-
keyList: metaData.keyList,
|
|
3483
|
-
colorMap: metaData.colors,
|
|
3484
|
-
isRia: this.customChartConfiguration?.isRia || false,
|
|
3485
|
-
};
|
|
3486
|
-
}
|
|
3487
|
-
calculateDimensions(chartContext) {
|
|
3488
|
-
const chartContainer = d3.select(this.containerElt.nativeElement);
|
|
3489
|
-
const verticalstackedcontainer = d3.select(this.groupcontainerElt.nativeElement);
|
|
3490
|
-
const margin = this.chartConfiguration.margin;
|
|
3491
|
-
let width = this.calculateWidth(chartContainer, margin);
|
|
3492
|
-
let height = this.calculateHeight(verticalstackedcontainer, margin);
|
|
3493
|
-
return { width, height, margin, chartContainer, verticalstackedcontainer };
|
|
3494
|
-
}
|
|
3495
|
-
calculateWidth(chartContainer, margin) {
|
|
3496
|
-
const baseWidth = parseInt(chartContainer.style('width')) - margin.left - margin.right;
|
|
3497
|
-
const dataLength = this.chartData.data.length;
|
|
3498
|
-
let width = baseWidth;
|
|
3499
|
-
if (dataLength > 30 && this.isZoomedOut) {
|
|
3500
|
-
const multiplier = this.chartData.dropdownData1 ? 60 : 40;
|
|
3501
|
-
width = Math.max(width, dataLength * multiplier);
|
|
3495
|
+
if (dataLength > this.CONSTANTS.ZOOM_IN_THRESHOLD && !this.isZoomedOut) {
|
|
3496
|
+
width = dataLength * 130;
|
|
3502
3497
|
}
|
|
3503
|
-
if (this.
|
|
3504
|
-
|
|
3498
|
+
if (this.chartConfiguration.isFullScreen) {
|
|
3499
|
+
height = this.chartConfiguration.svgHeight !== 80
|
|
3500
|
+
? this.chartConfiguration.svgHeight
|
|
3501
|
+
: containerHeight;
|
|
3505
3502
|
}
|
|
3506
|
-
if (
|
|
3507
|
-
|
|
3508
|
-
|
|
3503
|
+
if (this.chartConfiguration.isDrilldownChart) {
|
|
3504
|
+
height = containerHeight - margin.top - margin.bottom - 130;
|
|
3505
|
+
}
|
|
3506
|
+
const isMobileOrTablet = window.innerWidth < 1024;
|
|
3507
|
+
let barWidth;
|
|
3508
|
+
let barPadding;
|
|
3509
|
+
if (isMobileOrTablet) {
|
|
3510
|
+
if (dataLength === 1) {
|
|
3511
|
+
barWidth = 60;
|
|
3512
|
+
barPadding = 0;
|
|
3513
|
+
}
|
|
3514
|
+
else if (dataLength === 2) {
|
|
3515
|
+
barWidth = 50;
|
|
3516
|
+
barPadding = 45;
|
|
3517
|
+
}
|
|
3518
|
+
else if (dataLength === 3) {
|
|
3519
|
+
barWidth = 45;
|
|
3520
|
+
barPadding = 40;
|
|
3521
|
+
}
|
|
3522
|
+
else if (dataLength <= 5) {
|
|
3523
|
+
barWidth = 35;
|
|
3524
|
+
barPadding = 30;
|
|
3509
3525
|
}
|
|
3510
3526
|
else {
|
|
3511
|
-
|
|
3527
|
+
barWidth = 25;
|
|
3528
|
+
barPadding = 25;
|
|
3512
3529
|
}
|
|
3513
3530
|
}
|
|
3514
|
-
return width;
|
|
3515
|
-
}
|
|
3516
|
-
calculateHeight(verticalstackedcontainer, margin) {
|
|
3517
|
-
let height = parseInt(verticalstackedcontainer.style('height')) *
|
|
3518
|
-
(this.chartConfiguration.svgHeight / 100) -
|
|
3519
|
-
margin.top -
|
|
3520
|
-
margin.bottom;
|
|
3521
|
-
if (this.chartConfiguration.isFullScreen && this.chartConfiguration.svgHeight !== 70) {
|
|
3522
|
-
height = this.chartConfiguration.svgHeight;
|
|
3523
|
-
}
|
|
3524
|
-
else if (this.chartConfiguration.isFullScreen) {
|
|
3525
|
-
height = parseInt(verticalstackedcontainer.style('height'));
|
|
3526
|
-
}
|
|
3527
|
-
if (this.chartConfiguration.isDrilldownChart && !this.isHeaderVisible) {
|
|
3528
|
-
height = parseInt(verticalstackedcontainer.style('height')) - margin.top - margin.bottom - 130;
|
|
3529
|
-
}
|
|
3530
|
-
if (this.chartConfiguration.isHeaderVisible) {
|
|
3531
|
-
height = parseInt(verticalstackedcontainer.style('height')) - margin.top - margin.bottom - 100;
|
|
3532
|
-
}
|
|
3533
|
-
return height;
|
|
3534
|
-
}
|
|
3535
|
-
createScales(chartContext, dimensions) {
|
|
3536
|
-
const { data, metaData, lineData, keyList } = chartContext;
|
|
3537
|
-
const { width, height, margin } = dimensions;
|
|
3538
|
-
const leftAndRightSpaces = 50;
|
|
3539
|
-
const rightSvgWidth = 60;
|
|
3540
|
-
const groups = d3.map(data, (d) => d.name).keys();
|
|
3541
|
-
let x;
|
|
3542
|
-
if (this.chartConfiguration.isMultiChartGridLine !== undefined) {
|
|
3543
|
-
x = d3
|
|
3544
|
-
.scaleBand()
|
|
3545
|
-
.rangeRound([width, 0])
|
|
3546
|
-
.align(0.5)
|
|
3547
|
-
.padding(0.5)
|
|
3548
|
-
.domain(data.map((d) => d.name.toLowerCase()));
|
|
3549
|
-
}
|
|
3550
3531
|
else {
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
.domain(groups)
|
|
3554
|
-
.range([leftAndRightSpaces, width - rightSvgWidth - leftAndRightSpaces])
|
|
3555
|
-
.padding(0.3);
|
|
3556
|
-
}
|
|
3557
|
-
const xScaleFromOrigin = d3.scaleBand().domain(groups).range([0, width - rightSvgWidth]);
|
|
3558
|
-
const xSubgroup = d3.scaleBand().domain(keyList).range([0, x.bandwidth()]);
|
|
3559
|
-
const maxValue = this.calculateMaxValue(data, keyList);
|
|
3560
|
-
const y = d3.scaleLinear().domain([0, maxValue]).nice().rangeRound([height, 0]);
|
|
3561
|
-
let lineYscale = null;
|
|
3562
|
-
if (lineData) {
|
|
3563
|
-
lineYscale = this.createLineYScale(lineData, height);
|
|
3532
|
+
barWidth = this.CONSTANTS.DESKTOP_BAR_WIDTH;
|
|
3533
|
+
barPadding = this.CONSTANTS.BAR_GAP;
|
|
3564
3534
|
}
|
|
3565
|
-
const
|
|
3535
|
+
const totalBarsWidth = barWidth * dataLength;
|
|
3536
|
+
const totalGaps = barPadding * (dataLength - 1);
|
|
3537
|
+
const minRequiredWidth = totalBarsWidth + totalGaps + (this.CONSTANTS.LEFT_RIGHT_SPACES * 2);
|
|
3538
|
+
const requiredSvgWidth = Math.max(availableWidth, minRequiredWidth);
|
|
3566
3539
|
return {
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
rightSvgWidth,
|
|
3540
|
+
width,
|
|
3541
|
+
height,
|
|
3542
|
+
containerWidth,
|
|
3543
|
+
containerHeight,
|
|
3544
|
+
barWidth,
|
|
3545
|
+
barPadding,
|
|
3546
|
+
requiredSvgWidth,
|
|
3575
3547
|
};
|
|
3576
3548
|
}
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
if (this.chartConfiguration.customYscale) {
|
|
3585
|
-
maxValue *= this.chartConfiguration.customYscale;
|
|
3586
|
-
}
|
|
3587
|
-
if (this.chartData.targetLineData && maxValue < this.chartData.targetLineData.target) {
|
|
3588
|
-
const target = this.chartData.targetLineData.target;
|
|
3589
|
-
maxValue = maxValue < 10 && target < 10 ? target + 3 : target + 20;
|
|
3590
|
-
}
|
|
3591
|
-
return maxValue;
|
|
3592
|
-
}
|
|
3593
|
-
createLineYScale(lineData, height) {
|
|
3594
|
-
let maxLineValue = d3.max(lineData, (d) => +d.value) || 0;
|
|
3595
|
-
maxLineValue *= this.chartConfiguration.customYscale || 1;
|
|
3596
|
-
let minLineValue = d3.min(lineData, (d) => +d.value) || 0;
|
|
3597
|
-
if (maxLineValue > 0)
|
|
3598
|
-
minLineValue -= 3;
|
|
3599
|
-
if (minLineValue > 0)
|
|
3600
|
-
minLineValue = 0;
|
|
3601
|
-
return d3.scaleLinear().domain([minLineValue, maxLineValue]).range([height, minLineValue]);
|
|
3602
|
-
}
|
|
3603
|
-
createSVGStructure(dimensions) {
|
|
3604
|
-
const { chartContainer, height, margin } = dimensions;
|
|
3605
|
-
const rightSvgWidth = 60;
|
|
3606
|
-
// Calculate proper left SVG width to include label
|
|
3607
|
-
const leftSvgWidth = margin.left + 20;
|
|
3608
|
-
const outerContainer = chartContainer
|
|
3549
|
+
createSvgContainers(chartContainer, dimensions, margin, hasXLabel // Add this parameter
|
|
3550
|
+
) {
|
|
3551
|
+
// Calculate total height including space for X-axis label if present
|
|
3552
|
+
const xLabelSpace = hasXLabel ? 30 : 0;
|
|
3553
|
+
const totalHeight = dimensions.height + margin.top + margin.bottom + xLabelSpace;
|
|
3554
|
+
// Main wrapper
|
|
3555
|
+
const chartWrapper = chartContainer
|
|
3609
3556
|
.append('div')
|
|
3610
3557
|
.attr('id', this.uniqueId)
|
|
3611
|
-
.attr('class', '
|
|
3558
|
+
.attr('class', 'chart-wrapper-main')
|
|
3559
|
+
.style('position', 'relative')
|
|
3612
3560
|
.style('width', '100%')
|
|
3613
|
-
.style('height', `${
|
|
3614
|
-
|
|
3615
|
-
.
|
|
3616
|
-
.
|
|
3617
|
-
.style('margin-left', '15px')
|
|
3618
|
-
.style('position', 'relative'); // FIXED: For absolute positioning
|
|
3619
|
-
// FIXED: Create proper Y-axis SVG with enough space for label
|
|
3620
|
-
const svgYAxisLeft = outerContainer
|
|
3621
|
-
.append('svg')
|
|
3622
|
-
.attr('width', leftSvgWidth)
|
|
3623
|
-
.attr('height', height + margin.top + margin.bottom)
|
|
3561
|
+
.style('height', `${totalHeight}px`); // Include X-label space
|
|
3562
|
+
const leftAxisContainer = chartWrapper
|
|
3563
|
+
.append('div')
|
|
3564
|
+
.attr('class', 'left-axis-container')
|
|
3624
3565
|
.style('position', 'absolute')
|
|
3625
3566
|
.style('left', '0')
|
|
3626
3567
|
.style('top', '0')
|
|
3627
|
-
.style('
|
|
3628
|
-
.
|
|
3629
|
-
.
|
|
3630
|
-
|
|
3568
|
+
.style('width', '80px')
|
|
3569
|
+
.style('height', `${dimensions.height + margin.top + margin.bottom}px`)
|
|
3570
|
+
.style('background-color', 'var(--card-bg)')
|
|
3571
|
+
.style('z-index', '10');
|
|
3572
|
+
const svgYAxisLeft = leftAxisContainer
|
|
3631
3573
|
.append('svg')
|
|
3632
|
-
.attr('width',
|
|
3633
|
-
.attr('height', height + margin.top + margin.bottom)
|
|
3634
|
-
.style('position', 'absolute')
|
|
3635
|
-
.style('right', '12px')
|
|
3636
|
-
.style('top', '0')
|
|
3637
|
-
.style('z-index', 1)
|
|
3574
|
+
.attr('width', '80')
|
|
3575
|
+
.attr('height', dimensions.height + margin.top + margin.bottom)
|
|
3638
3576
|
.append('g')
|
|
3639
|
-
.attr('transform', `translate(
|
|
3640
|
-
|
|
3577
|
+
.attr('transform', `translate(79,${margin.top})`);
|
|
3578
|
+
// Right Y-axis - Fixed
|
|
3579
|
+
const rightAxisContainer = chartWrapper
|
|
3641
3580
|
.append('div')
|
|
3642
|
-
.attr('class', '
|
|
3643
|
-
.style('
|
|
3644
|
-
.style('
|
|
3581
|
+
.attr('class', 'right-axis-container')
|
|
3582
|
+
.style('position', 'absolute')
|
|
3583
|
+
.style('right', '0')
|
|
3584
|
+
.style('top', '0')
|
|
3585
|
+
.style('width', `${this.CONSTANTS.RIGHT_SVG_WIDTH}px`)
|
|
3586
|
+
.style('height', `${dimensions.height + margin.top + margin.bottom}px`) // Exclude X-label space
|
|
3587
|
+
.style('background-color', 'var(--card-bg)')
|
|
3588
|
+
.style('z-index', '10');
|
|
3589
|
+
const svgYAxisRight = rightAxisContainer
|
|
3590
|
+
.append('svg')
|
|
3591
|
+
.attr('width', this.CONSTANTS.RIGHT_SVG_WIDTH)
|
|
3592
|
+
.attr('height', dimensions.height + margin.top + margin.bottom)
|
|
3593
|
+
.append('g')
|
|
3594
|
+
.attr('transform', `translate(0,${margin.top})`);
|
|
3595
|
+
// Scrollable middle area
|
|
3596
|
+
const scrollableContainer = chartWrapper
|
|
3597
|
+
.append('div')
|
|
3598
|
+
.attr('class', 'scrollable-chart-container')
|
|
3599
|
+
.style('position', 'absolute')
|
|
3600
|
+
.style('left', '80px') // Exactly where left container ends
|
|
3601
|
+
.style('right', `${this.CONSTANTS.RIGHT_SVG_WIDTH}px`)
|
|
3602
|
+
.style('top', '0')
|
|
3603
|
+
.style('width', 'auto')
|
|
3604
|
+
.style('height', `${dimensions.height + margin.top + margin.bottom}px`)
|
|
3645
3605
|
.style('overflow-x', 'auto')
|
|
3646
3606
|
.style('overflow-y', 'hidden');
|
|
3607
|
+
const innerContainer = scrollableContainer
|
|
3608
|
+
.append('div')
|
|
3609
|
+
.attr('class', 'inner-chart-container')
|
|
3610
|
+
.style('min-width', '100%');
|
|
3647
3611
|
const svg = innerContainer
|
|
3648
3612
|
.append('svg')
|
|
3649
|
-
.attr('width', dimensions.
|
|
3650
|
-
.attr('height', height + margin.top + margin.bottom)
|
|
3613
|
+
.attr('width', dimensions.requiredSvgWidth)
|
|
3614
|
+
.attr('height', dimensions.height + margin.top + margin.bottom + 30)
|
|
3651
3615
|
.append('g')
|
|
3652
3616
|
.attr('transform', `translate(0,${margin.top})`);
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3617
|
+
// Fixed bottom container for X-axis label
|
|
3618
|
+
const bottomLabelContainer = chartWrapper
|
|
3619
|
+
.append('div')
|
|
3620
|
+
.attr('class', 'bottom-label-container')
|
|
3621
|
+
.style('position', 'absolute')
|
|
3622
|
+
.style('left', '80px')
|
|
3623
|
+
.style('right', `${this.CONSTANTS.RIGHT_SVG_WIDTH}px`)
|
|
3624
|
+
.style('bottom', '0')
|
|
3625
|
+
.style('height', `${xLabelSpace}px`)
|
|
3626
|
+
.style('display', 'flex')
|
|
3627
|
+
.style('justify-content', 'center')
|
|
3628
|
+
.style('align-items', 'center')
|
|
3629
|
+
.style('background-color', 'var(--card-bg)')
|
|
3630
|
+
.style('z-index', '10');
|
|
3631
|
+
return { svg, svgYAxisLeft, svgYAxisRight, innerContainer, bottomLabelContainer };
|
|
3632
|
+
}
|
|
3633
|
+
createScales(data, layers, lineData, dimensions) {
|
|
3634
|
+
const { width, height, barWidth, barPadding } = dimensions;
|
|
3635
|
+
// Calculate bar positioning
|
|
3636
|
+
const totalBarsWidth = data.length * barWidth;
|
|
3637
|
+
const totalSpacing = (data.length - 1) * barPadding;
|
|
3638
|
+
const requiredWidth = totalBarsWidth + totalSpacing + (this.CONSTANTS.LEFT_RIGHT_SPACES * 2);
|
|
3639
|
+
const effectiveWidth = Math.max(width, requiredWidth);
|
|
3640
|
+
const paddingRatio = barPadding / (barWidth + barPadding);
|
|
3641
|
+
// X-scale starts from 0 (no left spacing for grid alignment)
|
|
3642
|
+
const xScale = d3
|
|
3643
|
+
.scaleBand()
|
|
3644
|
+
.rangeRound([0, dimensions.requiredSvgWidth])
|
|
3645
|
+
.domain(data.map(d => d.name).reverse())
|
|
3646
|
+
.paddingInner(paddingRatio)
|
|
3647
|
+
.paddingOuter(0.1) // Small padding for visual spacing
|
|
3648
|
+
.align(0.5);
|
|
3649
|
+
const xScaleFromOrigin = d3
|
|
3650
|
+
.scaleBand()
|
|
3651
|
+
.rangeRound([width, 0])
|
|
3652
|
+
.domain(data.map(d => d.name).reverse());
|
|
3653
|
+
const yScale = d3.scaleLinear().rangeRound([height, 0]);
|
|
3654
|
+
let maxValue = d3.max(layers, (d) => d3.max(d, (d) => d[1]));
|
|
3655
|
+
if (maxValue === 0) {
|
|
3656
|
+
maxValue = this.chartData.targetLineData
|
|
3657
|
+
? Number(this.chartData.targetLineData.target) + 20
|
|
3658
|
+
: 100;
|
|
3664
3659
|
}
|
|
3665
|
-
if (this.chartConfiguration.
|
|
3666
|
-
this.
|
|
3660
|
+
if (this.chartConfiguration.customYscale) {
|
|
3661
|
+
maxValue *= this.chartConfiguration.customYscale;
|
|
3662
|
+
}
|
|
3663
|
+
if (this.chartData.targetLineData && maxValue < Number(this.chartData.targetLineData.target)) {
|
|
3664
|
+
const target = Number(this.chartData.targetLineData.target);
|
|
3665
|
+
maxValue = maxValue < 10 && target < 10 ? target + 3 : target + 20;
|
|
3667
3666
|
}
|
|
3668
|
-
|
|
3669
|
-
|
|
3667
|
+
yScale.domain([0, maxValue]).nice();
|
|
3668
|
+
let lineYscale = null;
|
|
3669
|
+
if (lineData) {
|
|
3670
|
+
lineYscale = d3
|
|
3671
|
+
.scaleLinear()
|
|
3672
|
+
.domain([0, d3.max(lineData, d => +d.value)])
|
|
3673
|
+
.range([height, 0]);
|
|
3670
3674
|
}
|
|
3675
|
+
return { xScale, xScaleFromOrigin, yScale, lineYscale };
|
|
3671
3676
|
}
|
|
3672
|
-
|
|
3673
|
-
const
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
.
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
3677
|
+
createAxes(scales) {
|
|
3678
|
+
const xAxis = d3
|
|
3679
|
+
.axisBottom(scales.xScale)
|
|
3680
|
+
.tickSize(0)
|
|
3681
|
+
.tickFormat(this.chartConfiguration.xAxisLabelFomatter);
|
|
3682
|
+
const yAxis = d3
|
|
3683
|
+
.axisLeft(scales.yScale)
|
|
3684
|
+
.ticks(this.chartConfiguration.numberOfYTicks)
|
|
3685
|
+
.tickSize(0)
|
|
3686
|
+
.tickFormat(this.chartConfiguration.yAxisLabelFomatter);
|
|
3687
|
+
let yLineAxis = null;
|
|
3688
|
+
if (scales.lineYscale) {
|
|
3689
|
+
yLineAxis = d3
|
|
3690
|
+
.axisRight(scales.lineYscale)
|
|
3691
|
+
.ticks(this.chartConfiguration.numberOfYTicks)
|
|
3692
|
+
.tickSize(0)
|
|
3693
|
+
.tickFormat(this.chartConfiguration.yLineAxisLabelFomatter);
|
|
3694
|
+
}
|
|
3695
|
+
return { xAxis, yAxis, yLineAxis };
|
|
3696
|
+
}
|
|
3697
|
+
renderBars(svg, layers, scales, metaData, dimensions) {
|
|
3698
|
+
const layer = svg
|
|
3699
|
+
.selectAll('.layer')
|
|
3700
|
+
.data(layers)
|
|
3701
|
+
.enter()
|
|
3702
|
+
.append('g')
|
|
3703
|
+
.attr('class', 'layer')
|
|
3704
|
+
.style('fill', (d) => metaData.colors[d.key]);
|
|
3705
|
+
const rect = layer
|
|
3706
|
+
.selectAll('rect')
|
|
3707
|
+
.data((d) => d)
|
|
3708
|
+
.enter();
|
|
3709
|
+
this.appendRectangles(rect, scales, metaData, dimensions);
|
|
3710
|
+
this.addInteractions(rect, svg, metaData, scales);
|
|
3711
|
+
return rect;
|
|
3712
|
+
}
|
|
3713
|
+
appendRectangles(rect, scales, metaData, dimensions) {
|
|
3714
|
+
const { barWidth, barPadding } = dimensions;
|
|
3715
|
+
const { xScale, yScale } = scales;
|
|
3716
|
+
rect
|
|
3717
|
+
.append('rect')
|
|
3718
|
+
.on('click', (d) => {
|
|
3719
|
+
if (!this.chartData.lineData || this.chartConfiguration.forComparison) {
|
|
3720
|
+
if (!metaData.barWithoutClick?.includes(d.data.name.toLowerCase())) {
|
|
3721
|
+
this.handleClick(d.data.name);
|
|
3722
|
+
}
|
|
3723
|
+
}
|
|
3724
|
+
})
|
|
3725
|
+
.attr('y', (d) => {
|
|
3726
|
+
if (!isNaN(d[0]) && !isNaN(d[1])) {
|
|
3727
|
+
const actualHeight = yScale(d[0]) - yScale(d[1]);
|
|
3728
|
+
return actualHeight < 3 ? yScale(d[0]) - 3 : yScale(d[1]);
|
|
3729
|
+
}
|
|
3730
|
+
return 0;
|
|
3731
|
+
})
|
|
3732
|
+
.attr('x', (d) => {
|
|
3733
|
+
const xPosition = xScale(d.data.name);
|
|
3734
|
+
const bandwidth = xScale.bandwidth();
|
|
3735
|
+
if (!this.chartConfiguration.isMultiChartGridLine) {
|
|
3736
|
+
return xPosition + (bandwidth - barWidth) / 2;
|
|
3737
|
+
}
|
|
3738
|
+
if (this.chartConfiguration.isDrilldownChart && this.chartData.data.length <= 3) {
|
|
3739
|
+
return xPosition + bandwidth / 2 - 35;
|
|
3740
|
+
}
|
|
3741
|
+
const calculatedWidth = bandwidth * 0.8;
|
|
3742
|
+
return xPosition + (bandwidth - calculatedWidth) / 2;
|
|
3743
|
+
})
|
|
3744
|
+
.attr('height', (d) => {
|
|
3745
|
+
if (!isNaN(d[0]) && !isNaN(d[1])) {
|
|
3746
|
+
const actualHeight = yScale(d[0]) - yScale(d[1]);
|
|
3747
|
+
return actualHeight < 3 ? 3 : actualHeight;
|
|
3695
3748
|
}
|
|
3749
|
+
return 0;
|
|
3750
|
+
})
|
|
3751
|
+
.attr('width', (d) => {
|
|
3752
|
+
if (!this.chartConfiguration.isMultiChartGridLine)
|
|
3753
|
+
return barWidth;
|
|
3754
|
+
if (this.chartConfiguration.isDrilldownChart && this.chartData.data.length <= 3) {
|
|
3755
|
+
return 70;
|
|
3756
|
+
}
|
|
3757
|
+
return xScale.bandwidth() * 0.8;
|
|
3758
|
+
})
|
|
3759
|
+
.style('cursor', (d) => {
|
|
3760
|
+
if (metaData.hasDrillDown) {
|
|
3761
|
+
if (metaData.barWithoutClick?.includes(d.data.name.toLowerCase())) {
|
|
3762
|
+
return 'default';
|
|
3763
|
+
}
|
|
3764
|
+
return 'pointer';
|
|
3765
|
+
}
|
|
3766
|
+
return 'default';
|
|
3767
|
+
})
|
|
3768
|
+
.style('fill', (d) => this.getBarColor(d, metaData));
|
|
3769
|
+
}
|
|
3770
|
+
getBarColor(d, metaData) {
|
|
3771
|
+
if (!isNaN(d[0]) &&
|
|
3772
|
+
!isNaN(d[1]) &&
|
|
3773
|
+
this.chartData.targetLineData &&
|
|
3774
|
+
parseFloat(d[1]) - parseFloat(d[0]) >= parseFloat(String(this.chartData.targetLineData.target))) {
|
|
3775
|
+
return this.chartData.targetLineData.barAboveTargetColor || metaData.colors[d.key];
|
|
3696
3776
|
}
|
|
3697
|
-
|
|
3698
|
-
|
|
3777
|
+
return metaData.colors[d.key];
|
|
3778
|
+
}
|
|
3779
|
+
addInteractions(rect, svg, metaData, scales) {
|
|
3780
|
+
rect
|
|
3781
|
+
.selectAll('rect')
|
|
3782
|
+
.on('mouseenter', (d) => this.handleMouseOver(d, svg, metaData, scales))
|
|
3783
|
+
.on('mouseout', (d) => this.handleMouseOut(svg, metaData));
|
|
3784
|
+
}
|
|
3785
|
+
handleMouseOver(d, svg, metaData, scales) {
|
|
3786
|
+
if (!this.chartConfiguration.displayTitleOnTop)
|
|
3787
|
+
return;
|
|
3788
|
+
svg.selectAll('rect')
|
|
3789
|
+
.filter((data) => data === d)
|
|
3790
|
+
.style('fill', (d) => this.getHoverColor(d, metaData));
|
|
3791
|
+
this.displayTooltip(d, svg, metaData, scales);
|
|
3792
|
+
}
|
|
3793
|
+
getHoverColor(d, metaData) {
|
|
3794
|
+
if (!isNaN(d[0]) &&
|
|
3795
|
+
!isNaN(d[1]) &&
|
|
3796
|
+
this.chartData.targetLineData &&
|
|
3797
|
+
parseFloat(d[1]) - parseFloat(d[0]) >= parseFloat(String(this.chartData.targetLineData.target))) {
|
|
3798
|
+
return this.chartData.targetLineData.barAboveTargetHoverColor ||
|
|
3799
|
+
this.chartData.targetLineData.barAboveTargetColor ||
|
|
3800
|
+
metaData.colors[d.key];
|
|
3699
3801
|
}
|
|
3700
|
-
|
|
3701
|
-
|
|
3802
|
+
return metaData.hoverColor || metaData.colors[d.key];
|
|
3803
|
+
}
|
|
3804
|
+
displayTooltip(d, svg, metaData, scales) {
|
|
3805
|
+
const { xScale, yScale } = scales;
|
|
3806
|
+
const value = d[1] - d[0];
|
|
3807
|
+
if (isNaN(value))
|
|
3808
|
+
return;
|
|
3809
|
+
const bandwidth = xScale.bandwidth();
|
|
3810
|
+
// Fixed tooltip width for all resolutions
|
|
3811
|
+
const width = /week/i.test(d.data.name) && /\d{4}-\d{2}-\d{2}/.test(d.data.name)
|
|
3812
|
+
? '250px'
|
|
3813
|
+
: bandwidth + this.CONSTANTS.LEFT_RIGHT_SPACES * 2 > 180
|
|
3814
|
+
? '180px'
|
|
3815
|
+
: bandwidth + this.CONSTANTS.LEFT_RIGHT_SPACES * 2;
|
|
3816
|
+
svg
|
|
3817
|
+
.append('foreignObject')
|
|
3818
|
+
.attr('x', this.calculateTooltipX(d, xScale, width))
|
|
3819
|
+
.attr('class', 'lib-verticalstack-title-ontop')
|
|
3820
|
+
.attr('y', yScale(d[1]) - 51)
|
|
3821
|
+
.attr('width', width)
|
|
3822
|
+
.attr('height', 40)
|
|
3823
|
+
.append('xhtml:div')
|
|
3824
|
+
.attr('class', 'title')
|
|
3825
|
+
.style('z-index', 99)
|
|
3826
|
+
.html(this.generateTooltipHtml(d, metaData, value));
|
|
3827
|
+
}
|
|
3828
|
+
calculateTooltipX(d, xScale, width) {
|
|
3829
|
+
const bandwidth = xScale.bandwidth();
|
|
3830
|
+
const numericWidth = typeof width === 'string' ? parseInt(width) : width;
|
|
3831
|
+
if (bandwidth + this.CONSTANTS.LEFT_RIGHT_SPACES * 2 > 180) {
|
|
3832
|
+
return xScale(d.data.name) - this.CONSTANTS.LEFT_RIGHT_SPACES +
|
|
3833
|
+
(bandwidth + this.CONSTANTS.LEFT_RIGHT_SPACES * 2 - 180) / 2;
|
|
3834
|
+
}
|
|
3835
|
+
return xScale(d.data.name) - this.CONSTANTS.LEFT_RIGHT_SPACES;
|
|
3836
|
+
}
|
|
3837
|
+
generateTooltipHtml(d, metaData, value) {
|
|
3838
|
+
if (value === 0)
|
|
3839
|
+
return '<span class="title-top-text">0</span>';
|
|
3840
|
+
const dataType = metaData.dataType || '';
|
|
3841
|
+
const name = d.data.name ? `<span class="title-bar-name">${d.data.name}</span>` : '';
|
|
3842
|
+
const valueText = metaData.unit
|
|
3843
|
+
? `${metaData.unit}${value} ${dataType}`
|
|
3844
|
+
: `${value} ${dataType}`;
|
|
3845
|
+
return `${name}<span class="title-top-text">${valueText}</span>`;
|
|
3846
|
+
}
|
|
3847
|
+
handleMouseOut(svg, metaData) {
|
|
3848
|
+
if (!this.chartConfiguration.displayTitleOnTop)
|
|
3849
|
+
return;
|
|
3850
|
+
svg.selectAll('rect')
|
|
3851
|
+
.style('fill', (d) => this.getBarColor(d, metaData));
|
|
3852
|
+
svg.selectAll('.lib-verticalstack-title-ontop').remove();
|
|
3853
|
+
}
|
|
3854
|
+
renderAxisLabels(svg, svgYAxisLeft, bottomLabelContainer, metaData, dimensions, margin) {
|
|
3855
|
+
if (metaData.yLabel) {
|
|
3856
|
+
this.addYAxisLabel(svgYAxisLeft, metaData.yLabel, dimensions.height, margin);
|
|
3857
|
+
}
|
|
3858
|
+
if (metaData.xLabel) {
|
|
3859
|
+
this.addXAxisLabel(bottomLabelContainer, metaData.xLabel);
|
|
3860
|
+
}
|
|
3861
|
+
}
|
|
3862
|
+
addYAxisLabel(svgYAxisLeft, label, height, margin) {
|
|
3863
|
+
const isria = this.customChartConfiguration?.isRia;
|
|
3864
|
+
const isAcronym = this.isAcronymLabel(label);
|
|
3865
|
+
const yPosition = isria ? -margin.left / 2 - 30 : -margin.left / 2 - 40;
|
|
3866
|
+
svgYAxisLeft.selectAll('.lib-axis-group-label, .lib-ylabel-drilldowncharts, .lib-ylabel-weeklyCharts').remove();
|
|
3867
|
+
svgYAxisLeft
|
|
3868
|
+
.append('text')
|
|
3869
|
+
.attr('class', this.getYAxisLabelClass())
|
|
3870
|
+
.attr('style', this.chartConfiguration.yAxisCustomlabelStyles)
|
|
3871
|
+
.attr('transform', 'rotate(-90)')
|
|
3872
|
+
.attr('y', yPosition)
|
|
3873
|
+
.attr('x', -height / 2)
|
|
3874
|
+
.attr('dy', '1em')
|
|
3875
|
+
.style('text-anchor', 'middle')
|
|
3876
|
+
.style('fill', 'var(--chart-text-color)')
|
|
3877
|
+
.text(isAcronym ? label.toUpperCase() : label.toLowerCase())
|
|
3878
|
+
.style('text-transform', isAcronym ? 'none' : 'capitalize');
|
|
3879
|
+
}
|
|
3880
|
+
addXAxisLabel(bottomLabelContainer, label) {
|
|
3881
|
+
const isAcronym = this.isAcronymLabel(label);
|
|
3882
|
+
bottomLabelContainer
|
|
3883
|
+
.append('div')
|
|
3884
|
+
.style('width', '100%')
|
|
3885
|
+
.style('text-align', 'center')
|
|
3886
|
+
.style('font-size', '12px')
|
|
3887
|
+
.style('font-weight', '600')
|
|
3888
|
+
.style('font-family', 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto')
|
|
3889
|
+
.style('color', 'var(--chart-text-color)')
|
|
3890
|
+
.style('text-transform', isAcronym ? 'none' : 'capitalize')
|
|
3891
|
+
.text(isAcronym ? label.toUpperCase() : label.toLowerCase());
|
|
3892
|
+
}
|
|
3893
|
+
isAcronymLabel(label) {
|
|
3894
|
+
const cleanLabel = label.replace(/[^A-Za-z]/g, '');
|
|
3895
|
+
return (label.length <= 4 && /^[A-Z]+$/.test(label)) ||
|
|
3896
|
+
(label === label.toUpperCase() && /[A-Z]/.test(label));
|
|
3897
|
+
}
|
|
3898
|
+
getYAxisLabelClass() {
|
|
3899
|
+
let baseClass = 'lib-axis-group-label font-size-1';
|
|
3900
|
+
if (this.chartConfiguration.isDrilldownChart) {
|
|
3901
|
+
return `${baseClass} lib-ylabel-drilldowncharts`;
|
|
3902
|
+
}
|
|
3903
|
+
if (this.chartConfiguration.isMultiChartGridLine !== undefined) {
|
|
3904
|
+
return `${baseClass} lib-ylabel-weeklyCharts`;
|
|
3905
|
+
}
|
|
3906
|
+
return `${baseClass} lib-axis-waterfall-label`;
|
|
3907
|
+
}
|
|
3908
|
+
getXAxisLabelClass() {
|
|
3909
|
+
let baseClass = 'lib-axis-group-label font-size-1';
|
|
3910
|
+
if (this.chartConfiguration.isDrilldownChart) {
|
|
3911
|
+
return `${baseClass} lib-xlabel-drilldowncharts`;
|
|
3702
3912
|
}
|
|
3703
|
-
|
|
3704
|
-
|
|
3913
|
+
if (this.chartConfiguration.isMultiChartGridLine !== undefined) {
|
|
3914
|
+
return `${baseClass} lib-xlabel-weeklyCharts`;
|
|
3915
|
+
}
|
|
3916
|
+
return `${baseClass} lib-axis-waterfall-label`;
|
|
3917
|
+
}
|
|
3918
|
+
renderGridsFromLeftAxis(svgMain, svgYAxisLeft, scales, dimensions) {
|
|
3919
|
+
if (!this.chartConfiguration.yAxisGrid)
|
|
3920
|
+
return;
|
|
3921
|
+
// We want horizontal grid lines to span the full visible width:
|
|
3922
|
+
// the inner SVG (requiredSvgWidth) plus the right axis width.
|
|
3923
|
+
const gridSpan = dimensions.requiredSvgWidth + this.CONSTANTS.RIGHT_SVG_WIDTH;
|
|
3924
|
+
// Append the grid to the main (inner) SVG so lines are rendered across the scrollable area.
|
|
3925
|
+
svgMain
|
|
3705
3926
|
.append('g')
|
|
3706
|
-
.attr('class', '
|
|
3707
|
-
.attr('transform',
|
|
3708
|
-
.
|
|
3709
|
-
.
|
|
3710
|
-
|
|
3711
|
-
.
|
|
3712
|
-
.
|
|
3713
|
-
.style('
|
|
3714
|
-
.
|
|
3715
|
-
|
|
3716
|
-
|
|
3717
|
-
|
|
3927
|
+
.attr('class', 'grid horizontal-grid-from-left')
|
|
3928
|
+
.attr('transform', 'translate(0,0)')
|
|
3929
|
+
.call(d3
|
|
3930
|
+
.axisLeft(scales.yScale)
|
|
3931
|
+
.ticks(this.chartConfiguration.numberOfYTicks)
|
|
3932
|
+
.tickSize(-gridSpan)
|
|
3933
|
+
.tickFormat(''))
|
|
3934
|
+
.style('color', 'var(--chart-grid-color)')
|
|
3935
|
+
.style('opacity', '1')
|
|
3936
|
+
.call((g) => {
|
|
3937
|
+
g.select('.domain').remove();
|
|
3938
|
+
g.selectAll('.tick line')
|
|
3939
|
+
.style('stroke', 'var(--chart-grid-color)')
|
|
3940
|
+
.style('stroke-width', '1px');
|
|
3941
|
+
});
|
|
3942
|
+
}
|
|
3943
|
+
applyConfigurationFlags() {
|
|
3944
|
+
if (this.chartConfiguration.isHeaderVisible !== undefined) {
|
|
3945
|
+
this.isHeaderVisible = this.chartConfiguration.isHeaderVisible;
|
|
3946
|
+
}
|
|
3947
|
+
if (this.chartConfiguration.isTopCaptionVisible !== undefined) {
|
|
3948
|
+
this.isTopCaptionVisible = this.chartConfiguration.isTopCaptionVisible;
|
|
3949
|
+
}
|
|
3950
|
+
if (this.chartConfiguration.isTransparentBackground !== undefined) {
|
|
3951
|
+
this.isTransparentBackground = this.chartConfiguration.isTransparentBackground;
|
|
3952
|
+
}
|
|
3953
|
+
}
|
|
3954
|
+
initializeStackedChart() {
|
|
3955
|
+
// Use fixed configuration for all resolutions
|
|
3956
|
+
this.chartConfiguration.margin = { top: 20, right: 20, bottom: 40, left: 40 };
|
|
3957
|
+
this.chartConfiguration.numberOfYTicks = 5;
|
|
3958
|
+
this.chartConfiguration.svgHeight = 70;
|
|
3959
|
+
this.mergeConfigurations();
|
|
3960
|
+
this.applyConfigurationFlags();
|
|
3961
|
+
const data = this.chartData.data;
|
|
3962
|
+
const metaData = this.prepareMetaData(this.chartData.metaData);
|
|
3963
|
+
const lineData = this.chartData.lineData;
|
|
3964
|
+
const colors = metaData.colors;
|
|
3965
|
+
const keyList = metaData.keyList;
|
|
3966
|
+
const chartContainer = d3.select(this.containerElt.nativeElement);
|
|
3967
|
+
const verticalstackedcontainer = d3.select(this.groupcontainerElt.nativeElement);
|
|
3968
|
+
const margin = this.chartConfiguration.margin;
|
|
3969
|
+
const dimensions = this.calculateDimensions(chartContainer, verticalstackedcontainer, margin, data.length);
|
|
3970
|
+
const hasXLabel = !!metaData.xLabel;
|
|
3971
|
+
const { svg, svgYAxisLeft, svgYAxisRight, bottomLabelContainer } = this.createSvgContainers(chartContainer, dimensions, margin, hasXLabel);
|
|
3972
|
+
const stack = d3.stack().keys(keyList).offset(d3.stackOffsetNone);
|
|
3973
|
+
const layers = stack(data);
|
|
3974
|
+
data.sort((a, b) => b.total - a.total);
|
|
3975
|
+
const scales = this.createScales(data, layers, lineData, dimensions);
|
|
3976
|
+
const axes = this.createAxes(scales);
|
|
3977
|
+
this.renderGridsFromLeftAxis(svg, svgYAxisLeft, scales, dimensions);
|
|
3978
|
+
this.renderGrids(svg, scales, dimensions);
|
|
3979
|
+
const rect = this.renderBars(svg, layers, scales, metaData, dimensions);
|
|
3980
|
+
this.renderAxes(svg, svgYAxisLeft, svgYAxisRight, axes, scales, dimensions, data);
|
|
3981
|
+
this.renderAxisLabels(svg, svgYAxisLeft, bottomLabelContainer, metaData, dimensions, margin);
|
|
3982
|
+
this.renderTargetLine(svg, svgYAxisRight, scales, dimensions, metaData);
|
|
3983
|
+
this.renderDataLabels(rect, scales, metaData, dimensions);
|
|
3984
|
+
this.renderLineChart(svg, lineData, scales, colors, metaData);
|
|
3985
|
+
}
|
|
3986
|
+
renderGrids(svg, scales, dimensions) {
|
|
3987
|
+
if (this.chartConfiguration.isXgridBetweenLabels) {
|
|
3988
|
+
svg
|
|
3989
|
+
.append('g')
|
|
3990
|
+
.attr('class', 'grid vertical-grid')
|
|
3991
|
+
.attr('transform', `translate(${scales.xScale.bandwidth() / 2},${dimensions.height})`)
|
|
3992
|
+
.call(d3.axisBottom(scales.xScale).tickSize(-dimensions.height).tickFormat(''))
|
|
3993
|
+
.style('stroke-dasharray', '5 5')
|
|
3994
|
+
.style('color', '#999999')
|
|
3995
|
+
.call((g) => g.select('.domain').remove());
|
|
3996
|
+
}
|
|
3997
|
+
if (this.chartConfiguration.xAxisGrid) {
|
|
3998
|
+
for (let j = 0; j < this.chartConfiguration.xAxisGrid.length; j++) {
|
|
3999
|
+
svg
|
|
4000
|
+
.append('g')
|
|
4001
|
+
.attr('class', `x${j + 2} axis${j + 2}`)
|
|
4002
|
+
.style('color', 'var(--chart-grid-color)')
|
|
4003
|
+
.attr('transform', `translate(0,${dimensions.height * this.chartConfiguration.xAxisGrid[j]})`)
|
|
4004
|
+
.call(d3.axisBottom(scales.xScale).tickSize(0).ticks(5).tickFormat(''))
|
|
4005
|
+
.style('fill', 'var(--chart-text-color)');
|
|
4006
|
+
}
|
|
4007
|
+
}
|
|
4008
|
+
}
|
|
4009
|
+
renderAxes(svg, svgYAxisLeft, svgYAxisRight, axes, scales, dimensions, data) {
|
|
4010
|
+
if (this.chartConfiguration.showXaxisTop) {
|
|
4011
|
+
svg
|
|
4012
|
+
.append('g')
|
|
4013
|
+
.attr('class', 'lib-line-axis-text lib-line-x-axis-text x-axis')
|
|
4014
|
+
.attr('style', this.chartConfiguration.xAxisCustomTextStyles)
|
|
4015
|
+
.call(d3.axisBottom(scales.xScale).tickSize(0));
|
|
4016
|
+
svg.selectAll('.x-axis > g > text').attr('class', 'lib-display-hidden');
|
|
4017
|
+
}
|
|
4018
|
+
if (!this.chartConfiguration.isMultiChartGridLine) {
|
|
4019
|
+
this.renderStandardAxes(svg, axes, scales, dimensions, data);
|
|
3718
4020
|
}
|
|
4021
|
+
else if (this.chartConfiguration.isDrilldownChart) {
|
|
4022
|
+
this.renderDrilldownAxes(svg, svgYAxisLeft, svgYAxisRight, axes, scales, dimensions);
|
|
4023
|
+
}
|
|
4024
|
+
else {
|
|
4025
|
+
this.renderMultiChartAxes(svg, axes, scales, dimensions);
|
|
4026
|
+
}
|
|
4027
|
+
this.applyAxisStyling(svg, svgYAxisLeft, svgYAxisRight);
|
|
4028
|
+
this.applyAxisConfigurations(svg, scales, dimensions, data);
|
|
3719
4029
|
}
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
3723
|
-
const
|
|
3724
|
-
svg
|
|
4030
|
+
renderStandardAxes(svg, axes, scales, dimensions, data) {
|
|
4031
|
+
const isMobileOrTablet = window.innerWidth < 1024;
|
|
4032
|
+
// X-axis with labels
|
|
4033
|
+
const xAxisGroup = svg
|
|
3725
4034
|
.append('g')
|
|
3726
|
-
.attr('
|
|
3727
|
-
.attr('
|
|
3728
|
-
.call(
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
svg.selectAll('g.x1.axis1 g.tick text').attr('class', 'lib-xaxis-labels-texts-weeklycharts').attr('y', () => {
|
|
3742
|
-
if (alternate_text) {
|
|
3743
|
-
alternate_text = false;
|
|
3744
|
-
return long_tick_length_bg;
|
|
3745
|
-
}
|
|
3746
|
-
else {
|
|
3747
|
-
alternate_text = true;
|
|
3748
|
-
return short_tick_length_bg;
|
|
3749
|
-
}
|
|
3750
|
-
});
|
|
3751
|
-
}
|
|
3752
|
-
renderXLabelsOnSameLine(svg, data, metaData) {
|
|
3753
|
-
const short_tick_length_bg = 5;
|
|
3754
|
-
const long_tick_length_bg = 30;
|
|
3755
|
-
svg
|
|
3756
|
-
.selectAll('g.x1.axis1 g.tick text')
|
|
3757
|
-
.attr('class', 'lib-xaxis-labels-texts-drilldown')
|
|
3758
|
-
.attr('y', short_tick_length_bg)
|
|
3759
|
-
.text((d) => {
|
|
3760
|
-
const isValueToBeIgnored = data.some((indiv) => indiv.name.toLowerCase() === d.trim().toLowerCase() &&
|
|
3761
|
-
indiv[metaData.keyList[0]] === -1);
|
|
3762
|
-
if (isValueToBeIgnored)
|
|
3763
|
-
return '';
|
|
3764
|
-
if (d.trim().indexOf(' ') > -1) {
|
|
3765
|
-
return d.trim().substring(0, d.indexOf(' ')).toLowerCase();
|
|
4035
|
+
.attr('transform', `translate(0,${dimensions.height})`)
|
|
4036
|
+
.attr('class', 'lib-stacked-x-axis-text')
|
|
4037
|
+
.call(axes.xAxis);
|
|
4038
|
+
// Style X-axis labels
|
|
4039
|
+
xAxisGroup
|
|
4040
|
+
.selectAll('text')
|
|
4041
|
+
.style('fill', 'var(--chart-text-color)')
|
|
4042
|
+
.style('font-size', isMobileOrTablet ? '10px' : '12px')
|
|
4043
|
+
.attr('text-anchor', 'middle')
|
|
4044
|
+
.attr('dy', '1em')
|
|
4045
|
+
.each(function (d) {
|
|
4046
|
+
const textElement = d3.select(this);
|
|
4047
|
+
const text = textElement.text();
|
|
4048
|
+
if (isMobileOrTablet && text.length > 12) {
|
|
4049
|
+
textElement.text(text.substring(0, 10) + '...');
|
|
3766
4050
|
}
|
|
3767
|
-
return d.toLowerCase();
|
|
3768
4051
|
});
|
|
4052
|
+
// Ensure X-axis line starts exactly at x=0
|
|
4053
|
+
xAxisGroup
|
|
4054
|
+
.select('.domain')
|
|
4055
|
+
.style('stroke', 'var(--chart-axis-color)')
|
|
4056
|
+
.style('stroke-width', '1px')
|
|
4057
|
+
.attr('d', `M0,0.5H${dimensions.requiredSvgWidth}`);
|
|
4058
|
+
// Y-axis
|
|
3769
4059
|
svg
|
|
3770
|
-
.
|
|
3771
|
-
.
|
|
3772
|
-
.attr('
|
|
3773
|
-
.
|
|
3774
|
-
.
|
|
3775
|
-
.
|
|
3776
|
-
if (d.trim().indexOf(' ') > -1) {
|
|
3777
|
-
return d.trim().substring(d.indexOf(' ')).toLowerCase();
|
|
3778
|
-
}
|
|
3779
|
-
return '';
|
|
3780
|
-
});
|
|
4060
|
+
.append('g')
|
|
4061
|
+
.attr('class', 'lib-stacked-y-axis-text')
|
|
4062
|
+
.attr('style', this.chartConfiguration.yAxisCustomTextStyles)
|
|
4063
|
+
.call(axes.yAxis)
|
|
4064
|
+
.selectAll('text')
|
|
4065
|
+
.style('fill', 'var(--chart-text-color)');
|
|
3781
4066
|
}
|
|
3782
|
-
|
|
3783
|
-
// Main Y-axis in chart area (hidden)
|
|
4067
|
+
renderDrilldownAxes(svg, svgYAxisLeft, svgYAxisRight, axes, scales, dimensions) {
|
|
3784
4068
|
svg
|
|
3785
4069
|
.append('g')
|
|
3786
|
-
.attr('
|
|
3787
|
-
.attr('
|
|
3788
|
-
.
|
|
3789
|
-
.call(y)
|
|
4070
|
+
.attr('transform', `translate(0,${dimensions.height})`)
|
|
4071
|
+
.attr('class', 'lib-stacked-x-axis-text multichart1')
|
|
4072
|
+
.call(axes.xAxis)
|
|
3790
4073
|
.style('display', 'none');
|
|
3791
|
-
|
|
3792
|
-
const yAxisLeft = d3
|
|
3793
|
-
.axisLeft(y)
|
|
3794
|
-
.tickSize(0)
|
|
3795
|
-
.ticks(this.chartConfiguration.numberOfYTicks)
|
|
3796
|
-
.tickFormat(this.chartConfiguration.yAxisLabelFomatter);
|
|
3797
|
-
const yAxisGroup = svgYAxisLeft
|
|
4074
|
+
svgYAxisLeft
|
|
3798
4075
|
.append('g')
|
|
3799
4076
|
.attr('class', 'lib-yaxis-labels-texts-drilldown yaxis-dashed')
|
|
3800
4077
|
.attr('style', this.chartConfiguration.yAxisCustomTextStyles)
|
|
3801
|
-
.
|
|
3802
|
-
.call(yAxisLeft);
|
|
3803
|
-
// FIXED: Show Y-axis vertical line
|
|
3804
|
-
yAxisGroup
|
|
3805
|
-
.select('.domain')
|
|
3806
|
-
.style('stroke', 'var(--chart-axis-color, #CCCCCC)')
|
|
3807
|
-
.style('stroke-width', '1px')
|
|
3808
|
-
.style('display', 'block');
|
|
3809
|
-
// FIXED: Position Y-axis values with proper spacing
|
|
3810
|
-
yAxisGroup
|
|
4078
|
+
.call(axes.yAxis)
|
|
3811
4079
|
.selectAll('text')
|
|
3812
|
-
.style('fill', 'var(--chart-text-color
|
|
3813
|
-
.style('font-size', '11px')
|
|
3814
|
-
.style('font-weight', '400')
|
|
3815
|
-
.attr('x', -6) // FIXED: Small gap from axis line
|
|
3816
|
-
.attr('text-anchor', 'end')
|
|
3817
|
-
.attr('dy', '0.32em');
|
|
3818
|
-
// Right Y-axis (hidden)
|
|
4080
|
+
.style('fill', 'var(--chart-text-color)');
|
|
3819
4081
|
svgYAxisRight
|
|
3820
4082
|
.append('g')
|
|
3821
4083
|
.attr('class', 'lib-yaxis-labels-texts-drilldown yaxis-dashed')
|
|
3822
4084
|
.attr('style', this.chartConfiguration.yAxisCustomTextStyles)
|
|
3823
|
-
.
|
|
3824
|
-
.call(y)
|
|
4085
|
+
.call(axes.yAxis)
|
|
3825
4086
|
.style('display', 'none');
|
|
3826
|
-
this.applyAxisVisibilitySettings();
|
|
3827
|
-
}
|
|
3828
|
-
applyAxisVisibilitySettings() {
|
|
3829
|
-
if (this.chartConfiguration.isXaxisLabelHidden) {
|
|
3830
|
-
d3.selectAll('g.lib-line-x-axis-text > g > text').attr('class', 'lib-display-hidden');
|
|
3831
|
-
}
|
|
3832
|
-
if (this.chartConfiguration.isYaxisLabelHidden) {
|
|
3833
|
-
d3.selectAll('.yaxis-dashed > g > text').attr('class', 'lib-display-hidden');
|
|
3834
|
-
// FIXED: Don't hide the Y-axis label element
|
|
3835
|
-
d3.selectAll('.lib-ylabel-visible').style('display', 'block');
|
|
3836
|
-
}
|
|
3837
|
-
if (this.chartConfiguration.isYaxisHidden) {
|
|
3838
|
-
d3.selectAll('.yaxis-dashed').attr('class', 'lib-display-hidden');
|
|
3839
|
-
// FIXED: Keep Y-axis label visible
|
|
3840
|
-
d3.selectAll('.lib-ylabel-visible').style('display', 'block');
|
|
3841
|
-
}
|
|
3842
|
-
if (this.chartConfiguration.isYaxisDashed) {
|
|
3843
|
-
d3.selectAll('.yaxis-dashed .domain').style('stroke-dasharray', '5 5').style('color', '#999999');
|
|
3844
|
-
}
|
|
3845
4087
|
}
|
|
3846
|
-
|
|
4088
|
+
renderMultiChartAxes(svg, axes, scales, dimensions) {
|
|
3847
4089
|
svg
|
|
3848
4090
|
.append('g')
|
|
3849
|
-
.attr('
|
|
3850
|
-
.
|
|
3851
|
-
.
|
|
3852
|
-
.
|
|
3853
|
-
.
|
|
3854
|
-
.style('color', '#EEEEEE') // FIXED: Lighter grid
|
|
3855
|
-
.style('opacity', '0.7')
|
|
3856
|
-
.style('stroke-dasharray', 'none')
|
|
3857
|
-
.call((g) => g.select('.domain').remove())
|
|
3858
|
-
.selectAll('line')
|
|
3859
|
-
.style('stroke-width', '0.5px');
|
|
3860
|
-
}
|
|
3861
|
-
renderXAxisGrid(svg, x, height) {
|
|
4091
|
+
.attr('transform', `translate(0,${dimensions.height})`)
|
|
4092
|
+
.attr('class', 'lib-stacked-x-axis-text multichart')
|
|
4093
|
+
.call(axes.xAxis)
|
|
4094
|
+
.selectAll('text')
|
|
4095
|
+
.style('fill', 'var(--chart-text-color)');
|
|
3862
4096
|
svg
|
|
3863
4097
|
.append('g')
|
|
3864
|
-
.attr('class', '
|
|
3865
|
-
.attr('transform', `translate(${x.bandwidth() / 2},${height})`)
|
|
3866
|
-
.call(d3.axisBottom(x).tickSize(-height).tickFormat(''))
|
|
3867
|
-
.style('stroke-dasharray', '5 5')
|
|
3868
|
-
.style('color', 'var(--chart-grid-color, #999999)')
|
|
3869
|
-
.call((g) => g.select('.domain').remove());
|
|
3870
|
-
}
|
|
3871
|
-
renderLineYAxis(svgYAxisRight, lineYscale) {
|
|
3872
|
-
const yLineAxis = d3
|
|
3873
|
-
.axisRight(lineYscale)
|
|
3874
|
-
.ticks(this.chartConfiguration.numberOfYTicks)
|
|
3875
|
-
.tickSize(0)
|
|
3876
|
-
.tickFormat(this.chartConfiguration.yLineAxisLabelFomatter);
|
|
3877
|
-
svgYAxisRight
|
|
3878
|
-
.append('g')
|
|
3879
|
-
.attr('class', 'lib-stacked-y-axis-text1')
|
|
4098
|
+
.attr('class', 'lib-stacked-y-axis-text yaxis-dashed')
|
|
3880
4099
|
.attr('style', this.chartConfiguration.yAxisCustomTextStyles)
|
|
3881
|
-
.
|
|
3882
|
-
.
|
|
3883
|
-
|
|
3884
|
-
renderBars(svg, chartContext, scales, dimensions) {
|
|
3885
|
-
const { data, metaData, keyList, isRia } = chartContext;
|
|
3886
|
-
const { x, xSubgroup, y } = scales;
|
|
3887
|
-
const { height } = dimensions;
|
|
3888
|
-
const state = svg
|
|
3889
|
-
.append('g')
|
|
3890
|
-
.selectAll('.state')
|
|
3891
|
-
.data(data)
|
|
3892
|
-
.enter()
|
|
3893
|
-
.append('g')
|
|
3894
|
-
.attr('transform', (d) => `translate(${x(d.name)},0)`);
|
|
3895
|
-
state
|
|
3896
|
-
.selectAll('rect')
|
|
3897
|
-
.data((d) => this.prepareBarData(d, keyList))
|
|
3898
|
-
.enter()
|
|
3899
|
-
.append('rect')
|
|
3900
|
-
.attr('class', 'bars')
|
|
3901
|
-
.on('click', (d) => this.handleBarClick(d, metaData))
|
|
3902
|
-
.attr('x', (d) => this.getBarX(d, data, x, xSubgroup))
|
|
3903
|
-
.attr('y', (d) => y(d.value))
|
|
3904
|
-
.attr('width', (d) => this.getBarWidth(d, data, x, xSubgroup))
|
|
3905
|
-
.attr('height', (d) => this.getBarHeight(d, y, height))
|
|
3906
|
-
.style('cursor', (d) => (metaData.hasDrillDown && !isRia ? 'pointer' : 'default'))
|
|
3907
|
-
.attr('fill', (d) => this.getBarColor(d, metaData));
|
|
3908
|
-
if (!isRia && (this.chartConfiguration.displayTitleOnTop || (!this.chartConfiguration.textsOnBar && !this.chartConfiguration.displayTitleOnTop))) {
|
|
3909
|
-
state.selectAll('rect').on('mouseout', (d, i) => this.handleMouseOut(svg)).on('mouseover', (d, i) => this.handleMouseOver(svg, d, data, metaData, x, y, scales.leftAndRightSpaces));
|
|
3910
|
-
}
|
|
3911
|
-
if (this.chartConfiguration.textsOnBar && !this.isZoomedOut) {
|
|
3912
|
-
this.renderBarTexts(state, data, metaData, keyList, x, xSubgroup, y, isRia, svg);
|
|
3913
|
-
}
|
|
3914
|
-
if (this.chartConfiguration.isDrilldownChart) {
|
|
3915
|
-
svg.selectAll('g.x1.axis1 g.tick line').style('display', 'none');
|
|
3916
|
-
}
|
|
3917
|
-
}
|
|
3918
|
-
prepareBarData(d, keyList) {
|
|
3919
|
-
return keyList.map((key) => ({ key, value: d[key], name: d.name }));
|
|
4100
|
+
.call(axes.yAxis)
|
|
4101
|
+
.selectAll('text')
|
|
4102
|
+
.style('fill', 'var(--chart-text-color)');
|
|
3920
4103
|
}
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
4104
|
+
applyAxisStyling(svg, svgYAxisLeft, svgYAxisRight) {
|
|
4105
|
+
const styleAxisDomain = (container) => {
|
|
4106
|
+
container.selectAll('.domain')
|
|
4107
|
+
.style('stroke', 'var(--chart-axis-color)')
|
|
4108
|
+
.style('stroke-width', '1px');
|
|
4109
|
+
};
|
|
4110
|
+
styleAxisDomain(svg);
|
|
4111
|
+
styleAxisDomain(svgYAxisLeft);
|
|
4112
|
+
styleAxisDomain(svgYAxisRight);
|
|
4113
|
+
if (this.chartConfiguration.isYaxisDashed) {
|
|
4114
|
+
d3.selectAll('.yaxis-dashed')
|
|
4115
|
+
.style('stroke-dasharray', '5 5')
|
|
4116
|
+
.style('color', 'var(--chart-grid-color)');
|
|
3927
4117
|
}
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
if (this.chartConfiguration.isDrilldownChart) {
|
|
3931
|
-
return this.calculateDrilldownBarX(d, data, x);
|
|
4118
|
+
if (this.chartConfiguration.isXaxisColor) {
|
|
4119
|
+
d3.selectAll('.multichart').style('color', this.chartConfiguration.isXaxisColor || 'var(--chart-text-color)');
|
|
3932
4120
|
}
|
|
3933
|
-
return xSubgroup(d.key);
|
|
3934
|
-
}
|
|
3935
|
-
calculateDrilldownBarX(d, data, x) {
|
|
3936
|
-
let tempScale;
|
|
3937
|
-
data.forEach((indiv) => {
|
|
3938
|
-
if (indiv.name === d.name) {
|
|
3939
|
-
const keys = Object.keys(indiv).filter((temp, i) => i !== 0);
|
|
3940
|
-
tempScale = d3.scaleBand().domain(keys).range([0, x.bandwidth()]);
|
|
3941
|
-
if (x.bandwidth() > 100) {
|
|
3942
|
-
tempScale = this.adjustDrilldownScale(tempScale, data, x);
|
|
3943
|
-
}
|
|
3944
|
-
}
|
|
3945
|
-
});
|
|
3946
|
-
return tempScale ? tempScale(d.key) : 0;
|
|
3947
4121
|
}
|
|
3948
|
-
|
|
3949
|
-
if (this.
|
|
3950
|
-
|
|
3951
|
-
const offset = keysLength === 2 ? 200 : 300;
|
|
3952
|
-
tempScale.range([
|
|
3953
|
-
0 + (x.bandwidth() - offset) / 2,
|
|
3954
|
-
x.bandwidth() - (x.bandwidth() - offset) / 2,
|
|
3955
|
-
]);
|
|
4122
|
+
applyAxisConfigurations(svg, scales, dimensions, data) {
|
|
4123
|
+
if (this.chartConfiguration.isMultiChartGridLine !== undefined) {
|
|
4124
|
+
d3.selectAll('.multichart > g > text').attr('class', 'lib-display-hidden');
|
|
3956
4125
|
}
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
0 + (x.bandwidth() - 125) / 2,
|
|
3960
|
-
x.bandwidth() - (x.bandwidth() - 125) / 2,
|
|
3961
|
-
]);
|
|
4126
|
+
if (this.chartConfiguration.isXaxisLabelHidden) {
|
|
4127
|
+
d3.selectAll('.multichart > g > text').attr('class', 'lib-display-hidden');
|
|
3962
4128
|
}
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
getBarWidth(d, data, x, xSubgroup) {
|
|
3966
|
-
if (this.chartConfiguration.isDrilldownChart) {
|
|
3967
|
-
let tempScale;
|
|
3968
|
-
data.forEach((indiv) => {
|
|
3969
|
-
if (indiv.name === d.name) {
|
|
3970
|
-
const keys = Object.keys(indiv).filter((temp, i) => i !== 0);
|
|
3971
|
-
tempScale = d3.scaleBand().domain(keys).range([0, x.bandwidth()]);
|
|
3972
|
-
if (x.bandwidth() > 100) {
|
|
3973
|
-
tempScale = this.adjustDrilldownScale(tempScale, data, x);
|
|
3974
|
-
}
|
|
3975
|
-
}
|
|
3976
|
-
});
|
|
3977
|
-
return tempScale ? tempScale.bandwidth() : 0;
|
|
4129
|
+
else if (this.chartConfiguration.isXaxisLabelHidden !== undefined) {
|
|
4130
|
+
this.renderCustomXAxis(svg, scales, dimensions, data);
|
|
3978
4131
|
}
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
getBarHeight(d, y, height) {
|
|
3982
|
-
if (d.value === -1)
|
|
3983
|
-
return height - y(0);
|
|
3984
|
-
if (d.value)
|
|
3985
|
-
return height - y(d.value);
|
|
3986
|
-
return height - y(0);
|
|
3987
|
-
}
|
|
3988
|
-
getBarColor(d, metaData) {
|
|
3989
|
-
if (d.value &&
|
|
3990
|
-
this.chartData.targetLineData &&
|
|
3991
|
-
d.value >= parseInt(this.chartData.targetLineData.target) &&
|
|
3992
|
-
this.chartData.metaData.colorAboveTarget) {
|
|
3993
|
-
return this.chartData.metaData.colorAboveTarget[d.key];
|
|
4132
|
+
if (this.chartConfiguration.isYaxisLabelHidden) {
|
|
4133
|
+
svg.selectAll('.yaxis-dashed > g > text').attr('class', 'lib-display-hidden');
|
|
3994
4134
|
}
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
renderBarTexts(state, data, metaData, keyList, x, xSubgroup, y, isRia, svg) {
|
|
3998
|
-
state
|
|
3999
|
-
.selectAll('text')
|
|
4000
|
-
.data((d) => this.prepareBarData(d, keyList))
|
|
4001
|
-
.enter()
|
|
4002
|
-
.append('text')
|
|
4003
|
-
.attr('x', 0)
|
|
4004
|
-
.attr('y', 0)
|
|
4005
|
-
.attr('class', 'lib-data-labels-weeklycharts')
|
|
4006
|
-
.text((d) => this.getBarTextLabel(d))
|
|
4007
|
-
.style('fill', '#000')
|
|
4008
|
-
.style('font-weight', 'bold')
|
|
4009
|
-
.style('font-size', () => this.getBarTextFontSize())
|
|
4010
|
-
.attr('transform', (d) => this.getBarTextTransform(d, data, x, xSubgroup, y))
|
|
4011
|
-
.on('click', (d) => this.handleBarClick(d, metaData));
|
|
4012
|
-
if (!isRia) {
|
|
4013
|
-
state
|
|
4014
|
-
.selectAll('.lib-data-labels-weeklycharts')
|
|
4015
|
-
.on('mouseout', (d, i) => this.handleMouseOut(svg))
|
|
4016
|
-
.on('mouseover', (d, i) => this.handleMouseOver(svg, d, data, metaData, x, y, x.bandwidth()));
|
|
4135
|
+
if (this.chartConfiguration.isYaxisHidden) {
|
|
4136
|
+
d3.selectAll('.yaxis-dashed').attr('class', 'lib-display-hidden');
|
|
4017
4137
|
}
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
|
|
4024
|
-
|
|
4025
|
-
if (this.chartConfiguration.isDrilldownChart) {
|
|
4026
|
-
if (window.innerWidth > 1900)
|
|
4027
|
-
return '18px';
|
|
4028
|
-
if (window.innerWidth < 1400)
|
|
4029
|
-
return '10px';
|
|
4030
|
-
return '14px';
|
|
4138
|
+
if (this.isZoomedOut && data.length > 9) {
|
|
4139
|
+
svg
|
|
4140
|
+
.selectAll('.lib-xaxis-labels-texts-drilldown')
|
|
4141
|
+
.attr('transform', 'rotate(-90)')
|
|
4142
|
+
.attr('text-anchor', 'end')
|
|
4143
|
+
.attr('x', '-5')
|
|
4144
|
+
.attr('dy', null);
|
|
4031
4145
|
}
|
|
4032
|
-
return '14px';
|
|
4033
4146
|
}
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
if (this.chartConfiguration.textAlwaysHorizontal) {
|
|
4046
|
-
return `translate(${xSubgroup(d.key)},${y(d.value) - 3})`;
|
|
4047
|
-
}
|
|
4048
|
-
if (tempScale && !isNaN(tempScale(d.key))) {
|
|
4049
|
-
return `translate(${tempScale(d.key) + tempScale.bandwidth() * 0.55},${y(0) - 10}) rotate(270)`;
|
|
4147
|
+
renderCustomXAxis(svg, scales, dimensions, data) {
|
|
4148
|
+
svg
|
|
4149
|
+
.append('g')
|
|
4150
|
+
.attr('class', 'x1 axis1')
|
|
4151
|
+
.attr('transform', `translate(0,${dimensions.height})`)
|
|
4152
|
+
.style('color', '#000')
|
|
4153
|
+
.call(d3.axisBottom(scales.xScale).tickSize(0))
|
|
4154
|
+
.call((g) => g.select('.domain').attr('fill', 'none'));
|
|
4155
|
+
this.styleCustomXAxisTicks(svg, data);
|
|
4156
|
+
if (this.chartConfiguration.xLabelsOnSameLine) {
|
|
4157
|
+
this.applyXLabelsOnSameLine(svg);
|
|
4050
4158
|
}
|
|
4051
|
-
return 'translate(0,0)';
|
|
4052
4159
|
}
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
tempScale = this.adjustDrilldownScale(tempScale, data, x);
|
|
4062
|
-
}
|
|
4160
|
+
styleCustomXAxisTicks(svg, data) {
|
|
4161
|
+
let alternateText = false;
|
|
4162
|
+
svg.selectAll('.x1.axis1 .tick line').attr('y2', () => {
|
|
4163
|
+
if (this.chartConfiguration.hideXaxisTick)
|
|
4164
|
+
return 0;
|
|
4165
|
+
if (alternateText && !this.chartConfiguration.isNoAlternateXaxisText) {
|
|
4166
|
+
alternateText = false;
|
|
4167
|
+
return this.CONSTANTS.LONG_TICK_LENGTH_BG - 7;
|
|
4063
4168
|
}
|
|
4169
|
+
alternateText = true;
|
|
4170
|
+
return this.CONSTANTS.SHORT_TICK_LENGTH_BG - 4;
|
|
4064
4171
|
});
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
.
|
|
4068
|
-
.attr('
|
|
4069
|
-
.
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
.append('xhtml:div')
|
|
4074
|
-
.attr('class', 'title')
|
|
4075
|
-
.style('z-index', 99)
|
|
4076
|
-
.html(() => this.getTooltipHTML(d, metaData));
|
|
4077
|
-
}
|
|
4078
|
-
calculateTooltipX(d, x, tempScale, metaData, leftAndRightSpaces) {
|
|
4079
|
-
if (metaData.hasDrillDown) {
|
|
4080
|
-
if (tempScale.bandwidth() + leftAndRightSpaces * 2 > 180) {
|
|
4081
|
-
return x(d.name) + tempScale(d.key) + tempScale.bandwidth() / 2 - 90;
|
|
4172
|
+
alternateText = false;
|
|
4173
|
+
svg
|
|
4174
|
+
.selectAll('g.x1.axis1 g.tick text')
|
|
4175
|
+
.attr('class', () => {
|
|
4176
|
+
if (this.chartConfiguration.isDrilldownChart) {
|
|
4177
|
+
return data.length > 8
|
|
4178
|
+
? 'lib-xaxis-labels-texts-drilldown-alt'
|
|
4179
|
+
: 'lib-xaxis-labels-texts-drilldown';
|
|
4082
4180
|
}
|
|
4083
|
-
return
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
tempScale(d.key) -
|
|
4090
|
-
(tempScale.bandwidth() + leftAndRightSpaces * 2) / 2 +
|
|
4091
|
-
tempScale.bandwidth() / 2);
|
|
4092
|
-
}
|
|
4093
|
-
calculateTooltipWidth(tempScale, metaData, leftAndRightSpaces) {
|
|
4094
|
-
if (metaData.hasDrillDown) {
|
|
4095
|
-
if (tempScale.bandwidth() + leftAndRightSpaces * 2 > 180) {
|
|
4096
|
-
return '180px';
|
|
4181
|
+
return 'lib-xaxis-labels-texts-weeklycharts';
|
|
4182
|
+
})
|
|
4183
|
+
.attr('y', () => {
|
|
4184
|
+
if (alternateText) {
|
|
4185
|
+
alternateText = false;
|
|
4186
|
+
return this.CONSTANTS.LONG_TICK_LENGTH_BG;
|
|
4097
4187
|
}
|
|
4098
|
-
|
|
4099
|
-
|
|
4100
|
-
|
|
4101
|
-
}
|
|
4102
|
-
getTooltipHTML(d, metaData) {
|
|
4103
|
-
const dataType = metaData.dataType || '';
|
|
4104
|
-
if (!this.isZoomedOut) {
|
|
4105
|
-
return `<span class="title-bar-name">${d.name}</span><span class="title-bar-value"><span>${d.value}</span>${dataType}</span>`;
|
|
4106
|
-
}
|
|
4107
|
-
else {
|
|
4108
|
-
const tempKey = d.name.length <= 8 ? d.name : d.name.substring(0, 5) + '...';
|
|
4109
|
-
return `<span class="title-bar-name">${tempKey}:${d.value}${dataType}</span><span class="title-bar-value">${d.name}</span>`;
|
|
4110
|
-
}
|
|
4111
|
-
}
|
|
4112
|
-
handleMouseOut(svg) {
|
|
4113
|
-
svg.selectAll('.lib-verticalstack-title-ontop').remove();
|
|
4114
|
-
}
|
|
4115
|
-
renderLabels(svgElements, scales, chartContext, dimensions) {
|
|
4116
|
-
const { svg, svgYAxisLeft, svgYAxisRight } = svgElements;
|
|
4117
|
-
const { metaData } = chartContext;
|
|
4118
|
-
const { width, height, margin } = dimensions;
|
|
4119
|
-
if (metaData.yLabel) {
|
|
4120
|
-
this.renderYAxisLabel(svgYAxisLeft, metaData.yLabel, height, margin);
|
|
4121
|
-
}
|
|
4122
|
-
if (metaData.xLabel) {
|
|
4123
|
-
this.renderXAxisLabel(svg, metaData.xLabel, width, height, margin);
|
|
4124
|
-
}
|
|
4125
|
-
if (metaData.lineyLabel) {
|
|
4126
|
-
this.renderLineYAxisLabel(svgYAxisRight, metaData.lineyLabel);
|
|
4127
|
-
}
|
|
4188
|
+
alternateText = true;
|
|
4189
|
+
return this.CONSTANTS.SHORT_TICK_LENGTH_BG;
|
|
4190
|
+
});
|
|
4128
4191
|
}
|
|
4129
|
-
|
|
4130
|
-
|
|
4131
|
-
|
|
4192
|
+
applyXLabelsOnSameLine(svg) {
|
|
4193
|
+
svg
|
|
4194
|
+
.selectAll('g.x1.axis1 g.tick text')
|
|
4195
|
+
.attr('class', 'lib-xaxis-labels-texts-drilldown')
|
|
4196
|
+
.attr('y', this.CONSTANTS.SHORT_TICK_LENGTH_BG)
|
|
4197
|
+
.text((d) => {
|
|
4198
|
+
const trimmed = d.trim();
|
|
4199
|
+
const spaceIndex = trimmed.indexOf(' ');
|
|
4200
|
+
return spaceIndex > -1
|
|
4201
|
+
? trimmed.substring(0, spaceIndex).toLowerCase()
|
|
4202
|
+
: trimmed.toLowerCase();
|
|
4203
|
+
});
|
|
4204
|
+
svg
|
|
4205
|
+
.selectAll('g.x1.axis1 g.tick')
|
|
4132
4206
|
.append('text')
|
|
4133
|
-
.attr('class', 'lib-
|
|
4134
|
-
.attr('
|
|
4135
|
-
.attr('
|
|
4136
|
-
.
|
|
4137
|
-
|
|
4138
|
-
.
|
|
4139
|
-
|
|
4140
|
-
|
|
4141
|
-
|
|
4142
|
-
|
|
4143
|
-
if (this.chartConfiguration.isMultiChartGridLine === undefined) {
|
|
4144
|
-
svgYAxisLeft.selectAll('.lib-axis-group-label').text(yLabel);
|
|
4145
|
-
}
|
|
4146
|
-
else {
|
|
4147
|
-
svgYAxisLeft
|
|
4148
|
-
.selectAll('.lib-axis-group-label')
|
|
4149
|
-
.attr('class', 'lib-ylabel-weeklyCharts lib-ylabel-visible')
|
|
4150
|
-
.text(yLabel.toLowerCase());
|
|
4151
|
-
}
|
|
4207
|
+
.attr('class', 'lib-xaxis-labels-texts-drilldown')
|
|
4208
|
+
.attr('y', this.CONSTANTS.LONG_TICK_LENGTH_BG)
|
|
4209
|
+
.attr('fill', 'currentColor')
|
|
4210
|
+
.text((d) => {
|
|
4211
|
+
const trimmed = d.trim();
|
|
4212
|
+
const spaceIndex = trimmed.indexOf(' ');
|
|
4213
|
+
return spaceIndex > -1
|
|
4214
|
+
? trimmed.substring(spaceIndex).toLowerCase()
|
|
4215
|
+
: '';
|
|
4216
|
+
});
|
|
4152
4217
|
}
|
|
4153
|
-
|
|
4154
|
-
|
|
4155
|
-
|
|
4156
|
-
if (this.chartConfiguration.isDrilldownChart) {
|
|
4157
|
-
baseClass += ' lib-xlabel-drilldowncharts';
|
|
4218
|
+
renderDataLabels(rect, scales, metaData, dimensions) {
|
|
4219
|
+
if (!this.isCC && !this.chartConfiguration.isMultiChartGridLine) {
|
|
4220
|
+
rect.append('svg:title').text((d) => d[1] - d[0]);
|
|
4158
4221
|
}
|
|
4159
|
-
|
|
4160
|
-
|
|
4222
|
+
if (this.chartConfiguration.showTotalOnTop) {
|
|
4223
|
+
this.renderTopLabels(rect, scales, metaData);
|
|
4161
4224
|
}
|
|
4162
|
-
|
|
4163
|
-
|
|
4225
|
+
if (this.chartConfiguration.showAngledLabels) {
|
|
4226
|
+
this.renderAngledLabels(rect, scales, metaData);
|
|
4164
4227
|
}
|
|
4165
|
-
svg
|
|
4166
|
-
.append('text')
|
|
4167
|
-
.attr('class', baseClass)
|
|
4168
|
-
.attr('style', this.chartConfiguration.xAxisCustomlabelStyles)
|
|
4169
|
-
// FIXED: Adjusted for reduced bottom margin
|
|
4170
|
-
.attr('transform', `translate(${width / 2},${height + 32})`)
|
|
4171
|
-
.style('text-anchor', 'middle')
|
|
4172
|
-
.style('fill', 'var(--chart-text-color, #666666)')
|
|
4173
|
-
.style('font-size', '11px')
|
|
4174
|
-
.text(isAcronym ? xLabel.toUpperCase() : xLabel.toLowerCase())
|
|
4175
|
-
.style('text-transform', isAcronym ? 'none' : 'capitalize');
|
|
4176
4228
|
}
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
|
|
4229
|
+
renderTopLabels(rect, scales, metaData) {
|
|
4230
|
+
const formatFromBackend = this.chartConfiguration.textFormatter
|
|
4231
|
+
? ChartHelper.dataValueFormatter(this.chartConfiguration.textFormatter)
|
|
4232
|
+
: (d) => d;
|
|
4233
|
+
const formatForHugeNumbers = ChartHelper.dataValueFormatter('.2s');
|
|
4234
|
+
rect
|
|
4235
|
+
.append('text')
|
|
4236
|
+
.attr('x', (d) => scales.xScale(d.data.name) + scales.xScale.bandwidth() / 2)
|
|
4237
|
+
.attr('class', 'lib-verticalstack-labels-ontop-weklycharts')
|
|
4238
|
+
.attr('y', (d) => scales.yScale(d[1]) - 3)
|
|
4239
|
+
.text((d) => {
|
|
4240
|
+
const value = d[1] - d[0];
|
|
4241
|
+
if (isNaN(value) || value === 0)
|
|
4242
|
+
return;
|
|
4243
|
+
const formattedValue = value <= 999
|
|
4244
|
+
? formatFromBackend(value)
|
|
4245
|
+
: formatForHugeNumbers(value);
|
|
4246
|
+
return metaData.unit ? metaData.unit + formattedValue : formattedValue;
|
|
4247
|
+
});
|
|
4180
4248
|
}
|
|
4181
|
-
|
|
4182
|
-
|
|
4249
|
+
renderAngledLabels(rect, scales, metaData) {
|
|
4250
|
+
const formatFromBackend = this.chartConfiguration.textFormatter
|
|
4251
|
+
? ChartHelper.dataValueFormatter(this.chartConfiguration.textFormatter)
|
|
4252
|
+
: (d) => d;
|
|
4253
|
+
const formatForHugeNumbers = ChartHelper.dataValueFormatter('.2s');
|
|
4254
|
+
const tempObjectHolder = {};
|
|
4255
|
+
rect
|
|
4183
4256
|
.append('text')
|
|
4184
|
-
.attr('
|
|
4185
|
-
.attr('
|
|
4186
|
-
.attr('
|
|
4187
|
-
.attr('
|
|
4188
|
-
.
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
4257
|
+
.attr('x', 0)
|
|
4258
|
+
.attr('y', 0)
|
|
4259
|
+
.attr('fill', (d) => metaData.colors[d.key])
|
|
4260
|
+
.attr('class', 'lib-data-labels-angled-weeklycharts')
|
|
4261
|
+
.text((d) => {
|
|
4262
|
+
const value = d[1] - d[0];
|
|
4263
|
+
if (isNaN(value) || value <= 0)
|
|
4264
|
+
return;
|
|
4265
|
+
const formattedValue = value <= 999
|
|
4266
|
+
? formatFromBackend(value)
|
|
4267
|
+
: formatForHugeNumbers(value);
|
|
4268
|
+
return metaData.unit ? metaData.unit + formattedValue : formattedValue;
|
|
4269
|
+
})
|
|
4270
|
+
.attr('transform', (d) => {
|
|
4271
|
+
const value = d[1] - d[0];
|
|
4272
|
+
if (isNaN(value) || value <= 0)
|
|
4273
|
+
return 'rotate(0)';
|
|
4274
|
+
let total = 0;
|
|
4275
|
+
let incrementer = 1;
|
|
4276
|
+
metaData.keyList.forEach(key => {
|
|
4277
|
+
if (d.data[key]) {
|
|
4278
|
+
total += d.data[key];
|
|
4279
|
+
}
|
|
4280
|
+
else {
|
|
4281
|
+
incrementer = 2;
|
|
4282
|
+
}
|
|
4283
|
+
});
|
|
4284
|
+
tempObjectHolder[d.data.name] = (tempObjectHolder[d.data.name] || 0) + incrementer;
|
|
4285
|
+
const position = tempObjectHolder[d.data.name];
|
|
4286
|
+
const xPos = scales.xScale(d.data.name);
|
|
4287
|
+
const bandwidth = scales.xScale.bandwidth();
|
|
4288
|
+
const yPos = scales.yScale(total) - 3;
|
|
4289
|
+
switch (position) {
|
|
4290
|
+
case 1:
|
|
4291
|
+
return `translate(${xPos + bandwidth / 3},${yPos}) rotate(270)`;
|
|
4292
|
+
case 2:
|
|
4293
|
+
return `translate(${xPos + bandwidth / 2 + 2},${yPos}) rotate(270)`;
|
|
4294
|
+
default:
|
|
4295
|
+
return `translate(${xPos + (bandwidth * 3) / 4},${yPos}) rotate(270)`;
|
|
4296
|
+
}
|
|
4297
|
+
});
|
|
4193
4298
|
}
|
|
4194
|
-
renderTargetLine(
|
|
4299
|
+
renderTargetLine(svg, svgYAxisRight, scales, dimensions, metaData) {
|
|
4195
4300
|
if (!this.chartData.targetLineData)
|
|
4196
4301
|
return;
|
|
4197
|
-
const
|
|
4198
|
-
const
|
|
4199
|
-
const { width } = dimensions;
|
|
4200
|
-
const { metaData } = chartContext;
|
|
4201
|
-
const targetData = this.chartData.targetLineData;
|
|
4202
|
-
const yZero = y(targetData.target);
|
|
4302
|
+
const parsedTarget = this.parseTargetValue(this.chartData.targetLineData.target);
|
|
4303
|
+
const yZero = scales.yScale(parsedTarget);
|
|
4203
4304
|
svg
|
|
4204
4305
|
.append('line')
|
|
4205
4306
|
.attr('x1', 0)
|
|
4206
|
-
.attr('x2', width)
|
|
4307
|
+
.attr('x2', dimensions.width)
|
|
4207
4308
|
.attr('y1', yZero)
|
|
4208
4309
|
.attr('y2', yZero)
|
|
4209
4310
|
.style('stroke-dasharray', '5 5')
|
|
4210
|
-
.style('stroke',
|
|
4211
|
-
|
|
4311
|
+
.style('stroke', this.chartData.targetLineData.color);
|
|
4312
|
+
this.renderTargetLabel(svgYAxisRight, yZero, metaData);
|
|
4313
|
+
}
|
|
4314
|
+
parseTargetValue(target) {
|
|
4315
|
+
const parsed = parseFloat(String(target));
|
|
4316
|
+
if (isNaN(parsed))
|
|
4317
|
+
return 0;
|
|
4318
|
+
return Number.isInteger(parsed) ? parseInt(String(target)) : parsed;
|
|
4319
|
+
}
|
|
4320
|
+
renderTargetLabel(svgYAxisRight, yZero, metaData) {
|
|
4321
|
+
const dataType = metaData.dataType || '';
|
|
4322
|
+
const targetName = this.chartData.targetLineData.targetName || 'target';
|
|
4212
4323
|
svgYAxisRight
|
|
4213
4324
|
.append('foreignObject')
|
|
4214
|
-
.attr('transform', `translate(0,${yZero -
|
|
4215
|
-
.attr('width',
|
|
4325
|
+
.attr('transform', `translate(0,${yZero - 13})`)
|
|
4326
|
+
.attr('width', this.CONSTANTS.RIGHT_SVG_WIDTH)
|
|
4216
4327
|
.attr('height', 50)
|
|
4217
4328
|
.append('xhtml:div')
|
|
4218
4329
|
.attr('class', 'target-display')
|
|
4219
4330
|
.style('color', 'var(--chart-text-color)')
|
|
4220
|
-
.html(
|
|
4221
|
-
const dataType = metaData.dataType || '';
|
|
4222
|
-
const targetName = targetData.targetName || 'target';
|
|
4223
|
-
return `<div>${targetName}</div><div>${targetData.target}${dataType}</div>`;
|
|
4224
|
-
});
|
|
4331
|
+
.html(`<div>${targetName}</div><div>${this.chartData.targetLineData.target}${dataType}</div>`);
|
|
4225
4332
|
}
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
if (!lineData)
|
|
4333
|
+
renderLineChart(svg, lineData, scales, colors, metaData) {
|
|
4334
|
+
if (!lineData || !colors)
|
|
4229
4335
|
return;
|
|
4230
|
-
const
|
|
4231
|
-
|
|
4232
|
-
.
|
|
4233
|
-
.
|
|
4234
|
-
|
|
4235
|
-
.attr('stroke', this.chartConfiguration.lineGraphColor)
|
|
4236
|
-
.attr('stroke-width', 1.5)
|
|
4237
|
-
.attr('d', d3
|
|
4336
|
+
const dataGroup = d3
|
|
4337
|
+
.nest()
|
|
4338
|
+
.key((d) => d.category)
|
|
4339
|
+
.entries(lineData);
|
|
4340
|
+
const lineGen = d3
|
|
4238
4341
|
.line()
|
|
4239
|
-
.x((d) =>
|
|
4240
|
-
.y((d) => lineYscale(d.value))
|
|
4342
|
+
.x((d) => scales.xScale(d.name) + scales.xScale.bandwidth() / 2)
|
|
4343
|
+
.y((d) => scales.lineYscale(d.value));
|
|
4344
|
+
dataGroup.forEach((group) => {
|
|
4345
|
+
svg
|
|
4346
|
+
.append('path')
|
|
4347
|
+
.datum(group.values)
|
|
4348
|
+
.attr('fill', 'none')
|
|
4349
|
+
.attr('stroke', (d) => {
|
|
4350
|
+
return d[0]?.category
|
|
4351
|
+
? colors[d[0].category]
|
|
4352
|
+
: this.chartConfiguration.lineGraphColor;
|
|
4353
|
+
})
|
|
4354
|
+
.attr('stroke-width', 2.5)
|
|
4355
|
+
.attr('d', lineGen);
|
|
4356
|
+
this.renderLineDots(svg, group.values, scales, colors);
|
|
4357
|
+
});
|
|
4358
|
+
}
|
|
4359
|
+
renderLineDots(svg, values, scales, colors) {
|
|
4241
4360
|
const dot = svg
|
|
4242
|
-
.selectAll('
|
|
4243
|
-
.data(
|
|
4361
|
+
.selectAll('.line-dots')
|
|
4362
|
+
.data(values)
|
|
4244
4363
|
.enter()
|
|
4245
4364
|
.append('g')
|
|
4246
|
-
.on('click', (d) => this.
|
|
4365
|
+
.on('click', (d) => this.handleClick(d));
|
|
4247
4366
|
dot
|
|
4248
4367
|
.append('circle')
|
|
4249
|
-
.attr('fill',
|
|
4368
|
+
.attr('fill', (d) => {
|
|
4369
|
+
return d.category
|
|
4370
|
+
? colors[d.category]
|
|
4371
|
+
: this.chartConfiguration.lineGraphColor;
|
|
4372
|
+
})
|
|
4250
4373
|
.attr('stroke', 'none')
|
|
4251
|
-
.attr('cx', (d) =>
|
|
4252
|
-
.attr('cy', (d) => lineYscale(d.value))
|
|
4253
|
-
.
|
|
4254
|
-
.
|
|
4374
|
+
.attr('cx', (d) => scales.xScale(d.name) + scales.xScale.bandwidth() / 2)
|
|
4375
|
+
.attr('cy', (d) => scales.lineYscale(d.value))
|
|
4376
|
+
.attr('r', 3)
|
|
4377
|
+
.style('cursor', 'pointer');
|
|
4255
4378
|
if (this.chartConfiguration.lineGraphColor) {
|
|
4256
4379
|
dot
|
|
4257
4380
|
.append('text')
|
|
4258
|
-
.attr('class', '
|
|
4259
|
-
.attr('
|
|
4260
|
-
.
|
|
4261
|
-
.
|
|
4262
|
-
.attr('
|
|
4381
|
+
.attr('class', 'dots')
|
|
4382
|
+
.attr('fill', this.chartConfiguration.lineGraphColor)
|
|
4383
|
+
.style('font-size', '.85em')
|
|
4384
|
+
.style('font-weight', 'bold')
|
|
4385
|
+
.attr('x', (d) => scales.xScale(d.name) + scales.xScale.bandwidth() / 2)
|
|
4386
|
+
.attr('y', (d) => scales.lineYscale(d.value))
|
|
4263
4387
|
.attr('dy', '-1em')
|
|
4264
4388
|
.text((d) => this.chartConfiguration.labelFormatter(d.value));
|
|
4265
4389
|
}
|
|
4266
4390
|
}
|
|
4267
4391
|
handleClick(d) {
|
|
4268
|
-
if (this.chartData
|
|
4392
|
+
if (this.chartData?.metaData?.hasDrillDown || d?.toggleFrom) {
|
|
4269
4393
|
this.clickEvent.emit(d);
|
|
4270
4394
|
}
|
|
4271
4395
|
}
|
|
4272
4396
|
handleHeaderMenuClick(id) {
|
|
4273
4397
|
this.headerMenuclickEvent.emit(id);
|
|
4274
4398
|
}
|
|
4275
|
-
handleDD1Click(event) {
|
|
4276
|
-
this.isDD1Open = true;
|
|
4277
|
-
this.isDD2Open = false;
|
|
4278
|
-
}
|
|
4279
|
-
handleDD2Click(event) {
|
|
4280
|
-
this.isDD2Open = true;
|
|
4281
|
-
this.isDD1Open = false;
|
|
4282
|
-
}
|
|
4283
4399
|
handleCompareByFilterSelection(event) {
|
|
4284
4400
|
this.clickEvent.emit(event);
|
|
4285
4401
|
}
|
|
4402
|
+
handleZoominZoomoutClick({ isZoomOut, event }) {
|
|
4403
|
+
this.isZoomOutSelected(isZoomOut);
|
|
4404
|
+
}
|
|
4286
4405
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: GroupChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4287
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: GroupChartComponent, selector: "lib-group-chart", inputs: { chartData: "chartData", customChartConfiguration: "customChartConfiguration" }, outputs: { clickEvent: "clickEvent", headerMenuclickEvent: "headerMenuclickEvent" }, viewQueries: [{ propertyName: "containerElt", first: true, predicate: ["groupchartcontainer"], descendants: true, static: true }, { propertyName: "groupcontainerElt", first: true, predicate: ["groupcontainer"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<div\r\n #groupcontainer\r\n class=\"lib-chart-wrapper\"\r\n [ngClass]=\"{ 'lib-no-background': isTransparentBackground }\"\r\n style=\"background-color: var(--card-bg);\"\r\n (resized)=\"onResized($event)\"\r\n>\r\n\r\n<div class=\"header-alt\" *ngIf=\"!isHeaderVisible\">\r\n <lib-chart-header-v2\r\n [chartData]=\"chartData\"\r\n [chartConfiguration]=\"chartConfiguration\"\r\n (clickEvent)=\"handleClick($event)\"\r\n ></lib-chart-header-v2>\r\n <lib-chart-header-v3\r\n [chartData]=\"chartData\"\r\n [chartConfiguration]=\"chartConfiguration\"\r\n (compareByFilterSelection)=\"handleCompareByFilterSelection($event)\"\r\n (zoomInZoomOutClick)=\"handleZoominZoomoutClick($event)\"\r\n ></lib-chart-header-v3>\r\n</div>\r\n\r\n <lib-chart-header-v1\r\n [title]=\"chartData.metaData.title\"\r\n [hasDrillDown]=\"chartData.metaData.hasDrillDown\"\r\n [isEditEnabled]=\"chartData.metaData.isEditEnabled\"\r\n [menuOptions]=\"chartConfiguration.headerMenuOptions\"\r\n [isria]=\"customChartConfiguration.isRia\"\r\n [selectedKpiTooltop]=\"chartConfiguration.selectedKpiTooltop\"\r\n (menuOptionClickEvent)=\"handleHeaderMenuClick($event)\"\r\n [isAlertEnabled]=\"isAlertEnabled\"\r\n *ngIf=\"isHeaderVisible\"\r\n></lib-chart-header-v1>\r\n\r\n <div\r\n [style.height]=\"chartConfiguration.svgHeight\"\r\n id=\"groupchartcontainer\"\r\n #groupchartcontainer\r\n class=\"lib-chart-svg\"\r\n ></div>\r\n</div>\r\n", styles: [".lib-stacked-y-axis-text text,.lib-stacked-x-axis-text text{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto;font-weight:400;letter-spacing:0px;color:#000;opacity:1;font-size:1.2em}.lib-axis-group-label{font-size:.85em;font-weight:600;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto;letter-spacing:0px;color:#000;opacity:1}.dots{font-size:10px}.inline__display{display:flex;justify-content:space-around;padding-top:2%}.verticalbar__text{font-style:normal;font-variant:normal;font-weight:400;font-size:13px;line-height:20px;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto;letter-spacing:0px;opacity:1}.lib-line-label-item{display:inline-block!important;font-size:.85em;margin-right:10px;font-weight:600}.lib-line-label-wrapper-vertical{display:flex;justify-content:center}.target-display{font-size:12px;line-height:14.52px;font-weight:700;text-transform:uppercase;float:right}.title{background-color:#d9d9d9;height:35px;display:flex;flex-direction:column;justify-content:center;align-items:center;border-radius:3px;line-height:1}.title:after{content:\"\";position:absolute;bottom:0;left:50%;margin-left:-10px;width:0;height:0;border-top:solid 10px #d3d3d3;border-left:solid 10px transparent;border-right:solid 10px transparent}.title-top-text{color:#000;font-size:14px;font-weight:600}.title-bar-name{color:#000;font-size:12px;font-weight:700;text-transform:capitalize}.title-bottom-text{color:#4f4f4f;font-size:12px}.zoomIcons-holder{display:flex;align-items:center;margin-right:15px}.zoomIcons{border:.5px solid #b6b6b6;cursor:pointer;display:flex;justify-content:center;align-items:center;width:30px;height:30px;color:var(--color)!important}.zoom-active{background-color:#2d5ca0;opacity:1}.zoom-inactive{background-color:#d9d9d9;opacity:.5}@media screen and (min-width: 1024px) and (min-height: 400px){.lib-stacked-y-axis-text text,.lib-stacked-x-axis-text text{font-size:10px!important}.dots{font-size:10px!important}}@media screen and (min-width: 1024px) and (min-height: 1000px){.lib-stacked-y-axis-text text,.lib-stacked-x-axis-text text{font-size:10px!important}.dots{font-size:10px!important}}@media screen and (min-width: 1024px) and (min-height: 1500px){.lib-stacked-y-axis-text text,.lib-stacked-x-axis-text text{font-size:10px!important}.dots{font-size:10px!important}}@media screen and (min-width: 1366px) and (min-height: 400px){.lib-stacked-y-axis-text text,.lib-stacked-x-axis-text text{font-size:12px!important}.dots{font-size:12px!important}}@media screen and (min-width: 1366px) and (min-height: 1000px){.lib-stacked-y-axis-text text,.lib-stacked-x-axis-text text{font-size:12px!important}.dots{font-size:12px!important}}@media screen and (min-width: 1366px) and (min-height: 1500px){.lib-stacked-y-axis-text text,.lib-stacked-x-axis-text text{font-size:12px!important}.dots{font-size:12px!important}}@media screen and (min-width: 1920px) and (min-height: 400px){.lib-stacked-y-axis-text text,.lib-stacked-x-axis-text text{font-size:14px!important}.dots{font-size:14px!important}}@media screen and (min-width: 1920px) and (min-height: 1000px){.lib-stacked-y-axis-text text,.lib-stacked-x-axis-text text{font-size:14px!important}.dots{font-size:14px!important}}@media screen and (min-width: 1920px) and (min-height: 1500px){.lib-stacked-y-axis-text text,.lib-stacked-x-axis-text text{font-size:14px!important}.dots{font-size:14px!important}}@media screen and (min-width: 2560px) and (min-height: 500px){.lib-stacked-y-axis-text text,.lib-stacked-x-axis-text text{font-size:16px!important}.dots{font-size:16px!important}}@media screen and (min-width: 2560px) and (min-height: 1000px){.lib-stacked-y-axis-text text,.lib-stacked-x-axis-text text{font-size:16px!important}.dots{font-size:16px!important}}@media screen and (min-width: 2560px) and (min-height: 1500px){.lib-stacked-y-axis-text text,.lib-stacked-x-axis-text text{font-size:16px!important}}.bottom__text{position:absolute!important;bottom:0!important;display:flex!important;justify-content:center!important;align-items:center!important;width:100%!important}.box__heightwidth{opacity:1;height:10px;width:10px;border:none!important;border-radius:50%}.label__text{margin-right:10px;display:flex;justify-content:center;align-items:center;font-style:normal;font-variant:normal;font-weight:400;font-size:10px;line-height:13px;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Open Sans,Helvetica Neue,sans-serif;letter-spacing:.2px;color:#707070!important}.lib-verticalstack-labels-ontop-weklycharts{font-style:normal;font-variant:normal;font-weight:700;font-size:10px;line-height:11px;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto;letter-spacing:-.05px;text-anchor:middle;fill:#000}.lib-verticalstack-title-ontop{font-style:normal;font-variant:normal;font-size:14px;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto;letter-spacing:-.05px;text-anchor:middle;fill:#000}.marginLeft-20{margin-left:20px}.flex-inline{display:flex;justify-content:center;align-items:center;font-size:14px}\n", ".lib-chart-wrapper{width:100%;height:100%;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto;background:#fff 0% 0% no-repeat padding-box;position:relative}.lib-chart-wrapper-wo-shadow{width:100%;height:100%;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto}.lib-chart-wrapper:hover .chart-header-v1:not(.header-no-background){background-color:#2e3640}.lib-chart-wrapper:hover .chart-header-v1:not(.header-no-background) .chart-title{color:#fff}.lib-chart-svg{width:100%}.lib-chart-header{text-align:center;background-color:#052340;color:#fff;width:100%;height:17%;word-spacing:.5px;line-height:1.8;font-weight:700;padding-top:2%;letter-spacing:0;font-size:1.2em}.lib-donut-chart-footer{width:100%;text-align:right}.lib-donut-label-text{font-size:.9em;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto;font-weight:400;letter-spacing:0px;color:#000;opacity:1}.lib-donut-label-icon{display:inline-block;width:10px;height:10px;margin-right:20px;border-radius:3px}.lib-donut-label-item{font-weight:400;font-size:.85em;color:#2f2f2f}.lib-donut-justified-label-wrapper{width:100%;display:inline-block;text-align:center;list-style-type:none}.lib-donut-justified-label-item{font-weight:400;font-size:.85em;color:#2f2f2f;display:inline-block;text-align:left;padding:0 10px}.lib-donut-justified-label-icon{display:inline-block;width:10px;height:10px;margin-right:5px;border-radius:3px}.lib-no-background{background:none!important}.lib-display-hidden{display:none}.lib-ylabel-weeklyCharts{font-style:normal;font-variant:normal;font-weight:800;font-size:10px;line-height:12px;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto;letter-spacing:-.07px;text-transform:capitalize;color:#000}.lib-data-labels-weeklycharts{font-style:normal;font-variant:normal;font-weight:400;font-size:12px;line-height:14px;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto;letter-spacing:-.06px;color:#000}.lib-data-labels-angled-weeklycharts{font-style:normal;font-variant:normal;font-weight:800;font-size:9.5px;line-height:11px;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto;letter-spacing:.4px;text-anchor:start}.lib-xaxis-labels-texts-weeklycharts{font-style:normal;font-variant:normal;font-weight:800;font-size:10px;line-height:11px;letter-spacing:-.05px;fill:#000}.lib-xaxis-labels-texts-drilldown{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto;font-size:14px;letter-spacing:-1px;color:#000;opacity:1;text-transform:capitalize}.lib-white-space-nowrap{white-space:nowrap}.lib-xaxis-labels-texts-drilldown-alt{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto;font-size:10px;letter-spacing:0px;color:#000;opacity:1;text-transform:capitalize}.lib-yaxis-labels-texts-drilldown{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto;font-size:14px;letter-spacing:0px;color:#000!important;opacity:1}.lib-ylabel-drilldowncharts,.lib-xlabel-drilldowncharts{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto;font-size:16px;letter-spacing:-.1px;color:#000!important;opacity:1}.lib-donut-justified-label-icon-drilldown{display:inline-block;width:14px;height:14px;margin-right:10px;border-radius:50%}.marginright-2{margin-right:2%}.margintop-5{margin-top:5%}.width-100{width:100%}.float-right{float:right}.marginBottom-10{margin-bottom:10px}.header-alt{align-items:center;margin-bottom:10px}input::placeholder{font-size:20px;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto;letter-spacing:0px;color:#000;opacity:1}.padding-5{padding:5px}.hidden{visibility:hidden}.font-weight-bold{font-weight:900}.textalign-center{text-align:center}.cursor-pointer{cursor:pointer}.cursor-default{cursor:default}.font-weight-600{font-weight:600}.marginRight-15{margin-right:15px}.marginRight-20{margin-right:20px}.switch{position:relative;display:inline-block;width:46px;height:24px;margin-left:5px;margin-right:5px}.switch input{opacity:0;width:0;height:0}.slider{position:absolute;cursor:pointer;inset:0;background-color:#2d5ca0;-webkit-transition:.4s;transition:.4s}.slider:before{position:absolute;content:\"\";height:18px;width:18px;right:3px;bottom:3px;background-color:#fff;-webkit-transition:.4s;transition:.4s}.slider.round{border-radius:18px}.slider.round:before{border-radius:50%}.slider1{position:absolute;cursor:pointer;inset:0;background-color:#015ba2cf;-webkit-transition:.4s;transition:.4s}.slider1:before{position:absolute;content:\"\";height:18px;width:18px;left:3px;bottom:3px;background-color:#fff;-webkit-transition:.4s;transition:.4s}.slider1.round1{border-radius:18px}.slider1.round1:before{border-radius:50%}.lib-display-flex{display:flex}.lib-align-items-center{align-items:center}.lib-flex-direction-column{flex-direction:column}.lib-justify-content-space-between{justify-content:space-between}.lib-justify-content-space-around{justify-content:space-around}.lib-justify-content-center{justify-content:center}.lib-justify-content-start{justify-content:start}.lib-justify-content-end{justify-content:end}.lib-ml-20{margin-left:20px}.lib-position-absolute{position:absolute}.lib-z-index-9{z-index:9}.marginright-3{margin-right:3px}@media (min-height: 900px){.lib-chart-wrapper{border-radius:8px}.header-font-size-1{font-size:18px!important}.font-size-1{font-size:14px!important}.font-size-2{font-size:16px!important}.font-size-3{font-size:14px!important}.font-size-4{font-size:22px!important}.font-size-5{font-size:24px!important}}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.ResizedDirective, selector: "[resized]", outputs: ["resized"] }, { kind: "component", type: ChartHeaderV1Component, selector: "lib-chart-header-v1", inputs: ["isAlertEnabled", "title", "menuOptions", "isEditEnabled", "isria", "hasDrillDown", "selectedKpiTooltop"], outputs: ["menuOptionClickEvent"] }, { kind: "component", type: ChartHeaderV2Component, selector: "lib-chart-header-v2", inputs: ["chartData", "chartConfiguration"], outputs: ["clickEvent", "zoomInZoomOutClick"] }, { kind: "component", type: ChartHeaderV3Component, selector: "lib-chart-header-v3", inputs: ["chartData", "chartConfiguration"], outputs: ["compareByFilterSelection", "zoomInZoomOutClick"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
4406
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: GroupChartComponent, selector: "lib-group-chart", inputs: { chartData: "chartData", customChartConfiguration: "customChartConfiguration" }, outputs: { clickEvent: "clickEvent", headerMenuclickEvent: "headerMenuclickEvent" }, viewQueries: [{ propertyName: "containerElt", first: true, predicate: ["groupchartcontainer"], descendants: true, static: true }, { propertyName: "groupcontainerElt", first: true, predicate: ["groupcontainer"], descendants: true, static: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div\r\n #groupcontainer\r\n class=\"lib-chart-wrapper\"\r\n [ngClass]=\"{ 'lib-no-background': isTransparentBackground }\"\r\n style=\"background-color: var(--card-bg);\"\r\n (resized)=\"onResized($event)\"\r\n>\r\n\r\n<div class=\"header-alt\" *ngIf=\"!isHeaderVisible\">\r\n <lib-chart-header-v2\r\n [chartData]=\"chartData\"\r\n [chartConfiguration]=\"chartConfiguration\"\r\n (clickEvent)=\"handleClick($event)\"\r\n ></lib-chart-header-v2>\r\n <lib-chart-header-v3\r\n [chartData]=\"chartData\"\r\n [chartConfiguration]=\"chartConfiguration\"\r\n (compareByFilterSelection)=\"handleCompareByFilterSelection($event)\"\r\n (zoomInZoomOutClick)=\"handleZoominZoomoutClick($event)\"\r\n ></lib-chart-header-v3>\r\n</div>\r\n\r\n <lib-chart-header-v1\r\n [title]=\"chartData.metaData.title\"\r\n [hasDrillDown]=\"chartData.metaData.hasDrillDown\"\r\n [isEditEnabled]=\"chartData.metaData.isEditEnabled\"\r\n [menuOptions]=\"chartConfiguration.headerMenuOptions\"\r\n [isria]=\"customChartConfiguration.isRia\"\r\n [selectedKpiTooltop]=\"chartConfiguration.selectedKpiTooltop\"\r\n (menuOptionClickEvent)=\"handleHeaderMenuClick($event)\"\r\n [isAlertEnabled]=\"isAlertEnabled\"\r\n *ngIf=\"isHeaderVisible\"\r\n></lib-chart-header-v1>\r\n\r\n <div\r\n [style.height]=\"chartConfiguration.svgHeight\"\r\n id=\"groupchartcontainer\"\r\n #groupchartcontainer\r\n class=\"lib-chart-svg\"\r\n ></div>\r\n</div>\r\n", styles: [".lib-stacked-y-axis-text text,.lib-stacked-x-axis-text text{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto;font-weight:400;letter-spacing:0px;color:#000;opacity:1;font-size:1.2em}.lib-axis-group-label{font-size:.85em;font-weight:600;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto;letter-spacing:0px;color:#000;opacity:1}.dots{font-size:10px}.inline__display{display:flex;justify-content:space-around;padding-top:2%}.verticalbar__text{font-style:normal;font-variant:normal;font-weight:400;font-size:13px;line-height:20px;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto;letter-spacing:0px;opacity:1}.lib-line-label-item{display:inline-block!important;font-size:.85em;margin-right:10px;font-weight:600}.lib-line-label-wrapper-vertical{display:flex;justify-content:center}.target-display{font-size:12px;line-height:14.52px;font-weight:700;text-transform:uppercase;float:right}.title{background-color:#d9d9d9;height:35px;display:flex;flex-direction:column;justify-content:center;align-items:center;border-radius:3px;line-height:1}.title:after{content:\"\";position:absolute;bottom:0;left:50%;margin-left:-10px;width:0;height:0;border-top:solid 10px #d3d3d3;border-left:solid 10px transparent;border-right:solid 10px transparent}.title-top-text{color:#000;font-size:14px;font-weight:600}.title-bar-name{color:#000;font-size:12px;font-weight:700;text-transform:capitalize}.title-bottom-text{color:#4f4f4f;font-size:12px}.zoomIcons-holder{display:flex;align-items:center;margin-right:15px}.zoomIcons{border:.5px solid #b6b6b6;cursor:pointer;display:flex;justify-content:center;align-items:center;width:30px;height:30px;color:var(--color)!important}.zoom-active{background-color:#2d5ca0;opacity:1}.zoom-inactive{background-color:#d9d9d9;opacity:.5}@media screen and (min-width: 1024px) and (min-height: 400px){.lib-stacked-y-axis-text text,.lib-stacked-x-axis-text text{font-size:10px!important}.dots{font-size:10px!important}}@media screen and (min-width: 1024px) and (min-height: 1000px){.lib-stacked-y-axis-text text,.lib-stacked-x-axis-text text{font-size:10px!important}.dots{font-size:10px!important}}@media screen and (min-width: 1024px) and (min-height: 1500px){.lib-stacked-y-axis-text text,.lib-stacked-x-axis-text text{font-size:10px!important}.dots{font-size:10px!important}}@media screen and (min-width: 1366px) and (min-height: 400px){.lib-stacked-y-axis-text text,.lib-stacked-x-axis-text text{font-size:12px!important}.dots{font-size:12px!important}}@media screen and (min-width: 1366px) and (min-height: 1000px){.lib-stacked-y-axis-text text,.lib-stacked-x-axis-text text{font-size:12px!important}.dots{font-size:12px!important}}@media screen and (min-width: 1366px) and (min-height: 1500px){.lib-stacked-y-axis-text text,.lib-stacked-x-axis-text text{font-size:12px!important}.dots{font-size:12px!important}}@media screen and (min-width: 1920px) and (min-height: 400px){.lib-stacked-y-axis-text text,.lib-stacked-x-axis-text text{font-size:14px!important}.dots{font-size:14px!important}}@media screen and (min-width: 1920px) and (min-height: 1000px){.lib-stacked-y-axis-text text,.lib-stacked-x-axis-text text{font-size:14px!important}.dots{font-size:14px!important}}@media screen and (min-width: 1920px) and (min-height: 1500px){.lib-stacked-y-axis-text text,.lib-stacked-x-axis-text text{font-size:14px!important}.dots{font-size:14px!important}}@media screen and (min-width: 2560px) and (min-height: 500px){.lib-stacked-y-axis-text text,.lib-stacked-x-axis-text text{font-size:16px!important}.dots{font-size:16px!important}}@media screen and (min-width: 2560px) and (min-height: 1000px){.lib-stacked-y-axis-text text,.lib-stacked-x-axis-text text{font-size:16px!important}.dots{font-size:16px!important}}@media screen and (min-width: 2560px) and (min-height: 1500px){.lib-stacked-y-axis-text text,.lib-stacked-x-axis-text text{font-size:16px!important}}.bottom__text{position:absolute!important;bottom:0!important;display:flex!important;justify-content:center!important;align-items:center!important;width:100%!important}.box__heightwidth{opacity:1;height:10px;width:10px;border:none!important;border-radius:50%}.label__text{margin-right:10px;display:flex;justify-content:center;align-items:center;font-style:normal;font-variant:normal;font-weight:400;font-size:10px;line-height:13px;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Open Sans,Helvetica Neue,sans-serif;letter-spacing:.2px;color:#707070!important}.lib-verticalstack-labels-ontop-weklycharts{font-style:normal;font-variant:normal;font-weight:700;font-size:10px;line-height:11px;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto;letter-spacing:-.05px;text-anchor:middle;fill:#000}.lib-verticalstack-title-ontop{font-style:normal;font-variant:normal;font-size:14px;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto;letter-spacing:-.05px;text-anchor:middle;fill:#000}.marginLeft-20{margin-left:20px}.flex-inline{display:flex;justify-content:center;align-items:center;font-size:14px}\n", ".lib-chart-wrapper{width:100%;height:100%;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto;background:#fff 0% 0% no-repeat padding-box;position:relative}.lib-chart-wrapper-wo-shadow{width:100%;height:100%;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto}.lib-chart-wrapper:hover .chart-header-v1:not(.header-no-background){background-color:#2e3640}.lib-chart-wrapper:hover .chart-header-v1:not(.header-no-background) .chart-title{color:#fff}.lib-chart-svg{width:100%}.lib-chart-header{text-align:center;background-color:#052340;color:#fff;width:100%;height:17%;word-spacing:.5px;line-height:1.8;font-weight:700;padding-top:2%;letter-spacing:0;font-size:1.2em}.lib-donut-chart-footer{width:100%;text-align:right}.lib-donut-label-text{font-size:.9em;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto;font-weight:400;letter-spacing:0px;color:#000;opacity:1}.lib-donut-label-icon{display:inline-block;width:10px;height:10px;margin-right:20px;border-radius:3px}.lib-donut-label-item{font-weight:400;font-size:.85em;color:#2f2f2f}.lib-donut-justified-label-wrapper{width:100%;display:inline-block;text-align:center;list-style-type:none}.lib-donut-justified-label-item{font-weight:400;font-size:.85em;color:#2f2f2f;display:inline-block;text-align:left;padding:0 10px}.lib-donut-justified-label-icon{display:inline-block;width:10px;height:10px;margin-right:5px;border-radius:3px}.lib-no-background{background:none!important}.lib-display-hidden{display:none}.lib-ylabel-weeklyCharts{font-style:normal;font-variant:normal;font-weight:800;font-size:10px;line-height:12px;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto;letter-spacing:-.07px;text-transform:capitalize;color:#000}.lib-data-labels-weeklycharts{font-style:normal;font-variant:normal;font-weight:400;font-size:12px;line-height:14px;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto;letter-spacing:-.06px;color:#000}.lib-data-labels-angled-weeklycharts{font-style:normal;font-variant:normal;font-weight:800;font-size:9.5px;line-height:11px;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto;letter-spacing:.4px;text-anchor:start}.lib-xaxis-labels-texts-weeklycharts{font-style:normal;font-variant:normal;font-weight:800;font-size:10px;line-height:11px;letter-spacing:-.05px;fill:#000}.lib-xaxis-labels-texts-drilldown{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto;font-size:14px;letter-spacing:-1px;color:#000;opacity:1;text-transform:capitalize}.lib-white-space-nowrap{white-space:nowrap}.lib-xaxis-labels-texts-drilldown-alt{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto;font-size:10px;letter-spacing:0px;color:#000;opacity:1;text-transform:capitalize}.lib-yaxis-labels-texts-drilldown{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto;font-size:14px;letter-spacing:0px;color:#000!important;opacity:1}.lib-ylabel-drilldowncharts,.lib-xlabel-drilldowncharts{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto;font-size:16px;letter-spacing:-.1px;color:#000!important;opacity:1}.lib-donut-justified-label-icon-drilldown{display:inline-block;width:14px;height:14px;margin-right:10px;border-radius:50%}.marginright-2{margin-right:2%}.margintop-5{margin-top:5%}.width-100{width:100%}.float-right{float:right}.marginBottom-10{margin-bottom:10px}.header-alt{align-items:center;margin-bottom:10px}input::placeholder{font-size:20px;font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto;letter-spacing:0px;color:#000;opacity:1}.padding-5{padding:5px}.hidden{visibility:hidden}.font-weight-bold{font-weight:900}.textalign-center{text-align:center}.cursor-pointer{cursor:pointer}.cursor-default{cursor:default}.font-weight-600{font-weight:600}.marginRight-15{margin-right:15px}.marginRight-20{margin-right:20px}.switch{position:relative;display:inline-block;width:46px;height:24px;margin-left:5px;margin-right:5px}.switch input{opacity:0;width:0;height:0}.slider{position:absolute;cursor:pointer;inset:0;background-color:#2d5ca0;-webkit-transition:.4s;transition:.4s}.slider:before{position:absolute;content:\"\";height:18px;width:18px;right:3px;bottom:3px;background-color:#fff;-webkit-transition:.4s;transition:.4s}.slider.round{border-radius:18px}.slider.round:before{border-radius:50%}.slider1{position:absolute;cursor:pointer;inset:0;background-color:#015ba2cf;-webkit-transition:.4s;transition:.4s}.slider1:before{position:absolute;content:\"\";height:18px;width:18px;left:3px;bottom:3px;background-color:#fff;-webkit-transition:.4s;transition:.4s}.slider1.round1{border-radius:18px}.slider1.round1:before{border-radius:50%}.lib-display-flex{display:flex}.lib-align-items-center{align-items:center}.lib-flex-direction-column{flex-direction:column}.lib-justify-content-space-between{justify-content:space-between}.lib-justify-content-space-around{justify-content:space-around}.lib-justify-content-center{justify-content:center}.lib-justify-content-start{justify-content:start}.lib-justify-content-end{justify-content:end}.lib-ml-20{margin-left:20px}.lib-position-absolute{position:absolute}.lib-z-index-9{z-index:9}.marginright-3{margin-right:3px}@media (min-height: 900px){.lib-chart-wrapper{border-radius:8px}.header-font-size-1{font-size:18px!important}.font-size-1{font-size:14px!important}.font-size-2{font-size:16px!important}.font-size-3{font-size:14px!important}.font-size-4{font-size:22px!important}.font-size-5{font-size:24px!important}}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.ResizedDirective, selector: "[resized]", outputs: ["resized"] }, { kind: "component", type: ChartHeaderV1Component, selector: "lib-chart-header-v1", inputs: ["isAlertEnabled", "title", "menuOptions", "isEditEnabled", "isria", "hasDrillDown", "selectedKpiTooltop"], outputs: ["menuOptionClickEvent"] }, { kind: "component", type: ChartHeaderV2Component, selector: "lib-chart-header-v2", inputs: ["chartData", "chartConfiguration"], outputs: ["clickEvent", "zoomInZoomOutClick"] }, { kind: "component", type: ChartHeaderV3Component, selector: "lib-chart-header-v3", inputs: ["chartData", "chartConfiguration"], outputs: ["compareByFilterSelection", "zoomInZoomOutClick"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
4288
4407
|
}
|
|
4289
4408
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: GroupChartComponent, decorators: [{
|
|
4290
4409
|
type: Component,
|