axidio-styleguide-library1-v2 0.2.26 → 0.2.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/lib/horizontal-grouped-bar-with-scroll-zoom/horizontal-grouped-bar-with-scroll-zoom.component.mjs +1944 -888
- package/fesm2022/axidio-styleguide-library1-v2.mjs +1947 -891
- package/fesm2022/axidio-styleguide-library1-v2.mjs.map +1 -1
- package/lib/horizontal-grouped-bar-with-scroll-zoom/horizontal-grouped-bar-with-scroll-zoom.component.d.ts +34 -8
- package/package.json +1 -1
|
@@ -8187,734 +8187,1955 @@ class HorizontalGroupedBarWithScrollZoomComponent extends ComponentUniqueId {
|
|
|
8187
8187
|
get isAlertEnabled() {
|
|
8188
8188
|
return this.chartConfiguration?.headerMenuOptions?.some((option) => option.id === 'editAlert');
|
|
8189
8189
|
}
|
|
8190
|
+
// initializegroupChart() {
|
|
8191
|
+
// var self = this;
|
|
8192
|
+
// let data = [];
|
|
8193
|
+
// let metaData: any = null;
|
|
8194
|
+
// let keyList = null;
|
|
8195
|
+
// let lineData = null;
|
|
8196
|
+
// let colorMap = {};
|
|
8197
|
+
// var formatFromBackend;
|
|
8198
|
+
// var formatForHugeNumbers;
|
|
8199
|
+
// const isMobile = window.innerWidth < 576;
|
|
8200
|
+
// const isTablet = window.innerWidth >= 576 && window.innerWidth < 992;
|
|
8201
|
+
// const isDesktop = window.innerWidth >= 992;
|
|
8202
|
+
// let isria = this.customChartConfiguration.isRia
|
|
8203
|
+
// var x: any;
|
|
8204
|
+
// var alternate_text = false;
|
|
8205
|
+
// var short_tick_length = 4;
|
|
8206
|
+
// var long_tick_length = 16;
|
|
8207
|
+
// /**
|
|
8208
|
+
// * longer tick length needed for weekly charts
|
|
8209
|
+
// */
|
|
8210
|
+
// var short_tick_length_bg = 5;
|
|
8211
|
+
// var long_tick_length_bg = 30;
|
|
8212
|
+
// var leftAndRightSpaces = 50;
|
|
8213
|
+
// var rightSvgWidth = 60;
|
|
8214
|
+
// var tempScale;
|
|
8215
|
+
// for (var i in this.defaultConfiguration) {
|
|
8216
|
+
// this.chartConfiguration[i] = ChartHelper.getValueByConfigurationType(
|
|
8217
|
+
// i,
|
|
8218
|
+
// this.defaultConfiguration,
|
|
8219
|
+
// this.customChartConfiguration
|
|
8220
|
+
// );
|
|
8221
|
+
// }
|
|
8222
|
+
// data = this.chartData.data;
|
|
8223
|
+
// metaData = this.chartData.metaData;
|
|
8224
|
+
// lineData = this.chartData.lineData;
|
|
8225
|
+
// // if (lineData || this.chartData.targetLineData) {
|
|
8226
|
+
// // rightSvgWidth = 60;
|
|
8227
|
+
// // }
|
|
8228
|
+
// if (!metaData.colorAboveTarget) {
|
|
8229
|
+
// metaData['colorAboveTarget'] = metaData.colors;
|
|
8230
|
+
// }
|
|
8231
|
+
// colorMap = metaData.colors;
|
|
8232
|
+
// keyList = metaData.keyList;
|
|
8233
|
+
// var chartContainer = d3.select(this.containerElt.nativeElement);
|
|
8234
|
+
// var verticalstackedcontainer = d3.select(
|
|
8235
|
+
// this.groupcontainerElt.nativeElement
|
|
8236
|
+
// );
|
|
8237
|
+
// var margin = this.chartConfiguration.margin;
|
|
8238
|
+
// const { width, height } = this.calculateChartDimensions(
|
|
8239
|
+
// chartContainer,
|
|
8240
|
+
// verticalstackedcontainer,
|
|
8241
|
+
// margin,
|
|
8242
|
+
// self
|
|
8243
|
+
// );
|
|
8244
|
+
// /**
|
|
8245
|
+
// * for hiding header
|
|
8246
|
+
// * used by weekly charts
|
|
8247
|
+
// */
|
|
8248
|
+
// if (this.chartConfiguration.isHeaderVisible != undefined)
|
|
8249
|
+
// this.isHeaderVisible = this.chartConfiguration.isHeaderVisible;
|
|
8250
|
+
// /**
|
|
8251
|
+
// * for hiding legends
|
|
8252
|
+
// * used by weekly charts
|
|
8253
|
+
// */
|
|
8254
|
+
// if (this.chartConfiguration.legendVisible != undefined) {
|
|
8255
|
+
// this.legendVisible = this.chartConfiguration.legendVisible;
|
|
8256
|
+
// }
|
|
8257
|
+
// /**
|
|
8258
|
+
// * for removing background color so that it can take parents color
|
|
8259
|
+
// *
|
|
8260
|
+
// */
|
|
8261
|
+
// if (this.chartConfiguration.isTransparentBackground != undefined) {
|
|
8262
|
+
// this.isTransparentBackground =
|
|
8263
|
+
// this.chartConfiguration.isTransparentBackground;
|
|
8264
|
+
// }
|
|
8265
|
+
// /**
|
|
8266
|
+
// * format data values based on configuration received
|
|
8267
|
+
// */
|
|
8268
|
+
// if (this.chartConfiguration.textFormatter != undefined) {
|
|
8269
|
+
// formatFromBackend = ChartHelper.dataValueFormatter(
|
|
8270
|
+
// this.chartConfiguration.textFormatter
|
|
8271
|
+
// );
|
|
8272
|
+
// formatForHugeNumbers = ChartHelper.dataValueFormatter('.2s');
|
|
8273
|
+
// }
|
|
8274
|
+
// const {
|
|
8275
|
+
// outerContainer,
|
|
8276
|
+
// svgYAxisLeft,
|
|
8277
|
+
// svgYAxisRight,
|
|
8278
|
+
// innerContainer,
|
|
8279
|
+
// svg
|
|
8280
|
+
// } = this.createChartContainers(chartContainer, margin, height, rightSvgWidth, self, width);
|
|
8281
|
+
// var subgroups: any = keyList;
|
|
8282
|
+
// var groups = d3
|
|
8283
|
+
// .map(data, function (d) {
|
|
8284
|
+
// return d.name;
|
|
8285
|
+
// })
|
|
8286
|
+
// .keys();
|
|
8287
|
+
// /**
|
|
8288
|
+
// * x axis range made similar to line chart or vertical stack so that all the charts will get aligned with each other.
|
|
8289
|
+
// */
|
|
8290
|
+
// if (this.chartConfiguration.isMultiChartGridLine != undefined) {
|
|
8291
|
+
// x = d3
|
|
8292
|
+
// .scaleBand()
|
|
8293
|
+
// .rangeRound([width, 0])
|
|
8294
|
+
// .align(0.5)
|
|
8295
|
+
// .padding([0.5])
|
|
8296
|
+
// .domain(
|
|
8297
|
+
// data.map(function (d: any) {
|
|
8298
|
+
// return d.name.toLowerCase();
|
|
8299
|
+
// })
|
|
8300
|
+
// );
|
|
8301
|
+
// } else {
|
|
8302
|
+
// x = d3
|
|
8303
|
+
// .scaleBand()
|
|
8304
|
+
// .domain(groups)
|
|
8305
|
+
// .range([leftAndRightSpaces, width - rightSvgWidth - leftAndRightSpaces])
|
|
8306
|
+
// .padding([0.3]);
|
|
8307
|
+
// }
|
|
8308
|
+
// // x.bandwidth(96);
|
|
8309
|
+
// var xScaleFromOrigin = d3
|
|
8310
|
+
// .scaleBand()
|
|
8311
|
+
// .domain(groups)
|
|
8312
|
+
// .range([0, width - rightSvgWidth]);
|
|
8313
|
+
// // .padding([0.2]);
|
|
8314
|
+
// if (this.chartConfiguration.isMultiChartGridLine == undefined) {
|
|
8315
|
+
// /**
|
|
8316
|
+
// * normal ticks for all dashboard charts
|
|
8317
|
+
// */
|
|
8318
|
+
// svg
|
|
8319
|
+
// .append('g')
|
|
8320
|
+
// .attr('class', 'x1 axis1')
|
|
8321
|
+
// .attr('transform', 'translate(0,' + height + ')')
|
|
8322
|
+
// .call(d3.axisBottom(x))
|
|
8323
|
+
// .call((g) => g.select('.domain').remove());
|
|
8324
|
+
// svg.selectAll('g.x1.axis1 g.tick line').remove();
|
|
8325
|
+
// // Only move x-axis labels further down for grouped charts if there is no xLabel
|
|
8326
|
+
// if (subgroups.length > 1 && !metaData.xLabel) {
|
|
8327
|
+
// svg
|
|
8328
|
+
// .selectAll('g.x1.axis1 g.tick text')
|
|
8329
|
+
// .attr('class', 'lib-xaxis-labels-texts-drilldown')
|
|
8330
|
+
// .style('fill', 'var(--chart-text-color)')
|
|
8331
|
+
// .attr('y', 32); // Increase distance from bars (default is ~9)
|
|
8332
|
+
// } else {
|
|
8333
|
+
// svg
|
|
8334
|
+
// .selectAll('g.x1.axis1 g.tick text')
|
|
8335
|
+
// .attr('class', 'lib-xaxis-labels-texts-drilldown')
|
|
8336
|
+
// .style('fill', 'var(--chart-text-color)');
|
|
8337
|
+
// }
|
|
8338
|
+
// }
|
|
8339
|
+
// else {
|
|
8340
|
+
// /**
|
|
8341
|
+
// * bigger ticks for weekly charts and more space from x axis to labels
|
|
8342
|
+
// */
|
|
8343
|
+
// /**
|
|
8344
|
+
// * draw x axis
|
|
8345
|
+
// */
|
|
8346
|
+
// svg
|
|
8347
|
+
// .append('g')
|
|
8348
|
+
// .attr('class', 'x1 axis1')
|
|
8349
|
+
// .attr('transform', 'translate(0,' + height + ')')
|
|
8350
|
+
// .call(d3.axisBottom(x).tickSize(0))
|
|
8351
|
+
// .call((g) => g.select('.domain').attr('fill', 'none'));
|
|
8352
|
+
// /**
|
|
8353
|
+
// * tick line size in alternate fashion
|
|
8354
|
+
// */
|
|
8355
|
+
// svg.selectAll('g.x1.axis1 g.tick line').attr('y2', function () {
|
|
8356
|
+
// if (
|
|
8357
|
+
// alternate_text &&
|
|
8358
|
+
// self.chartConfiguration.isNoAlternateXaxisText == undefined
|
|
8359
|
+
// ) {
|
|
8360
|
+
// alternate_text = false;
|
|
8361
|
+
// return long_tick_length_bg - 7;
|
|
8362
|
+
// } else {
|
|
8363
|
+
// alternate_text = true;
|
|
8364
|
+
// return short_tick_length_bg - 4;
|
|
8365
|
+
// }
|
|
8366
|
+
// });
|
|
8367
|
+
// /**
|
|
8368
|
+
// * reset the flag so that values can be shown in same alternate fashion
|
|
8369
|
+
// */
|
|
8370
|
+
// alternate_text = false;
|
|
8371
|
+
// /**
|
|
8372
|
+
// * print x-axis label texts
|
|
8373
|
+
// * used by weekly charts
|
|
8374
|
+
// */
|
|
8375
|
+
// svg
|
|
8376
|
+
// .selectAll('g.x1.axis1 g.tick text')
|
|
8377
|
+
// .attr('class', 'lib-xaxis-labels-texts-weeklycharts')
|
|
8378
|
+
// .attr('y', function () {
|
|
8379
|
+
// // Minimize gap in maximized (fullscreen) view for weekly charts
|
|
8380
|
+
// if (self.chartConfiguration.isFullScreen) {
|
|
8381
|
+
// return short_tick_length_bg;
|
|
8382
|
+
// }
|
|
8383
|
+
// if (alternate_text) {
|
|
8384
|
+
// alternate_text = false;
|
|
8385
|
+
// return long_tick_length_bg;
|
|
8386
|
+
// } else {
|
|
8387
|
+
// alternate_text = true;
|
|
8388
|
+
// return short_tick_length_bg;
|
|
8389
|
+
// }
|
|
8390
|
+
// });
|
|
8391
|
+
// }
|
|
8392
|
+
// if (self.chartConfiguration.xLabelsOnSameLine) {
|
|
8393
|
+
// const xAxisLabels = svg
|
|
8394
|
+
// .selectAll('g.x1.axis1 g.tick text')
|
|
8395
|
+
// .attr('class', 'lib-xaxis-labels-texts-drilldown')
|
|
8396
|
+
// .style('font-size', this.isHeaderVisible ? '18px' : '14px')
|
|
8397
|
+
// .attr('text-anchor', 'middle')
|
|
8398
|
+
// .attr('y', function(d) {
|
|
8399
|
+
// // For grouped bar charts with many bars and xLabel present, only add 5 if the label is a date
|
|
8400
|
+
// if (subgroups.length > 1 && data.length > 8 && metaData.xLabel) {
|
|
8401
|
+
// const isDateLabel = /\d{2,4}[-\/]/.test(d);
|
|
8402
|
+
// if (self.chartConfiguration.isFullScreen) {
|
|
8403
|
+
// return isDateLabel ? short_tick_length_bg + 14 : short_tick_length_bg;
|
|
8404
|
+
// }
|
|
8405
|
+
// return isDateLabel ? short_tick_length_bg + 14 : short_tick_length_bg;
|
|
8406
|
+
// }
|
|
8407
|
+
// // For grouped bar charts with many bars and NO xLabel, add space as before, but reduce in fullscreen
|
|
8408
|
+
// if (subgroups.length > 1 && data.length > 8 && !metaData.xLabel) {
|
|
8409
|
+
// const chartHasExtraBottom = (self.chartConfiguration.margin && self.chartConfiguration.margin.bottom >= 40);
|
|
8410
|
+
// if (self.chartConfiguration.isFullScreen) {
|
|
8411
|
+
// // Reduce extra gap in maximized view
|
|
8412
|
+
// return short_tick_length_bg + 2;
|
|
8413
|
+
// }
|
|
8414
|
+
// return chartHasExtraBottom ? short_tick_length_bg : short_tick_length_bg + 10;
|
|
8415
|
+
// }
|
|
8416
|
+
// // Default/fallback logic for other cases
|
|
8417
|
+
// let baseY = self.isHeaderVisible ? short_tick_length_bg + 25 : short_tick_length_bg;
|
|
8418
|
+
// if (
|
|
8419
|
+
// subgroups.length > 1 &&
|
|
8420
|
+
// !metaData.xLabel &&
|
|
8421
|
+
// (/\d{2,4}[-\/]\d{2}[-\/]\d{2,4}/.test(d) || /\d{2,4}[-\/]\d{2,4}/.test(d))
|
|
8422
|
+
// ) {
|
|
8423
|
+
// baseY = self.isHeaderVisible ? short_tick_length_bg + 15 : short_tick_length_bg + 25;
|
|
8424
|
+
// }
|
|
8425
|
+
// if (/\d{2,4}[-\/]\d{2,4}/.test(d) && d.indexOf(' ') > -1) {
|
|
8426
|
+
// baseY += 4;
|
|
8427
|
+
// }
|
|
8428
|
+
// // In maximized view, reduce baseY slightly for grouped bars
|
|
8429
|
+
// if (self.chartConfiguration.isFullScreen && subgroups.length > 1) {
|
|
8430
|
+
// baseY = Math.max(short_tick_length_bg, baseY - 10);
|
|
8431
|
+
// }
|
|
8432
|
+
// return baseY;
|
|
8433
|
+
// })
|
|
8434
|
+
// .attr('x', function (d) {
|
|
8435
|
+
// if (self.chartData.data.length > 8 && !self.isZoomedOut) {
|
|
8436
|
+
// return 1; // Move first line text slightly to the left in zoom-in view for better alignment
|
|
8437
|
+
// }
|
|
8438
|
+
// return 0; // Default position
|
|
8439
|
+
// })
|
|
8440
|
+
// .text(function (d) {
|
|
8441
|
+
// var isValueToBeIgnored = false;
|
|
8442
|
+
// if (isMobile && !self.isHeaderVisible) {
|
|
8443
|
+
// let firstPart = d.split(/[\s\-]+/)[0];
|
|
8444
|
+
// return firstPart.substring(0, 3).toLowerCase();
|
|
8445
|
+
// }
|
|
8446
|
+
// (data as any[]).map((indiv: any) => {
|
|
8447
|
+
// if (
|
|
8448
|
+
// indiv.name &&
|
|
8449
|
+
// indiv.name.toLowerCase() == d.trim().toLowerCase() &&
|
|
8450
|
+
// indiv[metaData.keyList[0]] == -1
|
|
8451
|
+
// ) {
|
|
8452
|
+
// isValueToBeIgnored = true;
|
|
8453
|
+
// }
|
|
8454
|
+
// });
|
|
8455
|
+
// if (isValueToBeIgnored) {
|
|
8456
|
+
// return '';
|
|
8457
|
+
// }
|
|
8458
|
+
// // Always add space before and after hyphen for date range labels, even when header is visible and label is single line
|
|
8459
|
+
// // Apply for grouped bar charts and single bar charts, header visible, single line
|
|
8460
|
+
// const dateRangeRegex = /(\d{2,4}[-\/]\d{2}[-\/]\d{2,4})\s*-\s*(\d{2,4}[-\/]\d{2}[-\/]\d{2,4})/;
|
|
8461
|
+
// if (dateRangeRegex.test(d.trim())) {
|
|
8462
|
+
// return d.trim().replace(dateRangeRegex, (m, d1, d2) => `${d1} - ${d2}`);
|
|
8463
|
+
// }
|
|
8464
|
+
// // Split date and week labels into two lines in grouped bar zoom-in view (and minimized view)
|
|
8465
|
+
// const isDateLabel = /\d{2,4}[-\/]/.test(d);
|
|
8466
|
+
// const isWeekLabel = /week|wk|w\d+/i.test(d);
|
|
8467
|
+
// if (
|
|
8468
|
+
// subgroups.length > 1 && !self.isZoomedOut && data.length > 8 && d.indexOf(' ') > -1 && (isDateLabel || isWeekLabel)
|
|
8469
|
+
// ) {
|
|
8470
|
+
// var first = d.substring(0, d.indexOf(' '));
|
|
8471
|
+
// var second = d.substring(d.indexOf(' ') + 1).trim();
|
|
8472
|
+
// return first + '\n' + second;
|
|
8473
|
+
// }
|
|
8474
|
+
// // Also keep previous logic for minimized view
|
|
8475
|
+
// if (isDateLabel) {
|
|
8476
|
+
// if (!self.isHeaderVisible && data.length > 8 && d.indexOf(' ') > -1) {
|
|
8477
|
+
// var first = d.substring(0, d.indexOf(' '));
|
|
8478
|
+
// var second = d.substring(d.indexOf(' ') + 1).trim();
|
|
8479
|
+
// return first + '\n' + second;
|
|
8480
|
+
// } else {
|
|
8481
|
+
// return d;
|
|
8482
|
+
// }
|
|
8483
|
+
// }
|
|
8484
|
+
// if (d.trim().indexOf(' ') > -1) {
|
|
8485
|
+
// return d.trim().substring(0, d.indexOf(' ')).toLowerCase();
|
|
8486
|
+
// }
|
|
8487
|
+
// return d.toLowerCase();
|
|
8488
|
+
// // If label looks like a date (contains digits and - or /)
|
|
8489
|
+
// const isDateLabel2 = /\d{2,4}[-\/]/.test(d);
|
|
8490
|
+
// // Only split date/week labels if there are many grouped bars and header is not visible
|
|
8491
|
+
// if (isDateLabel) {
|
|
8492
|
+
// if (!self.isHeaderVisible && data.length > 8 && d.indexOf(' ') > -1) {
|
|
8493
|
+
// var first = d.substring(0, d.indexOf(' '));
|
|
8494
|
+
// var second = d.substring(d.indexOf(' ') + 1).trim();
|
|
8495
|
+
// return first + '\n' + second;
|
|
8496
|
+
// } else {
|
|
8497
|
+
// return d;
|
|
8498
|
+
// }
|
|
8499
|
+
// }
|
|
8500
|
+
// if (d.trim().indexOf(' ') > -1) {
|
|
8501
|
+
// return d.trim().substring(0, d.indexOf(' ')).toLowerCase();
|
|
8502
|
+
// }
|
|
8503
|
+
// return d.toLowerCase();
|
|
8504
|
+
// });
|
|
8505
|
+
// // Now apply writing-mode: sideways-lr for grouped charts with date labels in zoomed-out view and many bars
|
|
8506
|
+
// xAxisLabels.each(function(this: SVGTextElement, d: any) {
|
|
8507
|
+
// // Only apply writing-mode for exact date labels, not those containing 'week' or similar
|
|
8508
|
+
// const isDateLabel = /^(\d{2,4}[-\/])?\d{2,4}[-\/]\d{2,4}$/.test(d.trim());
|
|
8509
|
+
// const isWeekLabel = /week|wk|w\d+/i.test(d);
|
|
8510
|
+
// if (subgroups.length > 1 && self.isZoomedOut && data.length > 8 && isDateLabel && !isWeekLabel) {
|
|
8511
|
+
// d3.select(this).style('writing-mode', 'sideways-lr');
|
|
8512
|
+
// }
|
|
8513
|
+
// });
|
|
8514
|
+
// if (!isMobile) {
|
|
8515
|
+
// svg
|
|
8516
|
+
// .selectAll('g.x1.axis1 g.tick')
|
|
8517
|
+
// .filter(function (d) {
|
|
8518
|
+
// return !/\d{2,4}[-\/]/.test(d); // Only process non-date labels
|
|
8519
|
+
// })
|
|
8520
|
+
// .append('text')
|
|
8521
|
+
// .attr('class', 'lib-xaxis-labels-texts-drilldown')
|
|
8522
|
+
// .attr('y', long_tick_length_bg)
|
|
8523
|
+
// .attr('fill', 'var(--chart-text-color)')
|
|
8524
|
+
// .attr('x', function (d) {
|
|
8525
|
+
// if (self.chartData.data.length > 8 && !self.isZoomedOut) {
|
|
8526
|
+
// return 1; // Move text slightly to the left
|
|
8527
|
+
// }
|
|
8528
|
+
// return 0; // Default position
|
|
8529
|
+
// })
|
|
8530
|
+
// .text(function (d) {
|
|
8531
|
+
// if (d.trim().indexOf(' ') > -1) {
|
|
8532
|
+
// return d.trim().substring(d.indexOf(' '), d.length).toLowerCase();
|
|
8533
|
+
// }
|
|
8534
|
+
// return '';
|
|
8535
|
+
// });
|
|
8536
|
+
// }
|
|
8537
|
+
// }
|
|
8538
|
+
// if (isria && self.chartData.data.length > 8) {
|
|
8539
|
+
// svg
|
|
8540
|
+
// .selectAll('g.x1.axis1 g.tick text')
|
|
8541
|
+
// .classed('mobile-xaxis-override', true)
|
|
8542
|
+
// .text(function (d: string) {
|
|
8543
|
+
// return d.substring(0, 3);
|
|
8544
|
+
// })
|
|
8545
|
+
// .style('font-size', '12px')
|
|
8546
|
+
// .attr('y', 5)
|
|
8547
|
+
// .attr('x', 5)
|
|
8548
|
+
// .style('text-anchor', 'middle');
|
|
8549
|
+
// }
|
|
8550
|
+
// if (isMobile && !this.isHeaderVisible) {
|
|
8551
|
+
// svg
|
|
8552
|
+
// .selectAll('g.x1.axis1 g.tick text')
|
|
8553
|
+
// .classed('mobile-xaxis-override', true);
|
|
8554
|
+
// }
|
|
8555
|
+
// /**y scale for left y axis */
|
|
8556
|
+
// var y = d3.scaleLinear().rangeRound([height, 0]);
|
|
8557
|
+
// var maxValue = d3.max(data, (d) => d3.max(keyList, (key) => +d[key]));
|
|
8558
|
+
// if (maxValue == 0) {
|
|
8559
|
+
// if (this.chartData.targetLineData) {
|
|
8560
|
+
// maxValue = this.chartData.targetLineData.target + 20;
|
|
8561
|
+
// } else {
|
|
8562
|
+
// maxValue = 100;
|
|
8563
|
+
// }
|
|
8564
|
+
// }
|
|
8565
|
+
// if (this.chartConfiguration.customYscale) {
|
|
8566
|
+
// /**
|
|
8567
|
+
// * increase y-scale so that values wont cross or exceed out of range
|
|
8568
|
+
// * used in weekly charts
|
|
8569
|
+
// */
|
|
8570
|
+
// maxValue = maxValue * this.chartConfiguration.customYscale;
|
|
8571
|
+
// }
|
|
8572
|
+
// if (
|
|
8573
|
+
// this.chartData.targetLineData &&
|
|
8574
|
+
// maxValue < this.chartData.targetLineData.target
|
|
8575
|
+
// ) {
|
|
8576
|
+
// maxValue =
|
|
8577
|
+
// maxValue < 10 && this.chartData.targetLineData.target < 10
|
|
8578
|
+
// ? this.chartData.targetLineData.target + 3
|
|
8579
|
+
// : this.chartData.targetLineData.target + 20;
|
|
8580
|
+
// }
|
|
8581
|
+
// y.domain([0, maxValue]).nice();
|
|
8582
|
+
// let lineYscale;
|
|
8583
|
+
// if (lineData != null) {
|
|
8584
|
+
// let maxLineValue = d3.max(lineData, function (d) {
|
|
8585
|
+
// return +d.value;
|
|
8586
|
+
// });
|
|
8587
|
+
// maxLineValue = maxLineValue * this.chartConfiguration.customYscale;
|
|
8588
|
+
// let minLineValue = d3.min(lineData, function (d) {
|
|
8589
|
+
// return +d.value;
|
|
8590
|
+
// });
|
|
8591
|
+
// if (maxLineValue > 0) minLineValue = minLineValue - 3;
|
|
8592
|
+
// if (minLineValue > 0) {
|
|
8593
|
+
// minLineValue = 0;
|
|
8594
|
+
// }
|
|
8595
|
+
// lineYscale = d3
|
|
8596
|
+
// .scaleLinear()
|
|
8597
|
+
// .domain([minLineValue, maxLineValue])
|
|
8598
|
+
// .range([height, minLineValue]);
|
|
8599
|
+
// }
|
|
8600
|
+
// let yLineAxis;
|
|
8601
|
+
// if (lineYscale != null) {
|
|
8602
|
+
// yLineAxis = d3
|
|
8603
|
+
// .axisRight(lineYscale)
|
|
8604
|
+
// .ticks(self.chartConfiguration.numberOfYTicks)
|
|
8605
|
+
// .tickSize(0)
|
|
8606
|
+
// .tickFormat(self.chartConfiguration.yLineAxisLabelFomatter);
|
|
8607
|
+
// }
|
|
8608
|
+
// /**
|
|
8609
|
+
// * show x-axis grid between labels
|
|
8610
|
+
// * used by weekly charts
|
|
8611
|
+
// */
|
|
8612
|
+
// if (self.chartConfiguration.isXgridBetweenLabels) {
|
|
8613
|
+
// svg
|
|
8614
|
+
// .append('g')
|
|
8615
|
+
// .attr('class', 'grid')
|
|
8616
|
+
// .attr(
|
|
8617
|
+
// 'transform',
|
|
8618
|
+
// 'translate(' + x.bandwidth() / 2 + ',' + height + ')'
|
|
8619
|
+
// )
|
|
8620
|
+
// .call(d3.axisBottom(x).tickSize(-height).tickFormat(''))
|
|
8621
|
+
// .style('stroke-dasharray', '5 5')
|
|
8622
|
+
// .style('color', 'var(--chart-grid-color, #999999)') // Use CSS variable
|
|
8623
|
+
// .call((g) => g.select('.domain').remove());
|
|
8624
|
+
// }
|
|
8625
|
+
// if (this.chartConfiguration.yAxisGrid) {
|
|
8626
|
+
// svg
|
|
8627
|
+
// .append('g')
|
|
8628
|
+
// .call(
|
|
8629
|
+
// d3
|
|
8630
|
+
// .axisLeft(y)
|
|
8631
|
+
// .ticks(self.chartConfiguration.numberOfYTicks)
|
|
8632
|
+
// .tickSize(-width)
|
|
8633
|
+
// )
|
|
8634
|
+
// .style('color', 'var(--chart-axis-color, #B9B9B9)')
|
|
8635
|
+
// .style('opacity', '0.5')
|
|
8636
|
+
// .call((g) => {
|
|
8637
|
+
// g.select('.domain')
|
|
8638
|
+
// .remove()
|
|
8639
|
+
// .style('stroke', 'var(--chart-domain-color, #000000)'); // Add CSS variable for domain
|
|
8640
|
+
// });
|
|
8641
|
+
// } else {
|
|
8642
|
+
// svg
|
|
8643
|
+
// .append('g')
|
|
8644
|
+
// .call(d3.axisLeft(y).ticks(self.chartConfiguration.numberOfYTicks))
|
|
8645
|
+
// .style('color', 'var(--chart-axis-color, #B9B9B9)')
|
|
8646
|
+
// .style('opacity', '0.5')
|
|
8647
|
+
// .call((g) => {
|
|
8648
|
+
// g.select('.domain')
|
|
8649
|
+
// .style('stroke', 'var(--chart-domain-color, #000000)') // Add CSS variable for domain
|
|
8650
|
+
// .style('stroke-width', '1px'); // Ensure visibility
|
|
8651
|
+
// });
|
|
8652
|
+
// }
|
|
8653
|
+
// var xSubgroup = d3.scaleBand().domain(subgroups);
|
|
8654
|
+
// if (subgroups.length > 1 && !this.isZoomedOut) {
|
|
8655
|
+
// // For grouped bar charts in zoom-in view, use full x.bandwidth() for subgroups
|
|
8656
|
+
// xSubgroup.range([0, x.bandwidth()]);
|
|
8657
|
+
// } else if (subgroups.length === 1 && !this.isZoomedOut) {
|
|
8658
|
+
// // For single-bar (non-grouped) charts in zoom-in view, set bar width to 100 (increased from 80)
|
|
8659
|
+
// xSubgroup.range([0, 100]);
|
|
8660
|
+
// } else if (this.chartConfiguration.isMultiChartGridLine == undefined) {
|
|
8661
|
+
// xSubgroup.range([0, x.bandwidth()]);
|
|
8662
|
+
// } else {
|
|
8663
|
+
// // used to make grouped bars with lesser width as we are not using padding for width
|
|
8664
|
+
// xSubgroup.range([0, x.bandwidth()]);
|
|
8665
|
+
// }
|
|
8666
|
+
// // if (this.chartConfiguration.isDrilldownChart) {
|
|
8667
|
+
// // }
|
|
8668
|
+
// var color = d3
|
|
8669
|
+
// .scaleOrdinal()
|
|
8670
|
+
// .domain(subgroups)
|
|
8671
|
+
// .range(Object.values(metaData.colors));
|
|
8672
|
+
// // var colorAboveTarget = d3
|
|
8673
|
+
// // .scaleOrdinal()
|
|
8674
|
+
// // .domain(subgroups)
|
|
8675
|
+
// // .range(Object.values(metaData.colorAboveTarget));
|
|
8676
|
+
// var state = svg
|
|
8677
|
+
// .append('g')
|
|
8678
|
+
// .selectAll('.state')
|
|
8679
|
+
// .data(data)
|
|
8680
|
+
// .enter()
|
|
8681
|
+
// .append('g')
|
|
8682
|
+
// .attr('transform', function (d) {
|
|
8683
|
+
// return 'translate(' + x(d.name) + ',0)';
|
|
8684
|
+
// });
|
|
8685
|
+
// state
|
|
8686
|
+
// .selectAll('rect')
|
|
8687
|
+
// .data(function (d) {
|
|
8688
|
+
// let newList: any = [];
|
|
8689
|
+
// subgroups.map(function (key) {
|
|
8690
|
+
// // if (key !== "group") {
|
|
8691
|
+
// let obj: any = { key: key, value: d[key], name: d.name };
|
|
8692
|
+
// newList.push(obj);
|
|
8693
|
+
// // }
|
|
8694
|
+
// });
|
|
8695
|
+
// return newList;
|
|
8696
|
+
// })
|
|
8697
|
+
// .enter()
|
|
8698
|
+
// .append('rect')
|
|
8699
|
+
// .attr('class', 'bars')
|
|
8700
|
+
// .on('click', function (d) {
|
|
8701
|
+
// if (d.key != 'Target') {
|
|
8702
|
+
// if (
|
|
8703
|
+
// !metaData.barWithoutClick ||
|
|
8704
|
+
// !metaData.barWithoutClick.length ||
|
|
8705
|
+
// (!metaData.barWithoutClick.includes(d?.name) &&
|
|
8706
|
+
// !metaData.barWithoutClick.includes(d?.key))
|
|
8707
|
+
// )
|
|
8708
|
+
// // self.handleClick(d.data.name);
|
|
8709
|
+
// self.handleClick(d);
|
|
8710
|
+
// }
|
|
8711
|
+
// })
|
|
8712
|
+
// .attr('x', function (d) {
|
|
8713
|
+
// if (self.chartConfiguration.isDrilldownChart) {
|
|
8714
|
+
// data.map((indiv: any) => {
|
|
8715
|
+
// if (indiv.name == d.name) {
|
|
8716
|
+
// let keys = Object.keys(indiv).filter((temp, i) => i != 0);
|
|
8717
|
+
// tempScale = d3.scaleBand().domain(keys).range([0, x.bandwidth()]);
|
|
8718
|
+
// if (x.bandwidth() > 100) {
|
|
8719
|
+
// // Increase bar width a bit in zoom-in view
|
|
8720
|
+
// let reducedBarWidth = 60;
|
|
8721
|
+
// if (!self.isZoomedOut) {
|
|
8722
|
+
// reducedBarWidth = 30;
|
|
8723
|
+
// }
|
|
8724
|
+
// if (self.chartData.data.length == 1) {
|
|
8725
|
+
// if (Object.keys(self.chartData.data[0]).length == 2) {
|
|
8726
|
+
// tempScale.range([
|
|
8727
|
+
// 0 + (x.bandwidth() - reducedBarWidth) / 2,
|
|
8728
|
+
// x.bandwidth() - (x.bandwidth() - reducedBarWidth) / 2,
|
|
8729
|
+
// ]);
|
|
8730
|
+
// } else
|
|
8731
|
+
// tempScale.range([
|
|
8732
|
+
// 0 + (x.bandwidth() - reducedBarWidth) / 2,
|
|
8733
|
+
// x.bandwidth() - (x.bandwidth() - reducedBarWidth) / 2,
|
|
8734
|
+
// ]);
|
|
8735
|
+
// } else
|
|
8736
|
+
// tempScale.range([
|
|
8737
|
+
// 0 + (x.bandwidth() - reducedBarWidth) / 2,
|
|
8738
|
+
// x.bandwidth() - (x.bandwidth() - reducedBarWidth) / 2,
|
|
8739
|
+
// ]);
|
|
8740
|
+
// }
|
|
8741
|
+
// }
|
|
8742
|
+
// });
|
|
8743
|
+
// return tempScale(d.key);
|
|
8744
|
+
// }
|
|
8745
|
+
// return xSubgroup(d.key);
|
|
8746
|
+
// })
|
|
8747
|
+
// .attr('y', function (d) {
|
|
8748
|
+
// if (d.value == -1) {
|
|
8749
|
+
// return y(0);
|
|
8750
|
+
// }
|
|
8751
|
+
// if (d.value >= 0) {
|
|
8752
|
+
// const barHeight = height - y(d.value);
|
|
8753
|
+
// const minHeight = self.chartConfiguration.defaultBarHeight || 2;
|
|
8754
|
+
// return barHeight < minHeight ? y(0) - minHeight : y(d.value);
|
|
8755
|
+
// }
|
|
8756
|
+
// return y(0);
|
|
8757
|
+
// })
|
|
8758
|
+
// .attr('width', function (d) {
|
|
8759
|
+
// // For grouped bar charts in zoom-in view, set bar width to 50 for maximum thickness
|
|
8760
|
+
// if (subgroups.length > 1 && !self.isZoomedOut) {
|
|
8761
|
+
// return 50;
|
|
8762
|
+
// }
|
|
8763
|
+
// // For single-bar (non-grouped) charts in zoom-in view, set bar width to 80
|
|
8764
|
+
// if (subgroups.length === 1 && !self.isZoomedOut) {
|
|
8765
|
+
// return 80;
|
|
8766
|
+
// }
|
|
8767
|
+
// let tempScale = d3.scaleBand().domain([]).range([0, 0]);
|
|
8768
|
+
// // Default logic for other chart types
|
|
8769
|
+
// if (self.chartConfiguration.isDrilldownChart) {
|
|
8770
|
+
// data.map((indiv: any) => {
|
|
8771
|
+
// if (indiv.name == d.name) {
|
|
8772
|
+
// let keys = Object.keys(indiv).filter((temp, i) => i != 0);
|
|
8773
|
+
// tempScale = d3.scaleBand().domain(keys).range([0, x.bandwidth()]);
|
|
8774
|
+
// if (x.bandwidth() > 100) {
|
|
8775
|
+
// // Increase bar width a bit in zoom-in view
|
|
8776
|
+
// let reducedBarWidth = 60;
|
|
8777
|
+
// if (!self.isZoomedOut) {
|
|
8778
|
+
// reducedBarWidth = 100;
|
|
8779
|
+
// }
|
|
8780
|
+
// if (self.chartData.data.length == 1) {
|
|
8781
|
+
// if (Object.keys(self.chartData.data[0]).length == 2) {
|
|
8782
|
+
// tempScale.range([
|
|
8783
|
+
// 0 + (x.bandwidth() - reducedBarWidth) / 2,
|
|
8784
|
+
// x.bandwidth() - (x.bandwidth() - reducedBarWidth) / 2,
|
|
8785
|
+
// ]);
|
|
8786
|
+
// } else
|
|
8787
|
+
// tempScale.range([
|
|
8788
|
+
// 0 + (x.bandwidth() - reducedBarWidth) / 2,
|
|
8789
|
+
// x.bandwidth() - (x.bandwidth() - reducedBarWidth) / 2,
|
|
8790
|
+
// ]);
|
|
8791
|
+
// } else
|
|
8792
|
+
// tempScale.range([
|
|
8793
|
+
// 0 + (x.bandwidth() - reducedBarWidth) / 2,
|
|
8794
|
+
// x.bandwidth() - (x.bandwidth() - reducedBarWidth) / 2,
|
|
8795
|
+
// ]);
|
|
8796
|
+
// }
|
|
8797
|
+
// }
|
|
8798
|
+
// });
|
|
8799
|
+
// return self.isZoomedOut
|
|
8800
|
+
// ? tempScale.bandwidth()
|
|
8801
|
+
// : self.chartData.data.length && self.chartData.data.length > 8
|
|
8802
|
+
// ? tempScale.bandwidth()
|
|
8803
|
+
// : tempScale.bandwidth();
|
|
8804
|
+
// }
|
|
8805
|
+
// return self.isZoomedOut
|
|
8806
|
+
// ? tempScale.bandwidth()
|
|
8807
|
+
// : self.chartData.data.length && self.chartData.data.length > 8
|
|
8808
|
+
// ? tempScale.bandwidth()
|
|
8809
|
+
// : tempScale.bandwidth();
|
|
8810
|
+
// })
|
|
8811
|
+
// .attr('height', function (d) {
|
|
8812
|
+
// if (d.value == -1) {
|
|
8813
|
+
// return height - y(0);
|
|
8814
|
+
// }
|
|
8815
|
+
// if (d.value >= 0) {
|
|
8816
|
+
// const barHeight = height - y(d.value);
|
|
8817
|
+
// const minHeight = self.chartConfiguration.defaultBarHeight || 2;
|
|
8818
|
+
// return Math.max(barHeight, minHeight);
|
|
8819
|
+
// }
|
|
8820
|
+
// return height - y(0);
|
|
8821
|
+
// })
|
|
8822
|
+
// .style('cursor', function (d) {
|
|
8823
|
+
// if (metaData.hasDrillDown && !isria) return 'pointer';
|
|
8824
|
+
// else return 'default';
|
|
8825
|
+
// })
|
|
8826
|
+
// .attr('fill', function (d) {
|
|
8827
|
+
// if (
|
|
8828
|
+
// d.value &&
|
|
8829
|
+
// self.chartData.targetLineData &&
|
|
8830
|
+
// d.value >= parseFloat(self.chartData.targetLineData.target) &&
|
|
8831
|
+
// self.chartData.metaData.colorAboveTarget
|
|
8832
|
+
// ) {
|
|
8833
|
+
// const key = d.key.toLowerCase();
|
|
8834
|
+
// const colorAboveTarget = Object.keys(self.chartData.metaData.colorAboveTarget).find(
|
|
8835
|
+
// k => k.toLowerCase() === key
|
|
8836
|
+
// );
|
|
8837
|
+
// if (colorAboveTarget) {
|
|
8838
|
+
// return self.chartData.metaData.colorAboveTarget[colorAboveTarget];
|
|
8839
|
+
// }
|
|
8840
|
+
// }
|
|
8841
|
+
// return self.chartData.metaData.colors[d.key];
|
|
8842
|
+
// });
|
|
8843
|
+
// /**
|
|
8844
|
+
// * display angled texts on the bars
|
|
8845
|
+
// */
|
|
8846
|
+
// if (this.chartConfiguration.textsOnBar != undefined && !this.isZoomedOut) {
|
|
8847
|
+
// state
|
|
8848
|
+
// .selectAll('text')
|
|
8849
|
+
// .data(function (d) {
|
|
8850
|
+
// let newList: any = [];
|
|
8851
|
+
// subgroups.map(function (key) {
|
|
8852
|
+
// let obj: any = { key: key, value: d[key], name: d.name };
|
|
8853
|
+
// newList.push(obj);
|
|
8854
|
+
// });
|
|
8855
|
+
// return newList;
|
|
8856
|
+
// })
|
|
8857
|
+
// .enter()
|
|
8858
|
+
// .append('text')
|
|
8859
|
+
// .attr('fill', 'var(--chart-text-color)')
|
|
8860
|
+
// .attr('x', function (d) {
|
|
8861
|
+
// return 0;
|
|
8862
|
+
// })
|
|
8863
|
+
// .attr('y', function (d) {
|
|
8864
|
+
// return 0;
|
|
8865
|
+
// })
|
|
8866
|
+
// .attr('class', 'lib-data-labels-weeklycharts')
|
|
8867
|
+
// .text(function (d) {
|
|
8868
|
+
// return d.key && d.value
|
|
8869
|
+
// ? d.key.length > 20
|
|
8870
|
+
// ? d.key.substring(0, 17) + '...'
|
|
8871
|
+
// : d.key
|
|
8872
|
+
// : '';
|
|
8873
|
+
// })
|
|
8874
|
+
// .style('fill', function (d) {
|
|
8875
|
+
// return '#000';
|
|
8876
|
+
// })
|
|
8877
|
+
// .style('font-weight', 'bold')
|
|
8878
|
+
// .style('font-size', function (d) {
|
|
8879
|
+
// if (self.isZoomedOut) {
|
|
8880
|
+
// return '9px'; // 👈 Zoomed out mode
|
|
8881
|
+
// }
|
|
8882
|
+
// if (self.chartConfiguration.isDrilldownChart) {
|
|
8883
|
+
// if (window.innerWidth > 1900) {
|
|
8884
|
+
// return '18px';
|
|
8885
|
+
// } else if (window.innerWidth < 1400) {
|
|
8886
|
+
// return '10px';
|
|
8887
|
+
// } else {
|
|
8888
|
+
// return '14px';
|
|
8889
|
+
// }
|
|
8890
|
+
// } else {
|
|
8891
|
+
// return '14px';
|
|
8892
|
+
// }
|
|
8893
|
+
// })
|
|
8894
|
+
// .attr('transform', function (d) {
|
|
8895
|
+
// data.map((indiv: any) => {
|
|
8896
|
+
// if (indiv.name == d.name) {
|
|
8897
|
+
// let keys = Object.keys(indiv).filter((temp, i) => i != 0);
|
|
8898
|
+
// var temp;
|
|
8899
|
+
// tempScale = d3.scaleBand().domain(keys).range([0, x.bandwidth()]);
|
|
8900
|
+
// if (x.bandwidth() > 100) {
|
|
8901
|
+
// if (self.chartData.data.length == 1) {
|
|
8902
|
+
// if (Object.keys(self.chartData.data[0]).length == 2) {
|
|
8903
|
+
// tempScale.range([
|
|
8904
|
+
// 0 + (x.bandwidth() - 200) / 2,
|
|
8905
|
+
// x.bandwidth() - (x.bandwidth() - 200) / 2,
|
|
8906
|
+
// ]);
|
|
8907
|
+
// // .padding(0.05);
|
|
8908
|
+
// } else
|
|
8909
|
+
// tempScale.range([
|
|
8910
|
+
// 0 + (x.bandwidth() - 300) / 2,
|
|
8911
|
+
// x.bandwidth() - (x.bandwidth() - 300) / 2,
|
|
8912
|
+
// ]);
|
|
8913
|
+
// // .padding(0.05);
|
|
8914
|
+
// } else
|
|
8915
|
+
// tempScale.range([
|
|
8916
|
+
// 0 + (x.bandwidth() - 125) / 2,
|
|
8917
|
+
// x.bandwidth() - (x.bandwidth() - 125) / 2,
|
|
8918
|
+
// ]);
|
|
8919
|
+
// }
|
|
8920
|
+
// }
|
|
8921
|
+
// });
|
|
8922
|
+
// /**
|
|
8923
|
+
// * if set, then all texts ll be horizontal
|
|
8924
|
+
// */
|
|
8925
|
+
// if (self.chartConfiguration.textAlwaysHorizontal) {
|
|
8926
|
+
// return (
|
|
8927
|
+
// 'translate(' + xSubgroup(d.key) + ',' + (y(d.value) - 3) + ')'
|
|
8928
|
+
// );
|
|
8929
|
+
// }
|
|
8930
|
+
// /**
|
|
8931
|
+
// * rotate texts having more than one digits
|
|
8932
|
+
// */
|
|
8933
|
+
// // if (d.value > 9)
|
|
8934
|
+
// if (!isNaN(tempScale(d.key)))
|
|
8935
|
+
// return (
|
|
8936
|
+
// 'translate(' +
|
|
8937
|
+
// (tempScale(d.key) + tempScale.bandwidth() * 0.55) +
|
|
8938
|
+
// ',' +
|
|
8939
|
+
// (y(0) - 10) +
|
|
8940
|
+
// ') rotate(270)'
|
|
8941
|
+
// );
|
|
8942
|
+
// return 'translate(0,0)';
|
|
8943
|
+
// // else
|
|
8944
|
+
// // return (
|
|
8945
|
+
// // 'translate(' +
|
|
8946
|
+
// // (tempScale(d.key) + tempScale.bandwidth() / 2) +
|
|
8947
|
+
// // ',' +
|
|
8948
|
+
// // y(0) +
|
|
8949
|
+
// // ')'
|
|
8950
|
+
// // );
|
|
8951
|
+
// })
|
|
8952
|
+
// .on('click', function (d) {
|
|
8953
|
+
// if (
|
|
8954
|
+
// !metaData.barWithoutClick ||
|
|
8955
|
+
// !metaData.barWithoutClick.length ||
|
|
8956
|
+
// (!metaData.barWithoutClick.includes(d?.name) &&
|
|
8957
|
+
// !metaData.barWithoutClick.includes(d?.key))
|
|
8958
|
+
// )
|
|
8959
|
+
// self.handleClick(d);
|
|
8960
|
+
// });
|
|
8961
|
+
// if (!isria) {
|
|
8962
|
+
// state
|
|
8963
|
+
// .selectAll('.lib-data-labels-weeklycharts')
|
|
8964
|
+
// .on('mouseout', handleMouseOut)
|
|
8965
|
+
// .on('mouseover', handleMouseOver);
|
|
8966
|
+
// }
|
|
8967
|
+
// }
|
|
8968
|
+
// if (this.chartConfiguration.displayTitleOnTop || (
|
|
8969
|
+
// this.chartConfiguration.textsOnBar == undefined &&
|
|
8970
|
+
// this.chartConfiguration.displayTitleOnTop == undefined
|
|
8971
|
+
// )) {
|
|
8972
|
+
// if (!isria) {
|
|
8973
|
+
// state
|
|
8974
|
+
// .selectAll('rect')
|
|
8975
|
+
// .on('mouseout', handleMouseOut)
|
|
8976
|
+
// .on('mouseover', handleMouseOver);
|
|
8977
|
+
// }
|
|
8978
|
+
// }
|
|
8979
|
+
// function handleMouseOver(d, i) {
|
|
8980
|
+
// svg.selectAll('.lib-verticalstack-title-ontop').remove();
|
|
8981
|
+
// svg
|
|
8982
|
+
// .append('foreignObject')
|
|
8983
|
+
// .attr('x', function () {
|
|
8984
|
+
// // ...existing code for tempScale calculation...
|
|
8985
|
+
// var elementsCounter;
|
|
8986
|
+
// data.map((indiv: any) => {
|
|
8987
|
+
// if (indiv.name == d.name) {
|
|
8988
|
+
// let keys = Object.keys(indiv).filter((temp, i) => i != 0);
|
|
8989
|
+
// elementsCounter = keys.length;
|
|
8990
|
+
// tempScale = d3.scaleBand().domain(keys).range([0, x.bandwidth()]);
|
|
8991
|
+
// if (x.bandwidth() > 100) {
|
|
8992
|
+
// if (self.chartData.data.length == 1) {
|
|
8993
|
+
// if (Object.keys(self.chartData.data[0]).length == 2) {
|
|
8994
|
+
// tempScale.range([
|
|
8995
|
+
// 0 + (x.bandwidth() - 200) / 2,
|
|
8996
|
+
// x.bandwidth() - (x.bandwidth() - 200) / 2,
|
|
8997
|
+
// ]);
|
|
8998
|
+
// } else
|
|
8999
|
+
// tempScale.range([
|
|
9000
|
+
// 0 + (x.bandwidth() - 300) / 2,
|
|
9001
|
+
// x.bandwidth() - (x.bandwidth() - 300) / 2,
|
|
9002
|
+
// ]);
|
|
9003
|
+
// } else
|
|
9004
|
+
// tempScale.range([
|
|
9005
|
+
// 0 + (x.bandwidth() - 125) / 2,
|
|
9006
|
+
// x.bandwidth() - (x.bandwidth() - 125) / 2,
|
|
9007
|
+
// ]);
|
|
9008
|
+
// }
|
|
9009
|
+
// }
|
|
9010
|
+
// });
|
|
9011
|
+
// if (metaData.hasDrillDown) {
|
|
9012
|
+
// if (tempScale.bandwidth() + leftAndRightSpaces * 2 > 180) {
|
|
9013
|
+
// return (
|
|
9014
|
+
// x(d.name) + tempScale(d.key) + tempScale.bandwidth() / 2 - 90
|
|
9015
|
+
// );
|
|
9016
|
+
// }
|
|
9017
|
+
// return (
|
|
9018
|
+
// x(d.name) +
|
|
9019
|
+
// tempScale(d.key) -
|
|
9020
|
+
// (tempScale.bandwidth() + leftAndRightSpaces * 2) / 2 +
|
|
9021
|
+
// tempScale.bandwidth() / 2
|
|
9022
|
+
// );
|
|
9023
|
+
// } else return x(d.name) + tempScale(d.key) - (tempScale.bandwidth() + leftAndRightSpaces * 2) / 2 + tempScale.bandwidth() / 2;
|
|
9024
|
+
// })
|
|
9025
|
+
// .attr('class', 'lib-verticalstack-title-ontop')
|
|
9026
|
+
// .attr('y', function () {
|
|
9027
|
+
// return y(d.value) - 3 - 40 - 10;
|
|
9028
|
+
// })
|
|
9029
|
+
// .attr('dy', function () {
|
|
9030
|
+
// return d.class;
|
|
9031
|
+
// })
|
|
9032
|
+
// .attr('width', function () {
|
|
9033
|
+
// data.map((indiv: any) => {
|
|
9034
|
+
// if (indiv.name == d.name) {
|
|
9035
|
+
// let keys = Object.keys(indiv).filter((temp, i) => i != 0);
|
|
9036
|
+
// tempScale = d3.scaleBand().domain(keys).range([0, x.bandwidth()]);
|
|
9037
|
+
// if (x.bandwidth() > 100) {
|
|
9038
|
+
// if (self.chartData.data.length == 1) {
|
|
9039
|
+
// if (Object.keys(self.chartData.data[0]).length == 2) {
|
|
9040
|
+
// tempScale.range([
|
|
9041
|
+
// 0 + (x.bandwidth() - 200) / 2,
|
|
9042
|
+
// x.bandwidth() - (x.bandwidth() - 200) / 2,
|
|
9043
|
+
// ]);
|
|
9044
|
+
// } else
|
|
9045
|
+
// tempScale.range([
|
|
9046
|
+
// 0 + (x.bandwidth() - 300) / 2,
|
|
9047
|
+
// x.bandwidth() - (x.bandwidth() - 300) / 2,
|
|
9048
|
+
// ]);
|
|
9049
|
+
// } else
|
|
9050
|
+
// tempScale.range([
|
|
9051
|
+
// 0 + (x.bandwidth() - 125) / 2,
|
|
9052
|
+
// x.bandwidth() - (x.bandwidth() - 125) / 2,
|
|
9053
|
+
// ]);
|
|
9054
|
+
// }
|
|
9055
|
+
// }
|
|
9056
|
+
// });
|
|
9057
|
+
// if (metaData.hasDrillDown) {
|
|
9058
|
+
// if (tempScale.bandwidth() + leftAndRightSpaces * 2 > 180) {
|
|
9059
|
+
// return '180px';
|
|
9060
|
+
// }
|
|
9061
|
+
// return tempScale.bandwidth() + leftAndRightSpaces * 2;
|
|
9062
|
+
// } else return tempScale.bandwidth() + leftAndRightSpaces * 2;
|
|
9063
|
+
// })
|
|
9064
|
+
// .attr('height', 50)
|
|
9065
|
+
// .append('xhtml:div')
|
|
9066
|
+
// .attr('class', 'title')
|
|
9067
|
+
// .style('z-index', 99)
|
|
9068
|
+
// .html(function () {
|
|
9069
|
+
// let barLabel = d.key;
|
|
9070
|
+
// let dataType = metaData.dataType ? metaData.dataType : '';
|
|
9071
|
+
// let value = d.value;
|
|
9072
|
+
// let desiredText =
|
|
9073
|
+
// '<span class="title-bar-name">' + barLabel + '</span>';
|
|
9074
|
+
// desiredText +=
|
|
9075
|
+
// '<span class="title-bar-value"><span>' +
|
|
9076
|
+
// value +
|
|
9077
|
+
// '</span>' +
|
|
9078
|
+
// dataType +
|
|
9079
|
+
// '</span>';
|
|
9080
|
+
// return desiredText;
|
|
9081
|
+
// });
|
|
9082
|
+
// }
|
|
9083
|
+
// function handleMouseOut(d, i) {
|
|
9084
|
+
// svg.selectAll('.lib-verticalstack-title-ontop').remove();
|
|
9085
|
+
// }
|
|
9086
|
+
// svg
|
|
9087
|
+
// .append('g')
|
|
9088
|
+
// .attr('class', 'x2 axis2')
|
|
9089
|
+
// .attr('transform', 'translate(0,' + height + ')')
|
|
9090
|
+
// .style('color', 'var(--chart-axis-color, #000)') // Use CSS variable instead of hardcoded #000
|
|
9091
|
+
// .call(d3.axisBottom(xScaleFromOrigin).tickSize(0))
|
|
9092
|
+
// .call((g) => g.select('.domain').attr('fill', 'none'));
|
|
9093
|
+
// svg.selectAll('g.x2.axis2 g.tick text').style('display', 'none');
|
|
9094
|
+
// svg
|
|
9095
|
+
// .append('g')
|
|
9096
|
+
// .attr('class', 'lib-stacked-y-axis-text yaxis-dashed')
|
|
9097
|
+
// .attr('style', self.chartConfiguration.yAxisCustomTextStyles)
|
|
9098
|
+
// .attr('transform', 'translate(0,0)')
|
|
9099
|
+
// .call(y)
|
|
9100
|
+
// .style('display', 'none');
|
|
9101
|
+
// svgYAxisLeft
|
|
9102
|
+
// .append('g')
|
|
9103
|
+
// .append('g')
|
|
9104
|
+
// .attr('class', 'lib-yaxis-labels-texts-drilldown yaxis-dashed')
|
|
9105
|
+
// .attr('style', self.chartConfiguration.yAxisCustomTextStyles)
|
|
9106
|
+
// .attr('transform', 'translate(0,0)')
|
|
9107
|
+
// .call(
|
|
9108
|
+
// d3
|
|
9109
|
+
// .axisLeft(y)
|
|
9110
|
+
// .tickSize(0)
|
|
9111
|
+
// .ticks(self.chartConfiguration.numberOfYTicks)
|
|
9112
|
+
// .tickFormat(function (d) {
|
|
9113
|
+
// const formatted = self.chartConfiguration.yAxisLabelFomatter
|
|
9114
|
+
// ? self.chartConfiguration.yAxisLabelFomatter(d)
|
|
9115
|
+
// : d;
|
|
9116
|
+
// return formatted >= 1000 ? formatted / 1000 + 'k' : formatted;
|
|
9117
|
+
// })
|
|
9118
|
+
// )
|
|
9119
|
+
// .call((g) => {
|
|
9120
|
+
// // Style the domain line for theme support
|
|
9121
|
+
// g.select('.domain')
|
|
9122
|
+
// .style('stroke', 'var(--chart-domain-color, #000000)')
|
|
9123
|
+
// .style('stroke-width', '1px');
|
|
9124
|
+
// })
|
|
9125
|
+
// .selectAll('text')
|
|
9126
|
+
// .style('fill', 'var(--chart-text-color)');
|
|
9127
|
+
// svgYAxisRight
|
|
9128
|
+
// .append('g')
|
|
9129
|
+
// .attr('class', 'lib-yaxis-labels-texts-drilldown yaxis-dashed')
|
|
9130
|
+
// .attr('style', self.chartConfiguration.yAxisCustomTextStyles)
|
|
9131
|
+
// .attr('transform', 'translate(0,0)')
|
|
9132
|
+
// .call(y)
|
|
9133
|
+
// .style('display', 'none');
|
|
9134
|
+
// /**
|
|
9135
|
+
// * hide x axis labels
|
|
9136
|
+
// * config is there for future use
|
|
9137
|
+
// * used by weekly charts
|
|
9138
|
+
// */
|
|
9139
|
+
// if (
|
|
9140
|
+
// this.chartConfiguration.isXaxisLabelHidden != undefined &&
|
|
9141
|
+
// this.chartConfiguration.isXaxisLabelHidden
|
|
9142
|
+
// ) {
|
|
9143
|
+
// d3.selectAll('g.lib-line-x-axis-text > g > text').attr(
|
|
9144
|
+
// 'class',
|
|
9145
|
+
// 'lib-display-hidden'
|
|
9146
|
+
// );
|
|
9147
|
+
// }
|
|
9148
|
+
// /**
|
|
9149
|
+
// * hide y axis labels
|
|
9150
|
+
// * used by weekly charts
|
|
9151
|
+
// */
|
|
9152
|
+
// if (
|
|
9153
|
+
// this.chartConfiguration.isYaxisLabelHidden != undefined &&
|
|
9154
|
+
// this.chartConfiguration.isYaxisLabelHidden
|
|
9155
|
+
// ) {
|
|
9156
|
+
// d3.selectAll('.yaxis-dashed > g > text').attr(
|
|
9157
|
+
// 'class',
|
|
9158
|
+
// 'lib-display-hidden'
|
|
9159
|
+
// );
|
|
9160
|
+
// }
|
|
9161
|
+
// /**
|
|
9162
|
+
// * hide y axis labels
|
|
9163
|
+
// * config is there for future use
|
|
9164
|
+
// */
|
|
9165
|
+
// if (
|
|
9166
|
+
// this.chartConfiguration.isYaxisHidden != undefined &&
|
|
9167
|
+
// this.chartConfiguration.isYaxisHidden
|
|
9168
|
+
// ) {
|
|
9169
|
+
// d3.selectAll('.yaxis-dashed').attr('class', 'lib-display-hidden');
|
|
9170
|
+
// }
|
|
9171
|
+
// /**
|
|
9172
|
+
// * dashed y axis
|
|
9173
|
+
// * used by weekly charts
|
|
9174
|
+
// */
|
|
9175
|
+
// if (
|
|
9176
|
+
// this.chartConfiguration.isYaxisDashed != undefined &&
|
|
9177
|
+
// this.chartConfiguration.isYaxisDashed
|
|
9178
|
+
// ) {
|
|
9179
|
+
// d3.selectAll('.yaxis-dashed')
|
|
9180
|
+
// .style('stroke-dasharray', '5 5')
|
|
9181
|
+
// .style('color', 'var(--chart-axis-color, #999999)'); // Use CSS variable
|
|
9182
|
+
// }
|
|
9183
|
+
// if (lineData != null) {
|
|
9184
|
+
// if (lineData && self.chartConfiguration.showLineChartAxis) {
|
|
9185
|
+
// svgYAxisRight
|
|
9186
|
+
// .append('g')
|
|
9187
|
+
// .attr('class', 'lib-stacked-y-axis-text1')
|
|
9188
|
+
// .attr('style', self.chartConfiguration.yAxisCustomTextStyles)
|
|
9189
|
+
// .attr('transform', 'translate(' + 0 + ',0)')
|
|
9190
|
+
// .call(yLineAxis);
|
|
9191
|
+
// }
|
|
9192
|
+
// }
|
|
9193
|
+
// /**
|
|
9194
|
+
// * used to display y label
|
|
9195
|
+
// */
|
|
9196
|
+
// // if (this.isZoomedOut) {
|
|
9197
|
+
// // svg
|
|
9198
|
+
// // .selectAll('.lib-xaxis-labels-texts-drilldown')
|
|
9199
|
+
// // .attr('class', 'lib-display-hidden');
|
|
9200
|
+
// // }
|
|
9201
|
+
// if (this.isZoomedOut) {
|
|
9202
|
+
// svg
|
|
9203
|
+
// .selectAll('.lib-xaxis-labels-texts-drilldown')
|
|
9204
|
+
// .each((d, i, nodes) => {
|
|
9205
|
+
// const text = d3.select(nodes[i]);
|
|
9206
|
+
// const label = text.text();
|
|
9207
|
+
// if (label.indexOf('\n') > -1) {
|
|
9208
|
+
// const lines = label.split('\n');
|
|
9209
|
+
// text.text(null);
|
|
9210
|
+
// lines.forEach((line, idx) => {
|
|
9211
|
+
// text.append('tspan')
|
|
9212
|
+
// .text(line)
|
|
9213
|
+
// .attr('x', 0)
|
|
9214
|
+
// .attr('dy', idx === 0 ? '1em' : '1.1em');
|
|
9215
|
+
// });
|
|
9216
|
+
// } else {
|
|
9217
|
+
// const words = label.split(' ');
|
|
9218
|
+
// text.text(null);
|
|
9219
|
+
// words.forEach((word, index) => {
|
|
9220
|
+
// text.append('tspan').text(word);
|
|
9221
|
+
// });
|
|
9222
|
+
// }
|
|
9223
|
+
// })
|
|
9224
|
+
// .style('fill', 'var(--chart-text-color)')
|
|
9225
|
+
// .attr('transform', null);
|
|
9226
|
+
// svg
|
|
9227
|
+
// .select('.x-axis')
|
|
9228
|
+
// .attr('transform', `translate(0, ${height - margin.bottom + 10})`);
|
|
9229
|
+
// }
|
|
9230
|
+
// /**
|
|
9231
|
+
// * used to write y labels based on configuration
|
|
9232
|
+
// */
|
|
9233
|
+
// if (metaData.yLabel) {
|
|
9234
|
+
// const yPosition = isria ? 0 - margin.left / 2 - 30 : 0 - margin.left / 2 - 40;
|
|
9235
|
+
// svgYAxisLeft
|
|
9236
|
+
// .append('text')
|
|
9237
|
+
// .attr('class', 'lib-axis-group-label font-size-1')
|
|
9238
|
+
// .attr('style', self.chartConfiguration.yAxisCustomlabelStyles)
|
|
9239
|
+
// .attr('transform', 'rotate(-90)')
|
|
9240
|
+
// .attr('y', yPosition)
|
|
9241
|
+
// .attr('x', 0 - height / 2)
|
|
9242
|
+
// .attr('dy', '1em')
|
|
9243
|
+
// .style('text-anchor', 'middle')
|
|
9244
|
+
// .attr('fill', 'var(--chart-text-color)');
|
|
9245
|
+
// if (this.chartConfiguration.isMultiChartGridLine === undefined) {
|
|
9246
|
+
// svgYAxisLeft
|
|
9247
|
+
// .selectAll('.lib-axis-group-label')
|
|
9248
|
+
// .style('font-size', 'smaller')
|
|
9249
|
+
// .text(metaData.yLabel);
|
|
9250
|
+
// } else {
|
|
9251
|
+
// svg
|
|
9252
|
+
// .selectAll('.lib-axis-group-label')
|
|
9253
|
+
// .attr('class', 'lib-ylabel-weeklyCharts')
|
|
9254
|
+
// .text(metaData.yLabel.toLowerCase());
|
|
9255
|
+
// }
|
|
9256
|
+
// }
|
|
9257
|
+
// if (this.chartData.targetLineData) {
|
|
9258
|
+
// const yZero = y(this.chartData.targetLineData.target);
|
|
9259
|
+
// svg
|
|
9260
|
+
// .append('line')
|
|
9261
|
+
// .attr('x1', 0)
|
|
9262
|
+
// .attr('x2', width)
|
|
9263
|
+
// .attr('y1', yZero)
|
|
9264
|
+
// .attr('y2', yZero)
|
|
9265
|
+
// .style('stroke-dasharray', '5 5')
|
|
9266
|
+
// .style('stroke', this.chartData.targetLineData.color);
|
|
9267
|
+
// // svgYAxisRight
|
|
9268
|
+
// // .append('line')
|
|
9269
|
+
// // .attr('x1', 0)
|
|
9270
|
+
// // .attr('x2', rightSvgWidth)
|
|
9271
|
+
// // .attr('y1', yZero)
|
|
9272
|
+
// // .attr('y2', yZero)
|
|
9273
|
+
// // .style('stroke', this.chartData.targetLineData.color);
|
|
9274
|
+
// svgYAxisRight
|
|
9275
|
+
// .append('foreignObject')
|
|
9276
|
+
// .attr('transform', 'translate(' + 0 + ',' + (yZero - 30) + ')')
|
|
9277
|
+
// .attr('width', rightSvgWidth)
|
|
9278
|
+
// .attr('height', 50)
|
|
9279
|
+
// .append('xhtml:div')
|
|
9280
|
+
// .attr('class', 'target-display')
|
|
9281
|
+
// .style('color', 'var(--chart-text-color)')
|
|
9282
|
+
// .html(function () {
|
|
9283
|
+
// let dataTypeTemp = '';
|
|
9284
|
+
// let targetLineName = 'target';
|
|
9285
|
+
// if (metaData.dataType) {
|
|
9286
|
+
// dataTypeTemp = metaData.dataType;
|
|
9287
|
+
// }
|
|
9288
|
+
// if (
|
|
9289
|
+
// self.chartData.targetLineData &&
|
|
9290
|
+
// self.chartData.targetLineData.targetName
|
|
9291
|
+
// ) {
|
|
9292
|
+
// targetLineName = self.chartData.targetLineData.targetName;
|
|
9293
|
+
// }
|
|
9294
|
+
// return (
|
|
9295
|
+
// `<div>${targetLineName}</div>` +
|
|
9296
|
+
// '<div>' +
|
|
9297
|
+
// self.chartData.targetLineData.target +
|
|
9298
|
+
// '' +
|
|
9299
|
+
// dataTypeTemp +
|
|
9300
|
+
// '</div>'
|
|
9301
|
+
// );
|
|
9302
|
+
// });
|
|
9303
|
+
// }
|
|
9304
|
+
// if (this.chartConfiguration.isDrilldownChart) {
|
|
9305
|
+
// /**
|
|
9306
|
+
// * used by drilldown charts
|
|
9307
|
+
// */
|
|
9308
|
+
// // svg
|
|
9309
|
+
// // .selectAll('.lib-axis-group-label')
|
|
9310
|
+
// // .attr('class', 'lib-ylabel-drilldowncharts')
|
|
9311
|
+
// // .text(metaData.yLabel.toLowerCase());
|
|
9312
|
+
// svg.selectAll('g.x1.axis1 g.tick line').style('display', 'none');
|
|
9313
|
+
// }
|
|
9314
|
+
// if (metaData.xLabel) {
|
|
9315
|
+
// function isAcronym(label) {
|
|
9316
|
+
// return (
|
|
9317
|
+
// (label.length <= 4 && /^[A-Z]+$/.test(label)) ||
|
|
9318
|
+
// (label === label.toUpperCase() && /[A-Z]/.test(label))
|
|
9319
|
+
// );
|
|
9320
|
+
// }
|
|
9321
|
+
// const xLabelText = metaData.xLabel;
|
|
9322
|
+
// const isAcr = isAcronym(xLabelText.replace(/[^A-Za-z]/g, ''));
|
|
9323
|
+
// const xPosition = isria ? (height + margin.top + margin.bottom) : (height + margin.top + margin.bottom + 40);
|
|
9324
|
+
// svg
|
|
9325
|
+
// .append('text')
|
|
9326
|
+
// .attr('class', function () {
|
|
9327
|
+
// let baseClass = 'lib-axis-group-label font-size-1';
|
|
9328
|
+
// if (self.chartConfiguration.isDrilldownChart)
|
|
9329
|
+
// return baseClass + ' lib-xlabel-drilldowncharts';
|
|
9330
|
+
// if (self.chartConfiguration.isMultiChartGridLine != undefined)
|
|
9331
|
+
// return baseClass + ' lib-xlabel-weeklyCharts';
|
|
9332
|
+
// return baseClass + ' lib-axis-waterfall-label';
|
|
9333
|
+
// })
|
|
9334
|
+
// .attr('style', self.chartConfiguration.xAxisCustomlabelStyles)
|
|
9335
|
+
// .attr(
|
|
9336
|
+
// 'transform',
|
|
9337
|
+
// 'translate(' + width / 2 + ' ,' + xPosition + ')'
|
|
9338
|
+
// )
|
|
9339
|
+
// .style('text-anchor', 'middle')
|
|
9340
|
+
// .style('fill', 'var(--chart-text-color)')
|
|
9341
|
+
// .text(isAcr ? xLabelText.toUpperCase() : xLabelText.toLowerCase())
|
|
9342
|
+
// .style('text-transform', isAcr ? 'none' : 'capitalize');
|
|
9343
|
+
// }
|
|
9344
|
+
// if (metaData.lineyLabel) {
|
|
9345
|
+
// svgYAxisRight
|
|
9346
|
+
// .append('text')
|
|
9347
|
+
// .attr('class', 'lib-axis-group-label lib-line-axis')
|
|
9348
|
+
// .attr('fill', 'var(--chart-text-color)')
|
|
9349
|
+
// .attr('style', self.chartConfiguration.yAxisCustomlabelStyles)
|
|
9350
|
+
// .attr('transform', 'translate(0,0) rotate(90)')
|
|
9351
|
+
// .attr('y', 0 - 100)
|
|
9352
|
+
// .attr('x', 0 + 100)
|
|
9353
|
+
// .attr('dy', '5em')
|
|
9354
|
+
// .style('text-anchor', 'middle')
|
|
9355
|
+
// .style('font-size', 'smaller')
|
|
9356
|
+
// .text(metaData.lineyLabel);
|
|
9357
|
+
// }
|
|
9358
|
+
// if (lineData) {
|
|
9359
|
+
// svg
|
|
9360
|
+
// .append('path')
|
|
9361
|
+
// .datum(lineData)
|
|
9362
|
+
// .attr('fill', 'none')
|
|
9363
|
+
// .attr('stroke', self.chartConfiguration.lineGraphColor)
|
|
9364
|
+
// .attr('stroke-width', 1.5)
|
|
9365
|
+
// .attr(
|
|
9366
|
+
// 'd',
|
|
9367
|
+
// d3
|
|
9368
|
+
// .line()
|
|
9369
|
+
// .x(function (d) {
|
|
9370
|
+
// return x(d.name) + x.bandwidth() / 2;
|
|
9371
|
+
// })
|
|
9372
|
+
// .y(function (d) {
|
|
9373
|
+
// return lineYscale(d.value);
|
|
9374
|
+
// })
|
|
9375
|
+
// );
|
|
9376
|
+
// var dot = svg
|
|
9377
|
+
// .selectAll('myCircles')
|
|
9378
|
+
// .data(lineData)
|
|
9379
|
+
// .enter()
|
|
9380
|
+
// .append('g')
|
|
9381
|
+
// .on('click', function (d) {
|
|
9382
|
+
// if (
|
|
9383
|
+
// !metaData.barWithoutClick ||
|
|
9384
|
+
// !metaData.barWithoutClick.length ||
|
|
9385
|
+
// (!metaData.barWithoutClick.includes(d?.name) &&
|
|
9386
|
+
// !metaData.barWithoutClick.includes(d?.key))
|
|
9387
|
+
// )
|
|
9388
|
+
// self.handleClick(d);
|
|
9389
|
+
// });
|
|
9390
|
+
// dot
|
|
9391
|
+
// .append('circle')
|
|
9392
|
+
// .attr('fill', function (d) {
|
|
9393
|
+
// return self.chartConfiguration.lineGraphColor;
|
|
9394
|
+
// })
|
|
9395
|
+
// .attr('stroke', 'none')
|
|
9396
|
+
// .attr('cx', function (d) {
|
|
9397
|
+
// return x(d.name) + x.bandwidth() / 2;
|
|
9398
|
+
// })
|
|
9399
|
+
// .attr('cy', function (d) {
|
|
9400
|
+
// return lineYscale(d.value);
|
|
9401
|
+
// })
|
|
9402
|
+
// .style('cursor', () =>
|
|
9403
|
+
// self.chartData.metaData.hasDrillDown ? 'pointer' : 'default'
|
|
9404
|
+
// )
|
|
9405
|
+
// .attr('r', 3);
|
|
9406
|
+
// if (self.chartConfiguration.lineGraphColor) {
|
|
9407
|
+
// dot
|
|
9408
|
+
// .append('text')
|
|
9409
|
+
// .attr('class', 'dot')
|
|
9410
|
+
// .attr('fill', 'var(--chart-text-color)')
|
|
9411
|
+
// .attr('color', self.chartConfiguration.lineGraphColor)
|
|
9412
|
+
// .attr('style', 'font-size: ' + '.85em')
|
|
9413
|
+
// .attr('x', function (d, i) {
|
|
9414
|
+
// return x(d.name) + x.bandwidth() / 2;
|
|
9415
|
+
// })
|
|
9416
|
+
// .attr('y', function (d) {
|
|
9417
|
+
// return lineYscale(d.value);
|
|
9418
|
+
// })
|
|
9419
|
+
// .attr('dy', '-1em')
|
|
9420
|
+
// .text(function (d) {
|
|
9421
|
+
// return self.chartConfiguration.labelFormatter(d.value);
|
|
9422
|
+
// });
|
|
9423
|
+
// }
|
|
9424
|
+
// }
|
|
9425
|
+
// }
|
|
8190
9426
|
initializegroupChart() {
|
|
8191
|
-
|
|
9427
|
+
// ==================== VARIABLE DECLARATIONS ====================
|
|
9428
|
+
const self = this;
|
|
8192
9429
|
let data = [];
|
|
8193
9430
|
let metaData = null;
|
|
8194
9431
|
let keyList = null;
|
|
8195
9432
|
let lineData = null;
|
|
8196
9433
|
let colorMap = {};
|
|
8197
|
-
|
|
8198
|
-
|
|
9434
|
+
let formatFromBackend;
|
|
9435
|
+
let formatForHugeNumbers;
|
|
9436
|
+
// Device detection
|
|
8199
9437
|
const isMobile = window.innerWidth < 576;
|
|
8200
9438
|
const isTablet = window.innerWidth >= 576 && window.innerWidth < 992;
|
|
8201
9439
|
const isDesktop = window.innerWidth >= 992;
|
|
8202
|
-
|
|
8203
|
-
|
|
8204
|
-
|
|
8205
|
-
|
|
8206
|
-
|
|
8207
|
-
|
|
8208
|
-
|
|
8209
|
-
|
|
8210
|
-
|
|
8211
|
-
|
|
8212
|
-
|
|
8213
|
-
|
|
8214
|
-
|
|
8215
|
-
|
|
8216
|
-
|
|
9440
|
+
const isria = this.customChartConfiguration.isRia;
|
|
9441
|
+
// Chart scale variables
|
|
9442
|
+
let x;
|
|
9443
|
+
let tempScale;
|
|
9444
|
+
// Tick length constants
|
|
9445
|
+
const SHORT_TICK_LENGTH = 4;
|
|
9446
|
+
const LONG_TICK_LENGTH = 16;
|
|
9447
|
+
const SHORT_TICK_LENGTH_BG = 5;
|
|
9448
|
+
const LONG_TICK_LENGTH_BG = 30;
|
|
9449
|
+
const LEFT_AND_RIGHT_SPACES = 50;
|
|
9450
|
+
const RIGHT_SVG_WIDTH = 60;
|
|
9451
|
+
// Flags
|
|
9452
|
+
let alternate_text = false;
|
|
9453
|
+
// ==================== CONFIGURATION SETUP ====================
|
|
9454
|
+
for (const key in this.defaultConfiguration) {
|
|
9455
|
+
this.chartConfiguration[key] = ChartHelper.getValueByConfigurationType(key, this.defaultConfiguration, this.customChartConfiguration);
|
|
8217
9456
|
}
|
|
9457
|
+
// Extract chart data
|
|
8218
9458
|
data = this.chartData.data;
|
|
8219
9459
|
metaData = this.chartData.metaData;
|
|
8220
9460
|
lineData = this.chartData.lineData;
|
|
9461
|
+
// Setup color mappings
|
|
8221
9462
|
if (!metaData.colorAboveTarget) {
|
|
8222
9463
|
metaData['colorAboveTarget'] = metaData.colors;
|
|
8223
9464
|
}
|
|
8224
9465
|
colorMap = metaData.colors;
|
|
8225
9466
|
keyList = metaData.keyList;
|
|
8226
|
-
|
|
8227
|
-
|
|
8228
|
-
|
|
9467
|
+
// ==================== CONTAINER SETUP ====================
|
|
9468
|
+
const chartContainer = d3.select(this.containerElt.nativeElement);
|
|
9469
|
+
const verticalstackedcontainer = d3.select(this.groupcontainerElt.nativeElement);
|
|
9470
|
+
const margin = this.chartConfiguration.margin;
|
|
8229
9471
|
const { width, height } = this.calculateChartDimensions(chartContainer, verticalstackedcontainer, margin, self);
|
|
8230
|
-
|
|
9472
|
+
// ==================== VISIBILITY CONFIGURATION ====================
|
|
9473
|
+
if (this.chartConfiguration.isHeaderVisible !== undefined) {
|
|
8231
9474
|
this.isHeaderVisible = this.chartConfiguration.isHeaderVisible;
|
|
8232
|
-
|
|
9475
|
+
}
|
|
9476
|
+
if (this.chartConfiguration.legendVisible !== undefined) {
|
|
8233
9477
|
this.legendVisible = this.chartConfiguration.legendVisible;
|
|
8234
9478
|
}
|
|
8235
|
-
if (this.chartConfiguration.isTransparentBackground
|
|
8236
|
-
this.isTransparentBackground =
|
|
8237
|
-
this.chartConfiguration.isTransparentBackground;
|
|
9479
|
+
if (this.chartConfiguration.isTransparentBackground !== undefined) {
|
|
9480
|
+
this.isTransparentBackground = this.chartConfiguration.isTransparentBackground;
|
|
8238
9481
|
}
|
|
8239
|
-
|
|
9482
|
+
// ==================== DATA FORMATTING ====================
|
|
9483
|
+
if (this.chartConfiguration.textFormatter !== undefined) {
|
|
8240
9484
|
formatFromBackend = ChartHelper.dataValueFormatter(this.chartConfiguration.textFormatter);
|
|
8241
9485
|
formatForHugeNumbers = ChartHelper.dataValueFormatter('.2s');
|
|
8242
9486
|
}
|
|
8243
|
-
|
|
8244
|
-
|
|
8245
|
-
|
|
8246
|
-
|
|
8247
|
-
|
|
8248
|
-
|
|
8249
|
-
|
|
8250
|
-
|
|
8251
|
-
x = d3
|
|
8252
|
-
.scaleBand()
|
|
9487
|
+
// ==================== SVG CONTAINERS CREATION ====================
|
|
9488
|
+
const { outerContainer, svgYAxisLeft, svgYAxisRight, innerContainer, svg } = this.createChartContainers(chartContainer, margin, height, RIGHT_SVG_WIDTH, self, width);
|
|
9489
|
+
// ==================== SCALES SETUP ====================
|
|
9490
|
+
const subgroups = keyList;
|
|
9491
|
+
const groups = d3.map(data, (d) => d.name).keys();
|
|
9492
|
+
// X-axis scale configuration
|
|
9493
|
+
if (this.chartConfiguration.isMultiChartGridLine !== undefined) {
|
|
9494
|
+
x = d3.scaleBand()
|
|
8253
9495
|
.rangeRound([width, 0])
|
|
8254
9496
|
.align(0.5)
|
|
8255
9497
|
.padding([0.5])
|
|
8256
|
-
.domain(data.map(
|
|
8257
|
-
return d.name.toLowerCase();
|
|
8258
|
-
}));
|
|
9498
|
+
.domain(data.map((d) => d.name.toLowerCase()));
|
|
8259
9499
|
}
|
|
8260
9500
|
else {
|
|
8261
|
-
x = d3
|
|
8262
|
-
.scaleBand()
|
|
9501
|
+
x = d3.scaleBand()
|
|
8263
9502
|
.domain(groups)
|
|
8264
|
-
.range([
|
|
9503
|
+
.range([LEFT_AND_RIGHT_SPACES, width - RIGHT_SVG_WIDTH - LEFT_AND_RIGHT_SPACES])
|
|
8265
9504
|
.padding([0.3]);
|
|
8266
9505
|
}
|
|
8267
|
-
|
|
8268
|
-
.scaleBand()
|
|
9506
|
+
const xScaleFromOrigin = d3.scaleBand()
|
|
8269
9507
|
.domain(groups)
|
|
8270
|
-
.range([0, width -
|
|
8271
|
-
|
|
8272
|
-
this.
|
|
8273
|
-
|
|
8274
|
-
|
|
8275
|
-
maxValue = this.calculateMaxValue(
|
|
9508
|
+
.range([0, width - RIGHT_SVG_WIDTH]);
|
|
9509
|
+
// ==================== X-AXIS RENDERING ====================
|
|
9510
|
+
this.renderXAxis(svg, x, height, metaData, subgroups, data, SHORT_TICK_LENGTH_BG, LONG_TICK_LENGTH_BG, self, isria, isMobile);
|
|
9511
|
+
// ==================== Y-AXIS SETUP ====================
|
|
9512
|
+
const y = d3.scaleLinear().rangeRound([height, 0]);
|
|
9513
|
+
let maxValue = this.calculateMaxValue(data, keyList);
|
|
8276
9514
|
if (this.chartConfiguration.customYscale) {
|
|
8277
9515
|
maxValue = maxValue * this.chartConfiguration.customYscale;
|
|
8278
9516
|
}
|
|
8279
|
-
if (this.chartData.targetLineData &&
|
|
8280
|
-
maxValue < this.chartData.targetLineData.target
|
|
8281
|
-
|
|
8282
|
-
|
|
8283
|
-
? this.chartData.targetLineData.target + 3
|
|
8284
|
-
: this.chartData.targetLineData.target + 20;
|
|
9517
|
+
if (this.chartData.targetLineData && maxValue < this.chartData.targetLineData.target) {
|
|
9518
|
+
maxValue = maxValue < 10 && this.chartData.targetLineData.target < 10
|
|
9519
|
+
? this.chartData.targetLineData.target + 3
|
|
9520
|
+
: this.chartData.targetLineData.target + 20;
|
|
8285
9521
|
}
|
|
8286
9522
|
y.domain([0, maxValue]).nice();
|
|
9523
|
+
// ==================== LINE CHART Y-SCALE ====================
|
|
8287
9524
|
let lineYscale;
|
|
9525
|
+
let yLineAxis;
|
|
8288
9526
|
if (lineData != null) {
|
|
8289
|
-
|
|
8290
|
-
|
|
9527
|
+
const result = this.setupLineYScale(lineData, height, self);
|
|
9528
|
+
lineYscale = result.lineYscale;
|
|
9529
|
+
yLineAxis = result.yLineAxis;
|
|
9530
|
+
}
|
|
9531
|
+
// ==================== GRID LINES ====================
|
|
9532
|
+
this.renderGridLines(svg, x, y, height, width, self);
|
|
9533
|
+
// ==================== BARS RENDERING ====================
|
|
9534
|
+
const xSubgroup = this.setupXSubgroupScale(subgroups, x, self);
|
|
9535
|
+
const color = d3.scaleOrdinal()
|
|
9536
|
+
.domain(subgroups)
|
|
9537
|
+
.range(Object.values(metaData.colors));
|
|
9538
|
+
this.renderBars(svg, data, subgroups, x, xSubgroup, y, height, color, metaData, self, LEFT_AND_RIGHT_SPACES, tempScale, isria);
|
|
9539
|
+
// ==================== BAR LABELS ====================
|
|
9540
|
+
if (this.chartConfiguration.textsOnBar !== undefined && !this.isZoomedOut) {
|
|
9541
|
+
this.renderBarLabels(svg, data, subgroups, x, xSubgroup, y, height, metaData, self, tempScale, isria);
|
|
9542
|
+
}
|
|
9543
|
+
// ==================== Y-AXIS RENDERING ====================
|
|
9544
|
+
this.renderYAxis(svg, svgYAxisLeft, svgYAxisRight, y, yLineAxis, lineData, self, isria, margin);
|
|
9545
|
+
// ==================== AXIS LABELS ====================
|
|
9546
|
+
this.renderAxisLabels(svg, svgYAxisLeft, svgYAxisRight, metaData, width, height, margin, self, isria, RIGHT_SVG_WIDTH);
|
|
9547
|
+
// ==================== TARGET LINE ====================
|
|
9548
|
+
if (this.chartData.targetLineData) {
|
|
9549
|
+
this.renderTargetLine(svg, svgYAxisRight, y, width, RIGHT_SVG_WIDTH, metaData, self);
|
|
9550
|
+
}
|
|
9551
|
+
// ==================== LINE CHART ====================
|
|
9552
|
+
if (lineData) {
|
|
9553
|
+
this.renderLineChart(svg, lineData, x, lineYscale, metaData, self);
|
|
9554
|
+
}
|
|
9555
|
+
// ==================== ZOOM HANDLING ====================
|
|
9556
|
+
if (this.isZoomedOut) {
|
|
9557
|
+
this.handleZoomOut(svg, height, margin);
|
|
9558
|
+
}
|
|
9559
|
+
}
|
|
9560
|
+
// ==================== HELPER METHODS ====================
|
|
9561
|
+
renderXAxis(svg, x, height, metaData, subgroups, data, shortTickLengthBg, longTickLengthBg, self, isria, isMobile) {
|
|
9562
|
+
let alternate_text = false;
|
|
9563
|
+
if (this.chartConfiguration.isMultiChartGridLine === undefined) {
|
|
9564
|
+
// Normal ticks for dashboard charts
|
|
9565
|
+
svg.append('g')
|
|
9566
|
+
.attr('class', 'x1 axis1')
|
|
9567
|
+
.attr('transform', `translate(0,${height})`)
|
|
9568
|
+
.call(d3.axisBottom(x))
|
|
9569
|
+
.call((g) => g.select('.domain').remove());
|
|
9570
|
+
svg.selectAll('g.x1.axis1 g.tick line').remove();
|
|
9571
|
+
const yOffset = subgroups.length > 1 && !metaData.xLabel ? 32 : 0;
|
|
9572
|
+
svg.selectAll('g.x1.axis1 g.tick text')
|
|
9573
|
+
.attr('class', 'lib-xaxis-labels-texts-drilldown')
|
|
9574
|
+
.style('fill', 'var(--chart-text-color)')
|
|
9575
|
+
.attr('y', yOffset || null);
|
|
9576
|
+
}
|
|
9577
|
+
else {
|
|
9578
|
+
// Bigger ticks for weekly charts
|
|
9579
|
+
svg.append('g')
|
|
9580
|
+
.attr('class', 'x1 axis1')
|
|
9581
|
+
.attr('transform', `translate(0,${height})`)
|
|
9582
|
+
.call(d3.axisBottom(x).tickSize(0))
|
|
9583
|
+
.call((g) => g.select('.domain').attr('fill', 'none'));
|
|
9584
|
+
// Alternate tick line sizes
|
|
9585
|
+
svg.selectAll('g.x1.axis1 g.tick line').attr('y2', function () {
|
|
9586
|
+
if (alternate_text && self.chartConfiguration.isNoAlternateXaxisText === undefined) {
|
|
9587
|
+
alternate_text = false;
|
|
9588
|
+
return longTickLengthBg - 7;
|
|
9589
|
+
}
|
|
9590
|
+
else {
|
|
9591
|
+
alternate_text = true;
|
|
9592
|
+
return shortTickLengthBg - 4;
|
|
9593
|
+
}
|
|
8291
9594
|
});
|
|
8292
|
-
|
|
8293
|
-
|
|
8294
|
-
|
|
9595
|
+
alternate_text = false;
|
|
9596
|
+
// X-axis label texts
|
|
9597
|
+
svg.selectAll('g.x1.axis1 g.tick text')
|
|
9598
|
+
.attr('class', 'lib-xaxis-labels-texts-weeklycharts')
|
|
9599
|
+
.attr('y', function () {
|
|
9600
|
+
if (self.chartConfiguration.isFullScreen) {
|
|
9601
|
+
return shortTickLengthBg;
|
|
9602
|
+
}
|
|
9603
|
+
if (alternate_text) {
|
|
9604
|
+
alternate_text = false;
|
|
9605
|
+
return longTickLengthBg;
|
|
9606
|
+
}
|
|
9607
|
+
else {
|
|
9608
|
+
alternate_text = true;
|
|
9609
|
+
return shortTickLengthBg;
|
|
9610
|
+
}
|
|
8295
9611
|
});
|
|
8296
|
-
|
|
8297
|
-
|
|
8298
|
-
|
|
8299
|
-
|
|
9612
|
+
}
|
|
9613
|
+
// Apply labels on same line configuration
|
|
9614
|
+
if (self.chartConfiguration.xLabelsOnSameLine) {
|
|
9615
|
+
this.applyXLabelsOnSameLine(svg, subgroups, data, metaData, self, shortTickLengthBg, isMobile, isria);
|
|
9616
|
+
}
|
|
9617
|
+
// Mobile override for RIA
|
|
9618
|
+
if (isria && self.chartData.data.length > 8) {
|
|
9619
|
+
svg.selectAll('g.x1.axis1 g.tick text')
|
|
9620
|
+
.classed('mobile-xaxis-override', true)
|
|
9621
|
+
.text((d) => d.substring(0, 3))
|
|
9622
|
+
.style('font-size', '12px')
|
|
9623
|
+
.attr('y', 5)
|
|
9624
|
+
.attr('x', 5)
|
|
9625
|
+
.style('text-anchor', 'middle');
|
|
9626
|
+
}
|
|
9627
|
+
// Mobile override
|
|
9628
|
+
if (isMobile && !this.isHeaderVisible) {
|
|
9629
|
+
svg.selectAll('g.x1.axis1 g.tick text')
|
|
9630
|
+
.classed('mobile-xaxis-override', true);
|
|
9631
|
+
}
|
|
9632
|
+
}
|
|
9633
|
+
applyXLabelsOnSameLine(svg, subgroups, data, metaData, self, shortTickLengthBg, isMobile, isria) {
|
|
9634
|
+
const xAxisLabels = svg.selectAll('g.x1.axis1 g.tick text')
|
|
9635
|
+
.attr('class', 'lib-xaxis-labels-texts-drilldown')
|
|
9636
|
+
.style('font-size', this.isHeaderVisible ? '18px' : '14px')
|
|
9637
|
+
.attr('text-anchor', 'middle')
|
|
9638
|
+
.attr('y', (d) => this.calculateXLabelYPosition(d, subgroups, data, metaData, self, shortTickLengthBg))
|
|
9639
|
+
.attr('x', (d) => (self.chartData.data.length > 8 && !self.isZoomedOut) ? 1 : 0)
|
|
9640
|
+
.text((d) => this.formatXLabelText(d, data, metaData, subgroups, self, isMobile));
|
|
9641
|
+
// Apply writing-mode for grouped charts with date labels in zoomed-out view
|
|
9642
|
+
xAxisLabels.each(function (d) {
|
|
9643
|
+
const isDateLabel = /^(\d{2,4}[-\/])?\d{2,4}[-\/]\d{2,4}$/.test(d.trim());
|
|
9644
|
+
const isWeekLabel = /week|wk|w\d+/i.test(d);
|
|
9645
|
+
if (subgroups.length > 1 && self.isZoomedOut && data.length > 8 && isDateLabel && !isWeekLabel) {
|
|
9646
|
+
d3.select(this).style('writing-mode', 'sideways-lr');
|
|
8300
9647
|
}
|
|
8301
|
-
|
|
8302
|
-
|
|
8303
|
-
|
|
8304
|
-
|
|
9648
|
+
});
|
|
9649
|
+
// Add second line for non-date labels on desktop
|
|
9650
|
+
if (!isMobile) {
|
|
9651
|
+
svg.selectAll('g.x1.axis1 g.tick')
|
|
9652
|
+
.filter((d) => !/\d{2,4}[-\/]/.test(d))
|
|
9653
|
+
.append('text')
|
|
9654
|
+
.attr('class', 'lib-xaxis-labels-texts-drilldown')
|
|
9655
|
+
.attr('y', 30)
|
|
9656
|
+
.attr('fill', 'var(--chart-text-color)')
|
|
9657
|
+
.attr('x', (d) => (self.chartData.data.length > 8 && !self.isZoomedOut) ? 1 : 0)
|
|
9658
|
+
.text((d) => {
|
|
9659
|
+
if (d.trim().indexOf(' ') > -1) {
|
|
9660
|
+
return d.trim().substring(d.indexOf(' '), d.length).toLowerCase();
|
|
9661
|
+
}
|
|
9662
|
+
return '';
|
|
9663
|
+
});
|
|
8305
9664
|
}
|
|
8306
|
-
|
|
8307
|
-
|
|
8308
|
-
|
|
8309
|
-
|
|
8310
|
-
|
|
8311
|
-
|
|
8312
|
-
|
|
9665
|
+
}
|
|
9666
|
+
calculateXLabelYPosition(d, subgroups, data, metaData, self, shortTickLengthBg) {
|
|
9667
|
+
// For grouped bar charts with many bars and xLabel present
|
|
9668
|
+
if (subgroups.length > 1 && data.length > 8 && metaData.xLabel) {
|
|
9669
|
+
const isDateLabel = /\d{2,4}[-\/]/.test(d);
|
|
9670
|
+
return isDateLabel ? shortTickLengthBg + 14 : shortTickLengthBg;
|
|
9671
|
+
}
|
|
9672
|
+
// For grouped bar charts with many bars and NO xLabel
|
|
9673
|
+
if (subgroups.length > 1 && data.length > 8 && !metaData.xLabel) {
|
|
9674
|
+
const chartHasExtraBottom = self.chartConfiguration.margin && self.chartConfiguration.margin.bottom >= 40;
|
|
9675
|
+
if (self.chartConfiguration.isFullScreen) {
|
|
9676
|
+
return shortTickLengthBg + 2;
|
|
9677
|
+
}
|
|
9678
|
+
return chartHasExtraBottom ? shortTickLengthBg : shortTickLengthBg + 10;
|
|
9679
|
+
}
|
|
9680
|
+
// Default/fallback logic
|
|
9681
|
+
let baseY = self.isHeaderVisible ? shortTickLengthBg + 25 : shortTickLengthBg;
|
|
9682
|
+
if (subgroups.length > 1 && !metaData.xLabel &&
|
|
9683
|
+
(/\d{2,4}[-\/]\d{2}[-\/]\d{2,4}/.test(d) || /\d{2,4}[-\/]\d{2,4}/.test(d))) {
|
|
9684
|
+
baseY = self.isHeaderVisible ? shortTickLengthBg + 15 : shortTickLengthBg + 25;
|
|
9685
|
+
}
|
|
9686
|
+
if (/\d{2,4}[-\/]\d{2,4}/.test(d) && d.indexOf(' ') > -1) {
|
|
9687
|
+
baseY += 4;
|
|
9688
|
+
}
|
|
9689
|
+
if (self.chartConfiguration.isFullScreen && subgroups.length > 1) {
|
|
9690
|
+
baseY = Math.max(shortTickLengthBg, baseY - 10);
|
|
9691
|
+
}
|
|
9692
|
+
return baseY;
|
|
9693
|
+
}
|
|
9694
|
+
formatXLabelText(d, data, metaData, subgroups, self, isMobile) {
|
|
9695
|
+
if (isMobile && !self.isHeaderVisible) {
|
|
9696
|
+
const firstPart = d.split(/[\s\-]+/)[0];
|
|
9697
|
+
return firstPart.substring(0, 3).toLowerCase();
|
|
9698
|
+
}
|
|
9699
|
+
// Check if value should be ignored
|
|
9700
|
+
const isValueToBeIgnored = data.some((indiv) => indiv.name && indiv.name.toLowerCase() === d.trim().toLowerCase() &&
|
|
9701
|
+
indiv[metaData.keyList[0]] === -1);
|
|
9702
|
+
if (isValueToBeIgnored) {
|
|
9703
|
+
return '';
|
|
9704
|
+
}
|
|
9705
|
+
// Handle date range labels
|
|
9706
|
+
const dateRangeRegex = /(\d{2,4}[-\/]\d{2}[-\/]\d{2,4})\s*-\s*(\d{2,4}[-\/]\d{2}[-\/]\d{2,4})/;
|
|
9707
|
+
if (dateRangeRegex.test(d.trim())) {
|
|
9708
|
+
return d.trim().replace(dateRangeRegex, (m, d1, d2) => `${d1} - ${d2}`);
|
|
9709
|
+
}
|
|
9710
|
+
// Split date and week labels into two lines
|
|
9711
|
+
const isDateLabel = /\d{2,4}[-\/]/.test(d);
|
|
9712
|
+
const isWeekLabel = /week|wk|w\d+/i.test(d);
|
|
9713
|
+
if (subgroups.length > 1 && !self.isZoomedOut && data.length > 8 &&
|
|
9714
|
+
d.indexOf(' ') > -1 && (isDateLabel || isWeekLabel)) {
|
|
9715
|
+
const first = d.substring(0, d.indexOf(' '));
|
|
9716
|
+
const second = d.substring(d.indexOf(' ') + 1).trim();
|
|
9717
|
+
return `${first}\n${second}`;
|
|
9718
|
+
}
|
|
9719
|
+
// Handle date labels in minimized view
|
|
9720
|
+
if (isDateLabel) {
|
|
9721
|
+
if (!self.isHeaderVisible && data.length > 8 && d.indexOf(' ') > -1) {
|
|
9722
|
+
const first = d.substring(0, d.indexOf(' '));
|
|
9723
|
+
const second = d.substring(d.indexOf(' ') + 1).trim();
|
|
9724
|
+
return `${first}\n${second}`;
|
|
9725
|
+
}
|
|
9726
|
+
return d;
|
|
9727
|
+
}
|
|
9728
|
+
// Handle labels with spaces
|
|
9729
|
+
if (d.trim().indexOf(' ') > -1) {
|
|
9730
|
+
return d.trim().substring(0, d.indexOf(' ')).toLowerCase();
|
|
9731
|
+
}
|
|
9732
|
+
return d.toLowerCase();
|
|
9733
|
+
}
|
|
9734
|
+
calculateMaxValue(data, keyList) {
|
|
9735
|
+
let maxValue = d3.max(data, (d) => d3.max(keyList, (key) => +d[key]));
|
|
9736
|
+
if (maxValue === 0) {
|
|
9737
|
+
if (this.chartData.targetLineData) {
|
|
9738
|
+
maxValue = this.chartData.targetLineData.target + 20;
|
|
9739
|
+
}
|
|
9740
|
+
else {
|
|
9741
|
+
maxValue = 100;
|
|
9742
|
+
}
|
|
8313
9743
|
}
|
|
9744
|
+
return maxValue;
|
|
9745
|
+
}
|
|
9746
|
+
setupLineYScale(lineData, height, self) {
|
|
9747
|
+
let maxLineValue = d3.max(lineData, (d) => +d.value);
|
|
9748
|
+
maxLineValue = maxLineValue * self.chartConfiguration.customYscale;
|
|
9749
|
+
let minLineValue = d3.min(lineData, (d) => +d.value);
|
|
9750
|
+
if (maxLineValue > 0)
|
|
9751
|
+
minLineValue = minLineValue - 3;
|
|
9752
|
+
if (minLineValue > 0)
|
|
9753
|
+
minLineValue = 0;
|
|
9754
|
+
const lineYscale = d3.scaleLinear()
|
|
9755
|
+
.domain([minLineValue, maxLineValue])
|
|
9756
|
+
.range([height, minLineValue]);
|
|
9757
|
+
const yLineAxis = d3.axisRight(lineYscale)
|
|
9758
|
+
.ticks(self.chartConfiguration.numberOfYTicks)
|
|
9759
|
+
.tickSize(0)
|
|
9760
|
+
.tickFormat(self.chartConfiguration.yLineAxisLabelFomatter);
|
|
9761
|
+
return { lineYscale, yLineAxis };
|
|
9762
|
+
}
|
|
9763
|
+
renderGridLines(svg, x, y, height, width, self) {
|
|
9764
|
+
// X-axis grid between labels
|
|
8314
9765
|
if (self.chartConfiguration.isXgridBetweenLabels) {
|
|
8315
|
-
svg
|
|
8316
|
-
.append('g')
|
|
9766
|
+
svg.append('g')
|
|
8317
9767
|
.attr('class', 'grid')
|
|
8318
|
-
.attr('transform',
|
|
9768
|
+
.attr('transform', `translate(${x.bandwidth() / 2},${height})`)
|
|
8319
9769
|
.call(d3.axisBottom(x).tickSize(-height).tickFormat(''))
|
|
8320
9770
|
.style('stroke-dasharray', '5 5')
|
|
8321
9771
|
.style('color', 'var(--chart-grid-color, #999999)')
|
|
8322
9772
|
.call((g) => g.select('.domain').remove());
|
|
8323
9773
|
}
|
|
9774
|
+
// Y-axis grid
|
|
8324
9775
|
if (this.chartConfiguration.yAxisGrid) {
|
|
8325
|
-
svg
|
|
8326
|
-
.
|
|
8327
|
-
.call(d3
|
|
8328
|
-
.axisLeft(y)
|
|
8329
|
-
.ticks(self.chartConfiguration.numberOfYTicks)
|
|
8330
|
-
.tickSize(-width))
|
|
9776
|
+
svg.append('g')
|
|
9777
|
+
.call(d3.axisLeft(y).ticks(self.chartConfiguration.numberOfYTicks).tickSize(-width))
|
|
8331
9778
|
.style('color', 'var(--chart-axis-color, #B9B9B9)')
|
|
8332
9779
|
.style('opacity', '0.5')
|
|
8333
|
-
.call((g) =>
|
|
8334
|
-
g.select('.domain')
|
|
8335
|
-
.remove()
|
|
8336
|
-
.style('stroke', 'var(--chart-domain-color, #000000)');
|
|
8337
|
-
});
|
|
9780
|
+
.call((g) => g.select('.domain').remove().style('stroke', 'var(--chart-domain-color, #000000)'));
|
|
8338
9781
|
}
|
|
8339
9782
|
else {
|
|
8340
|
-
svg
|
|
8341
|
-
.append('g')
|
|
9783
|
+
svg.append('g')
|
|
8342
9784
|
.call(d3.axisLeft(y).ticks(self.chartConfiguration.numberOfYTicks))
|
|
8343
9785
|
.style('color', 'var(--chart-axis-color, #B9B9B9)')
|
|
8344
9786
|
.style('opacity', '0.5')
|
|
8345
|
-
.call((g) =>
|
|
8346
|
-
|
|
8347
|
-
|
|
8348
|
-
.style('stroke-width', '1px');
|
|
8349
|
-
});
|
|
9787
|
+
.call((g) => g.select('.domain')
|
|
9788
|
+
.style('stroke', 'var(--chart-domain-color, #000000)')
|
|
9789
|
+
.style('stroke-width', '1px'));
|
|
8350
9790
|
}
|
|
8351
|
-
|
|
9791
|
+
}
|
|
9792
|
+
setupXSubgroupScale(subgroups, x, self) {
|
|
9793
|
+
const xSubgroup = d3.scaleBand().domain(subgroups);
|
|
8352
9794
|
if (subgroups.length > 1 && !this.isZoomedOut) {
|
|
8353
9795
|
xSubgroup.range([0, x.bandwidth()]);
|
|
8354
9796
|
}
|
|
8355
9797
|
else if (subgroups.length === 1 && !this.isZoomedOut) {
|
|
8356
9798
|
xSubgroup.range([0, 100]);
|
|
8357
9799
|
}
|
|
8358
|
-
else if (this.chartConfiguration.isMultiChartGridLine
|
|
9800
|
+
else if (this.chartConfiguration.isMultiChartGridLine === undefined) {
|
|
8359
9801
|
xSubgroup.range([0, x.bandwidth()]);
|
|
8360
9802
|
}
|
|
8361
9803
|
else {
|
|
8362
9804
|
xSubgroup.range([0, x.bandwidth()]);
|
|
8363
9805
|
}
|
|
8364
|
-
|
|
8365
|
-
|
|
8366
|
-
|
|
8367
|
-
|
|
8368
|
-
var state = svg
|
|
8369
|
-
.append('g')
|
|
9806
|
+
return xSubgroup;
|
|
9807
|
+
}
|
|
9808
|
+
renderBars(svg, data, subgroups, x, xSubgroup, y, height, color, metaData, self, leftAndRightSpaces, tempScale, isria) {
|
|
9809
|
+
const state = svg.append('g')
|
|
8370
9810
|
.selectAll('.state')
|
|
8371
9811
|
.data(data)
|
|
8372
9812
|
.enter()
|
|
8373
9813
|
.append('g')
|
|
8374
|
-
.attr('transform',
|
|
8375
|
-
|
|
8376
|
-
|
|
8377
|
-
state
|
|
8378
|
-
.selectAll('rect')
|
|
8379
|
-
.data(function (d) {
|
|
8380
|
-
let newList = [];
|
|
8381
|
-
subgroups.map(function (key) {
|
|
8382
|
-
// if (key !== "group") {
|
|
8383
|
-
let obj = { key: key, value: d[key], name: d.name };
|
|
8384
|
-
newList.push(obj);
|
|
8385
|
-
// }
|
|
8386
|
-
});
|
|
8387
|
-
return newList;
|
|
8388
|
-
})
|
|
9814
|
+
.attr('transform', (d) => `translate(${x(d.name)},0)`);
|
|
9815
|
+
const bars = state.selectAll('rect')
|
|
9816
|
+
.data((d) => this.prepareBarData(d, subgroups))
|
|
8389
9817
|
.enter()
|
|
8390
9818
|
.append('rect')
|
|
8391
9819
|
.attr('class', 'bars')
|
|
8392
|
-
.on('click',
|
|
8393
|
-
|
|
8394
|
-
|
|
8395
|
-
|
|
8396
|
-
|
|
8397
|
-
|
|
8398
|
-
|
|
8399
|
-
|
|
8400
|
-
|
|
8401
|
-
|
|
8402
|
-
|
|
8403
|
-
|
|
8404
|
-
|
|
8405
|
-
|
|
8406
|
-
|
|
8407
|
-
|
|
8408
|
-
|
|
8409
|
-
|
|
8410
|
-
|
|
8411
|
-
|
|
8412
|
-
|
|
8413
|
-
|
|
8414
|
-
|
|
8415
|
-
|
|
8416
|
-
|
|
8417
|
-
|
|
8418
|
-
|
|
8419
|
-
|
|
8420
|
-
}
|
|
8421
|
-
else
|
|
8422
|
-
tempScale.range([
|
|
8423
|
-
0 + (x.bandwidth() - reducedBarWidth) / 2,
|
|
8424
|
-
x.bandwidth() - (x.bandwidth() - reducedBarWidth) / 2,
|
|
8425
|
-
]);
|
|
8426
|
-
}
|
|
8427
|
-
else
|
|
8428
|
-
tempScale.range([
|
|
8429
|
-
0 + (x.bandwidth() - reducedBarWidth) / 2,
|
|
8430
|
-
x.bandwidth() - (x.bandwidth() - reducedBarWidth) / 2,
|
|
8431
|
-
]);
|
|
8432
|
-
}
|
|
8433
|
-
}
|
|
8434
|
-
});
|
|
8435
|
-
return tempScale(d.key);
|
|
8436
|
-
}
|
|
8437
|
-
return xSubgroup(d.key);
|
|
8438
|
-
})
|
|
8439
|
-
.attr('y', function (d) {
|
|
8440
|
-
if (d.value == -1) {
|
|
8441
|
-
return y(0);
|
|
9820
|
+
.on('click', (d) => this.handleBarClick(d, metaData, self))
|
|
9821
|
+
.attr('x', (d) => this.calculateBarX(d, data, x, xSubgroup, self, tempScale))
|
|
9822
|
+
.attr('y', (d) => this.calculateBarY(d, y, height, self))
|
|
9823
|
+
.attr('width', (d) => this.calculateBarWidth(d, data, subgroups, x, xSubgroup, self, tempScale))
|
|
9824
|
+
.attr('height', (d) => this.calculateBarHeight(d, y, height, self))
|
|
9825
|
+
.style('cursor', () => (metaData.hasDrillDown && !isria) ? 'pointer' : 'default')
|
|
9826
|
+
.attr('fill', (d) => this.getBarColor(d, metaData, self));
|
|
9827
|
+
// Attach mouse events if not RIA
|
|
9828
|
+
if (!isria && (this.chartConfiguration.displayTitleOnTop ||
|
|
9829
|
+
(this.chartConfiguration.textsOnBar === undefined &&
|
|
9830
|
+
this.chartConfiguration.displayTitleOnTop === undefined))) {
|
|
9831
|
+
bars.on('mouseout', (d, i) => this.handleMouseOut(svg))
|
|
9832
|
+
.on('mouseover', (d, i) => this.handleMouseOver(d, svg, data, x, y, height, metaData, self, leftAndRightSpaces, tempScale));
|
|
9833
|
+
}
|
|
9834
|
+
}
|
|
9835
|
+
prepareBarData(d, subgroups) {
|
|
9836
|
+
const newList = [];
|
|
9837
|
+
subgroups.forEach((key) => {
|
|
9838
|
+
newList.push({ key: key, value: d[key], name: d.name });
|
|
9839
|
+
});
|
|
9840
|
+
return newList;
|
|
9841
|
+
}
|
|
9842
|
+
handleBarClick(d, metaData, self) {
|
|
9843
|
+
if (d.key !== 'Target') {
|
|
9844
|
+
if (!metaData.barWithoutClick || !metaData.barWithoutClick.length ||
|
|
9845
|
+
(!metaData.barWithoutClick.includes(d?.name) &&
|
|
9846
|
+
!metaData.barWithoutClick.includes(d?.key))) {
|
|
9847
|
+
self.handleClick(d);
|
|
8442
9848
|
}
|
|
8443
|
-
|
|
8444
|
-
|
|
8445
|
-
|
|
8446
|
-
|
|
9849
|
+
}
|
|
9850
|
+
}
|
|
9851
|
+
calculateBarX(d, data, x, xSubgroup, self, tempScale) {
|
|
9852
|
+
if (self.chartConfiguration.isDrilldownChart) {
|
|
9853
|
+
return this.calculateDrilldownBarX(d, data, x, self, tempScale);
|
|
9854
|
+
}
|
|
9855
|
+
return xSubgroup(d.key);
|
|
9856
|
+
}
|
|
9857
|
+
calculateDrilldownBarX(d, data, x, self, tempScale) {
|
|
9858
|
+
data.forEach((indiv) => {
|
|
9859
|
+
if (indiv.name === d.name) {
|
|
9860
|
+
const keys = Object.keys(indiv).filter((temp, i) => i !== 0);
|
|
9861
|
+
tempScale = d3.scaleBand().domain(keys).range([0, x.bandwidth()]);
|
|
9862
|
+
if (x.bandwidth() > 100) {
|
|
9863
|
+
const reducedBarWidth = self.isZoomedOut ? 60 : 30;
|
|
9864
|
+
const offset = (x.bandwidth() - reducedBarWidth) / 2;
|
|
9865
|
+
tempScale.range([offset, x.bandwidth() - offset]);
|
|
9866
|
+
}
|
|
8447
9867
|
}
|
|
9868
|
+
});
|
|
9869
|
+
return tempScale(d.key);
|
|
9870
|
+
}
|
|
9871
|
+
calculateBarY(d, y, height, self) {
|
|
9872
|
+
if (d.value === -1) {
|
|
8448
9873
|
return y(0);
|
|
8449
|
-
}
|
|
8450
|
-
|
|
8451
|
-
|
|
8452
|
-
|
|
8453
|
-
|
|
8454
|
-
|
|
8455
|
-
|
|
8456
|
-
|
|
8457
|
-
|
|
8458
|
-
|
|
8459
|
-
|
|
8460
|
-
|
|
8461
|
-
|
|
8462
|
-
|
|
8463
|
-
|
|
8464
|
-
|
|
8465
|
-
|
|
8466
|
-
|
|
8467
|
-
|
|
8468
|
-
|
|
8469
|
-
|
|
8470
|
-
|
|
8471
|
-
|
|
8472
|
-
|
|
8473
|
-
|
|
8474
|
-
|
|
8475
|
-
|
|
8476
|
-
|
|
8477
|
-
]);
|
|
8478
|
-
}
|
|
8479
|
-
else
|
|
8480
|
-
tempScale.range([
|
|
8481
|
-
0 + (x.bandwidth() - reducedBarWidth) / 2,
|
|
8482
|
-
x.bandwidth() - (x.bandwidth() - reducedBarWidth) / 2,
|
|
8483
|
-
]);
|
|
8484
|
-
}
|
|
8485
|
-
else
|
|
8486
|
-
tempScale.range([
|
|
8487
|
-
0 + (x.bandwidth() - reducedBarWidth) / 2,
|
|
8488
|
-
x.bandwidth() - (x.bandwidth() - reducedBarWidth) / 2,
|
|
8489
|
-
]);
|
|
8490
|
-
}
|
|
8491
|
-
}
|
|
8492
|
-
});
|
|
8493
|
-
return self.isZoomedOut
|
|
8494
|
-
? tempScale.bandwidth()
|
|
8495
|
-
: self.chartData.data.length && self.chartData.data.length > 8
|
|
8496
|
-
? tempScale.bandwidth()
|
|
8497
|
-
: tempScale.bandwidth();
|
|
8498
|
-
}
|
|
8499
|
-
return self.isZoomedOut
|
|
8500
|
-
? tempScale.bandwidth()
|
|
8501
|
-
: self.chartData.data.length && self.chartData.data.length > 8
|
|
8502
|
-
? tempScale.bandwidth()
|
|
8503
|
-
: tempScale.bandwidth();
|
|
8504
|
-
})
|
|
8505
|
-
.attr('height', function (d) {
|
|
8506
|
-
if (d.value == -1) {
|
|
8507
|
-
return height - y(0);
|
|
8508
|
-
}
|
|
8509
|
-
if (d.value >= 0) {
|
|
8510
|
-
const barHeight = height - y(d.value);
|
|
8511
|
-
const minHeight = self.chartConfiguration.defaultBarHeight || 2;
|
|
8512
|
-
return Math.max(barHeight, minHeight);
|
|
8513
|
-
}
|
|
8514
|
-
return height - y(0);
|
|
8515
|
-
})
|
|
8516
|
-
.style('cursor', function (d) {
|
|
8517
|
-
if (metaData.hasDrillDown && !isria)
|
|
8518
|
-
return 'pointer';
|
|
8519
|
-
else
|
|
8520
|
-
return 'default';
|
|
8521
|
-
})
|
|
8522
|
-
.attr('fill', function (d) {
|
|
8523
|
-
if (d.value &&
|
|
8524
|
-
self.chartData.targetLineData &&
|
|
8525
|
-
d.value >= parseFloat(self.chartData.targetLineData.target) &&
|
|
8526
|
-
self.chartData.metaData.colorAboveTarget) {
|
|
8527
|
-
const key = d.key.toLowerCase();
|
|
8528
|
-
const colorAboveTarget = Object.keys(self.chartData.metaData.colorAboveTarget).find((k) => k.toLowerCase() === key);
|
|
8529
|
-
if (colorAboveTarget) {
|
|
8530
|
-
return self.chartData.metaData.colorAboveTarget[colorAboveTarget];
|
|
8531
|
-
}
|
|
8532
|
-
}
|
|
8533
|
-
return self.chartData.metaData.colors[d.key];
|
|
8534
|
-
});
|
|
8535
|
-
/**
|
|
8536
|
-
* display angled texts on the bars
|
|
8537
|
-
*/
|
|
8538
|
-
if (this.chartConfiguration.textsOnBar != undefined && !this.isZoomedOut) {
|
|
8539
|
-
state
|
|
8540
|
-
.selectAll('text')
|
|
8541
|
-
.data(function (d) {
|
|
8542
|
-
let newList = [];
|
|
8543
|
-
subgroups.map(function (key) {
|
|
8544
|
-
let obj = { key: key, value: d[key], name: d.name };
|
|
8545
|
-
newList.push(obj);
|
|
8546
|
-
});
|
|
8547
|
-
return newList;
|
|
8548
|
-
})
|
|
8549
|
-
.enter()
|
|
8550
|
-
.append('text')
|
|
8551
|
-
.attr('fill', 'var(--chart-text-color)')
|
|
8552
|
-
.attr('x', function (d) {
|
|
8553
|
-
return 0;
|
|
8554
|
-
})
|
|
8555
|
-
.attr('y', function (d) {
|
|
8556
|
-
return 0;
|
|
8557
|
-
})
|
|
8558
|
-
.attr('class', 'lib-data-labels-weeklycharts')
|
|
8559
|
-
.text(function (d) {
|
|
8560
|
-
return d.key && d.value
|
|
8561
|
-
? d.key.length > 20
|
|
8562
|
-
? d.key.substring(0, 17) + '...'
|
|
8563
|
-
: d.key
|
|
8564
|
-
: '';
|
|
8565
|
-
})
|
|
8566
|
-
.style('fill', function (d) {
|
|
8567
|
-
return '#000';
|
|
8568
|
-
})
|
|
8569
|
-
.style('font-weight', 'bold')
|
|
8570
|
-
.style('font-size', function (d) {
|
|
8571
|
-
if (self.isZoomedOut) {
|
|
8572
|
-
return '9px'; // 👈 Zoomed out mode
|
|
8573
|
-
}
|
|
8574
|
-
if (self.chartConfiguration.isDrilldownChart) {
|
|
8575
|
-
if (window.innerWidth > 1900) {
|
|
8576
|
-
return '18px';
|
|
8577
|
-
}
|
|
8578
|
-
else if (window.innerWidth < 1400) {
|
|
8579
|
-
return '10px';
|
|
8580
|
-
}
|
|
8581
|
-
else {
|
|
8582
|
-
return '14px';
|
|
8583
|
-
}
|
|
8584
|
-
}
|
|
8585
|
-
else {
|
|
8586
|
-
return '14px';
|
|
8587
|
-
}
|
|
8588
|
-
})
|
|
8589
|
-
.attr('transform', function (d) {
|
|
8590
|
-
data.map((indiv) => {
|
|
8591
|
-
if (indiv.name == d.name) {
|
|
8592
|
-
let keys = Object.keys(indiv).filter((temp, i) => i != 0);
|
|
8593
|
-
var temp;
|
|
8594
|
-
tempScale = d3.scaleBand().domain(keys).range([0, x.bandwidth()]);
|
|
8595
|
-
if (x.bandwidth() > 100) {
|
|
8596
|
-
if (self.chartData.data.length == 1) {
|
|
8597
|
-
if (Object.keys(self.chartData.data[0]).length == 2) {
|
|
8598
|
-
tempScale.range([
|
|
8599
|
-
0 + (x.bandwidth() - 200) / 2,
|
|
8600
|
-
x.bandwidth() - (x.bandwidth() - 200) / 2,
|
|
8601
|
-
]);
|
|
8602
|
-
// .padding(0.05);
|
|
8603
|
-
}
|
|
8604
|
-
else
|
|
8605
|
-
tempScale.range([
|
|
8606
|
-
0 + (x.bandwidth() - 300) / 2,
|
|
8607
|
-
x.bandwidth() - (x.bandwidth() - 300) / 2,
|
|
8608
|
-
]);
|
|
8609
|
-
// .padding(0.05);
|
|
8610
|
-
}
|
|
8611
|
-
else
|
|
8612
|
-
tempScale.range([
|
|
8613
|
-
0 + (x.bandwidth() - 125) / 2,
|
|
8614
|
-
x.bandwidth() - (x.bandwidth() - 125) / 2,
|
|
8615
|
-
]);
|
|
8616
|
-
}
|
|
9874
|
+
}
|
|
9875
|
+
if (d.value >= 0) {
|
|
9876
|
+
const barHeight = height - y(d.value);
|
|
9877
|
+
const minHeight = self.chartConfiguration.defaultBarHeight || 2;
|
|
9878
|
+
return barHeight < minHeight ? y(0) - minHeight : y(d.value);
|
|
9879
|
+
}
|
|
9880
|
+
return y(0);
|
|
9881
|
+
}
|
|
9882
|
+
calculateBarWidth(d, data, subgroups, x, xSubgroup, self, tempScale) {
|
|
9883
|
+
// For grouped bar charts in zoom-in view
|
|
9884
|
+
if (subgroups.length > 1 && !self.isZoomedOut) {
|
|
9885
|
+
return 50;
|
|
9886
|
+
}
|
|
9887
|
+
// For single-bar charts in zoom-in view
|
|
9888
|
+
if (subgroups.length === 1 && !self.isZoomedOut) {
|
|
9889
|
+
return 80;
|
|
9890
|
+
}
|
|
9891
|
+
// Default logic for drilldown charts
|
|
9892
|
+
if (self.chartConfiguration.isDrilldownChart) {
|
|
9893
|
+
let calculatedScale = d3.scaleBand().domain([]).range([0, 0]);
|
|
9894
|
+
data.forEach((indiv) => {
|
|
9895
|
+
if (indiv.name === d.name) {
|
|
9896
|
+
const keys = Object.keys(indiv).filter((temp, i) => i !== 0);
|
|
9897
|
+
calculatedScale = d3.scaleBand().domain(keys).range([0, x.bandwidth()]);
|
|
9898
|
+
if (x.bandwidth() > 100) {
|
|
9899
|
+
const reducedBarWidth = self.isZoomedOut ? 60 : 100;
|
|
9900
|
+
const offset = (x.bandwidth() - reducedBarWidth) / 2;
|
|
9901
|
+
calculatedScale.range([offset, x.bandwidth() - offset]);
|
|
8617
9902
|
}
|
|
8618
|
-
});
|
|
8619
|
-
/**
|
|
8620
|
-
* if set, then all texts ll be horizontal
|
|
8621
|
-
*/
|
|
8622
|
-
if (self.chartConfiguration.textAlwaysHorizontal) {
|
|
8623
|
-
return ('translate(' + xSubgroup(d.key) + ',' + (y(d.value) - 3) + ')');
|
|
8624
9903
|
}
|
|
8625
|
-
/**
|
|
8626
|
-
* rotate texts having more than one digits
|
|
8627
|
-
*/
|
|
8628
|
-
// if (d.value > 9)
|
|
8629
|
-
if (!isNaN(tempScale(d.key)))
|
|
8630
|
-
return ('translate(' +
|
|
8631
|
-
(tempScale(d.key) + tempScale.bandwidth() * 0.55) +
|
|
8632
|
-
',' +
|
|
8633
|
-
(y(0) - 10) +
|
|
8634
|
-
') rotate(270)');
|
|
8635
|
-
return 'translate(0,0)';
|
|
8636
|
-
// else
|
|
8637
|
-
// return (
|
|
8638
|
-
// 'translate(' +
|
|
8639
|
-
// (tempScale(d.key) + tempScale.bandwidth() / 2) +
|
|
8640
|
-
// ',' +
|
|
8641
|
-
// y(0) +
|
|
8642
|
-
// ')'
|
|
8643
|
-
// );
|
|
8644
|
-
})
|
|
8645
|
-
.on('click', function (d) {
|
|
8646
|
-
if (!metaData.barWithoutClick ||
|
|
8647
|
-
!metaData.barWithoutClick.length ||
|
|
8648
|
-
(!metaData.barWithoutClick.includes(d?.name) &&
|
|
8649
|
-
!metaData.barWithoutClick.includes(d?.key)))
|
|
8650
|
-
self.handleClick(d);
|
|
8651
9904
|
});
|
|
8652
|
-
|
|
8653
|
-
state
|
|
8654
|
-
.selectAll('.lib-data-labels-weeklycharts')
|
|
8655
|
-
.on('mouseout', handleMouseOut)
|
|
8656
|
-
.on('mouseover', handleMouseOver);
|
|
8657
|
-
}
|
|
9905
|
+
return calculatedScale.bandwidth();
|
|
8658
9906
|
}
|
|
8659
|
-
|
|
8660
|
-
|
|
8661
|
-
|
|
8662
|
-
|
|
8663
|
-
|
|
8664
|
-
|
|
8665
|
-
|
|
8666
|
-
|
|
9907
|
+
return xSubgroup.bandwidth();
|
|
9908
|
+
}
|
|
9909
|
+
calculateBarHeight(d, y, height, self) {
|
|
9910
|
+
if (d.value === -1) {
|
|
9911
|
+
return height - y(0);
|
|
9912
|
+
}
|
|
9913
|
+
if (d.value >= 0) {
|
|
9914
|
+
const barHeight = height - y(d.value);
|
|
9915
|
+
const minHeight = self.chartConfiguration.defaultBarHeight || 2;
|
|
9916
|
+
return Math.max(barHeight, minHeight);
|
|
9917
|
+
}
|
|
9918
|
+
return height - y(0);
|
|
9919
|
+
}
|
|
9920
|
+
getBarColor(d, metaData, self) {
|
|
9921
|
+
if (d.value && self.chartData.targetLineData &&
|
|
9922
|
+
d.value >= parseFloat(self.chartData.targetLineData.target) &&
|
|
9923
|
+
self.chartData.metaData.colorAboveTarget) {
|
|
9924
|
+
const key = d.key.toLowerCase();
|
|
9925
|
+
const colorAboveTarget = Object.keys(self.chartData.metaData.colorAboveTarget)
|
|
9926
|
+
.find(k => k.toLowerCase() === key);
|
|
9927
|
+
if (colorAboveTarget) {
|
|
9928
|
+
return self.chartData.metaData.colorAboveTarget[colorAboveTarget];
|
|
8667
9929
|
}
|
|
8668
9930
|
}
|
|
8669
|
-
|
|
8670
|
-
|
|
8671
|
-
|
|
8672
|
-
|
|
8673
|
-
|
|
8674
|
-
|
|
8675
|
-
|
|
8676
|
-
|
|
8677
|
-
|
|
8678
|
-
|
|
8679
|
-
|
|
8680
|
-
|
|
8681
|
-
|
|
8682
|
-
|
|
8683
|
-
|
|
8684
|
-
|
|
8685
|
-
|
|
8686
|
-
|
|
8687
|
-
|
|
8688
|
-
|
|
8689
|
-
|
|
8690
|
-
|
|
8691
|
-
|
|
8692
|
-
|
|
8693
|
-
|
|
8694
|
-
|
|
8695
|
-
|
|
8696
|
-
|
|
8697
|
-
|
|
8698
|
-
|
|
8699
|
-
|
|
8700
|
-
|
|
9931
|
+
return self.chartData.metaData.colors[d.key];
|
|
9932
|
+
}
|
|
9933
|
+
renderBarLabels(svg, data, subgroups, x, xSubgroup, y, height, metaData, self, tempScale, isria) {
|
|
9934
|
+
const state = svg.selectAll('.state');
|
|
9935
|
+
const labels = state.selectAll('text')
|
|
9936
|
+
.data((d) => this.prepareBarData(d, subgroups))
|
|
9937
|
+
.enter()
|
|
9938
|
+
.append('text')
|
|
9939
|
+
.attr('fill', 'var(--chart-text-color)')
|
|
9940
|
+
.attr('x', 0)
|
|
9941
|
+
.attr('y', 0)
|
|
9942
|
+
.attr('class', 'lib-data-labels-weeklycharts')
|
|
9943
|
+
.text((d) => this.formatBarLabel(d))
|
|
9944
|
+
.style('fill', '#000')
|
|
9945
|
+
.style('font-weight', 'bold')
|
|
9946
|
+
.style('font-size', (d) => this.calculateLabelFontSize(self))
|
|
9947
|
+
.attr('transform', (d) => this.calculateLabelTransform(d, data, x, xSubgroup, y, self, tempScale))
|
|
9948
|
+
.on('click', (d) => this.handleBarClick(d, metaData, self));
|
|
9949
|
+
if (!isria) {
|
|
9950
|
+
labels.on('mouseout', () => this.handleMouseOut(svg))
|
|
9951
|
+
.on('mouseover', (d) => this.handleMouseOver(d, svg, data, x, y, height, metaData, self, 50, tempScale));
|
|
9952
|
+
}
|
|
9953
|
+
}
|
|
9954
|
+
formatBarLabel(d) {
|
|
9955
|
+
if (!d.key || !d.value)
|
|
9956
|
+
return '';
|
|
9957
|
+
return d.key.length > 20 ? d.key.substring(0, 17) + '...' : d.key;
|
|
9958
|
+
}
|
|
9959
|
+
calculateLabelFontSize(self) {
|
|
9960
|
+
if (self.isZoomedOut)
|
|
9961
|
+
return '9px';
|
|
9962
|
+
if (self.chartConfiguration.isDrilldownChart) {
|
|
9963
|
+
if (window.innerWidth > 1900)
|
|
9964
|
+
return '18px';
|
|
9965
|
+
if (window.innerWidth < 1400)
|
|
9966
|
+
return '10px';
|
|
9967
|
+
return '14px';
|
|
9968
|
+
}
|
|
9969
|
+
return '14px';
|
|
9970
|
+
}
|
|
9971
|
+
calculateLabelTransform(d, data, x, xSubgroup, y, self, tempScale) {
|
|
9972
|
+
let calculatedScale;
|
|
9973
|
+
data.forEach((indiv) => {
|
|
9974
|
+
if (indiv.name === d.name) {
|
|
9975
|
+
const keys = Object.keys(indiv).filter((temp, i) => i !== 0);
|
|
9976
|
+
calculatedScale = d3.scaleBand().domain(keys).range([0, x.bandwidth()]);
|
|
9977
|
+
if (x.bandwidth() > 100) {
|
|
9978
|
+
if (self.chartData.data.length === 1) {
|
|
9979
|
+
const reducedWidth = Object.keys(self.chartData.data[0]).length === 2 ? 200 : 300;
|
|
9980
|
+
const offset = (x.bandwidth() - reducedWidth) / 2;
|
|
9981
|
+
calculatedScale.range([offset, x.bandwidth() - offset]);
|
|
8701
9982
|
}
|
|
8702
|
-
|
|
8703
|
-
|
|
8704
|
-
|
|
8705
|
-
return (x(d.name) + tempScale(d.key) + tempScale.bandwidth() / 2 - 90);
|
|
9983
|
+
else {
|
|
9984
|
+
const offset = (x.bandwidth() - 125) / 2;
|
|
9985
|
+
calculatedScale.range([offset, x.bandwidth() - offset]);
|
|
8706
9986
|
}
|
|
8707
|
-
return (x(d.name) +
|
|
8708
|
-
tempScale(d.key) -
|
|
8709
|
-
(tempScale.bandwidth() + leftAndRightSpaces * 2) / 2 +
|
|
8710
|
-
tempScale.bandwidth() / 2);
|
|
8711
9987
|
}
|
|
8712
|
-
|
|
8713
|
-
|
|
8714
|
-
|
|
8715
|
-
|
|
8716
|
-
|
|
8717
|
-
|
|
8718
|
-
})
|
|
8719
|
-
|
|
8720
|
-
|
|
8721
|
-
|
|
8722
|
-
|
|
8723
|
-
|
|
8724
|
-
|
|
8725
|
-
|
|
8726
|
-
|
|
8727
|
-
|
|
8728
|
-
|
|
8729
|
-
|
|
8730
|
-
|
|
8731
|
-
|
|
8732
|
-
|
|
8733
|
-
|
|
8734
|
-
|
|
8735
|
-
|
|
8736
|
-
tempScale.range([
|
|
8737
|
-
0 + (x.bandwidth() - 300) / 2,
|
|
8738
|
-
x.bandwidth() - (x.bandwidth() - 300) / 2,
|
|
8739
|
-
]);
|
|
8740
|
-
}
|
|
8741
|
-
else
|
|
8742
|
-
tempScale.range([
|
|
8743
|
-
0 + (x.bandwidth() - 125) / 2,
|
|
8744
|
-
x.bandwidth() - (x.bandwidth() - 125) / 2,
|
|
8745
|
-
]);
|
|
8746
|
-
}
|
|
9988
|
+
}
|
|
9989
|
+
});
|
|
9990
|
+
if (self.chartConfiguration.textAlwaysHorizontal) {
|
|
9991
|
+
return `translate(${xSubgroup(d.key)},${y(d.value) - 3})`;
|
|
9992
|
+
}
|
|
9993
|
+
if (!isNaN(calculatedScale(d.key))) {
|
|
9994
|
+
return `translate(${calculatedScale(d.key) + calculatedScale.bandwidth() * 0.55},${y(0) - 10}) rotate(270)`;
|
|
9995
|
+
}
|
|
9996
|
+
return 'translate(0,0)';
|
|
9997
|
+
}
|
|
9998
|
+
handleMouseOver(d, svg, data, x, y, height, metaData, self, leftAndRightSpaces, tempScale) {
|
|
9999
|
+
svg.selectAll('.lib-verticalstack-title-ontop').remove();
|
|
10000
|
+
let calculatedScale;
|
|
10001
|
+
let elementsCounter;
|
|
10002
|
+
data.forEach((indiv) => {
|
|
10003
|
+
if (indiv.name === d.name) {
|
|
10004
|
+
const keys = Object.keys(indiv).filter((temp, i) => i !== 0);
|
|
10005
|
+
elementsCounter = keys.length;
|
|
10006
|
+
calculatedScale = d3.scaleBand().domain(keys).range([0, x.bandwidth()]);
|
|
10007
|
+
if (x.bandwidth() > 100) {
|
|
10008
|
+
if (self.chartData.data.length === 1) {
|
|
10009
|
+
const reducedWidth = Object.keys(self.chartData.data[0]).length === 2 ? 200 : 300;
|
|
10010
|
+
const offset = (x.bandwidth() - reducedWidth) / 2;
|
|
10011
|
+
calculatedScale.range([offset, x.bandwidth() - offset]);
|
|
8747
10012
|
}
|
|
8748
|
-
|
|
8749
|
-
|
|
8750
|
-
|
|
8751
|
-
return '180px';
|
|
10013
|
+
else {
|
|
10014
|
+
const offset = (x.bandwidth() - 125) / 2;
|
|
10015
|
+
calculatedScale.range([offset, x.bandwidth() - offset]);
|
|
8752
10016
|
}
|
|
8753
|
-
return tempScale.bandwidth() + leftAndRightSpaces * 2;
|
|
8754
10017
|
}
|
|
8755
|
-
|
|
8756
|
-
|
|
8757
|
-
|
|
8758
|
-
|
|
8759
|
-
|
|
8760
|
-
|
|
8761
|
-
|
|
8762
|
-
|
|
8763
|
-
|
|
8764
|
-
|
|
8765
|
-
|
|
8766
|
-
|
|
8767
|
-
|
|
8768
|
-
|
|
8769
|
-
|
|
8770
|
-
|
|
8771
|
-
|
|
8772
|
-
|
|
8773
|
-
|
|
8774
|
-
|
|
8775
|
-
|
|
8776
|
-
|
|
8777
|
-
|
|
8778
|
-
|
|
8779
|
-
|
|
8780
|
-
|
|
8781
|
-
.
|
|
8782
|
-
.
|
|
8783
|
-
|
|
8784
|
-
|
|
8785
|
-
|
|
8786
|
-
|
|
8787
|
-
|
|
8788
|
-
|
|
10018
|
+
}
|
|
10019
|
+
});
|
|
10020
|
+
const xPosition = this.calculateTooltipX(d, x, calculatedScale, metaData, leftAndRightSpaces);
|
|
10021
|
+
const width = this.calculateTooltipWidth(calculatedScale, metaData, leftAndRightSpaces);
|
|
10022
|
+
svg.append('foreignObject')
|
|
10023
|
+
.attr('x', xPosition)
|
|
10024
|
+
.attr('class', 'lib-verticalstack-title-ontop')
|
|
10025
|
+
.attr('y', y(d.value) - 3 - 40 - 10)
|
|
10026
|
+
.attr('dy', d.class)
|
|
10027
|
+
.attr('width', width)
|
|
10028
|
+
.attr('height', 50)
|
|
10029
|
+
.append('xhtml:div')
|
|
10030
|
+
.attr('class', 'title')
|
|
10031
|
+
.style('z-index', 99)
|
|
10032
|
+
.html(() => this.generateTooltipHTML(d, metaData));
|
|
10033
|
+
}
|
|
10034
|
+
calculateTooltipX(d, x, calculatedScale, metaData, leftAndRightSpaces) {
|
|
10035
|
+
if (metaData.hasDrillDown) {
|
|
10036
|
+
if (calculatedScale.bandwidth() + leftAndRightSpaces * 2 > 180) {
|
|
10037
|
+
return x(d.name) + calculatedScale(d.key) + calculatedScale.bandwidth() / 2 - 90;
|
|
10038
|
+
}
|
|
10039
|
+
return x(d.name) + calculatedScale(d.key) -
|
|
10040
|
+
(calculatedScale.bandwidth() + leftAndRightSpaces * 2) / 2 +
|
|
10041
|
+
calculatedScale.bandwidth() / 2;
|
|
10042
|
+
}
|
|
10043
|
+
return x(d.name) + calculatedScale(d.key) -
|
|
10044
|
+
(calculatedScale.bandwidth() + leftAndRightSpaces * 2) / 2 +
|
|
10045
|
+
calculatedScale.bandwidth() / 2;
|
|
10046
|
+
}
|
|
10047
|
+
calculateTooltipWidth(calculatedScale, metaData, leftAndRightSpaces) {
|
|
10048
|
+
if (metaData.hasDrillDown) {
|
|
10049
|
+
if (calculatedScale.bandwidth() + leftAndRightSpaces * 2 > 180) {
|
|
10050
|
+
return '180px';
|
|
10051
|
+
}
|
|
10052
|
+
return calculatedScale.bandwidth() + leftAndRightSpaces * 2;
|
|
10053
|
+
}
|
|
10054
|
+
return calculatedScale.bandwidth() + leftAndRightSpaces * 2;
|
|
10055
|
+
}
|
|
10056
|
+
generateTooltipHTML(d, metaData) {
|
|
10057
|
+
const barLabel = d.key;
|
|
10058
|
+
const dataType = metaData.dataType || '';
|
|
10059
|
+
const value = d.value;
|
|
10060
|
+
let html = `<span class="title-bar-name">${barLabel}</span>`;
|
|
10061
|
+
html += `<span class="title-bar-value"><span>${value}</span>${dataType}</span>`;
|
|
10062
|
+
return html;
|
|
10063
|
+
}
|
|
10064
|
+
handleMouseOut(svg) {
|
|
10065
|
+
svg.selectAll('.lib-verticalstack-title-ontop').remove();
|
|
10066
|
+
}
|
|
10067
|
+
renderYAxis(svg, svgYAxisLeft, svgYAxisRight, y, yLineAxis, lineData, self, isria, margin) {
|
|
10068
|
+
// Hidden y-axis for reference
|
|
10069
|
+
svg.append('g')
|
|
8789
10070
|
.attr('class', 'lib-stacked-y-axis-text yaxis-dashed')
|
|
8790
10071
|
.attr('style', self.chartConfiguration.yAxisCustomTextStyles)
|
|
8791
10072
|
.attr('transform', 'translate(0,0)')
|
|
8792
10073
|
.call(y)
|
|
8793
10074
|
.style('display', 'none');
|
|
8794
|
-
|
|
8795
|
-
|
|
10075
|
+
// Left y-axis
|
|
10076
|
+
svgYAxisLeft.append('g')
|
|
8796
10077
|
.append('g')
|
|
8797
10078
|
.attr('class', 'lib-yaxis-labels-texts-drilldown yaxis-dashed')
|
|
8798
10079
|
.attr('style', self.chartConfiguration.yAxisCustomTextStyles)
|
|
8799
10080
|
.attr('transform', 'translate(0,0)')
|
|
8800
|
-
.call(d3
|
|
8801
|
-
.axisLeft(y)
|
|
10081
|
+
.call(d3.axisLeft(y)
|
|
8802
10082
|
.tickSize(0)
|
|
8803
10083
|
.ticks(self.chartConfiguration.numberOfYTicks)
|
|
8804
|
-
.tickFormat(
|
|
10084
|
+
.tickFormat((d) => {
|
|
8805
10085
|
const formatted = self.chartConfiguration.yAxisLabelFomatter
|
|
8806
10086
|
? self.chartConfiguration.yAxisLabelFomatter(d)
|
|
8807
10087
|
: d;
|
|
8808
10088
|
return formatted >= 1000 ? formatted / 1000 + 'k' : formatted;
|
|
8809
10089
|
}))
|
|
8810
10090
|
.call((g) => {
|
|
8811
|
-
// Style the domain line for theme support
|
|
8812
10091
|
g.select('.domain')
|
|
8813
10092
|
.style('stroke', 'var(--chart-domain-color, #000000)')
|
|
8814
10093
|
.style('stroke-width', '1px');
|
|
8815
10094
|
})
|
|
8816
10095
|
.selectAll('text')
|
|
8817
10096
|
.style('fill', 'var(--chart-text-color)');
|
|
8818
|
-
|
|
8819
|
-
|
|
10097
|
+
// Right y-axis (hidden by default)
|
|
10098
|
+
svgYAxisRight.append('g')
|
|
8820
10099
|
.attr('class', 'lib-yaxis-labels-texts-drilldown yaxis-dashed')
|
|
8821
10100
|
.attr('style', self.chartConfiguration.yAxisCustomTextStyles)
|
|
8822
10101
|
.attr('transform', 'translate(0,0)')
|
|
8823
10102
|
.call(y)
|
|
8824
10103
|
.style('display', 'none');
|
|
8825
|
-
|
|
8826
|
-
|
|
8827
|
-
|
|
8828
|
-
|
|
8829
|
-
|
|
8830
|
-
|
|
8831
|
-
|
|
8832
|
-
d3.selectAll('g.lib-line-x-axis-text > g > text').attr('class', 'lib-display-hidden');
|
|
8833
|
-
}
|
|
8834
|
-
/**
|
|
8835
|
-
* hide y axis labels
|
|
8836
|
-
* used by weekly charts
|
|
8837
|
-
*/
|
|
8838
|
-
if (this.chartConfiguration.isYaxisLabelHidden != undefined &&
|
|
8839
|
-
this.chartConfiguration.isYaxisLabelHidden) {
|
|
8840
|
-
d3.selectAll('.yaxis-dashed > g > text').attr('class', 'lib-display-hidden');
|
|
8841
|
-
}
|
|
8842
|
-
/**
|
|
8843
|
-
* hide y axis labels
|
|
8844
|
-
* config is there for future use
|
|
8845
|
-
*/
|
|
8846
|
-
if (this.chartConfiguration.isYaxisHidden != undefined &&
|
|
8847
|
-
this.chartConfiguration.isYaxisHidden) {
|
|
8848
|
-
d3.selectAll('.yaxis-dashed').attr('class', 'lib-display-hidden');
|
|
8849
|
-
}
|
|
8850
|
-
/**
|
|
8851
|
-
* dashed y axis
|
|
8852
|
-
* used by weekly charts
|
|
8853
|
-
*/
|
|
8854
|
-
if (this.chartConfiguration.isYaxisDashed != undefined &&
|
|
8855
|
-
this.chartConfiguration.isYaxisDashed) {
|
|
8856
|
-
d3.selectAll('.yaxis-dashed')
|
|
8857
|
-
.style('stroke-dasharray', '5 5')
|
|
8858
|
-
.style('color', 'var(--chart-axis-color, #999999)'); // Use CSS variable
|
|
8859
|
-
}
|
|
8860
|
-
if (lineData != null) {
|
|
8861
|
-
if (lineData && self.chartConfiguration.showLineChartAxis) {
|
|
8862
|
-
svgYAxisRight
|
|
8863
|
-
.append('g')
|
|
8864
|
-
.attr('class', 'lib-stacked-y-axis-text1')
|
|
8865
|
-
.attr('style', self.chartConfiguration.yAxisCustomTextStyles)
|
|
8866
|
-
.attr('transform', 'translate(' + 0 + ',0)')
|
|
8867
|
-
.call(yLineAxis);
|
|
8868
|
-
}
|
|
10104
|
+
// Line chart axis if applicable
|
|
10105
|
+
if (lineData != null && lineData && self.chartConfiguration.showLineChartAxis) {
|
|
10106
|
+
svgYAxisRight.append('g')
|
|
10107
|
+
.attr('class', 'lib-stacked-y-axis-text1')
|
|
10108
|
+
.attr('style', self.chartConfiguration.yAxisCustomTextStyles)
|
|
10109
|
+
.attr('transform', 'translate(0,0)')
|
|
10110
|
+
.call(yLineAxis);
|
|
8869
10111
|
}
|
|
8870
|
-
|
|
8871
|
-
|
|
8872
|
-
|
|
8873
|
-
|
|
8874
|
-
|
|
8875
|
-
|
|
8876
|
-
|
|
8877
|
-
// }
|
|
8878
|
-
if (this.isZoomedOut) {
|
|
8879
|
-
svg
|
|
8880
|
-
.selectAll('.lib-xaxis-labels-texts-drilldown')
|
|
8881
|
-
.each((d, i, nodes) => {
|
|
8882
|
-
const text = d3.select(nodes[i]);
|
|
8883
|
-
const label = text.text();
|
|
8884
|
-
if (label.indexOf('\n') > -1) {
|
|
8885
|
-
const lines = label.split('\n');
|
|
8886
|
-
text.text(null);
|
|
8887
|
-
lines.forEach((line, idx) => {
|
|
8888
|
-
text
|
|
8889
|
-
.append('tspan')
|
|
8890
|
-
.text(line)
|
|
8891
|
-
.attr('x', 0)
|
|
8892
|
-
.attr('dy', idx === 0 ? '1em' : '1.1em');
|
|
8893
|
-
});
|
|
8894
|
-
}
|
|
8895
|
-
else {
|
|
8896
|
-
const words = label.split(' ');
|
|
8897
|
-
text.text(null);
|
|
8898
|
-
words.forEach((word, index) => {
|
|
8899
|
-
text.append('tspan').text(word);
|
|
8900
|
-
});
|
|
8901
|
-
}
|
|
8902
|
-
})
|
|
8903
|
-
.style('fill', 'var(--chart-text-color)')
|
|
8904
|
-
.attr('transform', null);
|
|
8905
|
-
svg
|
|
8906
|
-
.select('.x-axis')
|
|
8907
|
-
.attr('transform', `translate(0, ${height - margin.bottom + 10})`);
|
|
10112
|
+
// Apply axis visibility configurations
|
|
10113
|
+
this.applyAxisVisibilityConfig(self);
|
|
10114
|
+
}
|
|
10115
|
+
applyAxisVisibilityConfig(self) {
|
|
10116
|
+
if (self.chartConfiguration.isXaxisLabelHidden) {
|
|
10117
|
+
d3.selectAll('g.lib-line-x-axis-text > g > text')
|
|
10118
|
+
.attr('class', 'lib-display-hidden');
|
|
8908
10119
|
}
|
|
8909
|
-
|
|
8910
|
-
|
|
8911
|
-
|
|
10120
|
+
if (self.chartConfiguration.isYaxisLabelHidden) {
|
|
10121
|
+
d3.selectAll('.yaxis-dashed > g > text')
|
|
10122
|
+
.attr('class', 'lib-display-hidden');
|
|
10123
|
+
}
|
|
10124
|
+
if (self.chartConfiguration.isYaxisHidden) {
|
|
10125
|
+
d3.selectAll('.yaxis-dashed')
|
|
10126
|
+
.attr('class', 'lib-display-hidden');
|
|
10127
|
+
}
|
|
10128
|
+
if (self.chartConfiguration.isYaxisDashed) {
|
|
10129
|
+
d3.selectAll('.yaxis-dashed')
|
|
10130
|
+
.style('stroke-dasharray', '5 5')
|
|
10131
|
+
.style('color', 'var(--chart-axis-color, #999999)');
|
|
10132
|
+
}
|
|
10133
|
+
}
|
|
10134
|
+
renderAxisLabels(svg, svgYAxisLeft, svgYAxisRight, metaData, width, height, margin, self, isria, rightSvgWidth) {
|
|
10135
|
+
// Y-axis label
|
|
8912
10136
|
if (metaData.yLabel) {
|
|
8913
|
-
const yPosition = isria
|
|
8914
|
-
|
|
8915
|
-
: 0 - margin.left / 2 - 40;
|
|
8916
|
-
svgYAxisLeft
|
|
8917
|
-
.append('text')
|
|
10137
|
+
const yPosition = isria ? 0 - margin.left / 2 - 30 : 0 - margin.left / 2 - 40;
|
|
10138
|
+
svgYAxisLeft.append('text')
|
|
8918
10139
|
.attr('class', 'lib-axis-group-label font-size-1')
|
|
8919
10140
|
.attr('style', self.chartConfiguration.yAxisCustomlabelStyles)
|
|
8920
10141
|
.attr('transform', 'rotate(-90)')
|
|
@@ -8924,172 +10145,155 @@ class HorizontalGroupedBarWithScrollZoomComponent extends ComponentUniqueId {
|
|
|
8924
10145
|
.style('text-anchor', 'middle')
|
|
8925
10146
|
.attr('fill', 'var(--chart-text-color)');
|
|
8926
10147
|
if (this.chartConfiguration.isMultiChartGridLine === undefined) {
|
|
8927
|
-
svgYAxisLeft
|
|
8928
|
-
.selectAll('.lib-axis-group-label')
|
|
10148
|
+
svgYAxisLeft.selectAll('.lib-axis-group-label')
|
|
8929
10149
|
.style('font-size', 'smaller')
|
|
8930
10150
|
.text(metaData.yLabel);
|
|
8931
10151
|
}
|
|
8932
10152
|
else {
|
|
8933
|
-
svg
|
|
8934
|
-
.selectAll('.lib-axis-group-label')
|
|
10153
|
+
svg.selectAll('.lib-axis-group-label')
|
|
8935
10154
|
.attr('class', 'lib-ylabel-weeklyCharts')
|
|
8936
10155
|
.text(metaData.yLabel.toLowerCase());
|
|
8937
10156
|
}
|
|
8938
10157
|
}
|
|
8939
|
-
|
|
8940
|
-
const yZero = y(this.chartData.targetLineData.target);
|
|
8941
|
-
svg
|
|
8942
|
-
.append('line')
|
|
8943
|
-
.attr('x1', 0)
|
|
8944
|
-
.attr('x2', width)
|
|
8945
|
-
.attr('y1', yZero)
|
|
8946
|
-
.attr('y2', yZero)
|
|
8947
|
-
.style('stroke-dasharray', '5 5')
|
|
8948
|
-
.style('stroke', this.chartData.targetLineData.color);
|
|
8949
|
-
// svgYAxisRight
|
|
8950
|
-
// .append('line')
|
|
8951
|
-
// .attr('x1', 0)
|
|
8952
|
-
// .attr('x2', rightSvgWidth)
|
|
8953
|
-
// .attr('y1', yZero)
|
|
8954
|
-
// .attr('y2', yZero)
|
|
8955
|
-
// .style('stroke', this.chartData.targetLineData.color);
|
|
8956
|
-
svgYAxisRight
|
|
8957
|
-
.append('foreignObject')
|
|
8958
|
-
.attr('transform', 'translate(' + 0 + ',' + (yZero - 30) + ')')
|
|
8959
|
-
.attr('width', rightSvgWidth)
|
|
8960
|
-
.attr('height', 50)
|
|
8961
|
-
.append('xhtml:div')
|
|
8962
|
-
.attr('class', 'target-display')
|
|
8963
|
-
.style('color', 'var(--chart-text-color)')
|
|
8964
|
-
.html(function () {
|
|
8965
|
-
let dataTypeTemp = '';
|
|
8966
|
-
let targetLineName = 'target';
|
|
8967
|
-
if (metaData.dataType) {
|
|
8968
|
-
dataTypeTemp = metaData.dataType;
|
|
8969
|
-
}
|
|
8970
|
-
if (self.chartData.targetLineData &&
|
|
8971
|
-
self.chartData.targetLineData.targetName) {
|
|
8972
|
-
targetLineName = self.chartData.targetLineData.targetName;
|
|
8973
|
-
}
|
|
8974
|
-
return (`<div>${targetLineName}</div>` +
|
|
8975
|
-
'<div>' +
|
|
8976
|
-
self.chartData.targetLineData.target +
|
|
8977
|
-
'' +
|
|
8978
|
-
dataTypeTemp +
|
|
8979
|
-
'</div>');
|
|
8980
|
-
});
|
|
8981
|
-
}
|
|
8982
|
-
if (this.chartConfiguration.isDrilldownChart) {
|
|
8983
|
-
/**
|
|
8984
|
-
* used by drilldown charts
|
|
8985
|
-
*/
|
|
8986
|
-
// svg
|
|
8987
|
-
// .selectAll('.lib-axis-group-label')
|
|
8988
|
-
// .attr('class', 'lib-ylabel-drilldowncharts')
|
|
8989
|
-
// .text(metaData.yLabel.toLowerCase());
|
|
8990
|
-
svg.selectAll('g.x1.axis1 g.tick line').style('display', 'none');
|
|
8991
|
-
}
|
|
10158
|
+
// X-axis label
|
|
8992
10159
|
if (metaData.xLabel) {
|
|
8993
|
-
|
|
8994
|
-
return ((label.length <= 4 && /^[A-Z]+$/.test(label)) ||
|
|
8995
|
-
(label === label.toUpperCase() && /[A-Z]/.test(label)));
|
|
8996
|
-
}
|
|
8997
|
-
const xLabelText = metaData.xLabel;
|
|
8998
|
-
const isAcr = isAcronym(xLabelText.replace(/[^A-Za-z]/g, ''));
|
|
10160
|
+
const isAcronym = this.isLabelAcronym(metaData.xLabel);
|
|
8999
10161
|
const xPosition = isria
|
|
9000
|
-
? height + margin.top + margin.bottom
|
|
9001
|
-
: height + margin.top + margin.bottom + 40;
|
|
9002
|
-
svg
|
|
9003
|
-
.
|
|
9004
|
-
.attr('class', function () {
|
|
9005
|
-
let baseClass = 'lib-axis-group-label font-size-1';
|
|
9006
|
-
if (self.chartConfiguration.isDrilldownChart)
|
|
9007
|
-
return baseClass + ' lib-xlabel-drilldowncharts';
|
|
9008
|
-
if (self.chartConfiguration.isMultiChartGridLine != undefined)
|
|
9009
|
-
return baseClass + ' lib-xlabel-weeklyCharts';
|
|
9010
|
-
return baseClass + ' lib-axis-waterfall-label';
|
|
9011
|
-
})
|
|
10162
|
+
? (height + margin.top + margin.bottom)
|
|
10163
|
+
: (height + margin.top + margin.bottom + 40);
|
|
10164
|
+
svg.append('text')
|
|
10165
|
+
.attr('class', this.getXLabelClass(self))
|
|
9012
10166
|
.attr('style', self.chartConfiguration.xAxisCustomlabelStyles)
|
|
9013
|
-
.attr('transform',
|
|
10167
|
+
.attr('transform', `translate(${width / 2},${xPosition})`)
|
|
9014
10168
|
.style('text-anchor', 'middle')
|
|
9015
10169
|
.style('fill', 'var(--chart-text-color)')
|
|
9016
|
-
.text(
|
|
9017
|
-
.style('text-transform',
|
|
10170
|
+
.text(isAcronym ? metaData.xLabel.toUpperCase() : metaData.xLabel.toLowerCase())
|
|
10171
|
+
.style('text-transform', isAcronym ? 'none' : 'capitalize');
|
|
9018
10172
|
}
|
|
10173
|
+
// Line y-axis label
|
|
9019
10174
|
if (metaData.lineyLabel) {
|
|
9020
|
-
svgYAxisRight
|
|
9021
|
-
.append('text')
|
|
10175
|
+
svgYAxisRight.append('text')
|
|
9022
10176
|
.attr('class', 'lib-axis-group-label lib-line-axis')
|
|
9023
10177
|
.attr('fill', 'var(--chart-text-color)')
|
|
9024
10178
|
.attr('style', self.chartConfiguration.yAxisCustomlabelStyles)
|
|
9025
10179
|
.attr('transform', 'translate(0,0) rotate(90)')
|
|
9026
|
-
.attr('y',
|
|
9027
|
-
.attr('x',
|
|
10180
|
+
.attr('y', -100)
|
|
10181
|
+
.attr('x', 100)
|
|
9028
10182
|
.attr('dy', '5em')
|
|
9029
10183
|
.style('text-anchor', 'middle')
|
|
9030
10184
|
.style('font-size', 'smaller')
|
|
9031
10185
|
.text(metaData.lineyLabel);
|
|
9032
10186
|
}
|
|
9033
|
-
|
|
9034
|
-
|
|
9035
|
-
|
|
9036
|
-
|
|
9037
|
-
|
|
9038
|
-
|
|
9039
|
-
|
|
9040
|
-
|
|
9041
|
-
|
|
9042
|
-
|
|
9043
|
-
|
|
9044
|
-
|
|
9045
|
-
|
|
9046
|
-
|
|
9047
|
-
|
|
9048
|
-
|
|
9049
|
-
|
|
9050
|
-
|
|
9051
|
-
|
|
9052
|
-
|
|
9053
|
-
|
|
9054
|
-
|
|
9055
|
-
|
|
9056
|
-
|
|
9057
|
-
|
|
9058
|
-
|
|
9059
|
-
|
|
9060
|
-
|
|
9061
|
-
|
|
9062
|
-
|
|
9063
|
-
|
|
9064
|
-
|
|
9065
|
-
|
|
9066
|
-
|
|
9067
|
-
|
|
9068
|
-
|
|
9069
|
-
|
|
9070
|
-
|
|
9071
|
-
|
|
9072
|
-
|
|
9073
|
-
|
|
9074
|
-
|
|
9075
|
-
|
|
9076
|
-
|
|
9077
|
-
|
|
9078
|
-
|
|
9079
|
-
|
|
9080
|
-
|
|
9081
|
-
|
|
9082
|
-
|
|
9083
|
-
|
|
9084
|
-
|
|
9085
|
-
|
|
9086
|
-
|
|
9087
|
-
|
|
9088
|
-
|
|
9089
|
-
|
|
10187
|
+
// Apply drilldown chart specific styles
|
|
10188
|
+
if (this.chartConfiguration.isDrilldownChart) {
|
|
10189
|
+
svg.selectAll('g.x1.axis1 g.tick line').style('display', 'none');
|
|
10190
|
+
}
|
|
10191
|
+
}
|
|
10192
|
+
isLabelAcronym(label) {
|
|
10193
|
+
return (label.length <= 4 && /^[A-Z]+$/.test(label)) ||
|
|
10194
|
+
(label === label.toUpperCase() && /[A-Z]/.test(label));
|
|
10195
|
+
}
|
|
10196
|
+
getXLabelClass(self) {
|
|
10197
|
+
let baseClass = 'lib-axis-group-label font-size-1';
|
|
10198
|
+
if (self.chartConfiguration.isDrilldownChart) {
|
|
10199
|
+
return baseClass + ' lib-xlabel-drilldowncharts';
|
|
10200
|
+
}
|
|
10201
|
+
if (self.chartConfiguration.isMultiChartGridLine !== undefined) {
|
|
10202
|
+
return baseClass + ' lib-xlabel-weeklyCharts';
|
|
10203
|
+
}
|
|
10204
|
+
return baseClass + ' lib-axis-waterfall-label';
|
|
10205
|
+
}
|
|
10206
|
+
renderTargetLine(svg, svgYAxisRight, y, width, rightSvgWidth, metaData, self) {
|
|
10207
|
+
const yZero = y(this.chartData.targetLineData.target);
|
|
10208
|
+
// Draw target line
|
|
10209
|
+
svg.append('line')
|
|
10210
|
+
.attr('x1', 0)
|
|
10211
|
+
.attr('x2', width)
|
|
10212
|
+
.attr('y1', yZero)
|
|
10213
|
+
.attr('y2', yZero)
|
|
10214
|
+
.style('stroke-dasharray', '5 5')
|
|
10215
|
+
.style('stroke', this.chartData.targetLineData.color);
|
|
10216
|
+
// Add target label
|
|
10217
|
+
const dataTypeTemp = metaData.dataType || '';
|
|
10218
|
+
const targetLineName = this.chartData.targetLineData.targetName || 'target';
|
|
10219
|
+
svgYAxisRight.append('foreignObject')
|
|
10220
|
+
.attr('transform', `translate(0,${yZero - 30})`)
|
|
10221
|
+
.attr('width', rightSvgWidth)
|
|
10222
|
+
.attr('height', 50)
|
|
10223
|
+
.append('xhtml:div')
|
|
10224
|
+
.attr('class', 'target-display')
|
|
10225
|
+
.style('color', 'var(--chart-text-color)')
|
|
10226
|
+
.html(`<div>${targetLineName}</div><div>${self.chartData.targetLineData.target}${dataTypeTemp}</div>`);
|
|
10227
|
+
}
|
|
10228
|
+
renderLineChart(svg, lineData, x, lineYscale, metaData, self) {
|
|
10229
|
+
// Draw line path
|
|
10230
|
+
svg.append('path')
|
|
10231
|
+
.datum(lineData)
|
|
10232
|
+
.attr('fill', 'none')
|
|
10233
|
+
.attr('stroke', self.chartConfiguration.lineGraphColor)
|
|
10234
|
+
.attr('stroke-width', 1.5)
|
|
10235
|
+
.attr('d', d3.line()
|
|
10236
|
+
.x((d) => x(d.name) + x.bandwidth() / 2)
|
|
10237
|
+
.y((d) => lineYscale(d.value)));
|
|
10238
|
+
// Add dots
|
|
10239
|
+
const dot = svg.selectAll('myCircles')
|
|
10240
|
+
.data(lineData)
|
|
10241
|
+
.enter()
|
|
10242
|
+
.append('g')
|
|
10243
|
+
.on('click', (d) => {
|
|
10244
|
+
if (!metaData.barWithoutClick || !metaData.barWithoutClick.length ||
|
|
10245
|
+
(!metaData.barWithoutClick.includes(d?.name) &&
|
|
10246
|
+
!metaData.barWithoutClick.includes(d?.key))) {
|
|
10247
|
+
self.handleClick(d);
|
|
10248
|
+
}
|
|
10249
|
+
});
|
|
10250
|
+
dot.append('circle')
|
|
10251
|
+
.attr('fill', self.chartConfiguration.lineGraphColor)
|
|
10252
|
+
.attr('stroke', 'none')
|
|
10253
|
+
.attr('cx', (d) => x(d.name) + x.bandwidth() / 2)
|
|
10254
|
+
.attr('cy', (d) => lineYscale(d.value))
|
|
10255
|
+
.style('cursor', () => self.chartData.metaData.hasDrillDown ? 'pointer' : 'default')
|
|
10256
|
+
.attr('r', 3);
|
|
10257
|
+
// Add value labels
|
|
10258
|
+
if (self.chartConfiguration.lineGraphColor) {
|
|
10259
|
+
dot.append('text')
|
|
10260
|
+
.attr('class', 'dot')
|
|
10261
|
+
.attr('fill', 'var(--chart-text-color)')
|
|
10262
|
+
.attr('color', self.chartConfiguration.lineGraphColor)
|
|
10263
|
+
.attr('style', 'font-size: .85em')
|
|
10264
|
+
.attr('x', (d) => x(d.name) + x.bandwidth() / 2)
|
|
10265
|
+
.attr('y', (d) => lineYscale(d.value))
|
|
10266
|
+
.attr('dy', '-1em')
|
|
10267
|
+
.text((d) => self.chartConfiguration.labelFormatter(d.value));
|
|
10268
|
+
}
|
|
10269
|
+
}
|
|
10270
|
+
handleZoomOut(svg, height, margin) {
|
|
10271
|
+
svg.selectAll('.lib-xaxis-labels-texts-drilldown')
|
|
10272
|
+
.each((d, i, nodes) => {
|
|
10273
|
+
const text = d3.select(nodes[i]);
|
|
10274
|
+
const label = text.text();
|
|
10275
|
+
if (label.indexOf('\n') > -1) {
|
|
10276
|
+
const lines = label.split('\n');
|
|
10277
|
+
text.text(null);
|
|
10278
|
+
lines.forEach((line, idx) => {
|
|
10279
|
+
text.append('tspan')
|
|
10280
|
+
.text(line)
|
|
10281
|
+
.attr('x', 0)
|
|
10282
|
+
.attr('dy', idx === 0 ? '1em' : '1.1em');
|
|
9090
10283
|
});
|
|
9091
10284
|
}
|
|
9092
|
-
|
|
10285
|
+
else {
|
|
10286
|
+
const words = label.split(' ');
|
|
10287
|
+
text.text(null);
|
|
10288
|
+
words.forEach((word) => {
|
|
10289
|
+
text.append('tspan').text(word);
|
|
10290
|
+
});
|
|
10291
|
+
}
|
|
10292
|
+
})
|
|
10293
|
+
.style('fill', 'var(--chart-text-color)')
|
|
10294
|
+
.attr('transform', null);
|
|
10295
|
+
svg.select('.x-axis')
|
|
10296
|
+
.attr('transform', `translate(0, ${height - margin.bottom + 10})`);
|
|
9093
10297
|
}
|
|
9094
10298
|
calculateChartDimensions(chartContainer, verticalstackedcontainer, margin, self) {
|
|
9095
10299
|
let width = parseInt(chartContainer.style('width')) - margin.left - margin.right;
|
|
@@ -9112,7 +10316,8 @@ class HorizontalGroupedBarWithScrollZoomComponent extends ComponentUniqueId {
|
|
|
9112
10316
|
width = dataLength * 120;
|
|
9113
10317
|
}
|
|
9114
10318
|
if (dataLength > 8 && !this.isZoomedOut) {
|
|
9115
|
-
if (this.chartData.dropdownData2 &&
|
|
10319
|
+
if (this.chartData.dropdownData2 &&
|
|
10320
|
+
width < dataLength * 250) {
|
|
9116
10321
|
width = dataLength * 250;
|
|
9117
10322
|
}
|
|
9118
10323
|
else {
|
|
@@ -9194,155 +10399,6 @@ class HorizontalGroupedBarWithScrollZoomComponent extends ComponentUniqueId {
|
|
|
9194
10399
|
.attr('transform', `translate(0,${margin.top})`);
|
|
9195
10400
|
return { outerContainer, svgYAxisLeft, svgYAxisRight, innerContainer, svg };
|
|
9196
10401
|
}
|
|
9197
|
-
renderXAxis(svg, x, height, subgroups, metaData, chartConfig, alternate_text, short_tick_length_bg, long_tick_length_bg, self) {
|
|
9198
|
-
if (chartConfig.isMultiChartGridLine == undefined) {
|
|
9199
|
-
// Normal dashboard charts
|
|
9200
|
-
svg
|
|
9201
|
-
.append('g')
|
|
9202
|
-
.attr('class', 'x1 axis1')
|
|
9203
|
-
.attr('transform', `translate(0,${height})`)
|
|
9204
|
-
.call(d3.axisBottom(x))
|
|
9205
|
-
.call((g) => g.select('.domain').remove());
|
|
9206
|
-
svg.selectAll('g.x1.axis1 g.tick line').remove();
|
|
9207
|
-
if (subgroups.length > 1 && !metaData.xLabel) {
|
|
9208
|
-
svg
|
|
9209
|
-
.selectAll('g.x1.axis1 g.tick text')
|
|
9210
|
-
.attr('class', 'lib-xaxis-labels-texts-drilldown')
|
|
9211
|
-
.style('fill', 'var(--chart-text-color)')
|
|
9212
|
-
.attr('y', 32);
|
|
9213
|
-
}
|
|
9214
|
-
else {
|
|
9215
|
-
svg
|
|
9216
|
-
.selectAll('g.x1.axis1 g.tick text')
|
|
9217
|
-
.attr('class', 'lib-xaxis-labels-texts-drilldown')
|
|
9218
|
-
.style('fill', 'var(--chart-text-color)');
|
|
9219
|
-
}
|
|
9220
|
-
}
|
|
9221
|
-
else {
|
|
9222
|
-
// Weekly charts / multi-chart
|
|
9223
|
-
svg
|
|
9224
|
-
.append('g')
|
|
9225
|
-
.attr('class', 'x1 axis1')
|
|
9226
|
-
.attr('transform', `translate(0,${height})`)
|
|
9227
|
-
.call(d3.axisBottom(x).tickSize(0))
|
|
9228
|
-
.call((g) => g.select('.domain').attr('fill', 'none'));
|
|
9229
|
-
// Tick line size in alternate fashion
|
|
9230
|
-
svg.selectAll('g.x1.axis1 g.tick line').attr('y2', function () {
|
|
9231
|
-
if (alternate_text && chartConfig.isNoAlternateXaxisText == undefined) {
|
|
9232
|
-
alternate_text = false;
|
|
9233
|
-
return long_tick_length_bg - 7;
|
|
9234
|
-
}
|
|
9235
|
-
else {
|
|
9236
|
-
alternate_text = true;
|
|
9237
|
-
return short_tick_length_bg - 4;
|
|
9238
|
-
}
|
|
9239
|
-
});
|
|
9240
|
-
// Reset flag
|
|
9241
|
-
alternate_text = false;
|
|
9242
|
-
// X-axis labels
|
|
9243
|
-
svg
|
|
9244
|
-
.selectAll('g.x1.axis1 g.tick text')
|
|
9245
|
-
.attr('class', 'lib-xaxis-labels-texts-weeklycharts')
|
|
9246
|
-
.attr('y', function () {
|
|
9247
|
-
if (chartConfig.isFullScreen)
|
|
9248
|
-
return short_tick_length_bg;
|
|
9249
|
-
if (alternate_text) {
|
|
9250
|
-
alternate_text = false;
|
|
9251
|
-
return long_tick_length_bg;
|
|
9252
|
-
}
|
|
9253
|
-
else {
|
|
9254
|
-
alternate_text = true;
|
|
9255
|
-
return short_tick_length_bg;
|
|
9256
|
-
}
|
|
9257
|
-
});
|
|
9258
|
-
}
|
|
9259
|
-
}
|
|
9260
|
-
renderXAxisLabels(svg, data, subgroups, metaData, chartConfig, short_tick_length_bg, long_tick_length_bg, isMobile, isria, self) {
|
|
9261
|
-
if (!chartConfig.xLabelsOnSameLine)
|
|
9262
|
-
return;
|
|
9263
|
-
const xAxisLabels = svg.selectAll('g.x1.axis1 g.tick text');
|
|
9264
|
-
this.applyLabelStyles(xAxisLabels, data, subgroups, metaData, chartConfig, short_tick_length_bg, long_tick_length_bg, isMobile, self);
|
|
9265
|
-
this.handleLabelText(xAxisLabels, data, subgroups, metaData, chartConfig, isMobile, self);
|
|
9266
|
-
if (isria && data.length > 8) {
|
|
9267
|
-
this.applyRiaLabelOverride(xAxisLabels);
|
|
9268
|
-
}
|
|
9269
|
-
if (isMobile && !self.isHeaderVisible) {
|
|
9270
|
-
xAxisLabels.classed('mobile-xaxis-override', true);
|
|
9271
|
-
}
|
|
9272
|
-
}
|
|
9273
|
-
applyLabelStyles(labels, data, subgroups, metaData, chartConfig, short_tick_length_bg, long_tick_length_bg, isMobile, self) {
|
|
9274
|
-
labels
|
|
9275
|
-
.attr('class', 'lib-xaxis-labels-texts-drilldown')
|
|
9276
|
-
.style('font-size', self.isHeaderVisible ? '18px' : '14px')
|
|
9277
|
-
.attr('text-anchor', 'middle')
|
|
9278
|
-
.attr('y', (d) => this.calculateLabelY(d, data, subgroups, metaData, chartConfig, short_tick_length_bg, long_tick_length_bg, self))
|
|
9279
|
-
.attr('x', (d) => this.calculateLabelX(d, data, self));
|
|
9280
|
-
}
|
|
9281
|
-
calculateLabelY(d, data, subgroups, metaData, chartConfig, short_tick_length_bg, long_tick_length_bg, self) {
|
|
9282
|
-
// Logic from your original code for y positioning
|
|
9283
|
-
if (subgroups.length > 1 && data.length > 8 && metaData.xLabel) {
|
|
9284
|
-
return short_tick_length_bg + 14;
|
|
9285
|
-
}
|
|
9286
|
-
if (subgroups.length > 1 && data.length > 8 && !metaData.xLabel) {
|
|
9287
|
-
return chartConfig.isFullScreen
|
|
9288
|
-
? short_tick_length_bg + 2
|
|
9289
|
-
: short_tick_length_bg + 10;
|
|
9290
|
-
}
|
|
9291
|
-
let baseY = self.isHeaderVisible
|
|
9292
|
-
? short_tick_length_bg + 25
|
|
9293
|
-
: short_tick_length_bg;
|
|
9294
|
-
return baseY;
|
|
9295
|
-
}
|
|
9296
|
-
calculateLabelX(d, data, self) {
|
|
9297
|
-
if (data.length > 8 && !self.isZoomedOut)
|
|
9298
|
-
return 1;
|
|
9299
|
-
return 0;
|
|
9300
|
-
}
|
|
9301
|
-
handleLabelText(labels, data, subgroups, metaData, chartConfig, isMobile, self) {
|
|
9302
|
-
labels.text((d) => {
|
|
9303
|
-
if (isMobile && !self.isHeaderVisible) {
|
|
9304
|
-
return d
|
|
9305
|
-
.split(/[\s\-]+/)[0]
|
|
9306
|
-
.substring(0, 3)
|
|
9307
|
-
.toLowerCase();
|
|
9308
|
-
}
|
|
9309
|
-
// Split dates or weeks, ignore -1 values, etc.
|
|
9310
|
-
// Keep all your previous text-processing logic here
|
|
9311
|
-
return d.toLowerCase(); // fallback
|
|
9312
|
-
});
|
|
9313
|
-
// Example of handling sideways labels for grouped zoomed-out charts
|
|
9314
|
-
labels.each(function (d) {
|
|
9315
|
-
const isDateLabel = /^(\d{2,4}[-\/])?\d{2,4}[-\/]\d{2,4}$/.test(d.trim());
|
|
9316
|
-
const isWeekLabel = /week|wk|w\d+/i.test(d);
|
|
9317
|
-
if (subgroups.length > 1 &&
|
|
9318
|
-
self.isZoomedOut &&
|
|
9319
|
-
data.length > 8 &&
|
|
9320
|
-
isDateLabel &&
|
|
9321
|
-
!isWeekLabel) {
|
|
9322
|
-
d3.select(this).style('writing-mode', 'sideways-lr');
|
|
9323
|
-
}
|
|
9324
|
-
});
|
|
9325
|
-
}
|
|
9326
|
-
applyRiaLabelOverride(labels) {
|
|
9327
|
-
labels
|
|
9328
|
-
.classed('mobile-xaxis-override', true)
|
|
9329
|
-
.text((d) => d.substring(0, 3))
|
|
9330
|
-
.style('font-size', '12px')
|
|
9331
|
-
.attr('y', 5)
|
|
9332
|
-
.attr('x', 5)
|
|
9333
|
-
.style('text-anchor', 'middle');
|
|
9334
|
-
}
|
|
9335
|
-
calculateMaxValue(maxValue) {
|
|
9336
|
-
if (maxValue === 0) {
|
|
9337
|
-
if (this.chartData.targetLineData) {
|
|
9338
|
-
return this.chartData.targetLineData.target + 20;
|
|
9339
|
-
}
|
|
9340
|
-
else {
|
|
9341
|
-
return 100;
|
|
9342
|
-
}
|
|
9343
|
-
}
|
|
9344
|
-
return maxValue;
|
|
9345
|
-
}
|
|
9346
10402
|
handleClick(d) {
|
|
9347
10403
|
if (this.chartData.metaData.hasDrillDown || d?.toggleFrom)
|
|
9348
10404
|
this.clickEvent.emit(d);
|