axidio-styleguide-library1-v2 0.4.23 → 0.4.25

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,1029 +3381,910 @@ class GroupChartComponent extends ComponentUniqueId {
3381
3381
  super();
3382
3382
  this.clickEvent = new EventEmitter();
3383
3383
  this.headerMenuclickEvent = new EventEmitter();
3384
- this.chartConfiguration = {};
3385
3384
  this.isHeaderVisible = true;
3386
- this.isTopCaptionVisible = true;
3387
- this.uniqueId = this.getUniqueId();
3385
+ this.legendVisible = true;
3388
3386
  this.isTransparentBackground = false;
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
- };
3387
+ this.chartConfiguration = {};
3388
+ this.objectKeys = Object.keys;
3404
3389
  this.defaultConfiguration = {
3405
- margin: { top: 20, right: 20, bottom: 20, left: 40 },
3390
+ "margin": {
3391
+ "top": 30,
3392
+ "left": 110,
3393
+ "right": 40,
3394
+ "bottom": 50
3395
+ },
3396
+ labelFormatter: ChartHelper.defaultFormatter,
3406
3397
  svgHeight: 70,
3407
- legendHeight: '10%',
3408
3398
  numberOfYTicks: 5,
3409
- labelFormatter: ChartHelper.defaultFormatter,
3410
- xAxisLabelFomatter: ChartHelper.defaultFormatter,
3411
- yAxisLabelFomatter: ChartHelper.defaultFormatter,
3399
+ legendJustified: true,
3412
3400
  yLineAxisLabelFomatter: ChartHelper.defaultFormatter,
3401
+ yAxisLabelFomatter: ChartHelper.defaultFormatter,
3413
3402
  lineGraphColor: '#F6D283',
3414
3403
  showLineChartAxis: true,
3415
- showLegend: false,
3416
- forComparison: true,
3404
+ showValues: true,
3417
3405
  headerMenuOptions: HeaderConfigHelper.headerConfig.headerMenuOptions,
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,
3406
+ yAxisGrid: true,
3407
+ legendVisible: true,
3408
+ isYaxisLabelHidden: false,
3409
+ backgroundColor: '#FFFFFF',
3410
+ hideLegendOnTop: true,
3411
+ isXaxisColor: '#999999',
3412
+ labelOverlapMinorFix: true,
3413
+ noHoverEffect: true,
3414
+ noHoverDisplayData: true,
3415
+ showXaxisTop: true,
3416
+ howmanyBarDetailsToDisplay: 0,
3446
3417
  };
3418
+ this.uniqueId = this.getUniqueId();
3419
+ this.isZoomedOut = false;
3420
+ this.isDD1Open = false;
3421
+ this.isDD2Open = false;
3422
+ this.keepOrder = (a, b) => a;
3447
3423
  }
3448
- ngOnChanges() {
3449
- this.removeExistingChart();
3450
- this.initializeStackedChart();
3424
+ ngOnInit() { }
3425
+ get isAlertEnabled() {
3426
+ return this.chartConfiguration?.headerMenuOptions?.some((option) => option.id === 'editAlert');
3451
3427
  }
3452
3428
  onResized(event) {
3453
3429
  setTimeout(() => {
3454
- this.removeExistingChart();
3455
- this.initializeStackedChart();
3430
+ d3.select('#' + this.uniqueId).remove();
3431
+ this.initializegroupChart();
3456
3432
  }, 10);
3457
3433
  }
3458
- isZoomOutSelected(isZoomOut) {
3434
+ isZoomOutSelected(isZoomOut, event) {
3459
3435
  this.isZoomedOut = isZoomOut;
3460
- this.ngOnChanges();
3436
+ this.onResized(event);
3461
3437
  }
3462
- removeExistingChart() {
3463
- d3.select('#' + this.uniqueId).remove();
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);
3444
+ }
3445
+ initializegroupChart() {
3446
+ this.mergeConfigurations();
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);
3464
3456
  }
3465
3457
  mergeConfigurations() {
3466
3458
  for (const key in this.defaultConfiguration) {
3467
3459
  this.chartConfiguration[key] = ChartHelper.getValueByConfigurationType(key, this.defaultConfiguration, this.customChartConfiguration);
3468
3460
  }
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());
3461
+ if (this.chartConfiguration.isHeaderVisible !== undefined) {
3462
+ this.isHeaderVisible = this.chartConfiguration.isHeaderVisible;
3477
3463
  }
3478
- else {
3479
- metaData.barWithoutClick = [];
3464
+ if (this.chartConfiguration.legendVisible !== undefined) {
3465
+ this.legendVisible = this.chartConfiguration.legendVisible;
3480
3466
  }
3481
- return metaData;
3482
- }
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);
3467
+ if (this.chartConfiguration.isTransparentBackground !== undefined) {
3468
+ this.isTransparentBackground = this.chartConfiguration.isTransparentBackground;
3494
3469
  }
3495
- if (dataLength > this.CONSTANTS.ZOOM_IN_THRESHOLD && !this.isZoomedOut) {
3496
- width = dataLength * 130;
3470
+ }
3471
+ prepareChartData() {
3472
+ const data = this.chartData.data;
3473
+ const metaData = this.chartData.metaData;
3474
+ const lineData = this.chartData.lineData;
3475
+ if (!metaData.colorAboveTarget) {
3476
+ metaData.colorAboveTarget = metaData.colors;
3497
3477
  }
3498
- if (this.chartConfiguration.isFullScreen) {
3499
- height = this.chartConfiguration.svgHeight !== 80
3500
- ? this.chartConfiguration.svgHeight
3501
- : containerHeight;
3478
+ return {
3479
+ data,
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);
3502
3502
  }
3503
- if (this.chartConfiguration.isDrilldownChart) {
3504
- height = containerHeight - margin.top - margin.bottom - 130;
3503
+ if (this.chartData.dropdownData2 && width < dataLength * 120 && this.isZoomedOut) {
3504
+ width = dataLength * 120;
3505
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;
3506
+ if (dataLength > 8 && !this.isZoomedOut) {
3507
+ if (this.chartData.dropdownData2 && width < dataLength * 250) {
3508
+ width = dataLength * 250;
3525
3509
  }
3526
3510
  else {
3527
- barWidth = 25;
3528
- barPadding = 25;
3511
+ width = dataLength * 160;
3529
3512
  }
3530
3513
  }
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
+ }
3531
3550
  else {
3532
- barWidth = this.CONSTANTS.DESKTOP_BAR_WIDTH;
3533
- barPadding = this.CONSTANTS.BAR_GAP;
3551
+ x = d3
3552
+ .scaleBand()
3553
+ .domain(groups)
3554
+ .range([leftAndRightSpaces, width - rightSvgWidth - leftAndRightSpaces])
3555
+ .padding(0.3);
3534
3556
  }
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);
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);
3564
+ }
3565
+ const color = d3.scaleOrdinal().domain(keyList).range(Object.values(metaData.colors));
3539
3566
  return {
3540
- width,
3541
- height,
3542
- containerWidth,
3543
- containerHeight,
3544
- barWidth,
3545
- barPadding,
3546
- requiredSvgWidth,
3567
+ x,
3568
+ xScaleFromOrigin,
3569
+ xSubgroup,
3570
+ y,
3571
+ lineYscale,
3572
+ color,
3573
+ leftAndRightSpaces,
3574
+ rightSvgWidth,
3547
3575
  };
3548
3576
  }
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
3577
+ calculateMaxValue(data, keyList) {
3578
+ let maxValue = d3.max(data, (d) => d3.max(keyList, (key) => +d[key])) || 0;
3579
+ if (maxValue === 0) {
3580
+ maxValue = this.chartData.targetLineData
3581
+ ? this.chartData.targetLineData.target + 20
3582
+ : 100;
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
3556
3609
  .append('div')
3557
3610
  .attr('id', this.uniqueId)
3558
- .attr('class', 'chart-wrapper-main')
3559
- .style('position', 'relative')
3611
+ .attr('class', 'outer-container')
3560
3612
  .style('width', '100%')
3561
- .style('height', `${totalHeight}px`); // Include X-label space
3562
- const leftAxisContainer = chartWrapper
3563
- .append('div')
3564
- .attr('class', 'left-axis-container')
3613
+ .style('height', `${height + margin.top + margin.bottom}px`)
3614
+ .style('overflow', 'hidden') // FIXED: Prevent all overflow
3615
+ .style('padding-left', `${margin.left}px`)
3616
+ .style('padding-right', `${rightSvgWidth}px`)
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)
3565
3624
  .style('position', 'absolute')
3566
3625
  .style('left', '0')
3567
3626
  .style('top', '0')
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
3573
- .append('svg')
3574
- .attr('width', '80')
3575
- .attr('height', dimensions.height + margin.top + margin.bottom)
3627
+ .style('z-index', 1)
3576
3628
  .append('g')
3577
- .attr('transform', `translate(79,${margin.top})`);
3578
- // Right Y-axis - Fixed
3579
- const rightAxisContainer = chartWrapper
3580
- .append('div')
3581
- .attr('class', 'right-axis-container')
3629
+ .attr('transform', `translate(${margin.left + 5},${margin.top})`);
3630
+ const svgYAxisRight = outerContainer
3631
+ .append('svg')
3632
+ .attr('width', rightSvgWidth)
3633
+ .attr('height', height + margin.top + margin.bottom)
3582
3634
  .style('position', 'absolute')
3583
- .style('right', '0')
3635
+ .style('right', '12px')
3584
3636
  .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)
3637
+ .style('z-index', 1)
3593
3638
  .append('g')
3594
3639
  .attr('transform', `translate(0,${margin.top})`);
3595
- // Scrollable middle area
3596
- const scrollableContainer = chartWrapper
3640
+ const innerContainer = outerContainer
3597
3641
  .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`)
3642
+ .attr('class', 'inner-container')
3643
+ .style('width', '100%')
3644
+ .style('height', '100%')
3605
3645
  .style('overflow-x', 'auto')
3606
3646
  .style('overflow-y', 'hidden');
3607
- const innerContainer = scrollableContainer
3608
- .append('div')
3609
- .attr('class', 'inner-chart-container')
3610
- .style('min-width', '100%');
3611
3647
  const svg = innerContainer
3612
3648
  .append('svg')
3613
- .attr('width', dimensions.requiredSvgWidth)
3614
- .attr('height', dimensions.height + margin.top + margin.bottom + 30)
3649
+ .attr('width', dimensions.width - rightSvgWidth)
3650
+ .attr('height', height + margin.top + margin.bottom + 60)
3615
3651
  .append('g')
3616
3652
  .attr('transform', `translate(0,${margin.top})`);
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;
3659
- }
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;
3666
- }
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]);
3674
- }
3675
- return { xScale, xScaleFromOrigin, yScale, lineYscale };
3676
- }
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;
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];
3776
- }
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];
3801
- }
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`;
3912
- }
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
3926
- .append('g')
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);
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);
3653
+ return { outerContainer, svgYAxisLeft, svgYAxisRight, svg };
3654
+ }
3655
+ renderAxes(svgElements, scales, chartContext, dimensions) {
3656
+ const { svg, svgYAxisLeft, svgYAxisRight } = svgElements;
3657
+ const { x, xScaleFromOrigin, y, lineYscale } = scales;
3658
+ const { height } = dimensions;
3659
+ const { metaData, lineData, keyList } = chartContext;
3660
+ this.renderXAxis(svg, x, xScaleFromOrigin, height, chartContext, keyList);
3661
+ this.renderYAxis(svg, svgYAxisLeft, svgYAxisRight, y, dimensions);
3662
+ if (this.chartConfiguration.yAxisGrid) {
3663
+ this.renderYAxisGrid(svg, y, dimensions.width);
4026
3664
  }
4027
- this.applyAxisStyling(svg, svgYAxisLeft, svgYAxisRight);
4028
- this.applyAxisConfigurations(svg, scales, dimensions, data);
4029
- }
4030
- renderStandardAxes(svg, axes, scales, dimensions, data) {
4031
- const isMobileOrTablet = window.innerWidth < 1024;
4032
- // X-axis with labels
4033
- const xAxisGroup = svg
4034
- .append('g')
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) + '...');
3665
+ if (this.chartConfiguration.isXgridBetweenLabels) {
3666
+ this.renderXAxisGrid(svg, x, height);
3667
+ }
3668
+ if (lineData && this.chartConfiguration.showLineChartAxis && lineYscale) {
3669
+ this.renderLineYAxis(svgYAxisRight, lineYscale);
3670
+ }
3671
+ }
3672
+ renderXAxis(svg, x, xScaleFromOrigin, height, chartContext, keyList) {
3673
+ const { data, metaData } = chartContext;
3674
+ if (this.chartConfiguration.isMultiChartGridLine === undefined) {
3675
+ const xAxis = svg
3676
+ .append('g')
3677
+ .attr('class', 'x1 axis1')
3678
+ .attr('transform', `translate(0,${height})`)
3679
+ .call(d3.axisBottom(x).tickSize(0));
3680
+ // FIXED: Show X-axis line
3681
+ xAxis
3682
+ .select('.domain')
3683
+ .style('stroke', 'var(--chart-axis-color, #CCCCCC)')
3684
+ .style('stroke-width', '1px')
3685
+ .style('display', 'block');
3686
+ xAxis.selectAll('g.tick line').remove();
3687
+ const textClass = 'lib-xaxis-labels-texts-drilldown';
3688
+ const textSelection = xAxis
3689
+ .selectAll('g.tick text')
3690
+ .attr('class', textClass)
3691
+ .style('fill', 'var(--chart-text-color, #666666)')
3692
+ .style('font-size', '11px');
3693
+ if (keyList.length > 1 && !metaData.xLabel) {
3694
+ textSelection.attr('y', 28);
4050
3695
  }
4051
- });
4052
- // Ensure X-axis line starts exactly at x=0
4053
- xAxisGroup
3696
+ }
3697
+ else {
3698
+ this.renderMultiChartXAxis(svg, x, height, data, metaData);
3699
+ }
3700
+ if (this.chartConfiguration.xLabelsOnSameLine) {
3701
+ this.renderXLabelsOnSameLine(svg, data, metaData);
3702
+ }
3703
+ // Bottom x-axis
3704
+ const xAxis2 = svg
3705
+ .append('g')
3706
+ .attr('class', 'x2 axis2')
3707
+ .attr('transform', `translate(0,${height})`)
3708
+ .style('color', '#000')
3709
+ .call(d3.axisBottom(xScaleFromOrigin).tickSize(0));
3710
+ xAxis2
4054
3711
  .select('.domain')
4055
- .style('stroke', 'var(--chart-axis-color)')
3712
+ .style('stroke', 'var(--chart-axis-color, #CCCCCC)')
4056
3713
  .style('stroke-width', '1px')
4057
- .attr('d', `M0,0.5H${dimensions.requiredSvgWidth}`);
4058
- // Y-axis
3714
+ .attr('fill', 'none');
3715
+ svg.selectAll('g.x2.axis2 g.tick text').style('display', 'none');
3716
+ if (this.isZoomedOut) {
3717
+ svg.selectAll('.lib-xaxis-labels-texts-drilldown').attr('class', 'lib-display-hidden');
3718
+ }
3719
+ }
3720
+ renderMultiChartXAxis(svg, x, height, data, metaData) {
3721
+ let alternate_text = false;
3722
+ const short_tick_length_bg = 5;
3723
+ const long_tick_length_bg = 30;
4059
3724
  svg
4060
3725
  .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)');
3726
+ .attr('class', 'x1 axis1')
3727
+ .attr('transform', `translate(0,${height})`)
3728
+ .call(d3.axisBottom(x).tickSize(0))
3729
+ .call((g) => g.select('.domain').attr('fill', 'none'));
3730
+ svg.selectAll('g.x1.axis1 g.tick line').attr('y2', () => {
3731
+ if (alternate_text && !this.chartConfiguration.isNoAlternateXaxisText) {
3732
+ alternate_text = false;
3733
+ return long_tick_length_bg - 7;
3734
+ }
3735
+ else {
3736
+ alternate_text = true;
3737
+ return short_tick_length_bg - 4;
3738
+ }
3739
+ });
3740
+ alternate_text = false;
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
+ });
4066
3751
  }
4067
- renderDrilldownAxes(svg, svgYAxisLeft, svgYAxisRight, axes, scales, dimensions) {
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();
3766
+ }
3767
+ return d.toLowerCase();
3768
+ });
3769
+ svg
3770
+ .selectAll('g.x1.axis1 g.tick')
3771
+ .append('text')
3772
+ .attr('class', 'lib-xaxis-labels-texts-drilldown')
3773
+ .attr('y', long_tick_length_bg)
3774
+ .attr('fill', 'currentColor')
3775
+ .text((d) => {
3776
+ if (d.trim().indexOf(' ') > -1) {
3777
+ return d.trim().substring(d.indexOf(' ')).toLowerCase();
3778
+ }
3779
+ return '';
3780
+ });
3781
+ }
3782
+ renderYAxis(svg, svgYAxisLeft, svgYAxisRight, y, dimensions) {
3783
+ // Main Y-axis in chart area (hidden)
4068
3784
  svg
4069
3785
  .append('g')
4070
- .attr('transform', `translate(0,${dimensions.height})`)
4071
- .attr('class', 'lib-stacked-x-axis-text multichart1')
4072
- .call(axes.xAxis)
3786
+ .attr('class', 'lib-stacked-y-axis-text yaxis-dashed')
3787
+ .attr('style', this.chartConfiguration.yAxisCustomTextStyles)
3788
+ .attr('transform', 'translate(0,0)')
3789
+ .call(y)
4073
3790
  .style('display', 'none');
4074
- svgYAxisLeft
3791
+ // FIXED: Left Y-axis with visible line
3792
+ const yAxisLeft = d3
3793
+ .axisLeft(y)
3794
+ .tickSize(0)
3795
+ .ticks(this.chartConfiguration.numberOfYTicks)
3796
+ .tickFormat(this.chartConfiguration.yAxisLabelFomatter);
3797
+ const yAxisGroup = svgYAxisLeft
4075
3798
  .append('g')
4076
3799
  .attr('class', 'lib-yaxis-labels-texts-drilldown yaxis-dashed')
4077
3800
  .attr('style', this.chartConfiguration.yAxisCustomTextStyles)
4078
- .call(axes.yAxis)
3801
+ .attr('transform', 'translate(0,0)')
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
4079
3811
  .selectAll('text')
4080
- .style('fill', 'var(--chart-text-color)');
3812
+ .style('fill', 'var(--chart-text-color, #666666)')
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)
4081
3819
  svgYAxisRight
4082
3820
  .append('g')
4083
3821
  .attr('class', 'lib-yaxis-labels-texts-drilldown yaxis-dashed')
4084
3822
  .attr('style', this.chartConfiguration.yAxisCustomTextStyles)
4085
- .call(axes.yAxis)
3823
+ .attr('transform', 'translate(0,0)')
3824
+ .call(y)
4086
3825
  .style('display', 'none');
3826
+ this.applyAxisVisibilitySettings();
4087
3827
  }
4088
- renderMultiChartAxes(svg, axes, scales, dimensions) {
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
+ }
3846
+ renderYAxisGrid(svg, y, width) {
4089
3847
  svg
4090
3848
  .append('g')
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)');
3849
+ .attr('class', 'y-axis-grid')
3850
+ .call(d3.axisLeft(y)
3851
+ .ticks(this.chartConfiguration.numberOfYTicks)
3852
+ .tickSize(-width)
3853
+ .tickFormat(''))
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) {
4096
3862
  svg
4097
3863
  .append('g')
4098
- .attr('class', 'lib-stacked-y-axis-text yaxis-dashed')
3864
+ .attr('class', 'grid')
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')
4099
3880
  .attr('style', this.chartConfiguration.yAxisCustomTextStyles)
4100
- .call(axes.yAxis)
4101
- .selectAll('text')
4102
- .style('fill', 'var(--chart-text-color)');
3881
+ .attr('transform', 'translate(0,0)')
3882
+ .call(yLineAxis);
4103
3883
  }
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)');
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);
4117
3913
  }
4118
- if (this.chartConfiguration.isXaxisColor) {
4119
- d3.selectAll('.multichart').style('color', this.chartConfiguration.isXaxisColor || 'var(--chart-text-color)');
3914
+ if (this.chartConfiguration.isDrilldownChart) {
3915
+ svg.selectAll('g.x1.axis1 g.tick line').style('display', 'none');
4120
3916
  }
4121
3917
  }
4122
- applyAxisConfigurations(svg, scales, dimensions, data) {
4123
- if (this.chartConfiguration.isMultiChartGridLine !== undefined) {
4124
- d3.selectAll('.multichart > g > text').attr('class', 'lib-display-hidden');
3918
+ prepareBarData(d, keyList) {
3919
+ return keyList.map((key) => ({ key, value: d[key], name: d.name }));
3920
+ }
3921
+ handleBarClick(d, metaData) {
3922
+ if (d.key === 'Target')
3923
+ return;
3924
+ if (!metaData.barWithoutClick?.length ||
3925
+ (!metaData.barWithoutClick.includes(d?.name) && !metaData.barWithoutClick.includes(d?.key))) {
3926
+ this.handleClick(d);
4125
3927
  }
4126
- if (this.chartConfiguration.isXaxisLabelHidden) {
4127
- d3.selectAll('.multichart > g > text').attr('class', 'lib-display-hidden');
3928
+ }
3929
+ getBarX(d, data, x, xSubgroup) {
3930
+ if (this.chartConfiguration.isDrilldownChart) {
3931
+ return this.calculateDrilldownBarX(d, data, x);
4128
3932
  }
4129
- else if (this.chartConfiguration.isXaxisLabelHidden !== undefined) {
4130
- this.renderCustomXAxis(svg, scales, dimensions, data);
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
+ }
3948
+ adjustDrilldownScale(tempScale, data, x) {
3949
+ if (this.chartData.data.length === 1) {
3950
+ const keysLength = Object.keys(this.chartData.data[0]).length;
3951
+ const offset = keysLength === 2 ? 200 : 300;
3952
+ tempScale.range([
3953
+ 0 + (x.bandwidth() - offset) / 2,
3954
+ x.bandwidth() - (x.bandwidth() - offset) / 2,
3955
+ ]);
4131
3956
  }
4132
- if (this.chartConfiguration.isYaxisLabelHidden) {
4133
- svg.selectAll('.yaxis-dashed > g > text').attr('class', 'lib-display-hidden');
3957
+ else {
3958
+ tempScale.range([
3959
+ 0 + (x.bandwidth() - 125) / 2,
3960
+ x.bandwidth() - (x.bandwidth() - 125) / 2,
3961
+ ]);
4134
3962
  }
4135
- if (this.chartConfiguration.isYaxisHidden) {
4136
- d3.selectAll('.yaxis-dashed').attr('class', 'lib-display-hidden');
3963
+ return tempScale;
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;
4137
3978
  }
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);
3979
+ return xSubgroup.bandwidth();
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];
4145
3994
  }
3995
+ return this.chartData.metaData.colors[d.key];
4146
3996
  }
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);
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()));
4158
4017
  }
4159
4018
  }
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;
4168
- }
4169
- alternateText = true;
4170
- return this.CONSTANTS.SHORT_TICK_LENGTH_BG - 4;
4171
- });
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';
4180
- }
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;
4019
+ getBarTextLabel(d) {
4020
+ if (!d.key || !d.value)
4021
+ return '';
4022
+ return d.key.length > 20 ? d.key.substring(0, 17) + '...' : d.key;
4023
+ }
4024
+ getBarTextFontSize() {
4025
+ if (this.chartConfiguration.isDrilldownChart) {
4026
+ if (window.innerWidth > 1900)
4027
+ return '18px';
4028
+ if (window.innerWidth < 1400)
4029
+ return '10px';
4030
+ return '14px';
4031
+ }
4032
+ return '14px';
4033
+ }
4034
+ getBarTextTransform(d, data, x, xSubgroup, y) {
4035
+ let tempScale;
4036
+ data.forEach((indiv) => {
4037
+ if (indiv.name === d.name) {
4038
+ const keys = Object.keys(indiv).filter((temp, i) => i !== 0);
4039
+ tempScale = d3.scaleBand().domain(keys).range([0, x.bandwidth()]);
4040
+ if (x.bandwidth() > 100) {
4041
+ tempScale = this.adjustDrilldownScale(tempScale, data, x);
4042
+ }
4187
4043
  }
4188
- alternateText = true;
4189
- return this.CONSTANTS.SHORT_TICK_LENGTH_BG;
4190
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)`;
4050
+ }
4051
+ return 'translate(0,0)';
4191
4052
  }
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')
4206
- .append('text')
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
- : '';
4053
+ handleMouseOver(svg, d, data, metaData, x, y, leftAndRightSpaces) {
4054
+ svg.selectAll('.lib-verticalstack-title-ontop').remove();
4055
+ let tempScale;
4056
+ data.forEach((indiv) => {
4057
+ if (indiv.name === d.name) {
4058
+ const keys = Object.keys(indiv).filter((temp, i) => i !== 0);
4059
+ tempScale = d3.scaleBand().domain(keys).range([0, x.bandwidth()]);
4060
+ if (x.bandwidth() > 100) {
4061
+ tempScale = this.adjustDrilldownScale(tempScale, data, x);
4062
+ }
4063
+ }
4216
4064
  });
4065
+ const foreignObject = svg
4066
+ .append('foreignObject')
4067
+ .attr('x', () => this.calculateTooltipX(d, x, tempScale, metaData, leftAndRightSpaces))
4068
+ .attr('y', () => y(d.value) - 43)
4069
+ .attr('class', 'lib-verticalstack-title-ontop')
4070
+ .attr('width', () => this.calculateTooltipWidth(tempScale, metaData, leftAndRightSpaces))
4071
+ .attr('height', 40);
4072
+ foreignObject
4073
+ .append('xhtml:div')
4074
+ .attr('class', 'title')
4075
+ .style('z-index', 99)
4076
+ .html(() => this.getTooltipHTML(d, metaData));
4217
4077
  }
4218
- renderDataLabels(rect, scales, metaData, dimensions) {
4219
- if (!this.isCC && !this.chartConfiguration.isMultiChartGridLine) {
4220
- rect.append('svg:title').text((d) => d[1] - d[0]);
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;
4082
+ }
4083
+ return (x(d.name) +
4084
+ tempScale(d.key) -
4085
+ (tempScale.bandwidth() + leftAndRightSpaces * 2) / 2 +
4086
+ tempScale.bandwidth() / 2);
4221
4087
  }
4222
- if (this.chartConfiguration.showTotalOnTop) {
4223
- this.renderTopLabels(rect, scales, metaData);
4088
+ return (x(d.name) +
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';
4097
+ }
4098
+ return tempScale.bandwidth() + leftAndRightSpaces * 2;
4224
4099
  }
4225
- if (this.chartConfiguration.showAngledLabels) {
4226
- this.renderAngledLabels(rect, scales, metaData);
4100
+ return tempScale.bandwidth() + leftAndRightSpaces * 2;
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>`;
4227
4110
  }
4228
4111
  }
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
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
+ }
4128
+ }
4129
+ renderYAxisLabel(svgYAxisLeft, yLabel, height, margin) {
4130
+ // FIXED: Proper Y-axis label with correct positioning
4131
+ svgYAxisLeft
4235
4132
  .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
- });
4133
+ .attr('class', 'lib-axis-group-label lib-ylabel-visible')
4134
+ .attr('style', this.chartConfiguration.yAxisCustomlabelStyles)
4135
+ .attr('transform', 'rotate(-90)')
4136
+ .attr('y', -margin.left)
4137
+ .attr('x', 0 - height / 2)
4138
+ .attr('dy', '1em')
4139
+ .style('text-anchor', 'middle')
4140
+ .style('font-size', '11px')
4141
+ .style('font-weight', '400')
4142
+ .style('fill', 'var(--chart-text-color, #666666)');
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
+ }
4248
4152
  }
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
4153
+ renderXAxisLabel(svg, xLabel, width, height, margin) {
4154
+ const isAcronym = this.isAcronym(xLabel.replace(/[^A-Za-z]/g, ''));
4155
+ let baseClass = 'lib-axis-group-label font-size-1';
4156
+ if (this.chartConfiguration.isDrilldownChart) {
4157
+ baseClass += ' lib-xlabel-drilldowncharts';
4158
+ }
4159
+ else if (this.chartConfiguration.isMultiChartGridLine !== undefined) {
4160
+ baseClass += ' lib-xlabel-weeklyCharts';
4161
+ }
4162
+ else {
4163
+ baseClass += ' lib-axis-waterfall-label';
4164
+ }
4165
+ svg
4256
4166
  .append('text')
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
- });
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');
4298
4176
  }
4299
- renderTargetLine(svg, svgYAxisRight, scales, dimensions, metaData) {
4177
+ isAcronym(label) {
4178
+ return ((label.length <= 4 && /^[A-Z]+$/.test(label)) ||
4179
+ (label === label.toUpperCase() && /[A-Z]/.test(label)));
4180
+ }
4181
+ renderLineYAxisLabel(svgYAxisRight, lineyLabel) {
4182
+ svgYAxisRight
4183
+ .append('text')
4184
+ .attr('class', 'lib-axis-group-label lib-line-axis')
4185
+ .attr('style', this.chartConfiguration.yAxisCustomlabelStyles)
4186
+ .attr('transform', 'translate(0,0) rotate(90)')
4187
+ .attr('y', -100)
4188
+ .attr('x', 100)
4189
+ .attr('dy', '5em')
4190
+ .style('text-anchor', 'middle')
4191
+ .style('font-size', 'smaller')
4192
+ .text(lineyLabel);
4193
+ }
4194
+ renderTargetLine(svgElements, scales, chartContext, dimensions) {
4300
4195
  if (!this.chartData.targetLineData)
4301
4196
  return;
4302
- const parsedTarget = this.parseTargetValue(this.chartData.targetLineData.target);
4303
- const yZero = scales.yScale(parsedTarget);
4197
+ const { svg, svgYAxisRight } = svgElements;
4198
+ const { y } = scales;
4199
+ const { width } = dimensions;
4200
+ const { metaData } = chartContext;
4201
+ const targetData = this.chartData.targetLineData;
4202
+ const yZero = y(targetData.target);
4304
4203
  svg
4305
4204
  .append('line')
4306
4205
  .attr('x1', 0)
4307
- .attr('x2', dimensions.width)
4206
+ .attr('x2', width)
4308
4207
  .attr('y1', yZero)
4309
4208
  .attr('y2', yZero)
4310
4209
  .style('stroke-dasharray', '5 5')
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';
4210
+ .style('stroke', targetData.color);
4211
+ const rightSvgWidth = 60;
4323
4212
  svgYAxisRight
4324
4213
  .append('foreignObject')
4325
- .attr('transform', `translate(0,${yZero - 13})`)
4326
- .attr('width', this.CONSTANTS.RIGHT_SVG_WIDTH)
4214
+ .attr('transform', `translate(0,${yZero - 30})`)
4215
+ .attr('width', rightSvgWidth)
4327
4216
  .attr('height', 50)
4328
4217
  .append('xhtml:div')
4329
4218
  .attr('class', 'target-display')
4330
4219
  .style('color', 'var(--chart-text-color)')
4331
- .html(`<div>${targetName}</div><div>${this.chartData.targetLineData.target}${dataType}</div>`);
4220
+ .html(() => {
4221
+ const dataType = metaData.dataType || '';
4222
+ const targetName = targetData.targetName || 'target';
4223
+ return `<div>${targetName}</div><div>${targetData.target}${dataType}</div>`;
4224
+ });
4332
4225
  }
4333
- renderLineChart(svg, lineData, scales, colors, metaData) {
4334
- if (!lineData || !colors)
4226
+ renderLineGraph(svg, chartContext, scales) {
4227
+ const { lineData, metaData } = chartContext;
4228
+ if (!lineData)
4335
4229
  return;
4336
- const dataGroup = d3
4337
- .nest()
4338
- .key((d) => d.category)
4339
- .entries(lineData);
4340
- const lineGen = d3
4230
+ const { x, lineYscale } = scales;
4231
+ svg
4232
+ .append('path')
4233
+ .datum(lineData)
4234
+ .attr('fill', 'none')
4235
+ .attr('stroke', this.chartConfiguration.lineGraphColor)
4236
+ .attr('stroke-width', 1.5)
4237
+ .attr('d', d3
4341
4238
  .line()
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) {
4239
+ .x((d) => x(d.name) + x.bandwidth() / 2)
4240
+ .y((d) => lineYscale(d.value)));
4360
4241
  const dot = svg
4361
- .selectAll('.line-dots')
4362
- .data(values)
4242
+ .selectAll('myCircles')
4243
+ .data(lineData)
4363
4244
  .enter()
4364
4245
  .append('g')
4365
- .on('click', (d) => this.handleClick(d));
4246
+ .on('click', (d) => this.handleBarClick(d, metaData));
4366
4247
  dot
4367
4248
  .append('circle')
4368
- .attr('fill', (d) => {
4369
- return d.category
4370
- ? colors[d.category]
4371
- : this.chartConfiguration.lineGraphColor;
4372
- })
4249
+ .attr('fill', this.chartConfiguration.lineGraphColor)
4373
4250
  .attr('stroke', 'none')
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');
4251
+ .attr('cx', (d) => x(d.name) + x.bandwidth() / 2)
4252
+ .attr('cy', (d) => lineYscale(d.value))
4253
+ .style('cursor', 'pointer')
4254
+ .attr('r', 3);
4378
4255
  if (this.chartConfiguration.lineGraphColor) {
4379
4256
  dot
4380
4257
  .append('text')
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))
4258
+ .attr('class', 'dot')
4259
+ .attr('color', this.chartConfiguration.lineGraphColor)
4260
+ .attr('style', 'font-size: .85em')
4261
+ .attr('x', (d) => x(d.name) + x.bandwidth() / 2)
4262
+ .attr('y', (d) => lineYscale(d.value))
4387
4263
  .attr('dy', '-1em')
4388
4264
  .text((d) => this.chartConfiguration.labelFormatter(d.value));
4389
4265
  }
4390
4266
  }
4391
4267
  handleClick(d) {
4392
- if (this.chartData?.metaData?.hasDrillDown || d?.toggleFrom) {
4268
+ if (this.chartData.metaData.hasDrillDown || d?.toggleFrom) {
4393
4269
  this.clickEvent.emit(d);
4394
4270
  }
4395
4271
  }
4396
4272
  handleHeaderMenuClick(id) {
4397
4273
  this.headerMenuclickEvent.emit(id);
4398
4274
  }
4275
+ handleDD1Click(event) {
4276
+ this.isDD1Open = true;
4277
+ this.isDD2Open = false;
4278
+ }
4279
+ handleDD2Click(event) {
4280
+ this.isDD2Open = true;
4281
+ this.isDD1Open = false;
4282
+ }
4399
4283
  handleCompareByFilterSelection(event) {
4400
4284
  this.clickEvent.emit(event);
4401
4285
  }
4402
- handleZoominZoomoutClick({ isZoomOut, event }) {
4403
- this.isZoomOutSelected(isZoomOut);
4404
- }
4405
4286
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: GroupChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
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 }); }
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 }); }
4407
4288
  }
4408
4289
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: GroupChartComponent, decorators: [{
4409
4290
  type: Component,