fix: adjust analytics chart layout
This commit is contained in:
@@ -562,6 +562,10 @@ select {
|
|||||||
align-content: start;
|
align-content: start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.analytics-card--trend .analytics-card__content {
|
||||||
|
grid-template-rows: auto minmax(0, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
.analytics-card--industries .analytics-card__content {
|
.analytics-card--industries .analytics-card__content {
|
||||||
align-content: start;
|
align-content: start;
|
||||||
}
|
}
|
||||||
@@ -613,35 +617,6 @@ select {
|
|||||||
overflow-wrap: anywhere;
|
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 {
|
.composition-layout {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: minmax(0, 280px) minmax(0, 1fr);
|
grid-template-columns: minmax(0, 280px) minmax(0, 1fr);
|
||||||
@@ -1442,25 +1417,59 @@ select {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.trend-chart-box {
|
.trend-chart-box {
|
||||||
height: 250px;
|
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
|
min-height: 0;
|
||||||
|
height: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.trend-chart-box > * {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.trend-chart-box .unovis-xy-container {
|
.trend-chart-box .unovis-xy-container {
|
||||||
--vis-axis-tick-label-font-size: 14px;
|
--vis-axis-tick-label-font-size: 14px;
|
||||||
|
height: 100% !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cluster-trend-chart-scroll {
|
.cluster-trend-chart-scroll {
|
||||||
|
position: relative;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
height: 280px;
|
min-height: 0;
|
||||||
|
height: 100%;
|
||||||
padding-bottom: 18px;
|
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'] {
|
.cluster-trend-chart-scroll [data-slot='scroll-area-viewport'] {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
height: 100%;
|
||||||
padding-bottom: 12px;
|
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'] {
|
.cluster-trend-chart-scroll [data-slot='scroll-area-scrollbar'] {
|
||||||
right: 6px;
|
right: 6px;
|
||||||
bottom: 4px;
|
bottom: 4px;
|
||||||
@@ -1475,17 +1484,19 @@ select {
|
|||||||
|
|
||||||
.cluster-trend-chart {
|
.cluster-trend-chart {
|
||||||
display: grid;
|
display: grid;
|
||||||
height: 250px;
|
min-height: 0;
|
||||||
|
height: 100%;
|
||||||
grid-auto-flow: column;
|
grid-auto-flow: column;
|
||||||
grid-auto-columns: minmax(104px, 1fr);
|
grid-auto-columns: minmax(104px, 1fr);
|
||||||
gap: 18px;
|
gap: 18px;
|
||||||
align-items: end;
|
align-items: end;
|
||||||
padding: 6px 6px 0;
|
padding: 42px 6px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cluster-trend-chart__item {
|
.cluster-trend-chart__item {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: grid;
|
display: grid;
|
||||||
|
height: 100%;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
grid-template-rows: minmax(120px, 1fr) auto;
|
grid-template-rows: minmax(120px, 1fr) auto;
|
||||||
align-items: end;
|
align-items: end;
|
||||||
@@ -1521,7 +1532,8 @@ select {
|
|||||||
.cluster-trend-chart__bar-wrap {
|
.cluster-trend-chart__bar-wrap {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 150px;
|
min-height: 150px;
|
||||||
|
height: 100%;
|
||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, ref } from 'vue'
|
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 type { ChartSeriesConfig } from '@gisp/ui-kit-shadcn-vue'
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
@@ -196,6 +196,10 @@ const isRankingTableContentSized = computed(() =>
|
|||||||
const clusterCreationTrendBlock = computed(() =>
|
const clusterCreationTrendBlock = computed(() =>
|
||||||
dashboard.trendBlock?.type === 'cluster_creation_dynamics' ? dashboard.trendBlock : null,
|
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 associationTypeTabs = computed(() => dashboard.filtersResponse.association_types)
|
||||||
const visibleAssociationTypeTabs = computed(() =>
|
const visibleAssociationTypeTabs = computed(() =>
|
||||||
@@ -739,28 +743,56 @@ const getSingleIndustryWidth = (row: SingleTopIndustryRow): string =>
|
|||||||
const getSingleIndustryColor = (block: SingleTopIndustriesBlock): string =>
|
const getSingleIndustryColor = (block: SingleTopIndustriesBlock): string =>
|
||||||
associationTypeColorMap[block.association_type]
|
associationTypeColorMap[block.association_type]
|
||||||
|
|
||||||
const clusterCreationMaxValue = computed(() =>
|
const clusterTrendVisibleStartIndex = computed(() => {
|
||||||
Math.max(
|
const pointsCount = clusterCreationTrendBlock.value?.points.length ?? 0
|
||||||
...(clusterCreationTrendBlock.value?.points ?? []).map((point) =>
|
const maxStartIndex = Math.max(0, pointsCount - clusterTrendVisiblePointsCount)
|
||||||
getNumericValue(point.clusters_count),
|
const rawStartIndex = Math.floor(
|
||||||
),
|
clusterTrendScrollLeft.value / (clusterTrendColumnWidth + clusterTrendColumnGap),
|
||||||
0,
|
)
|
||||||
),
|
|
||||||
)
|
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 =>
|
const getClusterCreationBarHeight = (value: number | undefined): string =>
|
||||||
getProgressWidth(getNumericValue(value), clusterCreationMaxValue.value)
|
getProgressWidth(getNumericValue(value), clusterCreationMaxValue.value)
|
||||||
|
|
||||||
const getClusterTrendMinWidth = (pointsCount: number): string => {
|
const getClusterTrendMinWidth = (pointsCount: number): string => {
|
||||||
const visiblePointsCount = 5
|
if (pointsCount <= clusterTrendVisiblePointsCount) {
|
||||||
const columnWidth = 128
|
|
||||||
const columnGap = 18
|
|
||||||
|
|
||||||
if (pointsCount <= visiblePointsCount) {
|
|
||||||
return '100%'
|
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 =>
|
const formatGrowthPercent = (value: number | null | undefined): string =>
|
||||||
@@ -1221,6 +1253,7 @@ const formatAreaUnit = (unit: string): string => (unit === 'ha' ? 'га' : unit)
|
|||||||
class="cluster-trend-chart-scroll"
|
class="cluster-trend-chart-scroll"
|
||||||
type="auto"
|
type="auto"
|
||||||
scrollbar-orientation="horizontal"
|
scrollbar-orientation="horizontal"
|
||||||
|
@scroll.capture="updateClusterTrendScrollState"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="cluster-trend-chart"
|
class="cluster-trend-chart"
|
||||||
@@ -1278,13 +1311,6 @@ const formatAreaUnit = (unit: string): string => (unit === 'ha' ? 'га' : unit)
|
|||||||
<CardContent class="analytics-card__content">
|
<CardContent class="analytics-card__content">
|
||||||
<header class="analytics-card__header">
|
<header class="analytics-card__header">
|
||||||
<h2 class="analytics-card__title">{{ dashboard.regionRanking.title }}</h2>
|
<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>
|
</header>
|
||||||
|
|
||||||
<ScrollArea
|
<ScrollArea
|
||||||
|
|||||||
Reference in New Issue
Block a user