fix: adjust analytics chart layout
Some checks failed
CI/CD Pipeline / Quality Gate (push) Failing after 33s
CI/CD Pipeline / Build and Deploy Dev via Compose (push) Has been skipped

This commit is contained in:
Gleb Korotkiy
2026-06-21 13:25:44 +03:00
parent da273308f9
commit 099d7d3f1f
2 changed files with 94 additions and 56 deletions

View File

@@ -562,6 +562,10 @@ select {
align-content: start;
}
.analytics-card--trend .analytics-card__content {
grid-template-rows: auto minmax(0, 1fr);
}
.analytics-card--industries .analytics-card__content {
align-content: start;
}
@@ -613,35 +617,6 @@ select {
overflow-wrap: anywhere;
}
.analytics-card__icon-button {
display: inline-flex;
width: 36px;
height: 36px;
flex: 0 0 auto;
align-items: center;
justify-content: center;
padding: 0;
border: 0;
border-radius: 10px;
background: transparent;
color: rgb(2 36 86 / 0.22);
cursor: pointer;
transition:
background-color 160ms ease,
color 160ms ease;
}
.analytics-card__icon-button:hover,
.analytics-card__icon-button:focus-visible {
background: var(--Infographic-BG-Cards, #f3f3f3);
color: var(--Infographic-Main-Dark-Blue, #022456);
}
.analytics-card__icon-button svg {
width: 20px;
height: 20px;
}
.composition-layout {
display: grid;
grid-template-columns: minmax(0, 280px) minmax(0, 1fr);
@@ -1442,25 +1417,59 @@ select {
}
.trend-chart-box {
height: 250px;
min-width: 0;
min-height: 0;
height: 100%;
overflow: hidden;
}
.trend-chart-box > * {
height: 100%;
}
.trend-chart-box .unovis-xy-container {
--vis-axis-tick-label-font-size: 14px;
height: 100% !important;
}
.cluster-trend-chart-scroll {
position: relative;
min-width: 0;
height: 280px;
min-height: 0;
height: 100%;
padding-bottom: 18px;
}
.cluster-trend-chart-scroll::before {
position: absolute;
z-index: 0;
top: 42px;
right: 6px;
bottom: 44px;
left: 6px;
pointer-events: none;
content: '';
background: repeating-linear-gradient(
to bottom,
rgb(2 36 86 / 0.11) 0,
rgb(2 36 86 / 0.11) 1px,
transparent 1px,
transparent 25%
);
}
.cluster-trend-chart-scroll [data-slot='scroll-area-viewport'] {
position: relative;
z-index: 1;
height: 100%;
padding-bottom: 12px;
}
.cluster-trend-chart-scroll [data-slot='scroll-area-viewport'] > * {
min-height: 100%;
height: 100%;
}
.cluster-trend-chart-scroll [data-slot='scroll-area-scrollbar'] {
right: 6px;
bottom: 4px;
@@ -1475,17 +1484,19 @@ select {
.cluster-trend-chart {
display: grid;
height: 250px;
min-height: 0;
height: 100%;
grid-auto-flow: column;
grid-auto-columns: minmax(104px, 1fr);
gap: 18px;
align-items: end;
padding: 6px 6px 0;
padding: 42px 6px 0;
}
.cluster-trend-chart__item {
position: relative;
display: grid;
height: 100%;
min-width: 0;
grid-template-rows: minmax(120px, 1fr) auto;
align-items: end;
@@ -1521,7 +1532,8 @@ select {
.cluster-trend-chart__bar-wrap {
position: relative;
display: flex;
height: 150px;
min-height: 150px;
height: 100%;
align-items: flex-end;
}

View File

@@ -1,6 +1,6 @@
<script setup lang="ts">
import { computed, ref } from 'vue'
import { ArrowUp, Building2 } from 'lucide-vue-next'
import { ArrowUp } from 'lucide-vue-next'
import type { ChartSeriesConfig } from '@gisp/ui-kit-shadcn-vue'
import {
Card,
@@ -196,6 +196,10 @@ const isRankingTableContentSized = computed(() =>
const clusterCreationTrendBlock = computed(() =>
dashboard.trendBlock?.type === 'cluster_creation_dynamics' ? dashboard.trendBlock : null,
)
const clusterTrendScrollLeft = ref(0)
const clusterTrendVisiblePointsCount = 5
const clusterTrendColumnWidth = 128
const clusterTrendColumnGap = 18
const associationTypeTabs = computed(() => dashboard.filtersResponse.association_types)
const visibleAssociationTypeTabs = computed(() =>
@@ -739,28 +743,56 @@ const getSingleIndustryWidth = (row: SingleTopIndustryRow): string =>
const getSingleIndustryColor = (block: SingleTopIndustriesBlock): string =>
associationTypeColorMap[block.association_type]
const clusterCreationMaxValue = computed(() =>
Math.max(
...(clusterCreationTrendBlock.value?.points ?? []).map((point) =>
getNumericValue(point.clusters_count),
),
0,
),
)
const clusterTrendVisibleStartIndex = computed(() => {
const pointsCount = clusterCreationTrendBlock.value?.points.length ?? 0
const maxStartIndex = Math.max(0, pointsCount - clusterTrendVisiblePointsCount)
const rawStartIndex = Math.floor(
clusterTrendScrollLeft.value / (clusterTrendColumnWidth + clusterTrendColumnGap),
)
return Math.max(0, Math.min(maxStartIndex, rawStartIndex))
})
const clusterCreationVisiblePoints = computed(() => {
const points = clusterCreationTrendBlock.value?.points ?? []
if (!points.length) {
return []
}
return points.slice(
clusterTrendVisibleStartIndex.value,
clusterTrendVisibleStartIndex.value + clusterTrendVisiblePointsCount,
)
})
const clusterCreationMaxValue = computed(() => {
const visiblePoints = clusterCreationVisiblePoints.value.length
? clusterCreationVisiblePoints.value
: (clusterCreationTrendBlock.value?.points ?? [])
return Math.max(...visiblePoints.map((point) => getNumericValue(point.clusters_count)), 0)
})
const getClusterCreationBarHeight = (value: number | undefined): string =>
getProgressWidth(getNumericValue(value), clusterCreationMaxValue.value)
const getClusterTrendMinWidth = (pointsCount: number): string => {
const visiblePointsCount = 5
const columnWidth = 128
const columnGap = 18
if (pointsCount <= visiblePointsCount) {
if (pointsCount <= clusterTrendVisiblePointsCount) {
return '100%'
}
return `${pointsCount * columnWidth + Math.max(0, pointsCount - 1) * columnGap}px`
return `${pointsCount * clusterTrendColumnWidth + Math.max(0, pointsCount - 1) * clusterTrendColumnGap}px`
}
const updateClusterTrendScrollState = (event: Event) => {
const target = event.target as HTMLElement | null
if (!target?.matches('[data-slot="scroll-area-viewport"]')) {
return
}
clusterTrendScrollLeft.value = target.scrollLeft
}
const formatGrowthPercent = (value: number | null | undefined): string =>
@@ -1221,6 +1253,7 @@ const formatAreaUnit = (unit: string): string => (unit === 'ha' ? 'га' : unit)
class="cluster-trend-chart-scroll"
type="auto"
scrollbar-orientation="horizontal"
@scroll.capture="updateClusterTrendScrollState"
>
<div
class="cluster-trend-chart"
@@ -1278,13 +1311,6 @@ const formatAreaUnit = (unit: string): string => (unit === 'ha' ? 'га' : unit)
<CardContent class="analytics-card__content">
<header class="analytics-card__header">
<h2 class="analytics-card__title">{{ dashboard.regionRanking.title }}</h2>
<button
type="button"
class="analytics-card__icon-button"
aria-label="Открыть таблицу рейтинга"
>
<Building2 aria-hidden="true" />
</button>
</header>
<ScrollArea