diff --git a/packages/analytics/analytics-chart/README.md b/packages/analytics/analytics-chart/README.md index 6d4a2eb16e..60562c21b6 100644 --- a/packages/analytics/analytics-chart/README.md +++ b/packages/analytics/analytics-chart/README.md @@ -94,7 +94,7 @@ yarn add @kong-ui-public/analytics-chart - type: `string` - required: `false` -- default: `'400px'` +- default: `'500px'` - set the chart height using css height values (px, %, etc...) #### `width` diff --git a/packages/analytics/analytics-chart/sandbox/App.vue b/packages/analytics/analytics-chart/sandbox/App.vue index 90ffc98af0..c8e1ac2656 100644 --- a/packages/analytics/analytics-chart/sandbox/App.vue +++ b/packages/analytics/analytics-chart/sandbox/App.vue @@ -360,9 +360,15 @@ const metricItems = [{ unit: 'bytes', }] +// Short labels const statusCodeLabels = [ - '200', '300', '400', '500', 'This is a really long chart label to test long labels', + '200', '300', '400', '500', ] + +// Long labels +// const statusCodeLabels = [ +// 'getmeakong123', 'getmeakong123123', 'testservice1233', 'testtesttest123123', 'This is a really long chart label to test long labels', +// ] const statusCodeDimensionValues = ref(new Set(statusCodeLabels)) const serviceDimensionValues = ref(new Set([ diff --git a/packages/analytics/analytics-chart/src/components/AnalyticsChart.vue b/packages/analytics/analytics-chart/src/components/AnalyticsChart.vue index 815b61b928..e306714429 100644 --- a/packages/analytics/analytics-chart/src/components/AnalyticsChart.vue +++ b/packages/analytics/analytics-chart/src/components/AnalyticsChart.vue @@ -48,6 +48,7 @@
@@ -104,7 +103,7 @@ import { ChartTypes, ChartLegendPosition } from '../enums' import StackedBarChart from './chart-types/StackedBarChart.vue' import DoughnutChart from './chart-types/DoughnutChart.vue' import type { PropType } from 'vue' -import { computed, provide, toRef } from 'vue' +import { computed, provide, ref, toRef } from 'vue' import { GranularityKeys, msToGranularity } from '@kong-ui-public/analytics-utilities' import type { AnalyticsExploreResult, AnalyticsExploreV2Result, GranularityFullObj } from '@kong-ui-public/analytics-utilities' import { datavisPalette, hasMillisecondTimestamps } from '../utils' @@ -151,7 +150,7 @@ const props = defineProps({ height: { type: String, required: false, - default: '400px', + default: '500px', validator: (value: string): boolean => { return /(\d *)(px|%)/.test(value) }, @@ -177,6 +176,11 @@ const props = defineProps({ }) const { i18n } = composables.useI18n() +const heightRef = ref(props.height) + +const handleHeightUpdate = (height: number) => { + heightRef.value = `${height}px` +} const computedChartData = computed(() => { return isTimeSeriesChart.value @@ -315,6 +319,10 @@ provide('legendPosition', toRef(props, 'legendPosition')) margin: $kui-space-60; padding: $kui-space-60; + .analytics-chart-parent { + overflow: hidden; + } + .chart-empty-state { padding: $kui-space-70 $kui-space-0 $kui-space-60 $kui-space-0; } diff --git a/packages/analytics/analytics-chart/src/components/chart-plugins/ChartLegend.vue b/packages/analytics/analytics-chart/src/components/chart-plugins/ChartLegend.vue index 221c92ad60..656fc4a9bc 100644 --- a/packages/analytics/analytics-chart/src/components/chart-plugins/ChartLegend.vue +++ b/packages/analytics/analytics-chart/src/components/chart-plugins/ChartLegend.vue @@ -17,6 +17,7 @@ :style="{ background: fillStyle, 'border-color': strokeStyle }" />
import { ChartLegendPosition } from '../../enums' -import { Chart } from 'chart.js' -import { inject, onBeforeUnmount, onMounted, ref, watch } from 'vue' +import { Chart, type LegendItem } from 'chart.js' +import { inject, onBeforeUnmount, onMounted, ref, watch, type PropType } from 'vue' +import { KUI_SPACE_100 } from '@kong/design-tokens' const props = defineProps({ id: { @@ -48,7 +50,7 @@ const props = defineProps({ required: true, }, items: { - type: Array, + type: Object as PropType, required: true, }, chartInstance: { @@ -57,9 +59,13 @@ const props = defineProps({ default: () => null, }, }) + const legendContainerRef = ref() const legendItemsRef = ref([]) const shouldTruncate = ref(false) +const showValues = inject('showLegendValues', true) +const position = inject('legendPosition', ref(ChartLegendPosition.Right)) +const legendItemsTracker = ref([]) // Return the number of rows for a grid layout // by cmparing the top position of each item. @@ -95,9 +101,55 @@ const checkForWrap = () => { } } -watch(() => props.items, checkForWrap, { immediate: true, flush: 'post' }) +// Set the grid-template-columns style based on the width of the widest item +const formatGrid = () => { + if (legendContainerRef.value && position.value === ChartLegendPosition.Bottom) { + let maxWidth = 0 + + legendItemsRef.value.forEach(item => { + // Each
  • has two elements: the legend and the label. + // Sum the width of each element to get the total width of the item. + const width = Array.from(item.children).reduce((total, element) => { + return total + (element as HTMLElement).offsetWidth + }, 0) + if (width > maxWidth) { + maxWidth = width + } + }) + const padding = parseInt(KUI_SPACE_100, 10) + legendContainerRef.value.style.gridTemplateColumns = `repeat(auto-fit, ${maxWidth + padding}px)` + } +} + +const legendItemsChanged = () => { + if (props.items.length !== legendItemsTracker.value.length) { + legendItemsTracker.value = props.items + return true + } + + for (let i = 0; i < props.items.length; i++) { + if (props.items[i].text !== legendItemsTracker.value[i].text) { + legendItemsTracker.value = props.items + return true + } + } + + return false +} + +watch(() => props.items, () => { + checkForWrap() + if (legendItemsChanged()) { + formatGrid() + } +}, { immediate: true, flush: 'post' }) + +watch(() => position.value, () => { + formatGrid() +}) onMounted(() => { + legendItemsTracker.value = props.items window.addEventListener('resize', checkForWrap) }) @@ -149,16 +201,12 @@ const positionToClass = (position: `${ChartLegendPosition}`) => { }[position] } -const showValues = inject('showLegendValues', true) -const position = inject('legendPosition', ref(ChartLegendPosition.Right)) -