axidio-styleguide-library1-v2 0.2.29 → 0.2.30
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.
|
@@ -3379,7 +3379,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
3379
3379
|
class GroupChartComponent extends ComponentUniqueId {
|
|
3380
3380
|
constructor() {
|
|
3381
3381
|
super();
|
|
3382
|
-
this.customChartConfiguration = {};
|
|
3383
3382
|
this.clickEvent = new EventEmitter();
|
|
3384
3383
|
this.headerMenuclickEvent = new EventEmitter();
|
|
3385
3384
|
this.isHeaderVisible = true;
|
|
@@ -3387,18 +3386,6 @@ class GroupChartComponent extends ComponentUniqueId {
|
|
|
3387
3386
|
this.isTransparentBackground = false;
|
|
3388
3387
|
this.chartConfiguration = {};
|
|
3389
3388
|
this.objectKeys = Object.keys;
|
|
3390
|
-
this.CONSTANTS = {
|
|
3391
|
-
SHORT_TICK_LENGTH: 4,
|
|
3392
|
-
LONG_TICK_LENGTH: 16,
|
|
3393
|
-
SHORT_TICK_LENGTH_BG: 5,
|
|
3394
|
-
LONG_TICK_LENGTH_BG: 30,
|
|
3395
|
-
LEFT_RIGHT_SPACES: 50,
|
|
3396
|
-
RIGHT_SVG_WIDTH: 60,
|
|
3397
|
-
ZOOM_WIDTH_MULTIPLIER: 40,
|
|
3398
|
-
DRILLDOWN_WIDTH_MULTIPLIER: 160,
|
|
3399
|
-
MIN_BAR_WIDTH_SINGLE: 200,
|
|
3400
|
-
MIN_BAR_WIDTH_MULTIPLE: 125,
|
|
3401
|
-
};
|
|
3402
3389
|
this.defaultConfiguration = {
|
|
3403
3390
|
margin: { top: 20, right: 20, bottom: 20, left: 40 },
|
|
3404
3391
|
labelFormatter: ChartHelper.defaultFormatter,
|
|
@@ -3427,11 +3414,9 @@ class GroupChartComponent extends ComponentUniqueId {
|
|
|
3427
3414
|
this.isZoomedOut = false;
|
|
3428
3415
|
this.isDD1Open = false;
|
|
3429
3416
|
this.isDD2Open = false;
|
|
3430
|
-
this.keepOrder = (a) => a;
|
|
3431
|
-
}
|
|
3432
|
-
ngOnInit() {
|
|
3433
|
-
this.initializeConfiguration();
|
|
3417
|
+
this.keepOrder = (a, b) => a;
|
|
3434
3418
|
}
|
|
3419
|
+
ngOnInit() { }
|
|
3435
3420
|
get isAlertEnabled() {
|
|
3436
3421
|
return this.chartConfiguration?.headerMenuOptions?.some((option) => option.id === 'editAlert');
|
|
3437
3422
|
}
|
|
@@ -3441,15 +3426,30 @@ class GroupChartComponent extends ComponentUniqueId {
|
|
|
3441
3426
|
this.initializegroupChart();
|
|
3442
3427
|
}, 10);
|
|
3443
3428
|
}
|
|
3444
|
-
|
|
3429
|
+
isZoomOutSelected(isZoomOut, event) {
|
|
3445
3430
|
this.isZoomedOut = isZoomOut;
|
|
3446
3431
|
this.onResized(event);
|
|
3447
3432
|
}
|
|
3433
|
+
handleZoominZoomoutClick({ isZoomOut, event }) {
|
|
3434
|
+
this.isZoomOutSelected(isZoomOut, event);
|
|
3435
|
+
}
|
|
3448
3436
|
isLegendVisible() {
|
|
3449
3437
|
return !!(this.chartData?.metaData?.colors &&
|
|
3450
3438
|
Object.keys(this.chartData.metaData.colors).length > 1);
|
|
3451
3439
|
}
|
|
3452
|
-
|
|
3440
|
+
initializegroupChart() {
|
|
3441
|
+
this.mergeConfigurations();
|
|
3442
|
+
const chartContext = this.prepareChartData();
|
|
3443
|
+
const dimensions = this.calculateDimensions(chartContext);
|
|
3444
|
+
const scales = this.createScales(chartContext, dimensions);
|
|
3445
|
+
const svgElements = this.createSVGStructure(dimensions);
|
|
3446
|
+
this.renderAxes(svgElements, scales, chartContext, dimensions);
|
|
3447
|
+
this.renderBars(svgElements.svg, chartContext, scales, dimensions);
|
|
3448
|
+
this.renderLabels(svgElements, scales, chartContext, dimensions);
|
|
3449
|
+
this.renderTargetLine(svgElements, scales, chartContext, dimensions);
|
|
3450
|
+
this.renderLineGraph(svgElements.svg, chartContext, scales);
|
|
3451
|
+
}
|
|
3452
|
+
mergeConfigurations() {
|
|
3453
3453
|
for (const key in this.defaultConfiguration) {
|
|
3454
3454
|
this.chartConfiguration[key] = ChartHelper.getValueByConfigurationType(key, this.defaultConfiguration, this.customChartConfiguration);
|
|
3455
3455
|
}
|
|
@@ -3463,143 +3463,113 @@ class GroupChartComponent extends ComponentUniqueId {
|
|
|
3463
3463
|
this.isTransparentBackground = this.chartConfiguration.isTransparentBackground;
|
|
3464
3464
|
}
|
|
3465
3465
|
}
|
|
3466
|
-
|
|
3466
|
+
prepareChartData() {
|
|
3467
3467
|
const data = this.chartData.data;
|
|
3468
|
-
const metaData = this.
|
|
3468
|
+
const metaData = this.chartData.metaData;
|
|
3469
3469
|
const lineData = this.chartData.lineData;
|
|
3470
|
-
const isRia = this.chartConfiguration.isRia || false;
|
|
3471
|
-
const { width, height } = this.calculateDimensions();
|
|
3472
|
-
const { svg, svgYAxisLeft, svgYAxisRight } = this.createSvgContainers(width, height);
|
|
3473
|
-
const scales = this.createScales(data, metaData, width, height, lineData);
|
|
3474
|
-
this.renderAxes(svg, svgYAxisLeft, svgYAxisRight, scales, width, height);
|
|
3475
|
-
this.renderBars(svg, data, metaData, scales, isRia);
|
|
3476
|
-
this.renderLabels(svg, svgYAxisLeft, svgYAxisRight, metaData, width, height, scales);
|
|
3477
|
-
this.renderTargetLine(svg, svgYAxisRight, scales.y, width);
|
|
3478
|
-
this.renderLineGraph(svg, lineData, metaData, scales, isRia);
|
|
3479
|
-
}
|
|
3480
|
-
prepareMetaData(metaData) {
|
|
3481
3470
|
if (!metaData.colorAboveTarget) {
|
|
3482
3471
|
metaData.colorAboveTarget = metaData.colors;
|
|
3483
3472
|
}
|
|
3484
|
-
return
|
|
3473
|
+
return {
|
|
3474
|
+
data,
|
|
3475
|
+
metaData,
|
|
3476
|
+
lineData,
|
|
3477
|
+
keyList: metaData.keyList,
|
|
3478
|
+
colorMap: metaData.colors,
|
|
3479
|
+
isRia: this.customChartConfiguration?.isRia || false,
|
|
3480
|
+
};
|
|
3485
3481
|
}
|
|
3486
|
-
calculateDimensions() {
|
|
3482
|
+
calculateDimensions(chartContext) {
|
|
3487
3483
|
const chartContainer = d3.select(this.containerElt.nativeElement);
|
|
3488
3484
|
const verticalstackedcontainer = d3.select(this.groupcontainerElt.nativeElement);
|
|
3489
3485
|
const margin = this.chartConfiguration.margin;
|
|
3490
|
-
let width =
|
|
3491
|
-
width = this.adjustWidthForZoom(width);
|
|
3486
|
+
let width = this.calculateWidth(chartContainer, margin);
|
|
3492
3487
|
let height = this.calculateHeight(verticalstackedcontainer, margin);
|
|
3493
|
-
return { width, height };
|
|
3488
|
+
return { width, height, margin, chartContainer, verticalstackedcontainer };
|
|
3494
3489
|
}
|
|
3495
|
-
|
|
3490
|
+
calculateWidth(chartContainer, margin) {
|
|
3491
|
+
const baseWidth = parseInt(chartContainer.style('width')) - margin.left - margin.right;
|
|
3496
3492
|
const dataLength = this.chartData.data.length;
|
|
3493
|
+
let width = baseWidth;
|
|
3497
3494
|
if (dataLength > 30 && this.isZoomedOut) {
|
|
3498
|
-
const
|
|
3499
|
-
|
|
3500
|
-
width = Math.max(width, dropdownWidth);
|
|
3495
|
+
const multiplier = this.chartData.dropdownData1 ? 60 : 40;
|
|
3496
|
+
width = Math.max(width, dataLength * multiplier);
|
|
3501
3497
|
}
|
|
3502
3498
|
if (this.chartData.dropdownData2 && width < dataLength * 120 && this.isZoomedOut) {
|
|
3503
3499
|
width = dataLength * 120;
|
|
3504
3500
|
}
|
|
3505
3501
|
if (dataLength > 8 && !this.isZoomedOut) {
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3502
|
+
if (this.chartData.dropdownData2 && width < dataLength * 250) {
|
|
3503
|
+
width = dataLength * 250;
|
|
3504
|
+
}
|
|
3505
|
+
else {
|
|
3506
|
+
width = dataLength * 160;
|
|
3507
|
+
}
|
|
3509
3508
|
}
|
|
3510
3509
|
return width;
|
|
3511
3510
|
}
|
|
3512
|
-
calculateHeight(
|
|
3513
|
-
let height = parseInt(
|
|
3514
|
-
(this.chartConfiguration.svgHeight / 100) -
|
|
3511
|
+
calculateHeight(verticalstackedcontainer, margin) {
|
|
3512
|
+
let height = parseInt(verticalstackedcontainer.style('height')) *
|
|
3513
|
+
(this.chartConfiguration.svgHeight / 100) -
|
|
3514
|
+
margin.top -
|
|
3515
|
+
margin.bottom;
|
|
3515
3516
|
if (this.chartConfiguration.isFullScreen && this.chartConfiguration.svgHeight !== 70) {
|
|
3516
3517
|
height = this.chartConfiguration.svgHeight;
|
|
3517
3518
|
}
|
|
3518
3519
|
else if (this.chartConfiguration.isFullScreen) {
|
|
3519
|
-
height = parseInt(
|
|
3520
|
+
height = parseInt(verticalstackedcontainer.style('height'));
|
|
3520
3521
|
}
|
|
3521
3522
|
if (this.chartConfiguration.isDrilldownChart && !this.isHeaderVisible) {
|
|
3522
|
-
height = parseInt(
|
|
3523
|
+
height = parseInt(verticalstackedcontainer.style('height')) - margin.top - margin.bottom - 130;
|
|
3523
3524
|
}
|
|
3524
3525
|
if (this.chartConfiguration.isHeaderVisible) {
|
|
3525
|
-
height = parseInt(
|
|
3526
|
+
height = parseInt(verticalstackedcontainer.style('height')) - margin.top - margin.bottom - 100;
|
|
3526
3527
|
}
|
|
3527
3528
|
return height;
|
|
3528
3529
|
}
|
|
3529
|
-
|
|
3530
|
-
const
|
|
3531
|
-
const margin =
|
|
3532
|
-
const
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
.append('svg')
|
|
3571
|
-
.attr('width', this.CONSTANTS.RIGHT_SVG_WIDTH)
|
|
3572
|
-
.attr('height', height + margin.top + margin.bottom + 10)
|
|
3573
|
-
.style('position', 'absolute')
|
|
3574
|
-
.style('right', '12px')
|
|
3575
|
-
.style('z-index', 1)
|
|
3576
|
-
.append('g')
|
|
3577
|
-
.attr('transform', `translate(0, ${margin.top})`);
|
|
3578
|
-
}
|
|
3579
|
-
createScales(data, metaData, width, height, lineData) {
|
|
3580
|
-
const { x, xScaleFromOrigin } = this.createXScales(data, width);
|
|
3581
|
-
const y = this.createYScale(data, metaData.keyList, height);
|
|
3582
|
-
const xSubgroup = this.createSubgroupScale(metaData.keyList, x);
|
|
3583
|
-
const lineYscale = lineData ? this.createLineYScale(lineData, height) : null;
|
|
3584
|
-
return { x, xScaleFromOrigin, y, xSubgroup, lineYscale };
|
|
3585
|
-
}
|
|
3586
|
-
createXScales(data, width) {
|
|
3587
|
-
const groups = data.map((d) => d.name);
|
|
3588
|
-
const x = d3
|
|
3589
|
-
.scaleBand()
|
|
3590
|
-
.domain(groups)
|
|
3591
|
-
.range([
|
|
3592
|
-
this.CONSTANTS.LEFT_RIGHT_SPACES,
|
|
3593
|
-
width - this.CONSTANTS.RIGHT_SVG_WIDTH - this.CONSTANTS.LEFT_RIGHT_SPACES,
|
|
3594
|
-
])
|
|
3595
|
-
.padding(0.3);
|
|
3596
|
-
const xScaleFromOrigin = d3
|
|
3597
|
-
.scaleBand()
|
|
3598
|
-
.domain(groups)
|
|
3599
|
-
.range([0, width - this.CONSTANTS.RIGHT_SVG_WIDTH]);
|
|
3600
|
-
return { x, xScaleFromOrigin };
|
|
3530
|
+
createScales(chartContext, dimensions) {
|
|
3531
|
+
const { data, metaData, lineData, keyList } = chartContext;
|
|
3532
|
+
const { width, height, margin } = dimensions;
|
|
3533
|
+
const leftAndRightSpaces = 50;
|
|
3534
|
+
const rightSvgWidth = 60;
|
|
3535
|
+
const groups = d3.map(data, (d) => d.name).keys();
|
|
3536
|
+
let x;
|
|
3537
|
+
if (this.chartConfiguration.isMultiChartGridLine !== undefined) {
|
|
3538
|
+
x = d3
|
|
3539
|
+
.scaleBand()
|
|
3540
|
+
.rangeRound([width, 0])
|
|
3541
|
+
.align(0.5)
|
|
3542
|
+
.padding(0.5)
|
|
3543
|
+
.domain(data.map((d) => d.name.toLowerCase()));
|
|
3544
|
+
}
|
|
3545
|
+
else {
|
|
3546
|
+
x = d3
|
|
3547
|
+
.scaleBand()
|
|
3548
|
+
.domain(groups)
|
|
3549
|
+
.range([leftAndRightSpaces, width - rightSvgWidth - leftAndRightSpaces])
|
|
3550
|
+
.padding(0.3);
|
|
3551
|
+
}
|
|
3552
|
+
const xScaleFromOrigin = d3.scaleBand().domain(groups).range([0, width - rightSvgWidth]);
|
|
3553
|
+
const xSubgroup = d3.scaleBand().domain(keyList).range([0, x.bandwidth()]);
|
|
3554
|
+
const maxValue = this.calculateMaxValue(data, keyList);
|
|
3555
|
+
const y = d3.scaleLinear().domain([0, maxValue]).nice().rangeRound([height, 0]);
|
|
3556
|
+
let lineYscale = null;
|
|
3557
|
+
if (lineData) {
|
|
3558
|
+
lineYscale = this.createLineYScale(lineData, height);
|
|
3559
|
+
}
|
|
3560
|
+
const color = d3.scaleOrdinal().domain(keyList).range(Object.values(metaData.colors));
|
|
3561
|
+
return {
|
|
3562
|
+
x,
|
|
3563
|
+
xScaleFromOrigin,
|
|
3564
|
+
xSubgroup,
|
|
3565
|
+
y,
|
|
3566
|
+
lineYscale,
|
|
3567
|
+
color,
|
|
3568
|
+
leftAndRightSpaces,
|
|
3569
|
+
rightSvgWidth,
|
|
3570
|
+
};
|
|
3601
3571
|
}
|
|
3602
|
-
|
|
3572
|
+
calculateMaxValue(data, keyList) {
|
|
3603
3573
|
let maxValue = d3.max(data, (d) => d3.max(keyList, (key) => +d[key])) || 0;
|
|
3604
3574
|
if (maxValue === 0) {
|
|
3605
3575
|
maxValue = this.chartData.targetLineData
|
|
@@ -3613,10 +3583,7 @@ class GroupChartComponent extends ComponentUniqueId {
|
|
|
3613
3583
|
const target = this.chartData.targetLineData.target;
|
|
3614
3584
|
maxValue = maxValue < 10 && target < 10 ? target + 3 : target + 20;
|
|
3615
3585
|
}
|
|
3616
|
-
return
|
|
3617
|
-
}
|
|
3618
|
-
createSubgroupScale(subgroups, x) {
|
|
3619
|
-
return d3.scaleBand().domain(subgroups).range([0, x.bandwidth()]);
|
|
3586
|
+
return maxValue;
|
|
3620
3587
|
}
|
|
3621
3588
|
createLineYScale(lineData, height) {
|
|
3622
3589
|
let maxLineValue = d3.max(lineData, (d) => +d.value) || 0;
|
|
@@ -3626,39 +3593,180 @@ class GroupChartComponent extends ComponentUniqueId {
|
|
|
3626
3593
|
minLineValue -= 3;
|
|
3627
3594
|
if (minLineValue > 0)
|
|
3628
3595
|
minLineValue = 0;
|
|
3629
|
-
return d3
|
|
3630
|
-
.scaleLinear()
|
|
3631
|
-
.domain([minLineValue, maxLineValue])
|
|
3632
|
-
.range([height, minLineValue]);
|
|
3596
|
+
return d3.scaleLinear().domain([minLineValue, maxLineValue]).range([height, minLineValue]);
|
|
3633
3597
|
}
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3598
|
+
createSVGStructure(dimensions) {
|
|
3599
|
+
const { chartContainer, height, margin } = dimensions;
|
|
3600
|
+
const rightSvgWidth = 60;
|
|
3601
|
+
const outerContainer = chartContainer
|
|
3602
|
+
.append('div')
|
|
3603
|
+
.attr('id', this.uniqueId)
|
|
3604
|
+
.attr('class', 'outer-container')
|
|
3605
|
+
.style('width', '100%')
|
|
3606
|
+
.style('height', height)
|
|
3607
|
+
.style('overflow-x', 'hidden')
|
|
3608
|
+
.style('padding-left', `${margin.left}px`)
|
|
3609
|
+
.style('padding-right', `${rightSvgWidth}px`)
|
|
3610
|
+
.style('margin-left', '15px');
|
|
3611
|
+
const svgYAxisLeft = outerContainer
|
|
3612
|
+
.append('svg')
|
|
3613
|
+
.attr('width', 100)
|
|
3614
|
+
.attr('height', height + margin.top + margin.bottom + 10)
|
|
3615
|
+
.style('position', 'absolute')
|
|
3616
|
+
.style('left', '0')
|
|
3617
|
+
.style('z-index', 1)
|
|
3618
|
+
.append('g')
|
|
3619
|
+
.attr('transform', `translate(${margin.left + 15},${margin.top})`);
|
|
3620
|
+
const svgYAxisRight = outerContainer
|
|
3621
|
+
.append('svg')
|
|
3622
|
+
.attr('width', rightSvgWidth)
|
|
3623
|
+
.attr('height', height + margin.top + margin.bottom + 10)
|
|
3624
|
+
.style('position', 'absolute')
|
|
3625
|
+
.style('right', '12px')
|
|
3626
|
+
.style('z-index', 1)
|
|
3627
|
+
.append('g')
|
|
3628
|
+
.attr('transform', `translate(0,${margin.top})`);
|
|
3629
|
+
const innerContainer = outerContainer
|
|
3630
|
+
.append('div')
|
|
3631
|
+
.attr('class', 'inner-container')
|
|
3632
|
+
.style('width', '100%')
|
|
3633
|
+
.style('overflow-x', 'auto');
|
|
3634
|
+
const svg = innerContainer
|
|
3635
|
+
.append('svg')
|
|
3636
|
+
.attr('width', dimensions.width - rightSvgWidth)
|
|
3637
|
+
.attr('height', height + margin.top + margin.bottom + 30)
|
|
3638
|
+
.append('g')
|
|
3639
|
+
.attr('transform', `translate(0,${margin.top})`);
|
|
3640
|
+
return { outerContainer, svgYAxisLeft, svgYAxisRight, svg };
|
|
3641
|
+
}
|
|
3642
|
+
renderAxes(svgElements, scales, chartContext, dimensions) {
|
|
3643
|
+
const { svg, svgYAxisLeft, svgYAxisRight } = svgElements;
|
|
3644
|
+
const { x, xScaleFromOrigin, y, lineYscale } = scales;
|
|
3645
|
+
const { height } = dimensions;
|
|
3646
|
+
const { metaData, lineData, keyList } = chartContext;
|
|
3647
|
+
this.renderXAxis(svg, x, xScaleFromOrigin, height, chartContext, keyList);
|
|
3648
|
+
this.renderYAxis(svg, svgYAxisLeft, svgYAxisRight, y, dimensions);
|
|
3649
|
+
if (this.chartConfiguration.yAxisGrid) {
|
|
3650
|
+
this.renderYAxisGrid(svg, y, dimensions.width);
|
|
3651
|
+
}
|
|
3652
|
+
if (this.chartConfiguration.isXgridBetweenLabels) {
|
|
3653
|
+
this.renderXAxisGrid(svg, x, height);
|
|
3654
|
+
}
|
|
3655
|
+
if (lineData && this.chartConfiguration.showLineChartAxis && lineYscale) {
|
|
3656
|
+
this.renderLineYAxis(svgYAxisRight, lineYscale);
|
|
3657
|
+
}
|
|
3638
3658
|
}
|
|
3639
|
-
renderXAxis(svg, x, height) {
|
|
3640
|
-
|
|
3659
|
+
renderXAxis(svg, x, xScaleFromOrigin, height, chartContext, keyList) {
|
|
3660
|
+
const { data, metaData } = chartContext;
|
|
3661
|
+
if (this.chartConfiguration.isMultiChartGridLine === undefined) {
|
|
3641
3662
|
svg
|
|
3642
3663
|
.append('g')
|
|
3643
3664
|
.attr('class', 'x1 axis1')
|
|
3644
|
-
.attr('transform', `translate(0
|
|
3665
|
+
.attr('transform', `translate(0,${height})`)
|
|
3645
3666
|
.call(d3.axisBottom(x))
|
|
3646
3667
|
.call((g) => g.select('.domain').remove());
|
|
3647
3668
|
svg.selectAll('g.x1.axis1 g.tick line').remove();
|
|
3648
|
-
const
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
.
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3669
|
+
const textClass = 'lib-xaxis-labels-texts-drilldown';
|
|
3670
|
+
const textSelection = svg.selectAll('g.x1.axis1 g.tick text').attr('class', textClass).style('fill', 'var(--chart-text-color)');
|
|
3671
|
+
if (keyList.length > 1 && !metaData.xLabel) {
|
|
3672
|
+
textSelection.attr('y', 32);
|
|
3673
|
+
}
|
|
3674
|
+
}
|
|
3675
|
+
else {
|
|
3676
|
+
this.renderMultiChartXAxis(svg, x, height, data, metaData);
|
|
3677
|
+
}
|
|
3678
|
+
if (this.chartConfiguration.xLabelsOnSameLine) {
|
|
3679
|
+
this.renderXLabelsOnSameLine(svg, data, metaData);
|
|
3680
|
+
}
|
|
3681
|
+
// Render bottom x-axis
|
|
3682
|
+
svg
|
|
3683
|
+
.append('g')
|
|
3684
|
+
.attr('class', 'x2 axis2')
|
|
3685
|
+
.attr('transform', `translate(0,${height})`)
|
|
3686
|
+
.style('color', '#000')
|
|
3687
|
+
.call(d3.axisBottom(xScaleFromOrigin).tickSize(0))
|
|
3688
|
+
.call((g) => g.select('.domain').attr('fill', 'none'));
|
|
3689
|
+
svg.selectAll('g.x2.axis2 g.tick text').style('display', 'none');
|
|
3690
|
+
if (this.isZoomedOut) {
|
|
3691
|
+
svg.selectAll('.lib-xaxis-labels-texts-drilldown').attr('class', 'lib-display-hidden');
|
|
3655
3692
|
}
|
|
3656
3693
|
}
|
|
3657
|
-
|
|
3694
|
+
renderMultiChartXAxis(svg, x, height, data, metaData) {
|
|
3695
|
+
let alternate_text = false;
|
|
3696
|
+
const short_tick_length_bg = 5;
|
|
3697
|
+
const long_tick_length_bg = 30;
|
|
3698
|
+
svg
|
|
3699
|
+
.append('g')
|
|
3700
|
+
.attr('class', 'x1 axis1')
|
|
3701
|
+
.attr('transform', `translate(0,${height})`)
|
|
3702
|
+
.call(d3.axisBottom(x).tickSize(0))
|
|
3703
|
+
.call((g) => g.select('.domain').attr('fill', 'none'));
|
|
3704
|
+
svg.selectAll('g.x1.axis1 g.tick line').attr('y2', () => {
|
|
3705
|
+
if (alternate_text && !this.chartConfiguration.isNoAlternateXaxisText) {
|
|
3706
|
+
alternate_text = false;
|
|
3707
|
+
return long_tick_length_bg - 7;
|
|
3708
|
+
}
|
|
3709
|
+
else {
|
|
3710
|
+
alternate_text = true;
|
|
3711
|
+
return short_tick_length_bg - 4;
|
|
3712
|
+
}
|
|
3713
|
+
});
|
|
3714
|
+
alternate_text = false;
|
|
3715
|
+
svg.selectAll('g.x1.axis1 g.tick text').attr('class', 'lib-xaxis-labels-texts-weeklycharts').attr('y', () => {
|
|
3716
|
+
if (alternate_text) {
|
|
3717
|
+
alternate_text = false;
|
|
3718
|
+
return long_tick_length_bg;
|
|
3719
|
+
}
|
|
3720
|
+
else {
|
|
3721
|
+
alternate_text = true;
|
|
3722
|
+
return short_tick_length_bg;
|
|
3723
|
+
}
|
|
3724
|
+
});
|
|
3725
|
+
}
|
|
3726
|
+
renderXLabelsOnSameLine(svg, data, metaData) {
|
|
3727
|
+
const short_tick_length_bg = 5;
|
|
3728
|
+
const long_tick_length_bg = 30;
|
|
3729
|
+
svg
|
|
3730
|
+
.selectAll('g.x1.axis1 g.tick text')
|
|
3731
|
+
.attr('class', 'lib-xaxis-labels-texts-drilldown')
|
|
3732
|
+
.attr('y', short_tick_length_bg)
|
|
3733
|
+
.text((d) => {
|
|
3734
|
+
const isValueToBeIgnored = data.some((indiv) => indiv.name.toLowerCase() === d.trim().toLowerCase() &&
|
|
3735
|
+
indiv[metaData.keyList[0]] === -1);
|
|
3736
|
+
if (isValueToBeIgnored)
|
|
3737
|
+
return '';
|
|
3738
|
+
if (d.trim().indexOf(' ') > -1) {
|
|
3739
|
+
return d.trim().substring(0, d.indexOf(' ')).toLowerCase();
|
|
3740
|
+
}
|
|
3741
|
+
return d.toLowerCase();
|
|
3742
|
+
});
|
|
3743
|
+
svg
|
|
3744
|
+
.selectAll('g.x1.axis1 g.tick')
|
|
3745
|
+
.append('text')
|
|
3746
|
+
.attr('class', 'lib-xaxis-labels-texts-drilldown')
|
|
3747
|
+
.attr('y', long_tick_length_bg)
|
|
3748
|
+
.attr('fill', 'currentColor')
|
|
3749
|
+
.text((d) => {
|
|
3750
|
+
if (d.trim().indexOf(' ') > -1) {
|
|
3751
|
+
return d.trim().substring(d.indexOf(' ')).toLowerCase();
|
|
3752
|
+
}
|
|
3753
|
+
return '';
|
|
3754
|
+
});
|
|
3755
|
+
}
|
|
3756
|
+
renderYAxis(svg, svgYAxisLeft, svgYAxisRight, y, dimensions) {
|
|
3757
|
+
svg
|
|
3758
|
+
.append('g')
|
|
3759
|
+
.attr('class', 'lib-stacked-y-axis-text yaxis-dashed')
|
|
3760
|
+
.attr('style', this.chartConfiguration.yAxisCustomTextStyles)
|
|
3761
|
+
.attr('transform', 'translate(0,0)')
|
|
3762
|
+
.call(y)
|
|
3763
|
+
.style('display', 'none');
|
|
3658
3764
|
svgYAxisLeft
|
|
3765
|
+
.append('g')
|
|
3659
3766
|
.append('g')
|
|
3660
3767
|
.attr('class', 'lib-yaxis-labels-texts-drilldown yaxis-dashed')
|
|
3661
3768
|
.attr('style', this.chartConfiguration.yAxisCustomTextStyles)
|
|
3769
|
+
.attr('transform', 'translate(0,0)')
|
|
3662
3770
|
.call(d3
|
|
3663
3771
|
.axisLeft(y)
|
|
3664
3772
|
.tickSize(0)
|
|
@@ -3666,32 +3774,16 @@ class GroupChartComponent extends ComponentUniqueId {
|
|
|
3666
3774
|
.tickFormat(this.chartConfiguration.yAxisLabelFomatter))
|
|
3667
3775
|
.selectAll('text')
|
|
3668
3776
|
.style('fill', 'var(--chart-text-color)');
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
.call(d3.axisBottom(scales.x).tickSize(-height).tickFormat(''))
|
|
3678
|
-
.style('stroke-dasharray', '5 5')
|
|
3679
|
-
.style('color', 'var(--chart-grid-color, #999999)')
|
|
3680
|
-
.call((g) => g.select('.domain').remove());
|
|
3681
|
-
}
|
|
3682
|
-
if (this.chartConfiguration.yAxisGrid) {
|
|
3683
|
-
svg
|
|
3684
|
-
.append('g')
|
|
3685
|
-
.call(d3
|
|
3686
|
-
.axisLeft(scales.y)
|
|
3687
|
-
.ticks(this.chartConfiguration.numberOfYTicks)
|
|
3688
|
-
.tickSize(-width))
|
|
3689
|
-
.style('color', 'var(--chart-axis-color, #B9B9B9)')
|
|
3690
|
-
.style('opacity', '0.5')
|
|
3691
|
-
.call((g) => g.select('.domain').remove());
|
|
3692
|
-
}
|
|
3777
|
+
svgYAxisRight
|
|
3778
|
+
.append('g')
|
|
3779
|
+
.attr('class', 'lib-yaxis-labels-texts-drilldown yaxis-dashed')
|
|
3780
|
+
.attr('style', this.chartConfiguration.yAxisCustomTextStyles)
|
|
3781
|
+
.attr('transform', 'translate(0,0)')
|
|
3782
|
+
.call(y)
|
|
3783
|
+
.style('display', 'none');
|
|
3784
|
+
this.applyAxisVisibilitySettings();
|
|
3693
3785
|
}
|
|
3694
|
-
|
|
3786
|
+
applyAxisVisibilitySettings() {
|
|
3695
3787
|
if (this.chartConfiguration.isXaxisLabelHidden) {
|
|
3696
3788
|
d3.selectAll('g.lib-line-x-axis-text > g > text').attr('class', 'lib-display-hidden');
|
|
3697
3789
|
}
|
|
@@ -3702,36 +3794,72 @@ class GroupChartComponent extends ComponentUniqueId {
|
|
|
3702
3794
|
d3.selectAll('.yaxis-dashed').attr('class', 'lib-display-hidden');
|
|
3703
3795
|
}
|
|
3704
3796
|
if (this.chartConfiguration.isYaxisDashed) {
|
|
3705
|
-
d3.selectAll('.yaxis-dashed')
|
|
3706
|
-
.style('stroke-dasharray', '5 5')
|
|
3707
|
-
.style('color', '#999999');
|
|
3797
|
+
d3.selectAll('.yaxis-dashed').style('stroke-dasharray', '5 5').style('color', '#999999');
|
|
3708
3798
|
}
|
|
3709
3799
|
}
|
|
3710
|
-
|
|
3800
|
+
renderYAxisGrid(svg, y, width) {
|
|
3801
|
+
svg
|
|
3802
|
+
.append('g')
|
|
3803
|
+
.call(d3.axisLeft(y).ticks(this.chartConfiguration.numberOfYTicks).tickSize(-width))
|
|
3804
|
+
.style('color', 'var(--chart-axis-color, #B9B9B9)')
|
|
3805
|
+
.style('opacity', '0.5')
|
|
3806
|
+
.call((g) => g.select('.domain').remove());
|
|
3807
|
+
}
|
|
3808
|
+
renderXAxisGrid(svg, x, height) {
|
|
3809
|
+
svg
|
|
3810
|
+
.append('g')
|
|
3811
|
+
.attr('class', 'grid')
|
|
3812
|
+
.attr('transform', `translate(${x.bandwidth() / 2},${height})`)
|
|
3813
|
+
.call(d3.axisBottom(x).tickSize(-height).tickFormat(''))
|
|
3814
|
+
.style('stroke-dasharray', '5 5')
|
|
3815
|
+
.style('color', 'var(--chart-grid-color, #999999)')
|
|
3816
|
+
.call((g) => g.select('.domain').remove());
|
|
3817
|
+
}
|
|
3818
|
+
renderLineYAxis(svgYAxisRight, lineYscale) {
|
|
3819
|
+
const yLineAxis = d3
|
|
3820
|
+
.axisRight(lineYscale)
|
|
3821
|
+
.ticks(this.chartConfiguration.numberOfYTicks)
|
|
3822
|
+
.tickSize(0)
|
|
3823
|
+
.tickFormat(this.chartConfiguration.yLineAxisLabelFomatter);
|
|
3824
|
+
svgYAxisRight
|
|
3825
|
+
.append('g')
|
|
3826
|
+
.attr('class', 'lib-stacked-y-axis-text1')
|
|
3827
|
+
.attr('style', this.chartConfiguration.yAxisCustomTextStyles)
|
|
3828
|
+
.attr('transform', 'translate(0,0)')
|
|
3829
|
+
.call(yLineAxis);
|
|
3830
|
+
}
|
|
3831
|
+
renderBars(svg, chartContext, scales, dimensions) {
|
|
3832
|
+
const { data, metaData, keyList, isRia } = chartContext;
|
|
3833
|
+
const { x, xSubgroup, y } = scales;
|
|
3834
|
+
const { height } = dimensions;
|
|
3711
3835
|
const state = svg
|
|
3712
3836
|
.append('g')
|
|
3713
3837
|
.selectAll('.state')
|
|
3714
3838
|
.data(data)
|
|
3715
3839
|
.enter()
|
|
3716
3840
|
.append('g')
|
|
3717
|
-
.attr('transform', (d) => `translate(${
|
|
3841
|
+
.attr('transform', (d) => `translate(${x(d.name)},0)`);
|
|
3718
3842
|
state
|
|
3719
3843
|
.selectAll('rect')
|
|
3720
|
-
.data((d) => this.prepareBarData(d,
|
|
3844
|
+
.data((d) => this.prepareBarData(d, keyList))
|
|
3721
3845
|
.enter()
|
|
3722
3846
|
.append('rect')
|
|
3723
3847
|
.attr('class', 'bars')
|
|
3724
3848
|
.on('click', (d) => this.handleBarClick(d, metaData))
|
|
3725
|
-
.attr('x', (d) => this.getBarX(d,
|
|
3726
|
-
.attr('y', (d) =>
|
|
3727
|
-
.attr('width', (d) => this.getBarWidth(d,
|
|
3728
|
-
.attr('height', (d) => this.getBarHeight(d,
|
|
3729
|
-
.style('cursor', metaData.hasDrillDown && !isRia ? 'pointer' : 'default')
|
|
3849
|
+
.attr('x', (d) => this.getBarX(d, data, x, xSubgroup))
|
|
3850
|
+
.attr('y', (d) => y(d.value))
|
|
3851
|
+
.attr('width', (d) => this.getBarWidth(d, data, x, xSubgroup))
|
|
3852
|
+
.attr('height', (d) => this.getBarHeight(d, y, height))
|
|
3853
|
+
.style('cursor', (d) => (metaData.hasDrillDown && !isRia ? 'pointer' : 'default'))
|
|
3730
3854
|
.attr('fill', (d) => this.getBarColor(d, metaData));
|
|
3731
|
-
if (!isRia && (this.chartConfiguration.displayTitleOnTop || !this.chartConfiguration.textsOnBar)) {
|
|
3732
|
-
state.selectAll('rect')
|
|
3733
|
-
|
|
3734
|
-
|
|
3855
|
+
if (!isRia && (this.chartConfiguration.displayTitleOnTop || (!this.chartConfiguration.textsOnBar && !this.chartConfiguration.displayTitleOnTop))) {
|
|
3856
|
+
state.selectAll('rect').on('mouseout', (d, i) => this.handleMouseOut(svg)).on('mouseover', (d, i) => this.handleMouseOver(svg, d, data, metaData, x, y, scales.leftAndRightSpaces));
|
|
3857
|
+
}
|
|
3858
|
+
if (this.chartConfiguration.textsOnBar && !this.isZoomedOut) {
|
|
3859
|
+
this.renderBarTexts(state, data, metaData, keyList, x, xSubgroup, y, isRia, svg);
|
|
3860
|
+
}
|
|
3861
|
+
if (this.chartConfiguration.isDrilldownChart) {
|
|
3862
|
+
svg.selectAll('g.x1.axis1 g.tick line').style('display', 'none');
|
|
3735
3863
|
}
|
|
3736
3864
|
}
|
|
3737
3865
|
prepareBarData(d, keyList) {
|
|
@@ -3740,138 +3868,212 @@ class GroupChartComponent extends ComponentUniqueId {
|
|
|
3740
3868
|
handleBarClick(d, metaData) {
|
|
3741
3869
|
if (d.key === 'Target')
|
|
3742
3870
|
return;
|
|
3743
|
-
|
|
3744
|
-
(metaData.barWithoutClick.includes(d?.name)
|
|
3745
|
-
if (!shouldBlock) {
|
|
3871
|
+
if (!metaData.barWithoutClick?.length ||
|
|
3872
|
+
(!metaData.barWithoutClick.includes(d?.name) && !metaData.barWithoutClick.includes(d?.key))) {
|
|
3746
3873
|
this.handleClick(d);
|
|
3747
3874
|
}
|
|
3748
3875
|
}
|
|
3749
|
-
getBarX(d,
|
|
3750
|
-
if (
|
|
3751
|
-
return
|
|
3876
|
+
getBarX(d, data, x, xSubgroup) {
|
|
3877
|
+
if (this.chartConfiguration.isDrilldownChart) {
|
|
3878
|
+
return this.calculateDrilldownBarX(d, data, x);
|
|
3752
3879
|
}
|
|
3753
|
-
|
|
3880
|
+
return xSubgroup(d.key);
|
|
3881
|
+
}
|
|
3882
|
+
calculateDrilldownBarX(d, data, x) {
|
|
3883
|
+
let tempScale;
|
|
3754
3884
|
data.forEach((indiv) => {
|
|
3755
3885
|
if (indiv.name === d.name) {
|
|
3756
|
-
const keys = Object.keys(indiv).filter((
|
|
3757
|
-
tempScale = d3.scaleBand().domain(keys).range([0,
|
|
3758
|
-
|
|
3886
|
+
const keys = Object.keys(indiv).filter((temp, i) => i !== 0);
|
|
3887
|
+
tempScale = d3.scaleBand().domain(keys).range([0, x.bandwidth()]);
|
|
3888
|
+
if (x.bandwidth() > 100) {
|
|
3889
|
+
tempScale = this.adjustDrilldownScale(tempScale, data, x);
|
|
3890
|
+
}
|
|
3759
3891
|
}
|
|
3760
3892
|
});
|
|
3761
|
-
return tempScale(d.key);
|
|
3893
|
+
return tempScale ? tempScale(d.key) : 0;
|
|
3762
3894
|
}
|
|
3763
|
-
|
|
3764
|
-
if (
|
|
3765
|
-
|
|
3895
|
+
adjustDrilldownScale(tempScale, data, x) {
|
|
3896
|
+
if (this.chartData.data.length === 1) {
|
|
3897
|
+
const keysLength = Object.keys(this.chartData.data[0]).length;
|
|
3898
|
+
const offset = keysLength === 2 ? 200 : 300;
|
|
3899
|
+
tempScale.range([
|
|
3900
|
+
0 + (x.bandwidth() - offset) / 2,
|
|
3901
|
+
x.bandwidth() - (x.bandwidth() - offset) / 2,
|
|
3902
|
+
]);
|
|
3903
|
+
}
|
|
3904
|
+
else {
|
|
3905
|
+
tempScale.range([
|
|
3906
|
+
0 + (x.bandwidth() - 125) / 2,
|
|
3907
|
+
x.bandwidth() - (x.bandwidth() - 125) / 2,
|
|
3908
|
+
]);
|
|
3766
3909
|
}
|
|
3767
|
-
let tempScale = scales.xSubgroup;
|
|
3768
|
-
data.forEach((indiv) => {
|
|
3769
|
-
if (indiv.name === d.name) {
|
|
3770
|
-
const keys = Object.keys(indiv).filter((_, i) => i !== 0);
|
|
3771
|
-
tempScale = d3.scaleBand().domain(keys).range([0, scales.x.bandwidth()]);
|
|
3772
|
-
tempScale = this.adjustScaleForWidth(tempScale, scales.x.bandwidth(), data.length);
|
|
3773
|
-
}
|
|
3774
|
-
});
|
|
3775
|
-
return tempScale.bandwidth();
|
|
3776
|
-
}
|
|
3777
|
-
adjustScaleForWidth(tempScale, bandwidth, dataLength) {
|
|
3778
|
-
if (bandwidth <= 100)
|
|
3779
|
-
return tempScale;
|
|
3780
|
-
const isSingleItem = dataLength === 1;
|
|
3781
|
-
const minWidth = isSingleItem
|
|
3782
|
-
? this.CONSTANTS.MIN_BAR_WIDTH_SINGLE
|
|
3783
|
-
: this.CONSTANTS.MIN_BAR_WIDTH_MULTIPLE;
|
|
3784
|
-
const offset = (bandwidth - minWidth) / 2;
|
|
3785
|
-
tempScale.range([offset, bandwidth - offset]);
|
|
3786
3910
|
return tempScale;
|
|
3787
3911
|
}
|
|
3788
|
-
|
|
3789
|
-
if (
|
|
3790
|
-
|
|
3912
|
+
getBarWidth(d, data, x, xSubgroup) {
|
|
3913
|
+
if (this.chartConfiguration.isDrilldownChart) {
|
|
3914
|
+
let tempScale;
|
|
3915
|
+
data.forEach((indiv) => {
|
|
3916
|
+
if (indiv.name === d.name) {
|
|
3917
|
+
const keys = Object.keys(indiv).filter((temp, i) => i !== 0);
|
|
3918
|
+
tempScale = d3.scaleBand().domain(keys).range([0, x.bandwidth()]);
|
|
3919
|
+
if (x.bandwidth() > 100) {
|
|
3920
|
+
tempScale = this.adjustDrilldownScale(tempScale, data, x);
|
|
3921
|
+
}
|
|
3922
|
+
}
|
|
3923
|
+
});
|
|
3924
|
+
return tempScale ? tempScale.bandwidth() : 0;
|
|
3791
3925
|
}
|
|
3792
|
-
return
|
|
3926
|
+
return xSubgroup.bandwidth();
|
|
3927
|
+
}
|
|
3928
|
+
getBarHeight(d, y, height) {
|
|
3929
|
+
if (d.value === -1)
|
|
3930
|
+
return height - y(0);
|
|
3931
|
+
if (d.value)
|
|
3932
|
+
return height - y(d.value);
|
|
3933
|
+
return height - y(0);
|
|
3793
3934
|
}
|
|
3794
3935
|
getBarColor(d, metaData) {
|
|
3795
|
-
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3936
|
+
if (d.value &&
|
|
3937
|
+
this.chartData.targetLineData &&
|
|
3938
|
+
d.value >= parseInt(this.chartData.targetLineData.target) &&
|
|
3939
|
+
this.chartData.metaData.colorAboveTarget) {
|
|
3940
|
+
return this.chartData.metaData.colorAboveTarget[d.key];
|
|
3799
3941
|
}
|
|
3800
|
-
return metaData.colors[d.key];
|
|
3942
|
+
return this.chartData.metaData.colors[d.key];
|
|
3943
|
+
}
|
|
3944
|
+
renderBarTexts(state, data, metaData, keyList, x, xSubgroup, y, isRia, svg) {
|
|
3945
|
+
state
|
|
3946
|
+
.selectAll('text')
|
|
3947
|
+
.data((d) => this.prepareBarData(d, keyList))
|
|
3948
|
+
.enter()
|
|
3949
|
+
.append('text')
|
|
3950
|
+
.attr('x', 0)
|
|
3951
|
+
.attr('y', 0)
|
|
3952
|
+
.attr('class', 'lib-data-labels-weeklycharts')
|
|
3953
|
+
.text((d) => this.getBarTextLabel(d))
|
|
3954
|
+
.style('fill', '#000')
|
|
3955
|
+
.style('font-weight', 'bold')
|
|
3956
|
+
.style('font-size', () => this.getBarTextFontSize())
|
|
3957
|
+
.attr('transform', (d) => this.getBarTextTransform(d, data, x, xSubgroup, y))
|
|
3958
|
+
.on('click', (d) => this.handleBarClick(d, metaData));
|
|
3959
|
+
if (!isRia) {
|
|
3960
|
+
state
|
|
3961
|
+
.selectAll('.lib-data-labels-weeklycharts')
|
|
3962
|
+
.on('mouseout', (d, i) => this.handleMouseOut(svg))
|
|
3963
|
+
.on('mouseover', (d, i) => this.handleMouseOver(svg, d, data, metaData, x, y, x.bandwidth()));
|
|
3964
|
+
}
|
|
3965
|
+
}
|
|
3966
|
+
getBarTextLabel(d) {
|
|
3967
|
+
if (!d.key || !d.value)
|
|
3968
|
+
return '';
|
|
3969
|
+
return d.key.length > 20 ? d.key.substring(0, 17) + '...' : d.key;
|
|
3970
|
+
}
|
|
3971
|
+
getBarTextFontSize() {
|
|
3972
|
+
if (this.chartConfiguration.isDrilldownChart) {
|
|
3973
|
+
if (window.innerWidth > 1900)
|
|
3974
|
+
return '18px';
|
|
3975
|
+
if (window.innerWidth < 1400)
|
|
3976
|
+
return '10px';
|
|
3977
|
+
return '14px';
|
|
3978
|
+
}
|
|
3979
|
+
return '14px';
|
|
3980
|
+
}
|
|
3981
|
+
getBarTextTransform(d, data, x, xSubgroup, y) {
|
|
3982
|
+
let tempScale;
|
|
3983
|
+
data.forEach((indiv) => {
|
|
3984
|
+
if (indiv.name === d.name) {
|
|
3985
|
+
const keys = Object.keys(indiv).filter((temp, i) => i !== 0);
|
|
3986
|
+
tempScale = d3.scaleBand().domain(keys).range([0, x.bandwidth()]);
|
|
3987
|
+
if (x.bandwidth() > 100) {
|
|
3988
|
+
tempScale = this.adjustDrilldownScale(tempScale, data, x);
|
|
3989
|
+
}
|
|
3990
|
+
}
|
|
3991
|
+
});
|
|
3992
|
+
if (this.chartConfiguration.textAlwaysHorizontal) {
|
|
3993
|
+
return `translate(${xSubgroup(d.key)},${y(d.value) - 3})`;
|
|
3994
|
+
}
|
|
3995
|
+
if (tempScale && !isNaN(tempScale(d.key))) {
|
|
3996
|
+
return `translate(${tempScale(d.key) + tempScale.bandwidth() * 0.55},${y(0) - 10}) rotate(270)`;
|
|
3997
|
+
}
|
|
3998
|
+
return 'translate(0,0)';
|
|
3801
3999
|
}
|
|
3802
|
-
handleMouseOver(
|
|
4000
|
+
handleMouseOver(svg, d, data, metaData, x, y, leftAndRightSpaces) {
|
|
3803
4001
|
svg.selectAll('.lib-verticalstack-title-ontop').remove();
|
|
4002
|
+
let tempScale;
|
|
4003
|
+
data.forEach((indiv) => {
|
|
4004
|
+
if (indiv.name === d.name) {
|
|
4005
|
+
const keys = Object.keys(indiv).filter((temp, i) => i !== 0);
|
|
4006
|
+
tempScale = d3.scaleBand().domain(keys).range([0, x.bandwidth()]);
|
|
4007
|
+
if (x.bandwidth() > 100) {
|
|
4008
|
+
tempScale = this.adjustDrilldownScale(tempScale, data, x);
|
|
4009
|
+
}
|
|
4010
|
+
}
|
|
4011
|
+
});
|
|
3804
4012
|
const foreignObject = svg
|
|
3805
4013
|
.append('foreignObject')
|
|
4014
|
+
.attr('x', () => this.calculateTooltipX(d, x, tempScale, metaData, leftAndRightSpaces))
|
|
4015
|
+
.attr('y', () => y(d.value) - 43)
|
|
3806
4016
|
.attr('class', 'lib-verticalstack-title-ontop')
|
|
3807
|
-
.attr('
|
|
3808
|
-
.attr('y', scales.y(d.value) - 43)
|
|
3809
|
-
.attr('width', this.getTooltipWidth(d, scales, data, metaData))
|
|
4017
|
+
.attr('width', () => this.calculateTooltipWidth(tempScale, metaData, leftAndRightSpaces))
|
|
3810
4018
|
.attr('height', 40);
|
|
3811
4019
|
foreignObject
|
|
3812
4020
|
.append('xhtml:div')
|
|
3813
4021
|
.attr('class', 'title')
|
|
3814
4022
|
.style('z-index', 99)
|
|
3815
|
-
.html(this.
|
|
3816
|
-
}
|
|
3817
|
-
getTooltipX(d, scales, data, metaData) {
|
|
3818
|
-
let tempScale = this.getTempScale(d, scales, data);
|
|
3819
|
-
const baseX = scales.x(d.name) + tempScale(d.key);
|
|
3820
|
-
if (!metaData.hasDrillDown) {
|
|
3821
|
-
return baseX - (tempScale.bandwidth() + this.CONSTANTS.LEFT_RIGHT_SPACES * 2) / 2 + tempScale.bandwidth() / 2;
|
|
3822
|
-
}
|
|
3823
|
-
if (tempScale.bandwidth() + this.CONSTANTS.LEFT_RIGHT_SPACES * 2 > 180) {
|
|
3824
|
-
return baseX + tempScale.bandwidth() / 2 - 90;
|
|
3825
|
-
}
|
|
3826
|
-
return baseX - (tempScale.bandwidth() + this.CONSTANTS.LEFT_RIGHT_SPACES * 2) / 2 + tempScale.bandwidth() / 2;
|
|
4023
|
+
.html(() => this.getTooltipHTML(d, metaData));
|
|
3827
4024
|
}
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
4025
|
+
calculateTooltipX(d, x, tempScale, metaData, leftAndRightSpaces) {
|
|
4026
|
+
if (metaData.hasDrillDown) {
|
|
4027
|
+
if (tempScale.bandwidth() + leftAndRightSpaces * 2 > 180) {
|
|
4028
|
+
return x(d.name) + tempScale(d.key) + tempScale.bandwidth() / 2 - 90;
|
|
4029
|
+
}
|
|
4030
|
+
return (x(d.name) +
|
|
4031
|
+
tempScale(d.key) -
|
|
4032
|
+
(tempScale.bandwidth() + leftAndRightSpaces * 2) / 2 +
|
|
4033
|
+
tempScale.bandwidth() / 2);
|
|
3835
4034
|
}
|
|
3836
|
-
return (
|
|
4035
|
+
return (x(d.name) +
|
|
4036
|
+
tempScale(d.key) -
|
|
4037
|
+
(tempScale.bandwidth() + leftAndRightSpaces * 2) / 2 +
|
|
4038
|
+
tempScale.bandwidth() / 2);
|
|
3837
4039
|
}
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
const keys = Object.keys(indiv).filter((_, i) => i !== 0);
|
|
3843
|
-
tempScale = d3.scaleBand().domain(keys).range([0, scales.x.bandwidth()]);
|
|
3844
|
-
tempScale = this.adjustScaleForWidth(tempScale, scales.x.bandwidth(), data.length);
|
|
4040
|
+
calculateTooltipWidth(tempScale, metaData, leftAndRightSpaces) {
|
|
4041
|
+
if (metaData.hasDrillDown) {
|
|
4042
|
+
if (tempScale.bandwidth() + leftAndRightSpaces * 2 > 180) {
|
|
4043
|
+
return '180px';
|
|
3845
4044
|
}
|
|
3846
|
-
|
|
3847
|
-
|
|
4045
|
+
return tempScale.bandwidth() + leftAndRightSpaces * 2;
|
|
4046
|
+
}
|
|
4047
|
+
return tempScale.bandwidth() + leftAndRightSpaces * 2;
|
|
3848
4048
|
}
|
|
3849
|
-
|
|
4049
|
+
getTooltipHTML(d, metaData) {
|
|
3850
4050
|
const dataType = metaData.dataType || '';
|
|
3851
4051
|
if (!this.isZoomedOut) {
|
|
3852
|
-
return `<span class="title-bar-name">${d.name}</span
|
|
3853
|
-
|
|
4052
|
+
return `<span class="title-bar-name">${d.name}</span><span class="title-bar-value"><span>${d.value}</span>${dataType}</span>`;
|
|
4053
|
+
}
|
|
4054
|
+
else {
|
|
4055
|
+
const tempKey = d.name.length <= 8 ? d.name : d.name.substring(0, 5) + '...';
|
|
4056
|
+
return `<span class="title-bar-name">${tempKey}:${d.value}${dataType}</span><span class="title-bar-value">${d.name}</span>`;
|
|
3854
4057
|
}
|
|
3855
|
-
const truncatedName = d.name.length <= 8 ? d.name : d.name.substring(0, 5) + '...';
|
|
3856
|
-
return `<span class="title-bar-name">${truncatedName}:${d.value}${dataType}</span>
|
|
3857
|
-
<span class="title-bar-value">${d.name}</span>`;
|
|
3858
4058
|
}
|
|
3859
4059
|
handleMouseOut(svg) {
|
|
3860
4060
|
svg.selectAll('.lib-verticalstack-title-ontop').remove();
|
|
3861
4061
|
}
|
|
3862
|
-
renderLabels(
|
|
4062
|
+
renderLabels(svgElements, scales, chartContext, dimensions) {
|
|
4063
|
+
const { svg, svgYAxisLeft, svgYAxisRight } = svgElements;
|
|
4064
|
+
const { metaData } = chartContext;
|
|
4065
|
+
const { width, height, margin } = dimensions;
|
|
3863
4066
|
if (metaData.yLabel) {
|
|
3864
|
-
this.
|
|
4067
|
+
this.renderYAxisLabel(svgYAxisLeft, metaData.yLabel, height, margin);
|
|
3865
4068
|
}
|
|
3866
4069
|
if (metaData.xLabel) {
|
|
3867
|
-
this.
|
|
4070
|
+
this.renderXAxisLabel(svg, metaData.xLabel, width, height, margin);
|
|
3868
4071
|
}
|
|
3869
4072
|
if (metaData.lineyLabel) {
|
|
3870
|
-
this.
|
|
4073
|
+
this.renderLineYAxisLabel(svgYAxisRight, metaData.lineyLabel);
|
|
3871
4074
|
}
|
|
3872
4075
|
}
|
|
3873
|
-
|
|
3874
|
-
const margin = this.chartConfiguration.margin;
|
|
4076
|
+
renderYAxisLabel(svgYAxisLeft, yLabel, height, margin) {
|
|
3875
4077
|
svgYAxisLeft
|
|
3876
4078
|
.append('text')
|
|
3877
4079
|
.attr('class', 'lib-axis-group-label font-size-1')
|
|
@@ -3881,33 +4083,44 @@ class GroupChartComponent extends ComponentUniqueId {
|
|
|
3881
4083
|
.attr('x', 0 - height / 2)
|
|
3882
4084
|
.attr('dy', '1em')
|
|
3883
4085
|
.style('text-anchor', 'middle')
|
|
3884
|
-
.attr('fill', 'var(--chart-text-color)')
|
|
3885
|
-
|
|
4086
|
+
.attr('fill', 'var(--chart-text-color)');
|
|
4087
|
+
if (this.chartConfiguration.isMultiChartGridLine === undefined) {
|
|
4088
|
+
svgYAxisLeft.selectAll('.lib-axis-group-label').style('font-size', 'smaller').text(yLabel);
|
|
4089
|
+
}
|
|
4090
|
+
else {
|
|
4091
|
+
svgYAxisLeft
|
|
4092
|
+
.selectAll('.lib-axis-group-label')
|
|
4093
|
+
.attr('class', 'lib-ylabel-weeklyCharts')
|
|
4094
|
+
.text(yLabel.toLowerCase());
|
|
4095
|
+
}
|
|
3886
4096
|
}
|
|
3887
|
-
|
|
3888
|
-
const margin = this.chartConfiguration.margin;
|
|
4097
|
+
renderXAxisLabel(svg, xLabel, width, height, margin) {
|
|
3889
4098
|
const isAcronym = this.isAcronym(xLabel.replace(/[^A-Za-z]/g, ''));
|
|
3890
|
-
let
|
|
4099
|
+
let baseClass = 'lib-axis-group-label font-size-1';
|
|
3891
4100
|
if (this.chartConfiguration.isDrilldownChart) {
|
|
3892
|
-
|
|
4101
|
+
baseClass += ' lib-xlabel-drilldowncharts';
|
|
3893
4102
|
}
|
|
3894
|
-
else if (this.chartConfiguration.isMultiChartGridLine) {
|
|
3895
|
-
|
|
4103
|
+
else if (this.chartConfiguration.isMultiChartGridLine !== undefined) {
|
|
4104
|
+
baseClass += ' lib-xlabel-weeklyCharts';
|
|
3896
4105
|
}
|
|
3897
4106
|
else {
|
|
3898
|
-
|
|
4107
|
+
baseClass += ' lib-axis-waterfall-label';
|
|
3899
4108
|
}
|
|
3900
4109
|
svg
|
|
3901
4110
|
.append('text')
|
|
3902
|
-
.attr('class',
|
|
4111
|
+
.attr('class', baseClass)
|
|
3903
4112
|
.attr('style', this.chartConfiguration.xAxisCustomlabelStyles)
|
|
3904
|
-
.attr('transform', `translate(${width / 2}
|
|
4113
|
+
.attr('transform', `translate(${width / 2},${height + margin.top + 20})`)
|
|
3905
4114
|
.style('text-anchor', 'middle')
|
|
3906
4115
|
.style('fill', 'var(--chart-text-color)')
|
|
3907
4116
|
.text(isAcronym ? xLabel.toUpperCase() : xLabel.toLowerCase())
|
|
3908
4117
|
.style('text-transform', isAcronym ? 'none' : 'capitalize');
|
|
3909
4118
|
}
|
|
3910
|
-
|
|
4119
|
+
isAcronym(label) {
|
|
4120
|
+
return ((label.length <= 4 && /^[A-Z]+$/.test(label)) ||
|
|
4121
|
+
(label === label.toUpperCase() && /[A-Z]/.test(label)));
|
|
4122
|
+
}
|
|
4123
|
+
renderLineYAxisLabel(svgYAxisRight, lineyLabel) {
|
|
3911
4124
|
svgYAxisRight
|
|
3912
4125
|
.append('text')
|
|
3913
4126
|
.attr('class', 'lib-axis-group-label lib-line-axis')
|
|
@@ -3920,15 +4133,15 @@ class GroupChartComponent extends ComponentUniqueId {
|
|
|
3920
4133
|
.style('font-size', 'smaller')
|
|
3921
4134
|
.text(lineyLabel);
|
|
3922
4135
|
}
|
|
3923
|
-
|
|
3924
|
-
return ((label.length <= 4 && /^[A-Z]+$/.test(label)) ||
|
|
3925
|
-
(label === label.toUpperCase() && /[A-Z]/.test(label)));
|
|
3926
|
-
}
|
|
3927
|
-
renderTargetLine(svg, svgYAxisRight, yScale, width) {
|
|
4136
|
+
renderTargetLine(svgElements, scales, chartContext, dimensions) {
|
|
3928
4137
|
if (!this.chartData.targetLineData)
|
|
3929
4138
|
return;
|
|
3930
|
-
const
|
|
3931
|
-
const
|
|
4139
|
+
const { svg, svgYAxisRight } = svgElements;
|
|
4140
|
+
const { y } = scales;
|
|
4141
|
+
const { width } = dimensions;
|
|
4142
|
+
const { metaData } = chartContext;
|
|
4143
|
+
const targetData = this.chartData.targetLineData;
|
|
4144
|
+
const yZero = y(targetData.target);
|
|
3932
4145
|
svg
|
|
3933
4146
|
.append('line')
|
|
3934
4147
|
.attr('x1', 0)
|
|
@@ -3936,45 +4149,49 @@ class GroupChartComponent extends ComponentUniqueId {
|
|
|
3936
4149
|
.attr('y1', yZero)
|
|
3937
4150
|
.attr('y2', yZero)
|
|
3938
4151
|
.style('stroke-dasharray', '5 5')
|
|
3939
|
-
.style('stroke',
|
|
3940
|
-
const
|
|
3941
|
-
const targetName = targetLineData.targetName || 'target';
|
|
4152
|
+
.style('stroke', targetData.color);
|
|
4153
|
+
const rightSvgWidth = 60;
|
|
3942
4154
|
svgYAxisRight
|
|
3943
4155
|
.append('foreignObject')
|
|
3944
|
-
.attr('transform', `translate(0
|
|
3945
|
-
.attr('width',
|
|
4156
|
+
.attr('transform', `translate(0,${yZero - 30})`)
|
|
4157
|
+
.attr('width', rightSvgWidth)
|
|
3946
4158
|
.attr('height', 50)
|
|
3947
4159
|
.append('xhtml:div')
|
|
3948
4160
|
.attr('class', 'target-display')
|
|
3949
4161
|
.style('color', 'var(--chart-text-color)')
|
|
3950
|
-
.html(
|
|
4162
|
+
.html(() => {
|
|
4163
|
+
const dataType = metaData.dataType || '';
|
|
4164
|
+
const targetName = targetData.targetName || 'target';
|
|
4165
|
+
return `<div>${targetName}</div><div>${targetData.target}${dataType}</div>`;
|
|
4166
|
+
});
|
|
3951
4167
|
}
|
|
3952
|
-
renderLineGraph(svg,
|
|
4168
|
+
renderLineGraph(svg, chartContext, scales) {
|
|
4169
|
+
const { lineData, metaData } = chartContext;
|
|
3953
4170
|
if (!lineData)
|
|
3954
4171
|
return;
|
|
3955
|
-
const
|
|
3956
|
-
.line()
|
|
3957
|
-
.x((d) => scales.x(d.name) + scales.x.bandwidth() / 2)
|
|
3958
|
-
.y((d) => scales.lineYscale(d.value));
|
|
4172
|
+
const { x, lineYscale } = scales;
|
|
3959
4173
|
svg
|
|
3960
4174
|
.append('path')
|
|
3961
4175
|
.datum(lineData)
|
|
3962
4176
|
.attr('fill', 'none')
|
|
3963
4177
|
.attr('stroke', this.chartConfiguration.lineGraphColor)
|
|
3964
4178
|
.attr('stroke-width', 1.5)
|
|
3965
|
-
.attr('d',
|
|
4179
|
+
.attr('d', d3
|
|
4180
|
+
.line()
|
|
4181
|
+
.x((d) => x(d.name) + x.bandwidth() / 2)
|
|
4182
|
+
.y((d) => lineYscale(d.value)));
|
|
3966
4183
|
const dot = svg
|
|
3967
4184
|
.selectAll('myCircles')
|
|
3968
4185
|
.data(lineData)
|
|
3969
4186
|
.enter()
|
|
3970
4187
|
.append('g')
|
|
3971
|
-
.on('click', (d) => this.
|
|
4188
|
+
.on('click', (d) => this.handleBarClick(d, metaData));
|
|
3972
4189
|
dot
|
|
3973
4190
|
.append('circle')
|
|
3974
4191
|
.attr('fill', this.chartConfiguration.lineGraphColor)
|
|
3975
4192
|
.attr('stroke', 'none')
|
|
3976
|
-
.attr('cx', (d) =>
|
|
3977
|
-
.attr('cy', (d) =>
|
|
4193
|
+
.attr('cx', (d) => x(d.name) + x.bandwidth() / 2)
|
|
4194
|
+
.attr('cy', (d) => lineYscale(d.value))
|
|
3978
4195
|
.style('cursor', 'pointer')
|
|
3979
4196
|
.attr('r', 3);
|
|
3980
4197
|
if (this.chartConfiguration.lineGraphColor) {
|
|
@@ -3983,19 +4200,12 @@ class GroupChartComponent extends ComponentUniqueId {
|
|
|
3983
4200
|
.attr('class', 'dot')
|
|
3984
4201
|
.attr('color', this.chartConfiguration.lineGraphColor)
|
|
3985
4202
|
.attr('style', 'font-size: .85em')
|
|
3986
|
-
.attr('x', (d) =>
|
|
3987
|
-
.attr('y', (d) =>
|
|
4203
|
+
.attr('x', (d) => x(d.name) + x.bandwidth() / 2)
|
|
4204
|
+
.attr('y', (d) => lineYscale(d.value))
|
|
3988
4205
|
.attr('dy', '-1em')
|
|
3989
4206
|
.text((d) => this.chartConfiguration.labelFormatter(d.value));
|
|
3990
4207
|
}
|
|
3991
4208
|
}
|
|
3992
|
-
handleLinePointClick(d, metaData) {
|
|
3993
|
-
const shouldBlock = metaData.barWithoutClick?.length &&
|
|
3994
|
-
(metaData.barWithoutClick.includes(d?.name) || metaData.barWithoutClick.includes(d?.key));
|
|
3995
|
-
if (!shouldBlock) {
|
|
3996
|
-
this.handleClick(d);
|
|
3997
|
-
}
|
|
3998
|
-
}
|
|
3999
4209
|
handleClick(d) {
|
|
4000
4210
|
if (this.chartData.metaData.hasDrillDown || d?.toggleFrom) {
|
|
4001
4211
|
this.clickEvent.emit(d);
|