This is an automated email from the ASF dual-hosted git repository.

nathanma pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/amoro.git


The following commit(s) were added to refs/heads/master by this push:
     new 75f3a600f [UI] Optimize snapshot charts representation (#4071)
75f3a600f is described below

commit 75f3a600fde69dab1220249aa4cd92f3da15eedf
Author: nathan.ma <[email protected]>
AuthorDate: Fri Jan 30 17:12:19 2026 +0800

    [UI] Optimize snapshot charts representation (#4071)
    
    Co-authored-by: majin.nathan <[email protected]>
---
 amoro-web/src/utils/chart.ts                       | 42 ++++++++++-----
 .../src/views/tables/components/Optimizing.vue     |  4 ++
 amoro-web/src/views/tables/components/Selector.vue | 10 +++-
 .../src/views/tables/components/Snapshots.vue      | 59 ++++++++++++++++++++--
 4 files changed, 97 insertions(+), 18 deletions(-)

diff --git a/amoro-web/src/utils/chart.ts b/amoro-web/src/utils/chart.ts
index 0fdcaf292..296a5368a 100644
--- a/amoro-web/src/utils/chart.ts
+++ b/amoro-web/src/utils/chart.ts
@@ -43,7 +43,7 @@ function sortLineChartDataByKey(obj: ILineChartOriginalData = 
{}, sortCallback:
  * @param data
  * @returns Echarts options
  */
-export function generateLineChartOption(titleText: string, data: 
ILineChartOriginalData) {
+export function generateLineChartOption(_titleText: string, data: 
ILineChartOriginalData) {
   if (!data) {
     return {}
   }
@@ -55,26 +55,30 @@ export function generateLineChartOption(titleText: string, 
data: ILineChartOrigi
     },
     yAxis: {
       type: 'value',
+      boundaryGap: [0, '1%'],
+      splitNumber: 6,
     },
     xAxis: {
       type: 'category',
       data: dataKeys.map(d => dateFormat(d)),
+      axisLabel: {
+        show: false,
+      },
       axisTick: {
-        alignWithLabel: true,
-        interval: 0,
+        show: false,
+      },
+      axisLine: {
+        show: false,
       },
     },
     grid: {
-      top: 40,
-      bottom: 50,
-      left: '1%',
+      left: 0,
+      right: 0,
+      top: 36,
+      bottom: 6,
       containLabel: true,
     },
   }
-  titleText && (option.title = {
-    left: 'center',
-    text: titleText,
-  })
   const legendMap: Record<string, number[]> = {}
   Object.values(data).forEach((val) => {
     const keys = Object.keys(val)
@@ -86,8 +90,22 @@ export function generateLineChartOption(titleText: string, 
data: ILineChartOrigi
       legendMap[tKey].push(val[key])
     })
   })
-  option.legend = { top: 'bottom', data: Object.keys(legendMap), lineStyle: { 
opacity: 0 } }
-  option.series = Object.keys(legendMap).map(key => ({
+  const legendKeys = Object.keys(legendMap)
+  option.legend = {
+    show: true,
+    top: 0,
+    left: 'center',
+    orient: 'horizontal',
+    itemWidth: 7,
+    itemHeight: 7,
+    icon: 'circle',
+    itemGap: 6,
+    textStyle: {
+      fontSize: 13,
+      lineHeight: 24,
+    },
+  }
+  option.series = legendKeys.map(key => ({
     name: key,
     type: 'line',
     symbol: 'circle',
diff --git a/amoro-web/src/views/tables/components/Optimizing.vue 
b/amoro-web/src/views/tables/components/Optimizing.vue
index 69e2da4c8..ebeccc05d 100644
--- a/amoro-web/src/views/tables/components/Optimizing.vue
+++ b/amoro-web/src/views/tables/components/Optimizing.vue
@@ -422,6 +422,10 @@ onMounted(() => {
   :deep(.ant-table-thead > tr > th) {
     padding: 4px 16px !important;
   }
+
+  :deep(.ant-table-row-expand-icon) {
+    border-radius: 0 !important;
+  }
 }
 
 .status-icon {
diff --git a/amoro-web/src/views/tables/components/Selector.vue 
b/amoro-web/src/views/tables/components/Selector.vue
index afcddf4e8..84e810e2a 100644
--- a/amoro-web/src/views/tables/components/Selector.vue
+++ b/amoro-web/src/views/tables/components/Selector.vue
@@ -171,12 +171,14 @@ onMounted(() => {
         </a-select-option>
       </a-select>
     </div>
+    <div class="selector-extra">
+      <slot name="extra" />
+    </div>
   </div>
 </template>
 
 <style lang="less">
 .branch-selector {
-  margin-top: 32px;
   display: flex;
   align-items: center;
 
@@ -252,5 +254,11 @@ onMounted(() => {
     text-align: center;
     color: #102048;
   }
+
+  .selector-extra {
+    display: flex;
+    align-items: center;
+    padding-left: 18px;
+  }
 }
 </style>
diff --git a/amoro-web/src/views/tables/components/Snapshots.vue 
b/amoro-web/src/views/tables/components/Snapshots.vue
index a56344377..f67286766 100644
--- a/amoro-web/src/views/tables/components/Snapshots.vue
+++ b/amoro-web/src/views/tables/components/Snapshots.vue
@@ -20,6 +20,7 @@ limitations under the License.
 import { onMounted, reactive, ref, shallowReactive } from 'vue'
 import { useI18n } from 'vue-i18n'
 import { useRoute } from 'vue-router'
+import { CaretDownOutlined, CaretRightOutlined } from '@ant-design/icons-vue'
 import Selector from './Selector.vue'
 import { usePagination } from '@/hooks/usePagination'
 import type { BreadcrumbSnapshotItem, IColumns, ILineChartOriginalData, 
SnapshotItem } from '@/types/common.type'
@@ -61,8 +62,10 @@ const sourceData = reactive({
   table: '',
   ...query,
 })
+
 const recordChartOption = ref<ECOption>({})
 const fileChartOption = ref<ECOption>({})
+const showCharts = ref(false)
 const tblRef = ref<string>('')
 const operation = ref<string>('')
 
@@ -185,6 +188,10 @@ function toggleBreadcrumb(record: SnapshotItem) {
   }
 }
 
+function toggleCharts() {
+  showCharts.value = !showCharts.value
+}
+
 onMounted(() => {
   hasBreadcrumb.value = false
 })
@@ -193,15 +200,36 @@ onMounted(() => {
 <template>
   <div class="table-snapshots">
     <template v-if="!hasBreadcrumb">
-      <a-row>
+      <Selector
+        :catalog="sourceData.catalog"
+        :db="sourceData.db"
+        :table="sourceData.table"
+        :disabled="loading"
+        @consumer-change="onConsumerChange"
+        @ref-change="onRefChange"
+      >
+        <template #extra>
+          <div class="snapshots-charts-header" @click="toggleCharts">
+            <span class="snapshots-charts-title">Charts</span>
+            <span class="snapshots-charts-icon">
+              <CaretRightOutlined v-if="!showCharts" />
+              <CaretDownOutlined v-else />
+            </span>
+          </div>
+        </template>
+      </Selector>
+      <a-row v-if="showCharts" :gutter="32">
         <a-col :span="12">
-          <Chart :loading="loading" :options="recordChartOption" />
+          <div class="snapshots-chart-wrap">
+            <Chart height="300px" :loading="loading" 
:options="recordChartOption" />
+          </div>
         </a-col>
         <a-col :span="12">
-          <Chart :loading="loading" :options="fileChartOption" />
+          <div class="snapshots-chart-wrap">
+            <Chart height="300px" :loading="loading" 
:options="fileChartOption" />
+          </div>
         </a-col>
       </a-row>
-      <Selector :catalog="sourceData.catalog" :db="sourceData.db" 
:table="sourceData.table" :disabled="loading" 
@consumer-change="onConsumerChange" @ref-change="onRefChange" />
       <a-table
         row-key="snapshotId"
         :columns="columns"
@@ -281,8 +309,29 @@ onMounted(() => {
     padding: 0;
   }
 
+  :deep(.ant-table-row-expand-icon) {
+    border-radius: 0 !important;
+  }
+
   .ant-table-wrapper {
-    margin-top: 24px;
+    margin-top: 18px;
+  }
+
+  .snapshots-charts-header {
+    display: flex;
+    align-items: center;
+    cursor: pointer;
+  }
+
+  .snapshots-charts-title {
+    margin-right: 4px;
+  }
+
+  .snapshots-charts-icon {
+    font-size: 10px;
+    color: #999;
+    display: inline-flex;
+    align-items: center;
   }
 }
 </style>

Reply via email to