From 347c3fe1912ab87423d63d38d8d49a1be644e4a7 Mon Sep 17 00:00:00 2001 From: "kenny.martin" Date: Sun, 23 Jan 2022 19:38:41 +0100 Subject: [PATCH] feat(stacked-series-chart): Improvements - Css variables for: Grip gap, Track size, Extra margin (for long tick format) - Calculation for ticks in bar format. Supports gaps in series - Tick function to always provide less or equal number of ticks than tracks - Ticks collapse improved to calculate proper distance between ticks - Now component is more lightweight - Documentation updated! - E2E tests fixed accordingly --- .../stacked-series-chart.e2e.ts | 26 +- .../stacked-series-chart.html | 15 +- .../stacked-series-chart.po.ts | 2 +- .../stacked-series-chart.ts | 2 +- .../stacked-series-chart-demo.component.html | 4 +- .../stacked-series-chart/README.md | 62 +- .../src/_stacked-series-chart-shared.scss | 6 +- .../src/stacked-series-chart-bar.scss | 34 +- .../src/stacked-series-chart-column.scss | 55 +- .../src/stacked-series-chart.html | 10 +- .../src/stacked-series-chart.scss | 13 +- .../src/stacked-series-chart.spec.ts | 3 - .../src/stacked-series-chart.ts | 283 +++++--- .../src/stacked-series-chart.util.ts | 10 +- .../stacked-series-chart-column-example.html | 7 +- .../stacked-series-chart-column-example.scss | 4 + .../stacked-series-chart-column-example.ts | 1 + .../stacked-series-chart-date-example.html | 17 +- .../stacked-series-chart-date-example.ts | 50 +- .../stacked-series-chart-demo-data.ts | 624 +++++++++++++++--- ...acked-series-chart-heat-field-example.html | 1 - ...acked-series-chart-heat-field-example.scss | 4 + ...stacked-series-chart-heat-field-example.ts | 1 + .../stacked-series-chart-linear-example.html | 1 + .../stacked-series-chart-linear-example.ts | 2 +- 25 files changed, 913 insertions(+), 324 deletions(-) create mode 100644 libs/examples/src/stacked-series-chart/stacked-series-chart-column-example/stacked-series-chart-column-example.scss create mode 100644 libs/examples/src/stacked-series-chart/stacked-series-chart-heat-field-example/stacked-series-chart-heat-field-example.scss diff --git a/apps/components-e2e/src/components/stacked-series-chart/stacked-series-chart.e2e.ts b/apps/components-e2e/src/components/stacked-series-chart/stacked-series-chart.e2e.ts index 6525d0b8a7..4b6018c0e0 100644 --- a/apps/components-e2e/src/components/stacked-series-chart/stacked-series-chart.e2e.ts +++ b/apps/components-e2e/src/components/stacked-series-chart/stacked-series-chart.e2e.ts @@ -23,7 +23,7 @@ import { body, chartContainer, chartWidth1200Btn, - chartWidth400Btn, + chartWidth300Btn, columnBtn, columnChart, continuousAxisFormat7f, @@ -69,6 +69,7 @@ import { unselectBtn, valueAxis, heatFieldTypeOverlap, + continuousAxisTypeNone, } from './stacked-series-chart.po'; // Reduced speed of hovering should get our e2e tests stable. @@ -286,7 +287,8 @@ test('should switch from full to compact on labelAxisMode auto', async (testCont .expect(chartContainer.classNames) .notContains(compactModeClassname) .click(autoLabelAxisModeBtn) - .click(chartWidth400Btn) + .click(chartWidth300Btn) + .click(continuousAxisTypeNone) .resizeWindowToFitDevice('ipad') .wait(250) // Wait for the DtViewportResizer event to trigger .expect(chartContainer.classNames) @@ -335,7 +337,7 @@ test('should render linear chart with format and auto-fitting ticks', async (tes // select column so that auto fit can be applied .click(autoLabelAxisModeBtn) .click(columnBtn) - .click(chartWidth400Btn) + .click(chartWidth300Btn) .click(continuousAxisFormat7f) // Check auto fitting ticks @@ -377,17 +379,17 @@ test('should render date chart with format and auto-fitting ticks', async (testC .click(autoLabelAxisModeBtn) .click(columnBtn) .expect(chartContainer.classNames) - .contains(compactModeClassname) + .notContains(compactModeClassname) // Check track ticks again .expect(labels.count) - .eql(28) + .eql(9) .expect(getLabel(0).textContent) - .match(/11:35/) + .match(/11:45/) .expect(getLabel(1).textContent) - .match(/11:40/) + .match(/12:00/) .expect(getLabel(2).textContent) - .match(/11:45/) + .match(/12:15/) // Check auto fitting ticks with long time format .click(continuousAxisFormatLong) @@ -396,13 +398,13 @@ test('should render date chart with format and auto-fitting ticks', async (testC // Check track ticks .expect(labels.count) - .eql(9) + .eql(4) .expect(getLabel(0).textContent) - .match(/11:45:00:000AM/) + .match(/ Dec, 31 \/ 12:00:00:000-------- /) .expect(getLabel(1).textContent) - .match(/12:00:00:000PM/) + .match(/ Dec, 31 \/ 12:30:00:000-------- /) .expect(getLabel(2).textContent) - .match(/12:15:00:000PM/) + .match(/ Dec, 31 \/ 13:00:00:000-------- /) // Check no compact mode with long width .click(chartWidth1200Btn) diff --git a/apps/components-e2e/src/components/stacked-series-chart/stacked-series-chart.html b/apps/components-e2e/src/components/stacked-series-chart/stacked-series-chart.html index aea3b2ac2a..296b60390a 100644 --- a/apps/components-e2e/src/components/stacked-series-chart/stacked-series-chart.html +++ b/apps/components-e2e/src/components/stacked-series-chart/stacked-series-chart.html @@ -16,7 +16,18 @@ [visibleLabel]="visibleLabel" [labelAxisMode]="labelAxisMode" [visibleTrackBackground]="visibleTrackBackground" - [maxTrackSize]="maxTrackSize" + [style.--dt-stacked-series-chart-grid-gap]=" + !continuousAxisFormat ? '40px' : null + " + [style.--dt-stacked-series-chart-max-bar-size]="maxTrackSize + 'px'" + [style.--dt-stacked-series-chart-extra-margin]=" + (!continuousAxisType || + continuousAxisType === 'none' || + continuousAxisFormat === continuousAxisFormatsByType.linear[1] || + continuousAxisFormat === continuousAxisFormatsByType.date[1] + ? 32 + : 0) + 'px' + " [continuousAxisType]="continuousAxisType" [continuousAxisInterval]="continuousAxisInterval" [continuousAxisFormat]="continuousAxisFormat" @@ -177,7 +188,7 @@
HeatField data
1200px - +
diff --git a/apps/components-e2e/src/components/stacked-series-chart/stacked-series-chart.po.ts b/apps/components-e2e/src/components/stacked-series-chart/stacked-series-chart.po.ts index d964b66114..ddce8fd29d 100644 --- a/apps/components-e2e/src/components/stacked-series-chart/stacked-series-chart.po.ts +++ b/apps/components-e2e/src/components/stacked-series-chart/stacked-series-chart.po.ts @@ -107,7 +107,7 @@ export const unselectBtn = Selector('#chart-unselect'); export const chartWidth1200Btn = Selector('#chart-width-1200'); export const chartWidth800Btn = Selector('#chart-width-800'); -export const chartWidth400Btn = Selector('#chart-width-400'); +export const chartWidth300Btn = Selector('#chart-width-300'); export const selectionModeNode = Selector('#chart-selection-mode-node'); export const selectionModeStack = Selector('#chart-selection-mode-stack'); diff --git a/apps/components-e2e/src/components/stacked-series-chart/stacked-series-chart.ts b/apps/components-e2e/src/components/stacked-series-chart/stacked-series-chart.ts index e880f64fa9..5cb906f3a2 100644 --- a/apps/components-e2e/src/components/stacked-series-chart/stacked-series-chart.ts +++ b/apps/components-e2e/src/components/stacked-series-chart/stacked-series-chart.ts @@ -69,7 +69,7 @@ export class DtE2EStackedSeriesChart { ]; continuousAxisFormatsByType = { linear: ['$.2f', '$.7f'], - date: ['%H:%M', '%H:%M:%S:%L%p'], + date: ['%H:%M', '%b, %d / %H:%M:%S:%L--------'], }; continuousAxisMapByType = { diff --git a/apps/dev/src/stacked-series-chart/stacked-series-chart-demo.component.html b/apps/dev/src/stacked-series-chart/stacked-series-chart-demo.component.html index 0be766d6ee..542bcb3784 100644 --- a/apps/dev/src/stacked-series-chart/stacked-series-chart-demo.component.html +++ b/apps/dev/src/stacked-series-chart/stacked-series-chart-demo.component.html @@ -10,7 +10,7 @@ [labelAxisMode]="labelAxisMode" [fillMode]="fillMode" [mode]="mode" - [maxTrackSize]="maxTrackSize" + [style.--dt-stacked-series-chart-max-bar-size]="maxTrackSize + 'px'" [visibleTrackBackground]="visibleTrackBackground" [class]="mode" > @@ -69,7 +69,7 @@

Background

Max size

- None + None 8 16 32 diff --git a/libs/barista-components/stacked-series-chart/README.md b/libs/barista-components/stacked-series-chart/README.md index a88a89d702..031e45944d 100644 --- a/libs/barista-components/stacked-series-chart/README.md +++ b/libs/barista-components/stacked-series-chart/README.md @@ -38,30 +38,48 @@ follow the same order given by the developer ### DtStackedSeriesChart +#### CSS variables + +Styling variables with default value. One can be set by doing the following: + +```css +dt-stacked-series-chart { + --dt-stacked-series-chart-grid-gap: 32px; + --dt-stacked-series-chart-max-bar-size: 32px; + --dt-stacked-series-chart-extra-margin: 16px; +} +``` + +| Name | Default | Description | +| ---------------------------------------- | -------- | -------------------------------------------------- | +| `--dt-stacked-series-chart-grid-gap` | `'16px'` | Gap between tracks | +| `--dt-stacked-series-chart-max-bar-size` | `'16px'` | Size of the track | +| `--dt-stacked-series-chart-extra-margin` | `'0px'` | For column type, extra margin for long tick format | + #### Inputs -| Name | Type | Default | Description | -| ------------------------ | --------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `mode` | `DtStackedSeriesChartMode` | `'bar'` | Display mode. | -| `series` | `DtStackedSeriesChartSeries[]` | - | Array of series with their nodes. | -| `heatFields` | `DtStackedSeriesHeatField[]` | - | Array of heat fields to be shown at the top -for columns- or at the left-side -for bars-. | -| `selectable` | `boolean` | false | Allow selections to be made on chart | -| `selected` | `[DtStackedSeriesChartSeries, DtStackedSeriesChartNode?]` | - | Current selection [series, node] node will be null if `selectionMode` is `stack` | -| `selectionMode` | `DtStackedSeriesChartSelectionMode` | 'node' | Whether to make just the nodes selectable or the whole stack. | -| `max` | `number \| undefined` | - | Max value in the chart. Useful when binding multiple stacked-series-chart. | -| `fillMode` | `DtStackedSeriesChartFillMode` | - | Whether each bar should be filled completely or should take into account their siblings and max. | -| `valueDisplayMode` | `DtStackedSeriesChartValueDisplayMode` | `'none'` | Sets the display mode for the stacked-series-chart values in legend to either 'none' 'percent' or 'absolute'. In single track chart value is displayed also in legend. For axis value 'none' falls back to 'absolute' | -| `legends` | `DtStackedSeriesChartLegend[]` | true | Array of legends that can be used to toggle bar nodes. As change detection is on push the changes will only affect when the reference is different. | -| `visibleLegend` | `boolean` | true | Visibility of the legend | -| `visibleTrackBackground` | `boolean` | true | Whether background should be transparent or show a background. | -| `visibleLabel` | `boolean` | true | Visibility of series label. | -| `visibleValueAxis` | `boolean` | true | Visibility of value axis. | -| `labelAxisMode` | `DtStackedSeriesChartLabelAxisMode` | `full` | Mode of the label axis, compact would make space for more labels. | -| `maxTrackSize` | `number` | 16 | Maximum size of the track. | -| `continuousAxisType` | `DtStackedSeriesChartValueContinuousAxisType` | `'none'` | Sets the type for continuous axis scale calculation to 'none', 'date' or 'linear'. Depending on the type, scale is created in specific way. | -| `continuousAxisInterval` | `TimeInterval` | - | In case we want a specific interval for ticks (every 5 mins, per day...). You can create custom intervals or install D3-time and use its built-in ones. If used, auto fitting ticks will be discarded | -| `continuousAxisFormat` | `string` | - | Specific format for tick label. It follows d3-format (https://github.com/d3/d3-format) for linear type and d3-time-format (https://github.com/d3/d3-time-format) for date type | -| `continuousAxisMap` | `DtStackedSeriesChartValueContinuousAxisMap` | - | Mapping function to create d3 domain. It is used for d3 understand the domain and build scales properly. If not defined, it will use an "Identity" function to return the label for every node | +| Name | Type | Default | Description | +| ------------------------ | --------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `mode` | `DtStackedSeriesChartMode` | `'bar'` | Display mode. | +| `series` | `DtStackedSeriesChartSeries[]` | - | Array of series with their nodes. | +| `heatFields` | `DtStackedSeriesHeatField[]` | - | Array of heat fields to be shown at the top -for columns- or at the left-side -for bars-. | +| `selectable` | `boolean` | false | Allow selections to be made on chart | +| `selected` | `[DtStackedSeriesChartSeries, DtStackedSeriesChartNode?]` | - | Current selection [series, node] node will be null if `selectionMode` is `stack` | +| `selectionMode` | `DtStackedSeriesChartSelectionMode` | 'node' | Whether to make just the nodes selectable or the whole stack. | +| `max` | `number \| undefined` | - | Max value in the chart. Useful when binding multiple stacked-series-chart. | +| `fillMode` | `DtStackedSeriesChartFillMode` | - | Whether each bar should be filled completely or should take into account their siblings and max. | +| `valueDisplayMode` | `DtStackedSeriesChartValueDisplayMode` | `'none'` | Sets the display mode for the stacked-series-chart values in legend to either 'none' 'percent' or 'absolute'. In single track chart value is displayed also in legend. For axis value 'none' falls back to 'absolute' | +| `legends` | `DtStackedSeriesChartLegend[]` | true | Array of legends that can be used to toggle bar nodes. As change detection is on push the changes will only affect when the reference is different. | +| `visibleLegend` | `boolean` | true | Visibility of the legend | +| `visibleTrackBackground` | `boolean` | true | Whether background should be transparent or show a background. | +| `visibleLabel` | `boolean` | true | Visibility of series label. | +| `visibleValueAxis` | `boolean` | true | Visibility of value axis. | +| `labelAxisMode` | `DtStackedSeriesChartLabelAxisMode` | `full` | Mode of the label axis, compact would make space for more labels. | +| `maxTrackSize` | `number` | 16 | Maximum size of the track. | +| `continuousAxisType` | `DtStackedSeriesChartValueContinuousAxisType` | `'none'` | Sets the type for continuous axis scale calculation to 'none', 'date' or 'linear'. Depending on the type, scale is created in specific way. | +| `continuousAxisInterval` | `TimeInterval` | - | (Only column mode) In case we want a specific interval for ticks (every 5 mins, per day...). You can create custom intervals or install D3-time and use its built-in ones. If used, auto fitting ticks will be discarded | +| `continuousAxisFormat` | `string` | - | Specific format for tick label. It follows d3-format (https://github.com/d3/d3-format) for linear type and d3-time-format (https://github.com/d3/d3-time-format) for date type | +| `continuousAxisMap` | `DtStackedSeriesChartValueContinuousAxisMap` | - | Mapping function to create d3 domain. It is used for d3 understand the domain and build scales properly. If not defined, it will use an "Identity" function to return the label for every node | #### Outputs diff --git a/libs/barista-components/stacked-series-chart/src/_stacked-series-chart-shared.scss b/libs/barista-components/stacked-series-chart/src/_stacked-series-chart-shared.scss index 35c3f3b8a7..f1a08ed006 100644 --- a/libs/barista-components/stacked-series-chart/src/_stacked-series-chart-shared.scss +++ b/libs/barista-components/stacked-series-chart/src/_stacked-series-chart-shared.scss @@ -1,6 +1,10 @@ @import '../../core/src/style/variables'; -$gap: calc(var(--dt-stacked-series-chart-grid-gap) * 1px); +$gap-default: 16px; +$bar-track-size-default: 16px; +$column-extra-margin-default: 0; + +$gap: var(--dt-stacked-series-chart-grid-gap); $heat-field-gap: 1px; $heat-field-size: 8px; $heat-field-size-selected: 12px; diff --git a/libs/barista-components/stacked-series-chart/src/stacked-series-chart-bar.scss b/libs/barista-components/stacked-series-chart/src/stacked-series-chart-bar.scss index 4d2cd33b40..b2e5bc6fac 100644 --- a/libs/barista-components/stacked-series-chart/src/stacked-series-chart-bar.scss +++ b/libs/barista-components/stacked-series-chart/src/stacked-series-chart-bar.scss @@ -7,7 +7,7 @@ See stacked-series-chart.layout.md $track-wrapper-height: calc( (var(--dt-stacked-series-chart-max-bar-size) + #{$gap}) * - var(--dt-stacked-series-chart-track-amount) + calc(var(--dt-stacked-series-chart-track-amount) - 1) ); $track-wrapper-margin-top: $gap; $track-wrapper-margin-bottom: calc(#{$gap} / 2); @@ -19,35 +19,14 @@ $track-wrapper-margin-bottom: calc(#{$gap} / 2); position: relative; } - .dt-stacked-series-chart-track-axis-container, .dt-stacked-series-chart-track-label-wrapper, .dt-stacked-series-chart-track-wrapper, .dt-stacked-series-chart-heat-field-wrapper { min-height: $track-wrapper-height; - height: 100%; grid-column: 2; grid-row: 1; - } - - .dt-stacked-series-chart-container:not(.dt-stacked-series-chart-scale-point) { - .dt-stacked-series-chart-track-label-wrapper, - .dt-stacked-series-chart-track-wrapper, - .dt-stacked-series-chart-heat-field-wrapper { - margin-top: $track-wrapper-margin-top; - margin-bottom: $track-wrapper-margin-bottom; - height: calc( - 100% - #{$track-wrapper-margin-top} - #{$track-wrapper-margin-bottom} - ); - } - - .dt-stacked-series-chart-track-axis-container { - @include trackAxisContainerMinSize( - min-height, - $track-wrapper-height, - $track-wrapper-margin-top, - $track-wrapper-margin-bottom - ); - } + margin: calc(var(--dt-stacked-series-chart-max-bar-size) / 2) 0; + height: calc(100% - var(--dt-stacked-series-chart-max-bar-size)); } .dt-stacked-series-chart-heat-field-wrapper { @@ -72,16 +51,12 @@ $track-wrapper-margin-bottom: calc(#{$gap} / 2); grid-template-columns: auto 1fr; &.dt-stacked-series-chart-has-heat-field { - column-gap: calc(#{$gap} + #{$heat-field-size-by-levels}); + column-gap: calc(#{$tick-gutter} + #{$heat-field-size-by-levels}); } &:not(.dt-stacked-series-chart-value-axis-none) { grid-template-rows: 1fr auto; } - - &.dt-stacked-series-chart-scale-point { - row-gap: calc(#{$gap} / 2); - } } .dt-stacked-series-chart-label-none.dt-stacked-series-chart-container { @@ -102,7 +77,6 @@ $track-wrapper-margin-bottom: calc(#{$gap} / 2); } .dt-stacked-series-chart-label-none { - .dt-stacked-series-chart-track-axis-container, .dt-stacked-series-chart-track-wrapper, .dt-stacked-series-chart-value-axis, .dt-stacked-series-chart-heat-field-wrapper { diff --git a/libs/barista-components/stacked-series-chart/src/stacked-series-chart-column.scss b/libs/barista-components/stacked-series-chart/src/stacked-series-chart-column.scss index 91937c4b5b..401ac5b1fc 100644 --- a/libs/barista-components/stacked-series-chart/src/stacked-series-chart-column.scss +++ b/libs/barista-components/stacked-series-chart/src/stacked-series-chart-column.scss @@ -6,13 +6,22 @@ See stacked-series-chart.layout.md */ - $track-wrapper-width: calc( (var(--dt-stacked-series-chart-max-bar-size) + #{$gap}) * - var(--dt-stacked-series-chart-track-amount) + calc(var(--dt-stacked-series-chart-track-amount) - 1) +); +$track-wrapper-margin-left: calc( + #{$gap} + var(--dt-stacked-series-chart-extra-margin) +); +$track-wrapper-margin-right: calc( + (#{$gap} * 1) + #{$tick-gutter} + var(--dt-stacked-series-chart-extra-margin) ); -$track-wrapper-margin-left: $gap; -$track-wrapper-margin-right: calc(#{$gap} * 2); + +:host { + --dt-stacked-series-chart-extra-margin: calc( + #{$column-extra-margin-default} * 1px + ); +} :host(.dt-stacked-series-chart-column) { .dt-stacked-series-chart-track-label-wrapper, @@ -25,17 +34,6 @@ $track-wrapper-margin-right: calc(#{$gap} * 2); margin-right: $track-wrapper-margin-right; } - .dt-stacked-series-chart-track-axis-container { - grid-column: 2; - grid-row: 1; - @include trackAxisContainerMinSize( - min-width, - $track-wrapper-width, - $track-wrapper-margin-left, - $track-wrapper-margin-right - ); - } - .dt-stacked-series-chart-track-label-wrapper { display: grid; } @@ -66,6 +64,17 @@ $track-wrapper-margin-right: calc(#{$gap} * 2); grid-column: 1; white-space: nowrap; + + &::after { + position: absolute; + display: block; + background: $axis-color; + width: 1px; + height: $tick-length; + top: -$tick-gutter; + right: 50%; + content: ' '; + } } .dt-stacked-series-chart-track { @@ -100,7 +109,7 @@ $track-wrapper-margin-right: calc(#{$gap} * 2); .dt-stacked-series-chart-track-label-content { display: block; white-space: nowrap; - padding: 0 4px; + padding: 0 math.div($tick-gutter, 2); } } @@ -118,24 +127,14 @@ $track-wrapper-margin-right: calc(#{$gap} * 2); width: 14px; height: 72px; - &::after { - position: absolute; - display: block; - background: $axis-color; - width: 1px; - height: 8px; - top: -16px; - right: 50%; - content: ' '; - } - .dt-stacked-series-chart-track-label-content { width: 85px; position: absolute; display: block; overflow: hidden; text-overflow: ellipsis; - transform: translate(-15%, 100%) rotate(45deg); + transform: translate(10%, -30%) rotate(45deg); + transform-origin: top left; white-space: nowrap; text-align: left; } diff --git a/libs/barista-components/stacked-series-chart/src/stacked-series-chart.html b/libs/barista-components/stacked-series-chart/src/stacked-series-chart.html index e05f6e18b4..0963f2a133 100644 --- a/libs/barista-components/stacked-series-chart/src/stacked-series-chart.html +++ b/libs/barista-components/stacked-series-chart/src/stacked-series-chart.html @@ -13,7 +13,9 @@ [style]=" _sanitizeCSS([ ['--dt-stacked-series-chart-track-amount', _trackAmount], - ['--dt-stacked-series-chart-max-bar-size', maxTrackSize + 'px'], + maxTrackSize != null + ? ['--dt-stacked-series-chart-max-bar-size', maxTrackSize + 'px'] + : [], [ '--dt-stacked-series-chart-heat-field-levels', _heatFieldLevels?.length || 0 @@ -26,14 +28,10 @@ class="dt-stacked-series-chart-series-axis" >
-
-
+
diff --git a/libs/barista-components/stacked-series-chart/src/stacked-series-chart.scss b/libs/barista-components/stacked-series-chart/src/stacked-series-chart.scss index e0396c6ada..dd3b75b092 100644 --- a/libs/barista-components/stacked-series-chart/src/stacked-series-chart.scss +++ b/libs/barista-components/stacked-series-chart/src/stacked-series-chart.scss @@ -6,12 +6,15 @@ See stacked-series-chart.layout.md */ :host { + --dt-stacked-series-chart-grid-gap: #{$gap-default}; + --dt-stacked-series-chart-max-bar-size: #{$bar-track-size-default}; + display: grid; align-items: center; grid-template-rows: 1fr auto; &.dt-stacked-series-chart-with-legend { - gap: $gap; + gap: $tick-gutter; } } @@ -20,13 +23,7 @@ See stacked-series-chart.layout.md display: grid; grid-auto-flow: dense; align-self: stretch; - gap: $gap; -} - -/** Chart orientation */ -.dt-stacked-series-chart-track-axis-container { - grid-column: 2; - grid-row: 1; + gap: $tick-gutter; } /** Track */ diff --git a/libs/barista-components/stacked-series-chart/src/stacked-series-chart.spec.ts b/libs/barista-components/stacked-series-chart/src/stacked-series-chart.spec.ts index 536d311dbc..19d1bb185a 100644 --- a/libs/barista-components/stacked-series-chart/src/stacked-series-chart.spec.ts +++ b/libs/barista-components/stacked-series-chart/src/stacked-series-chart.spec.ts @@ -220,7 +220,6 @@ describe('DtStackedSeriesChart', () => { visibleTrackBackground: true, visibleLabel: true, mode: 'bar', - maxTrackSize: 16, visibleValueAxis: true, }; @@ -776,7 +775,6 @@ describe('DtStackedSeriesChart', () => { [labelAxisMode]="labelAxisMode" [visibleValueAxis]="visibleValueAxis" [mode]="mode" - [maxTrackSize]="maxTrackSize" (hoverStart)="hoverStart = $event" (hoverEnd)="hoverEnd = $event" > @@ -803,7 +801,6 @@ class TestApp { labelAxisMode: DtStackedSeriesChartLabelAxisMode = 'full'; visibleValueAxis: boolean = true; mode: DtStackedSeriesChartMode; - maxTrackSize: number; theme = 'blue'; hasOverlay: boolean = true; diff --git a/libs/barista-components/stacked-series-chart/src/stacked-series-chart.ts b/libs/barista-components/stacked-series-chart/src/stacked-series-chart.ts index 3dee7161ec..4b74fe9eca 100644 --- a/libs/barista-components/stacked-series-chart/src/stacked-series-chart.ts +++ b/libs/barista-components/stacked-series-chart/src/stacked-series-chart.ts @@ -46,7 +46,6 @@ import { getDtChartColorPalette, } from '@dynatrace/barista-components/theming'; import { - NumberValue, ScaleLinear, scaleLinear, ScalePoint, @@ -56,49 +55,51 @@ import { } from 'd3-scale'; import { merge, ReplaySubject, Subject } from 'rxjs'; import { + debounceTime, + filter, first, - tap, + pairwise, switchMapTo, takeUntil, - debounceTime, - pairwise, - filter, + tap, } from 'rxjs/operators'; import { DtStackedSeriesChartNode } from '..'; import { - DtStackedSeriesChartOverlay, DtStackedSeriesChartHeatFieldOverlay, + DtStackedSeriesChartOverlay, } from './stacked-series-chart-overlay.directive'; import { DtStackedSeriesChartFilledSeries, DtStackedSeriesChartFillMode, + DtStackedSeriesChartLabelAxisMode, DtStackedSeriesChartLegend, DtStackedSeriesChartMode, + DtStackedSeriesChartSelection, + DtStackedSeriesChartSelectionMode, DtStackedSeriesChartSeries, DtStackedSeriesChartTooltipData, + DtStackedSeriesChartValueContinuousAxisMap, + DtStackedSeriesChartValueContinuousAxisType, DtStackedSeriesChartValueDisplayMode, - DtStackedSeriesChartSelectionMode, - DtStackedSeriesChartSelection, + DtStackedSeriesContinuousScale, + DtStackedSeriesContinuousTick, + DtStackedSeriesHeatField, + DtStackedSeriesHeatFieldLevel, + DtStackedSeriesHoverData, + DtStackedSeriesLegendHoverData, + DtStackedSeriesStackHoverData, fillSeries, getLegends, getSeriesWithState, getTotalMaxValue, - updateNodesVisibility, - DtStackedSeriesChartLabelAxisMode, - DtStackedSeriesStackHoverData, - DtStackedSeriesLegendHoverData, - DtStackedSeriesHoverData, - DtStackedSeriesChartValueContinuousAxisType, - DtStackedSeriesChartValueContinuousAxisMap, TimeInterval, - DtStackedSeriesHeatField, - DtStackedSeriesHeatFieldLevel, + updateNodesVisibility, } from './stacked-series-chart.util'; import { + BooleanInput, coerceBooleanProperty, coerceNumberProperty, NumberInput, - BooleanInput, } from '@angular/cdk/coercion'; import { Platform } from '@angular/cdk/platform'; @@ -107,6 +108,9 @@ const TICK_BAR_SPACING = 160; // vertical ticks const TICK_COLUMN_SPACING = 80; +// minimum tick for tracks +const MIN_TRACK_TICKS = 2; + @Component({ selector: 'dt-stacked-series-chart', exportAs: 'dtStackedSeriesChart', @@ -124,7 +128,6 @@ const TICK_COLUMN_SPACING = 80; '[class.dt-stacked-series-chart-with-value-axis]': 'visibleValueAxis', '[class.dt-stacked-series-chart-bar]': "mode === 'bar'", '[class.dt-stacked-series-chart-column]': "mode === 'column'", - '[style.--dt-stacked-series-chart-grid-gap]': '_gridGap', }, }) export class DtStackedSeriesChart implements OnDestroy, OnInit { @@ -328,7 +331,7 @@ export class DtStackedSeriesChart implements OnDestroy, OnInit { set maxTrackSize(value: number) { this._maxTrackSize = coerceNumberProperty(value); } - private _maxTrackSize = 16; + private _maxTrackSize: number; static ngAcceptInputType_maxTrackSize: NumberInput; /** Visibility of value axis */ @@ -345,6 +348,7 @@ export class DtStackedSeriesChart implements OnDestroy, OnInit { /** @internal Ticks for value axis */ _axisTicks: { position: number; value: number; valueRelative: number }[] = []; _trackTicks: { position: number; value: string }[] = []; + _defaultTicks: DtStackedSeriesContinuousTick[] = []; _trackAmount: number; /** @internal Value axis width to allow it inside the boundaries of the component */ @@ -371,12 +375,15 @@ export class DtStackedSeriesChart implements OnDestroy, OnInit { _selectedHeatFieldIndex: number = -1; @Input() labelAxisMode: DtStackedSeriesChartLabelAxisMode = 'full'; + /** @internal Support only for mode === 'column', wouldn't make sense for 'row' */ + private _isCompactModeEnabled: boolean = false; + get _labelAxisCompactModeEnabled(): boolean { return ( this.mode === 'column' && (this.labelAxisMode === 'compact' || - (this.labelAxisMode === 'auto' && this._isAnyLabelOverflowing())) + (this.labelAxisMode === 'auto' && this._isCompactModeEnabled)) ); } @@ -414,7 +421,10 @@ export class DtStackedSeriesChart implements OnDestroy, OnInit { @ContentChild(DtStackedSeriesChartHeatFieldOverlay, { read: TemplateRef }) _heatFieldOverlay: DtStackedSeriesChartHeatFieldOverlay; - /** @internal Reference to the root svgElement. */ + /** @internal Reference to the default label element. */ + @ViewChild('label') _defaultLabelElement: ElementRef; + + /** @internal Reference to the root axis Element. */ @ViewChild('valueAxis') _valueAxis: ElementRef; /** @internal Reference to the root element. */ @@ -486,13 +496,6 @@ export class DtStackedSeriesChart implements OnDestroy, OnInit { merge(this._shouldUpdateTicks, this._resizer.change()) .pipe( - tap(() => { - if (this.labelAxisMode === 'auto' && this.mode === 'column') { - // Recalculate every time the size changes only if we are on these modes - this._isAnyLabelOverflowing(); - this._changeDetectorRef.detectChanges(); - } - }), // Shift the updating/rendering to the next CD cycle, // because we need the dimensions of axis first, which is rendered in the main cycle. switchMapTo(this._zone.onStable.pipe(first())), @@ -505,6 +508,7 @@ export class DtStackedSeriesChart implements OnDestroy, OnInit { // the template bindings. this._zone.run(() => { this._updateTicks(); + this._isAnyLabelOverflowing(); this._changeDetectorRef.detectChanges(); }); }); @@ -516,7 +520,7 @@ export class DtStackedSeriesChart implements OnDestroy, OnInit { } /** @internal Toggle the selection of an element */ - _toggleSelect( + private _toggleSelect( series?: DtStackedSeriesChartSeries, node?: DtStackedSeriesChartNode, ): void { @@ -577,9 +581,14 @@ export class DtStackedSeriesChart implements OnDestroy, OnInit { * @internal Sanitization of the custom property is necessary as, custom property assignments do not work * in a viewEngine setup. This can be removed with angular version 10, if ivy is no longer opt out. */ - _sanitizeCSS(styles: [string, string | number | DtColors][]): SafeStyle { + _sanitizeCSS( + styles: ([string, string | number | DtColors] | [])[], + ): SafeStyle { return this._sanitizer.bypassSecurityTrustStyle( - styles.map(([prop, value]) => `${prop}: ${value}`).join('; '), + styles + .filter(([prop, value]) => prop && value != null) + .map(([prop, value]) => `${prop}: ${value}`) + .join('; '), ); } @@ -680,8 +689,7 @@ export class DtStackedSeriesChart implements OnDestroy, OnInit { () => { this._scale = scalePoint() .domain(mappedSeries as Iterable) - .range([0, 100]) - .padding(0.5); + .range([0, 100]); this._defaultLabel = mappedSeries?.reduce( (a, b) => ((a as string).length > (b as string).length ? a : b), @@ -734,8 +742,8 @@ export class DtStackedSeriesChart implements OnDestroy, OnInit { 'none', () => (bounds = [ - getPosition(this._tracks[0]), - getPosition(this._tracks.slice(-1)[0]), + this._tracks[0].position || 0, + this._tracks.slice(-1)[0].position || 0, ]), ], ]); @@ -795,31 +803,44 @@ export class DtStackedSeriesChart implements OnDestroy, OnInit { private _renderInner(): void { this._setScale(); + const getDistanceByValues = (trackA: number, trackB: number) => + (trackA || Infinity) - (trackB || 0); + const getNthTick = (minDistance, i) => + +this._scale.domain()[0] + minDistance * i; let getPosition; + let getDistance; + let getMappedNthTick; + this._applyFnForContinuousAxisType([ [ 'none', () => - (getPosition = (value) => - (this._scale as ScalePoint)( - this.continuousAxisMap(value) as string, - )), + (getPosition = (mappedValue) => + (this._scale as ScalePoint)(mappedValue)), ], [ 'linear', - () => - (getPosition = (value) => - (this._scale as ScaleLinear)( - this.continuousAxisMap(value) as NumberValue, - )), + () => { + getPosition = (mappedValue) => + (this._scale as ScaleLinear)(mappedValue); + getDistance = (track, i, tracks) => + getDistanceByValues(tracks[i + 1]?.mappedValue, track?.mappedValue); + getMappedNthTick = getNthTick; + }, ], [ 'date', - () => - (getPosition = (value) => - (this._scale as ScaleTime)( - this.continuousAxisMap(value) as Date, - )), + () => { + getPosition = (mappedValue) => + (this._scale as ScaleTime)(mappedValue); + getDistance = (track, i, tracks) => + getDistanceByValues( + +tracks[i + 1]?.mappedValue, + +track?.mappedValue, + ); + getMappedNthTick = (minDistance, i) => + new Date(getNthTick(minDistance, i)); + }, ], ]); @@ -827,21 +848,42 @@ export class DtStackedSeriesChart implements OnDestroy, OnInit { this._filledSeries, this._selected, this._fillMode === 'relative' ? this.max : undefined, - ).map((track) => ({ - ...track, - position: getPosition(track), - })); + ) + .map((track) => ({ + ...track, + mappedValue: this.continuousAxisMap(track), + })) + .map((track, i, tracks) => ({ + ...track, + position: getPosition(track.mappedValue), + distanceToNext: getDistance && getDistance(track, i, tracks), + })); // Calculating number of tracks (columns or bars) by their position // If there are <= 1 tracks, calculation is not possible so use track length try { - const [{ position: posA }, { position: posB }] = this._tracks.slice(0, 2); - this._trackAmount = Math.ceil(100 / ((posB || 0) - (posA || 0))); + if (this._isScalePoint) { + throw Error(); + } + + const range = this._tracks + .slice(0, -1) + .reduce((acc, { distanceToNext }) => acc + (distanceToNext || 0), 0); + const minDistance = Math.min( + ...this._tracks.map(({ distanceToNext }) => distanceToNext || Infinity), + ); + + this._trackAmount = Math.round(range / minDistance) + 1; + this._defaultTicks = Array(this._trackAmount) + .fill(null) + .map((_, i) => getMappedNthTick(minDistance, i)); } catch (e) { this._trackAmount = this._tracks.length; } - this._renderHeatFields(getPosition); + this._renderHeatFields((track) => + getPosition(this.continuousAxisMap(track)), + ); this._shouldUpdateTicks.next(); } @@ -855,6 +897,52 @@ export class DtStackedSeriesChart implements OnDestroy, OnInit { this._render(); } + /** Get usable width of axis container (column mode) */ + private _getAxisContainerWidth(): number { + return this._chartContainer.nativeElement.offsetWidth; + } + + /** Get usable width of axis container (column mode) */ + private _getTickGapWidth(): number { + return ( + (Math.abs( + (this._trackTicks[1]?.position || 0) - this._trackTicks[0].position, + ) * + this._getAxisContainerWidth()) / + 100 + ); + } + + /** Get usable width of axis container (column mode) */ + private _getTicksPerWidth(): number { + return Math.floor( + this._getAxisContainerWidth() / + this._defaultLabelElement.nativeElement.offsetWidth, + ); + } + + /** Get number of tick lower or equal than bar length */ + private _getLowerOrEqualTicks( + tickAmount: number, + ): DtStackedSeriesContinuousTick[] { + const upperBound = tickAmount; + + const isBarMode = this.mode === 'bar'; + let realTicks = isBarMode + ? this._defaultTicks + : (this._scale as DtStackedSeriesContinuousScale).ticks(tickAmount); + + if (!isBarMode && Number.isInteger(tickAmount)) { + while (tickAmount > MIN_TRACK_TICKS && realTicks.length > upperBound) { + realTicks = (this._scale as DtStackedSeriesContinuousScale).ticks( + --tickAmount, + ); + } + } + + return realTicks; + } + /** Calculate the ticks used for values */ private _updateTicks(): void { if (!this._platform.isBrowser) { @@ -869,63 +957,50 @@ export class DtStackedSeriesChart implements OnDestroy, OnInit { (this.mode === 'bar' ? this._tracks.length : Math.max( - 2, - Math.min( - this._tracks.length, - Math.floor( - (this._chartContainer.nativeElement.offsetWidth + - this._gridGap) / - this.labels.first.nativeElement.offsetWidth, - ), - ), + MIN_TRACK_TICKS, + Math.min(this._tracks.length, this._getTicksPerWidth()), )); this._applyFnForContinuousAxisType([ [ 'none', () => { - this._trackTicks = this._tracks - .map(this.continuousAxisMap) - .map((label: string) => { - return { - position: (this._scale as ScalePoint)(label) || 0, - value: label, - }; - }); + this._trackTicks = this._tracks.map( + ({ mappedValue, position }) => ({ + position: position || 0, + value: mappedValue, + }), + ); }, ], [ 'linear', () => { - this._trackTicks = (this._scale as ScaleTime) - .ticks(tickAmount) - .map((value) => { - return { - position: (this._scale as ScaleLinear)(value), - value: ( - this._scale as ScaleLinear - ).tickFormat( - Infinity, - this.continuousAxisFormat, - )(value), - }; - }); + this._trackTicks = this._getLowerOrEqualTicks( + tickAmount, + ).map((mappedValue) => ({ + position: (this._scale as ScaleLinear)( + mappedValue, + ), + value: (this._scale as ScaleLinear).tickFormat( + Infinity, + this.continuousAxisFormat, + )(mappedValue), + })); }, ], [ 'date', () => { - this._trackTicks = (this._scale as ScaleTime) - .ticks(tickAmount) - .map((value) => { - return { - position: (this._scale as ScaleTime)(value), - value: (this._scale as ScaleTime).tickFormat( - tickAmount, - this.continuousAxisFormat, - )(value), - }; - }); + this._trackTicks = this._getLowerOrEqualTicks( + tickAmount, + ).map((mappedValue) => ({ + position: (this._scale as ScaleTime)(mappedValue), + value: (this._scale as ScaleTime).tickFormat( + tickAmount, + this.continuousAxisFormat, + )(mappedValue), + })); }, ], ]); @@ -976,15 +1051,15 @@ export class DtStackedSeriesChart implements OnDestroy, OnInit { /** Whether there's a label on the label axis that is overflowing its allocated space on the css grid */ private _isAnyLabelOverflowing(): boolean { if ( + this.labelAxisMode !== 'auto' || + this.mode !== 'column' || !this.labels?.first || !this._trackTicks?.length || !this._chartContainer?.nativeElement ) - return false; - return ( - this.labels.first.nativeElement.offsetWidth > - (this._chartContainer.nativeElement.offsetWidth + this._gridGap) / - this._trackTicks.length - ); + return (this._isCompactModeEnabled = false); + + return (this._isCompactModeEnabled = + this.labels.first.nativeElement.offsetWidth > this._getTickGapWidth()); } } diff --git a/libs/barista-components/stacked-series-chart/src/stacked-series-chart.util.ts b/libs/barista-components/stacked-series-chart/src/stacked-series-chart.util.ts index cae5594c9b..a8588ef4a7 100644 --- a/libs/barista-components/stacked-series-chart/src/stacked-series-chart.util.ts +++ b/libs/barista-components/stacked-series-chart/src/stacked-series-chart.util.ts @@ -20,7 +20,7 @@ import { getDtChartColorPalette, } from '@dynatrace/barista-components/theming'; import { isEqual } from 'lodash-es'; -import { NumberValue } from 'd3-scale'; +import { NumberValue, ScaleLinear, ScaleTime } from 'd3-scale'; /** * Definition a series with all its nodes @@ -38,6 +38,10 @@ export interface DtStackedSeriesChartSeries { export interface DtStackedSeriesChartFilledSeries { /** Original series */ origin: DtStackedSeriesChartSeries; + /** Distance to next item */ + mappedValue?: string | NumberValue | Date; + /** Distance to next item */ + distanceToNext?: number; /** Position in % */ position?: number; /** Filled nodes for this series */ @@ -155,6 +159,10 @@ export interface DtStackedSeriesHeatFieldLevelItem { config: DtStackedSeriesHeatField; } export type DtStackedSeriesHeatFieldLevel = DtStackedSeriesHeatFieldLevelItem[]; +export type DtStackedSeriesContinuousScale = + | ScaleTime + | ScaleLinear; +export type DtStackedSeriesContinuousTick = Date | number; /** Output type for hovent output events, providing information on the hovered series and, when applicable, the hovered stack to the container component. */ export type DtStackedSeriesHoverData = diff --git a/libs/examples/src/stacked-series-chart/stacked-series-chart-column-example/stacked-series-chart-column-example.html b/libs/examples/src/stacked-series-chart/stacked-series-chart-column-example/stacked-series-chart-column-example.html index e9a041fce7..3453e85831 100644 --- a/libs/examples/src/stacked-series-chart/stacked-series-chart-column-example/stacked-series-chart-column-example.html +++ b/libs/examples/src/stacked-series-chart/stacked-series-chart-column-example/stacked-series-chart-column-example.html @@ -1,9 +1,4 @@ - + {{ tooltip.seriesOrigin.label }}
diff --git a/libs/examples/src/stacked-series-chart/stacked-series-chart-column-example/stacked-series-chart-column-example.scss b/libs/examples/src/stacked-series-chart/stacked-series-chart-column-example/stacked-series-chart-column-example.scss new file mode 100644 index 0000000000..fef76f6111 --- /dev/null +++ b/libs/examples/src/stacked-series-chart/stacked-series-chart-column-example/stacked-series-chart-column-example.scss @@ -0,0 +1,4 @@ +dt-stacked-series-chart { + --dt-stacked-series-chart-max-bar-size: 32px; + --dt-stacked-series-chart-grid-gap: 64px; +} diff --git a/libs/examples/src/stacked-series-chart/stacked-series-chart-column-example/stacked-series-chart-column-example.ts b/libs/examples/src/stacked-series-chart/stacked-series-chart-column-example/stacked-series-chart-column-example.ts index 6fbcc6dcb1..6bb49d165f 100644 --- a/libs/examples/src/stacked-series-chart/stacked-series-chart-column-example/stacked-series-chart-column-example.ts +++ b/libs/examples/src/stacked-series-chart/stacked-series-chart-column-example/stacked-series-chart-column-example.ts @@ -19,6 +19,7 @@ import { stackedSeriesChartDemoDataCoffee } from '../stacked-series-chart-demo-d @Component({ selector: 'dt-example-stacked-series-chart-column-barista', + styleUrls: ['./stacked-series-chart-column-example.scss'], templateUrl: './stacked-series-chart-column-example.html', }) export class DtExampleStackedSeriesChartColumn { diff --git a/libs/examples/src/stacked-series-chart/stacked-series-chart-date-example/stacked-series-chart-date-example.html b/libs/examples/src/stacked-series-chart/stacked-series-chart-date-example/stacked-series-chart-date-example.html index 79b36d723f..ca86f46fcb 100644 --- a/libs/examples/src/stacked-series-chart/stacked-series-chart-date-example/stacked-series-chart-date-example.html +++ b/libs/examples/src/stacked-series-chart/stacked-series-chart-date-example/stacked-series-chart-date-example.html @@ -1,7 +1,7 @@ +
Data
+ + Conversion/Bounces + Histogram - 30 min + Histogram - 7 days + +
Mode
Column diff --git a/libs/examples/src/stacked-series-chart/stacked-series-chart-date-example/stacked-series-chart-date-example.ts b/libs/examples/src/stacked-series-chart/stacked-series-chart-date-example/stacked-series-chart-date-example.ts index ecb00ce858..1da1947166 100644 --- a/libs/examples/src/stacked-series-chart/stacked-series-chart-date-example/stacked-series-chart-date-example.ts +++ b/libs/examples/src/stacked-series-chart/stacked-series-chart-date-example/stacked-series-chart-date-example.ts @@ -15,21 +15,39 @@ */ import { Component } from '@angular/core'; -import { stackedSeriesChartDemoDataConvertedBouncedDates } from '../stacked-series-chart-demo-data'; +import { + stackedSeriesChartDemoData_2h, + stackedSeriesChartDemoData_30m, + stackedSeriesChartDemoData_7d, +} from '../stacked-series-chart-demo-data'; import { timeMinute, timeHour } from 'd3-time'; -import { TimeInterval } from '@dynatrace/barista-components/stacked-series-chart'; +import { + DtStackedSeriesChartSeries, + DtStackedSeriesChartValueContinuousAxisMap, + TimeInterval, +} from '@dynatrace/barista-components/stacked-series-chart'; enum TimeIntervalKey { fiveMin, halfHour, hour, } +enum DataKey { + conversionBounces, + histogramThirtyMin, + histogramSevenDays, +} + +const conversionBouncesMap = ({ origin }) => { + const [hours, minutes] = origin.label.split(':').map(Number); + return new Date(0, 0, 0, hours, minutes, 0, 0); +}; +const histogramMap = ({ origin }) => new Date(origin.timeDate); @Component({ selector: 'dt-example-stacked-series-chart-date-barista', templateUrl: './stacked-series-chart-date-example.html', }) export class DtExampleStackedSeriesChartDate { - series = stackedSeriesChartDemoDataConvertedBouncedDates; mode: 'bar' | 'column' = 'column'; enableTimeInterval = false; @@ -39,13 +57,29 @@ export class DtExampleStackedSeriesChartDate { [TimeIntervalKey.halfHour]: timeMinute.every(30), [TimeIntervalKey.hour]: timeHour.every(1), }; + dataKey = DataKey.conversionBounces; + dataByKey: { + [key: string]: { + series: DtStackedSeriesChartSeries[]; + continuousAxisMap: DtStackedSeriesChartValueContinuousAxisMap; + }; + } = { + [DataKey.conversionBounces]: { + series: stackedSeriesChartDemoData_2h, + continuousAxisMap: conversionBouncesMap, + }, + [DataKey.histogramThirtyMin]: { + series: stackedSeriesChartDemoData_30m, + continuousAxisMap: histogramMap, + }, + [DataKey.histogramSevenDays]: { + series: stackedSeriesChartDemoData_7d, + continuousAxisMap: histogramMap, + }, + }; continuousAxisInterval = timeMinute.every(5); continuousAxisFormat = '%H:%M'; + DataKey = DataKey; TimeIntervalKey = TimeIntervalKey; - - continuousAxisMap = ({ origin }) => { - const [hours, minutes] = origin.label.split(':').map(Number); - return new Date(0, 0, 0, hours, minutes, 0, 0); - }; } diff --git a/libs/examples/src/stacked-series-chart/stacked-series-chart-demo-data.ts b/libs/examples/src/stacked-series-chart/stacked-series-chart-demo-data.ts index bc58752914..fe43bb85a5 100644 --- a/libs/examples/src/stacked-series-chart/stacked-series-chart-demo-data.ts +++ b/libs/examples/src/stacked-series-chart/stacked-series-chart-demo-data.ts @@ -214,22 +214,476 @@ export const stackedSeriesChartDemoDataShows: DtStackedSeriesChartSeries[] = [ }, ]; -export const stackedSeriesChartDemoDataConvertedBouncedDates = [ +export const stackedSeriesChartDemoData_7d = [ + { + label: 'Jan, 08 / 24:00', + timeDate: '2022-01-07T23:00:00.000Z', + nodes: [ + { + label: 'Espresso', + value: 0, + color: '#debbf3', + }, + { + label: 'Americano', + value: 4977536, + color: '#612c85', + }, + ], + }, + { + label: 'Jan, 08 / 12:00', + timeDate: '2022-01-08T11:00:00.000Z', + nodes: [ + { + label: 'Espresso', + value: 0, + color: '#debbf3', + }, + { + label: 'Americano', + value: 4935872, + color: '#612c85', + }, + ], + }, + { + label: 'Jan, 09 / 24:00', + timeDate: '2022-01-08T23:00:00.000Z', + nodes: [ + { + label: 'Espresso', + value: 0, + color: '#debbf3', + }, + { + label: 'Americano', + value: 4967168, + color: '#612c85', + }, + ], + }, + { + label: 'Jan, 09 / 12:00', + timeDate: '2022-01-09T11:00:00.000Z', + nodes: [ + { + label: 'Espresso', + value: 0, + color: '#debbf3', + }, + { + label: 'Americano', + value: 4985472, + color: '#612c85', + }, + ], + }, + { + label: 'Jan, 10 / 24:00', + timeDate: '2022-01-09T23:00:00.000Z', + nodes: [ + { + label: 'Espresso', + value: 0, + color: '#debbf3', + }, + { + label: 'Americano', + value: 4960000, + color: '#612c85', + }, + ], + }, + { + label: 'Jan, 10 / 12:00', + timeDate: '2022-01-10T11:00:00.000Z', + nodes: [ + { + label: 'Espresso', + value: 0, + color: '#debbf3', + }, + { + label: 'Americano', + value: 4932160, + color: '#612c85', + }, + ], + }, + { + label: 'Jan, 11 / 24:00', + timeDate: '2022-01-10T23:00:00.000Z', + nodes: [ + { + label: 'Espresso', + value: 0, + color: '#debbf3', + }, + { + label: 'Americano', + value: 4998400, + color: '#612c85', + }, + ], + }, + { + label: 'Jan, 11 / 12:00', + timeDate: '2022-01-11T11:00:00.000Z', + nodes: [ + { + label: 'Espresso', + value: 0, + color: '#debbf3', + }, + { + label: 'Americano', + value: 4954048, + color: '#612c85', + }, + ], + }, + { + label: 'Jan, 12 / 24:00', + timeDate: '2022-01-11T23:00:00.000Z', + nodes: [ + { + label: 'Espresso', + value: 0, + color: '#debbf3', + }, + { + label: 'Americano', + value: 4950720, + color: '#612c85', + }, + ], + }, + { + label: 'Jan, 12 / 12:00', + timeDate: '2022-01-12T11:00:00.000Z', + nodes: [ + { + label: 'Espresso', + value: 0, + color: '#debbf3', + }, + { + label: 'Americano', + value: 4917568, + color: '#612c85', + }, + ], + }, + { + label: 'Jan, 13 / 24:00', + timeDate: '2022-01-12T23:00:00.000Z', + nodes: [ + { + label: 'Espresso', + value: 0, + color: '#debbf3', + }, + { + label: 'Americano', + value: 4960640, + color: '#612c85', + }, + ], + }, + { + label: 'Jan, 13 / 12:00', + timeDate: '2022-01-13T11:00:00.000Z', + nodes: [ + { + label: 'Espresso', + value: 0, + color: '#debbf3', + }, + { + label: 'Americano', + value: 4977920, + color: '#612c85', + }, + ], + }, + { + label: 'Jan, 14 / 24:00', + timeDate: '2022-01-13T23:00:00.000Z', + nodes: [ + { + label: 'Espresso', + value: 1, + color: '#debbf3', + }, + { + label: 'Americano', + value: 5019712, + color: '#612c85', + }, + ], + }, + { + label: 'Jan, 14 / 12:00', + timeDate: '2022-01-14T11:00:00.000Z', + nodes: [ + { + label: 'Espresso', + value: 242808, + color: '#debbf3', + }, + { + label: 'Americano', + value: 1568960, + color: '#612c85', + }, + ], + }, +]; + +export const stackedSeriesChartDemoData_30m = [ + { + label: '14:56', + timeDate: '2022-01-14T13:56:00.000Z', + nodes: [ + { + label: 'Espresso', + value: 13448, + color: '#debbf3', + }, + { + label: 'Americano', + value: 119, + color: '#612c85', + }, + ], + }, + { + label: '15:00', + timeDate: '2022-01-14T14:00:00.000Z', + nodes: [ + { + label: 'Espresso', + value: 13604, + color: '#debbf3', + }, + { + label: 'Americano', + value: 121, + color: '#612c85', + }, + ], + }, + { + label: '15:02', + timeDate: '2022-01-14T14:02:00.000Z', + nodes: [ + { + label: 'Espresso', + value: 13018, + color: '#debbf3', + }, + { + label: 'Americano', + value: 128, + color: '#612c85', + }, + ], + }, + { + label: '15:04', + timeDate: '2022-01-14T14:04:00.000Z', + nodes: [ + { + label: 'Espresso', + value: 13909, + color: '#debbf3', + }, + { + label: 'Americano', + value: 117, + color: '#612c85', + }, + ], + }, + { + label: '15:06', + timeDate: '2022-01-14T14:06:00.000Z', + nodes: [ + { + label: 'Espresso', + value: 13860, + color: '#debbf3', + }, + { + label: 'Americano', + value: 126, + color: '#612c85', + }, + ], + }, + { + label: '15:08', + timeDate: '2022-01-14T14:08:00.000Z', + nodes: [ + { + label: 'Espresso', + value: 13634, + color: '#debbf3', + }, + { + label: 'Americano', + value: 122, + color: '#612c85', + }, + ], + }, + { + label: '15:10', + timeDate: '2022-01-14T14:10:00.000Z', + nodes: [ + { + label: 'Espresso', + value: 13499, + color: '#debbf3', + }, + { + label: 'Americano', + value: 121, + color: '#612c85', + }, + ], + }, + { + label: '15:12', + timeDate: '2022-01-14T14:12:00.000Z', + nodes: [ + { + label: 'Espresso', + value: 13780, + color: '#debbf3', + }, + { + label: 'Americano', + value: 119, + color: '#612c85', + }, + ], + }, + { + label: '15:14', + timeDate: '2022-01-14T14:14:00.000Z', + nodes: [ + { + label: 'Espresso', + value: 13722, + color: '#debbf3', + }, + { + label: 'Americano', + value: 118, + color: '#612c85', + }, + ], + }, + { + label: '15:16', + timeDate: '2022-01-14T14:16:00.000Z', + nodes: [ + { + label: 'Espresso', + value: 13732, + color: '#debbf3', + }, + { + label: 'Americano', + value: 78, + color: '#612c85', + }, + ], + }, + { + label: '15:18', + timeDate: '2022-01-14T14:18:00.000Z', + nodes: [ + { + label: 'Espresso', + value: 13642, + color: '#debbf3', + }, + { + label: 'Americano', + value: 38, + color: '#612c85', + }, + ], + }, + { + label: '15:20', + timeDate: '2022-01-14T14:20:00.000Z', + nodes: [ + { + label: 'Espresso', + value: 12890, + color: '#debbf3', + }, + { + label: 'Americano', + value: 20, + color: '#612c85', + }, + ], + }, + { + label: '15:22', + timeDate: '2022-01-14T14:22:00.000Z', + nodes: [ + { + label: 'Espresso', + value: 11422, + color: '#debbf3', + }, + { + label: 'Americano', + value: 0, + color: '#612c85', + }, + ], + }, + { + label: '15:24', + timeDate: '2022-01-14T14:24:00.000Z', + nodes: [ + { + label: 'Espresso', + value: 617, + color: '#debbf3', + }, + { + label: 'Americano', + value: 0, + color: '#612c85', + }, + ], + }, +]; + +export const stackedSeriesChartDemoData_2h = [ { label: '11:35', nodes: [ { - label: 'Converted', + label: 'Espresso', color: '#612c85', value: 5, }, { - label: 'Bounced', + label: 'Americano', color: '#a972cc', value: 3, }, { - label: 'Neither converted or bounced', + label: 'Mocha', color: '#debbf3', value: 2, }, @@ -239,17 +693,17 @@ export const stackedSeriesChartDemoDataConvertedBouncedDates = [ label: '11:40', nodes: [ { - label: 'Converted', + label: 'Espresso', color: '#612c85', value: 0, }, { - label: 'Bounced', + label: 'Americano', color: '#a972cc', value: 0, }, { - label: 'Neither converted or bounced', + label: 'Mocha', color: '#debbf3', value: 34, }, @@ -259,17 +713,17 @@ export const stackedSeriesChartDemoDataConvertedBouncedDates = [ label: '11:45', nodes: [ { - label: 'Converted', + label: 'Espresso', color: '#612c85', value: 0, }, { - label: 'Bounced', + label: 'Americano', color: '#a972cc', value: 0, }, { - label: 'Neither converted or bounced', + label: 'Mocha', color: '#debbf3', value: 991, }, @@ -279,17 +733,17 @@ export const stackedSeriesChartDemoDataConvertedBouncedDates = [ label: '11:50', nodes: [ { - label: 'Converted', + label: 'Espresso', color: '#612c85', value: 0, }, { - label: 'Bounced', + label: 'Americano', color: '#a972cc', value: 3880, }, { - label: 'Neither converted or bounced', + label: 'Mocha', color: '#debbf3', value: 16550, }, @@ -299,17 +753,17 @@ export const stackedSeriesChartDemoDataConvertedBouncedDates = [ label: '11:55', nodes: [ { - label: 'Converted', + label: 'Espresso', color: '#612c85', value: 0, }, { - label: 'Bounced', + label: 'Americano', color: '#a972cc', value: 9048, }, { - label: 'Neither converted or bounced', + label: 'Mocha', color: '#debbf3', value: 24252, }, @@ -319,17 +773,17 @@ export const stackedSeriesChartDemoDataConvertedBouncedDates = [ label: '12:00', nodes: [ { - label: 'Converted', + label: 'Espresso', color: '#612c85', value: 0, }, { - label: 'Bounced', + label: 'Americano', color: '#a972cc', value: 9178, }, { - label: 'Neither converted or bounced', + label: 'Mocha', color: '#debbf3', value: 24130, }, @@ -339,17 +793,17 @@ export const stackedSeriesChartDemoDataConvertedBouncedDates = [ label: '12:05', nodes: [ { - label: 'Converted', + label: 'Espresso', color: '#612c85', value: 0, }, { - label: 'Bounced', + label: 'Americano', color: '#a972cc', value: 9283, }, { - label: 'Neither converted or bounced', + label: 'Mocha', color: '#debbf3', value: 24197, }, @@ -359,17 +813,17 @@ export const stackedSeriesChartDemoDataConvertedBouncedDates = [ label: '12:10', nodes: [ { - label: 'Converted', + label: 'Espresso', color: '#612c85', value: 0, }, { - label: 'Bounced', + label: 'Americano', color: '#a972cc', value: 9240, }, { - label: 'Neither converted or bounced', + label: 'Mocha', color: '#debbf3', value: 23464, }, @@ -379,17 +833,17 @@ export const stackedSeriesChartDemoDataConvertedBouncedDates = [ label: '12:15', nodes: [ { - label: 'Converted', + label: 'Espresso', color: '#612c85', value: 0, }, { - label: 'Bounced', + label: 'Americano', color: '#a972cc', value: 9113, }, { - label: 'Neither converted or bounced', + label: 'Mocha', color: '#debbf3', value: 22858, }, @@ -399,17 +853,17 @@ export const stackedSeriesChartDemoDataConvertedBouncedDates = [ label: '12:20', nodes: [ { - label: 'Converted', + label: 'Espresso', color: '#612c85', value: 0, }, { - label: 'Bounced', + label: 'Americano', color: '#a972cc', value: 9346, }, { - label: 'Neither converted or bounced', + label: 'Mocha', color: '#debbf3', value: 24407, }, @@ -419,17 +873,17 @@ export const stackedSeriesChartDemoDataConvertedBouncedDates = [ label: '12:25', nodes: [ { - label: 'Converted', + label: 'Espresso', color: '#612c85', value: 0, }, { - label: 'Bounced', + label: 'Americano', color: '#a972cc', value: 9234, }, { - label: 'Neither converted or bounced', + label: 'Mocha', color: '#debbf3', value: 22962, }, @@ -439,17 +893,17 @@ export const stackedSeriesChartDemoDataConvertedBouncedDates = [ label: '12:30', nodes: [ { - label: 'Converted', + label: 'Espresso', color: '#612c85', value: 0, }, { - label: 'Bounced', + label: 'Americano', color: '#a972cc', value: 9139, }, { - label: 'Neither converted or bounced', + label: 'Mocha', color: '#debbf3', value: 24191, }, @@ -459,17 +913,17 @@ export const stackedSeriesChartDemoDataConvertedBouncedDates = [ label: '12:35', nodes: [ { - label: 'Converted', + label: 'Espresso', color: '#612c85', value: 0, }, { - label: 'Bounced', + label: 'Americano', color: '#a972cc', value: 9100, }, { - label: 'Neither converted or bounced', + label: 'Mocha', color: '#debbf3', value: 24208, }, @@ -479,17 +933,17 @@ export const stackedSeriesChartDemoDataConvertedBouncedDates = [ label: '12:40', nodes: [ { - label: 'Converted', + label: 'Espresso', color: '#612c85', value: 0, }, { - label: 'Bounced', + label: 'Americano', color: '#a972cc', value: 9000, }, { - label: 'Neither converted or bounced', + label: 'Mocha', color: '#debbf3', value: 24396, }, @@ -499,17 +953,17 @@ export const stackedSeriesChartDemoDataConvertedBouncedDates = [ label: '12:45', nodes: [ { - label: 'Converted', + label: 'Espresso', color: '#612c85', value: 0, }, { - label: 'Bounced', + label: 'Americano', color: '#a972cc', value: 8970, }, { - label: 'Neither converted or bounced', + label: 'Mocha', color: '#debbf3', value: 24362, }, @@ -519,17 +973,17 @@ export const stackedSeriesChartDemoDataConvertedBouncedDates = [ label: '12:50', nodes: [ { - label: 'Converted', + label: 'Espresso', color: '#612c85', value: 0, }, { - label: 'Bounced', + label: 'Americano', color: '#a972cc', value: 9121, }, { - label: 'Neither converted or bounced', + label: 'Mocha', color: '#debbf3', value: 24001, }, @@ -539,17 +993,17 @@ export const stackedSeriesChartDemoDataConvertedBouncedDates = [ label: '12:55', nodes: [ { - label: 'Converted', + label: 'Espresso', color: '#612c85', value: 0, }, { - label: 'Bounced', + label: 'Americano', color: '#a972cc', value: 9116, }, { - label: 'Neither converted or bounced', + label: 'Mocha', color: '#debbf3', value: 24342, }, @@ -559,17 +1013,17 @@ export const stackedSeriesChartDemoDataConvertedBouncedDates = [ label: '13:00', nodes: [ { - label: 'Converted', + label: 'Espresso', color: '#612c85', value: 0, }, { - label: 'Bounced', + label: 'Americano', color: '#a972cc', value: 9083, }, { - label: 'Neither converted or bounced', + label: 'Mocha', color: '#debbf3', value: 23997, }, @@ -579,17 +1033,17 @@ export const stackedSeriesChartDemoDataConvertedBouncedDates = [ label: '13:05', nodes: [ { - label: 'Converted', + label: 'Espresso', color: '#612c85', value: 0, }, { - label: 'Bounced', + label: 'Americano', color: '#a972cc', value: 9073, }, { - label: 'Neither converted or bounced', + label: 'Mocha', color: '#debbf3', value: 24192, }, @@ -599,17 +1053,17 @@ export const stackedSeriesChartDemoDataConvertedBouncedDates = [ label: '13:10', nodes: [ { - label: 'Converted', + label: 'Espresso', color: '#612c85', value: 0, }, { - label: 'Bounced', + label: 'Americano', color: '#a972cc', value: 9119, }, { - label: 'Neither converted or bounced', + label: 'Mocha', color: '#debbf3', value: 21318, }, @@ -619,17 +1073,17 @@ export const stackedSeriesChartDemoDataConvertedBouncedDates = [ label: '13:15', nodes: [ { - label: 'Converted', + label: 'Espresso', color: '#612c85', value: 0, }, { - label: 'Bounced', + label: 'Americano', color: '#a972cc', value: 2760, }, { - label: 'Neither converted or bounced', + label: 'Mocha', color: '#debbf3', value: 2793, }, @@ -639,17 +1093,17 @@ export const stackedSeriesChartDemoDataConvertedBouncedDates = [ label: '13:20', nodes: [ { - label: 'Converted', + label: 'Espresso', color: '#612c85', value: 0, }, { - label: 'Bounced', + label: 'Americano', color: '#a972cc', value: 134, }, { - label: 'Neither converted or bounced', + label: 'Mocha', color: '#debbf3', value: 72, }, @@ -659,17 +1113,17 @@ export const stackedSeriesChartDemoDataConvertedBouncedDates = [ label: '13:25', nodes: [ { - label: 'Converted', + label: 'Espresso', color: '#612c85', value: 0, }, { - label: 'Bounced', + label: 'Americano', color: '#a972cc', value: 142, }, { - label: 'Neither converted or bounced', + label: 'Mocha', color: '#debbf3', value: 71, }, @@ -679,17 +1133,17 @@ export const stackedSeriesChartDemoDataConvertedBouncedDates = [ label: '13:30', nodes: [ { - label: 'Converted', + label: 'Espresso', color: '#612c85', value: 0, }, { - label: 'Bounced', + label: 'Americano', color: '#a972cc', value: 147, }, { - label: 'Neither converted or bounced', + label: 'Mocha', color: '#debbf3', value: 70, }, @@ -699,17 +1153,17 @@ export const stackedSeriesChartDemoDataConvertedBouncedDates = [ label: '13:35', nodes: [ { - label: 'Converted', + label: 'Espresso', color: '#612c85', value: 0, }, { - label: 'Bounced', + label: 'Americano', color: '#a972cc', value: 132, }, { - label: 'Neither converted or bounced', + label: 'Mocha', color: '#debbf3', value: 68, }, @@ -719,17 +1173,17 @@ export const stackedSeriesChartDemoDataConvertedBouncedDates = [ label: '13:40', nodes: [ { - label: 'Converted', + label: 'Espresso', color: '#612c85', value: 0, }, { - label: 'Bounced', + label: 'Americano', color: '#a972cc', value: 141, }, { - label: 'Neither converted or bounced', + label: 'Mocha', color: '#debbf3', value: 69, }, @@ -739,17 +1193,17 @@ export const stackedSeriesChartDemoDataConvertedBouncedDates = [ label: '13:45', nodes: [ { - label: 'Converted', + label: 'Espresso', color: '#612c85', value: 0, }, { - label: 'Bounced', + label: 'Americano', color: '#a972cc', value: 96, }, { - label: 'Neither converted or bounced', + label: 'Mocha', color: '#debbf3', value: 43, }, @@ -759,17 +1213,17 @@ export const stackedSeriesChartDemoDataConvertedBouncedDates = [ label: '13:50', nodes: [ { - label: 'Converted', + label: 'Espresso', color: '#612c85', value: 0, }, { - label: 'Bounced', + label: 'Americano', color: '#a972cc', value: 0, }, { - label: 'Neither converted or bounced', + label: 'Mocha', color: '#debbf3', value: 0, }, diff --git a/libs/examples/src/stacked-series-chart/stacked-series-chart-heat-field-example/stacked-series-chart-heat-field-example.html b/libs/examples/src/stacked-series-chart/stacked-series-chart-heat-field-example/stacked-series-chart-heat-field-example.html index da3a7f99cd..0452567389 100644 --- a/libs/examples/src/stacked-series-chart/stacked-series-chart-heat-field-example/stacked-series-chart-heat-field-example.html +++ b/libs/examples/src/stacked-series-chart/stacked-series-chart-heat-field-example/stacked-series-chart-heat-field-example.html @@ -2,7 +2,6 @@ [mode]="mode" [series]="series" [heatFields]="heatFieldsByType[heatFieldType]" - maxTrackSize="32" style="height: 300px" > diff --git a/libs/examples/src/stacked-series-chart/stacked-series-chart-heat-field-example/stacked-series-chart-heat-field-example.scss b/libs/examples/src/stacked-series-chart/stacked-series-chart-heat-field-example/stacked-series-chart-heat-field-example.scss new file mode 100644 index 0000000000..928b0172a1 --- /dev/null +++ b/libs/examples/src/stacked-series-chart/stacked-series-chart-heat-field-example/stacked-series-chart-heat-field-example.scss @@ -0,0 +1,4 @@ +dt-stacked-series-chart { + --dt-stacked-series-chart-max-bar-size: 32px; + --dt-stacked-series-chart-grid-gap: 32px; +} diff --git a/libs/examples/src/stacked-series-chart/stacked-series-chart-heat-field-example/stacked-series-chart-heat-field-example.ts b/libs/examples/src/stacked-series-chart/stacked-series-chart-heat-field-example/stacked-series-chart-heat-field-example.ts index 7cbe2cfffa..8133d0a977 100644 --- a/libs/examples/src/stacked-series-chart/stacked-series-chart-heat-field-example/stacked-series-chart-heat-field-example.ts +++ b/libs/examples/src/stacked-series-chart/stacked-series-chart-heat-field-example/stacked-series-chart-heat-field-example.ts @@ -23,6 +23,7 @@ import { @Component({ selector: 'dt-example-heat-field-stacked-series-chart', + styleUrls: ['./stacked-series-chart-heat-field-example.scss'], templateUrl: './stacked-series-chart-heat-field-example.html', }) export class DtExampleStackedSeriesChartHeatField { diff --git a/libs/examples/src/stacked-series-chart/stacked-series-chart-linear-example/stacked-series-chart-linear-example.html b/libs/examples/src/stacked-series-chart/stacked-series-chart-linear-example/stacked-series-chart-linear-example.html index bfc288df05..f9fdaf2af9 100644 --- a/libs/examples/src/stacked-series-chart/stacked-series-chart-linear-example/stacked-series-chart-linear-example.html +++ b/libs/examples/src/stacked-series-chart/stacked-series-chart-linear-example/stacked-series-chart-linear-example.html @@ -4,6 +4,7 @@ [continuousAxisMap]="continuousAxisMap" [continuousAxisFormat]="continuousAxisFormat" continuousAxisType="linear" + labelAxisMode="auto" style="min-height: 200px" > diff --git a/libs/examples/src/stacked-series-chart/stacked-series-chart-linear-example/stacked-series-chart-linear-example.ts b/libs/examples/src/stacked-series-chart/stacked-series-chart-linear-example/stacked-series-chart-linear-example.ts index 14e2d898b0..c2160e0532 100644 --- a/libs/examples/src/stacked-series-chart/stacked-series-chart-linear-example/stacked-series-chart-linear-example.ts +++ b/libs/examples/src/stacked-series-chart/stacked-series-chart-linear-example/stacked-series-chart-linear-example.ts @@ -22,7 +22,7 @@ import { } from '@dynatrace/barista-components/stacked-series-chart'; @Component({ - selector: 'dt-example-stacked-series-chart-date-barista', + selector: 'dt-example-stacked-series-chart-linear-barista', templateUrl: './stacked-series-chart-linear-example.html', }) export class DtExampleStackedSeriesChartLinear {