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

ovilia pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/echarts-theme-builder.git

commit 19fa4bd8fb2094d83c8ae57ca302713eecb5d06c
Author: Ovilia <[email protected]>
AuthorDate: Mon Sep 1 16:35:04 2025 +0800

    feat: update theme working
---
 src/App.vue                          | 10 +++++---
 src/components/ChartPreviewPanel.vue | 49 +++++++++++++++++++++++++++++-------
 src/components/ThemePanel.vue        | 45 ++++++++++++++++++++++-----------
 src/i18n.ts                          | 12 ++++-----
 src/stores/theme.ts                  | 41 +++++++++++++++---------------
 src/types/theme.ts                   | 28 ++++++++++-----------
 src/utils/themeGenerator.ts          |  5 ----
 7 files changed, 118 insertions(+), 72 deletions(-)

diff --git a/src/App.vue b/src/App.vue
index 7e0b616..814e11b 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -1,21 +1,23 @@
 <script setup lang="ts">
+import { ref } from 'vue'
 // Simple fixed sidebar layout without responsive design
 import ChartPreviewPanel from './components/ChartPreviewPanel.vue'
 import ThemePanel from './components/ThemePanel.vue'
+
+// Get reference to chart preview panel
+const chartPreviewRef = ref<InstanceType<typeof ChartPreviewPanel> | 
null>(null)
 </script>
 
 <template>
   <div id="theme-builder">
     <div class="container-fluid" id="content">
       <van-row class="row-container" :gutter="0">
-        <!-- Left panel: Theme configuration - Fixed width -->
         <van-col span="6" class="theme-config">
-          <ThemePanel />
+          <ThemePanel :chart-preview-ref="chartPreviewRef" />
         </van-col>
 
-        <!-- Right panel: Chart preview - Remaining width -->
         <van-col span="18" class="chart-container">
-          <ChartPreviewPanel />
+          <ChartPreviewPanel ref="chartPreviewRef" />
         </van-col>
       </van-row>
     </div>
diff --git a/src/components/ChartPreviewPanel.vue 
b/src/components/ChartPreviewPanel.vue
index 2c2da56..d2ab378 100644
--- a/src/components/ChartPreviewPanel.vue
+++ b/src/components/ChartPreviewPanel.vue
@@ -23,8 +23,10 @@
 import { ref, onMounted, onUnmounted, nextTick } from 'vue'
 import * as echarts from 'echarts'
 import { getChartConfigs } from '../utils/chartConfigs'
+import { useThemeStore } from '../stores/theme'
 import type { ECharts } from 'echarts'
 
+const themeStore = useThemeStore()
 const chartInstances = ref<ECharts[]>([])
 const chartRefs = ref<(HTMLElement | null)[]>([])
 
@@ -38,23 +40,59 @@ function setChartRef(el: any, index: number) {
   }
 }
 
+// Register and apply current theme
+function registerCurrentTheme() {
+  const currentTheme = themeStore.getEChartsTheme(false)
+  echarts.registerTheme('customized', currentTheme)
+}
+
 // Initialize all charts
 function initializeCharts() {
   // Dispose existing charts
   chartInstances.value.forEach(chart => chart.dispose())
   chartInstances.value = []
 
+  // Register current theme
+  registerCurrentTheme()
+
   // Create new chart instances
   displayedCharts.value.forEach((config, index) => {
     const container = chartRefs.value[index]
     if (container) {
-      const chart = echarts.init(container)
+      // Initialize chart with theme
+      const chart = echarts.init(container, 'customized')
       chart.setOption(config.option)
       chartInstances.value.push(chart)
     }
   })
 }
 
+// Update charts when theme changes
+function updateCharts() {
+  if (chartInstances.value.length === 0) {
+    return
+  }
+
+  // Get current theme and register with unique ID to force refresh
+  const currentTheme = themeStore.getEChartsTheme(false)
+  const themeId = `customized-${Date.now()}`
+  echarts.registerTheme(themeId, currentTheme)
+
+  // Recreate charts with new theme
+  displayedCharts.value.forEach((config, index) => {
+    const container = chartRefs.value[index]
+    if (container && chartInstances.value[index]) {
+      chartInstances.value[index].dispose()
+      const chart = echarts.init(container, themeId)
+      chart.setOption(config.option)
+      chartInstances.value[index] = chart
+    }
+  })
+}// Expose updateCharts method for external calling
+defineExpose({
+  updateCharts
+})
+
 // Resize charts when window resizes
 function handleResize() {
   chartInstances.value.forEach(chart => chart.resize())
@@ -99,7 +137,7 @@ onUnmounted(() => {
   flex: 1;
   display: grid;
   grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
-  gap: 20px;
+  gap: 12px;
   overflow-y: auto;
   padding-right: 8px;
 }
@@ -108,13 +146,6 @@ onUnmounted(() => {
   background: #fff;
   border: 1px solid #e9ecef;
   border-radius: 8px;
-  padding: 16px;
-  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
-  transition: box-shadow 0.2s ease;
-}
-
-.chart-item:hover {
-  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
 }
 
 .chart-container {
diff --git a/src/components/ThemePanel.vue b/src/components/ThemePanel.vue
index 135f77d..8db099e 100644
--- a/src/components/ThemePanel.vue
+++ b/src/components/ThemePanel.vue
@@ -412,6 +412,13 @@ import { useThemeStore } from '../stores/theme'
 import { PRE_DEFINED_THEMES } from '../stores/theme'
 import ColorPicker from './ColorPicker.vue'
 import ColorList from './ColorList.vue'
+import type ChartPreviewPanel from './ChartPreviewPanel.vue'
+
+// Props
+interface Props {
+  chartPreviewRef?: InstanceType<typeof ChartPreviewPanel> | null
+}
+const props = defineProps<Props>()
 
 // Component state
 const activeNames = ref(['functions'])  // Functions panel expanded by default
@@ -427,7 +434,6 @@ const preDefinedThemes = PRE_DEFINED_THEMES
 // Methods
 const downloadTheme = () => {
   // TODO: Implement theme download
-  console.log('Download theme')
 }
 
 const importConfig = () => {
@@ -436,12 +442,10 @@ const importConfig = () => {
 
 const exportConfig = () => {
   // TODO: Implement config export
-  console.log('Export config')
 }
 
 const refreshCharts = () => {
   // TODO: Implement chart refresh
-  console.log('Refresh charts')
 }
 
 const resetTheme = () => {
@@ -450,11 +454,19 @@ const resetTheme = () => {
 
 const showHelp = () => {
   // TODO: Implement help dialog
-  console.log('Show help')
 }
 
-const selectPreDefinedTheme = (index: number) => {
-  themeStore.loadPreDefinedTheme(index)
+const selectPreDefinedTheme = async (index: number) => {
+  try {
+    await themeStore.loadPreDefinedTheme(index)
+
+    // Manually trigger chart update
+    if (props.chartPreviewRef?.updateCharts) {
+      props.chartPreviewRef.updateCharts()
+    }
+  } catch (error) {
+    console.error('Error selecting predefined theme:', error)
+  }
 }
 
 const onAxisSettingChange = () => {
@@ -525,15 +537,18 @@ const handleFileImport = (event: Event) => {
 }
 
 .theme-item {
-  padding: 8px;
-  border: 1px solid #ebedf0;
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: space-between;
+  width: auto;
+  height: 22px;
+  margin-bottom: 5px;
+  overflow: hidden;
+  border: 1px solid #eee;
+  padding: 5px;
   border-radius: 4px;
   cursor: pointer;
   transition: all 0.2s;
-  min-height: 60px;
-  display: flex;
-  flex-wrap: wrap;
-  align-content: flex-start;
   gap: 2px;
 }
 
@@ -543,10 +558,12 @@ const handleFileImport = (event: Event) => {
 }
 
 .color-dot {
-  width: 12px;
-  height: 12px;
+  width: 20px;
+  height: 20px;
+  margin: 0 2px 4px 2px;
   border-radius: 2px;
   border: 1px solid rgba(0, 0, 0, 0.1);
+  flex-shrink: 0;
 }
 
 .axis-group {
diff --git a/src/i18n.ts b/src/i18n.ts
index ed8b5d4..bfcad36 100644
--- a/src/i18n.ts
+++ b/src/i18n.ts
@@ -2,13 +2,13 @@ import { createI18n } from 'vue-i18n'
 import en from './locales/en.json'
 import zh from './locales/zh.json'
 
-// 从 localStorage 获取保存的语言设置,默认为中文
+// Get saved language setting from localStorage, default to Chinese
 const getStoredLanguage = (): string => {
   const stored = localStorage.getItem('echarts-theme-builder-locale')
   if (stored && ['en', 'zh'].includes(stored)) {
     return stored
   }
-  // 根据浏览器语言自动选择
+  // Auto-select based on browser language
   const browserLang = navigator.language.toLowerCase()
   if (browserLang.startsWith('zh')) {
     return 'zh'
@@ -17,7 +17,7 @@ const getStoredLanguage = (): string => {
 }
 
 const i18n = createI18n({
-  legacy: false, // 使用 Composition API 模式
+  legacy: false, // Use Composition API mode
   locale: getStoredLanguage(),
   fallbackLocale: 'en',
   messages: {
@@ -26,7 +26,7 @@ const i18n = createI18n({
   }
 })
 
-// 保存语言设置到 localStorage
+// Save language setting to localStorage
 export const setLocale = (locale: string) => {
   if (['en', 'zh'].includes(locale)) {
     i18n.global.locale.value = locale as 'en' | 'zh'
@@ -34,12 +34,12 @@ export const setLocale = (locale: string) => {
   }
 }
 
-// 获取当前语言
+// Get current language
 export const getCurrentLocale = () => {
   return i18n.global.locale.value
 }
 
-// 获取可用语言列表
+// Get available languages list
 export const getAvailableLocales = () => {
   return [
     { code: 'en', name: 'English' },
diff --git a/src/stores/theme.ts b/src/stores/theme.ts
index f1b8069..4be2c75 100644
--- a/src/stores/theme.ts
+++ b/src/stores/theme.ts
@@ -2,7 +2,7 @@ import { ref, reactive } from 'vue'
 import type { ThemeData, PreDefinedTheme } from '../types/theme'
 import { generateEChartsTheme, generateThemeJsFile, 
generateThemeConfigForDownload } from '../utils/themeGenerator'
 
-// 预定义主题
+// Predefined themes configuration
 export const PRE_DEFINED_THEMES: PreDefinedTheme[] = [
   {
     name: 'vintage',
@@ -108,13 +108,13 @@ export const PRE_DEFINED_THEMES: PreDefinedTheme[] = [
   }
 ]
 
-// 默认主题配置
+// Default theme axes configuration
 const createDefaultAxes = () => {
   const types = ['all', 'category', 'value', 'log', 'time']
-  const names = ['通用', '类目', '数值', '对数', '时间']
+  const names = ['General', 'Category', 'Value', 'Log', 'Time']
   return types.map((type, i) => ({
     type,
-    name: names[i] + '坐标轴',
+    name: names[i] + ' Axis',
     axisLineShow: type !== 'value' && type !== 'log',
     axisLineColor: '#6E7079',
     axisTickShow: type !== 'value' && type !== 'log',
@@ -194,8 +194,10 @@ export const createDefaultTheme = (): ThemeData => {
   }
 }
 
-// 全局状态管理
-export const useThemeStore = () => {
+// Global state management - Singleton pattern
+let themeStoreInstance: ReturnType<typeof createThemeStore> | null = null
+
+const createThemeStore = () => {
   const theme = reactive<ThemeData>(createDefaultTheme())
   const themeName = ref('customized')
   const isPauseChartUpdating = ref(false)
@@ -210,15 +212,12 @@ export const useThemeStore = () => {
   }
 
   const loadPreDefinedTheme = async (index: number) => {
-    console.log('🏪 loadPreDefinedTheme called with index:', index)
     const preTheme = PRE_DEFINED_THEMES[index]
     if (!preTheme) {
-      console.error('❌ No theme found at index:', index)
+      console.error('No theme found at index:', index)
       return
     }
 
-    console.log('🏪 Loading theme:', preTheme.name)
-
     try {
       // Load the complete theme configuration from JSON file
       const response = await fetch(`/themes/${preTheme.name}.json`)
@@ -227,7 +226,6 @@ export const useThemeStore = () => {
       }
 
       const themeData = await response.json()
-      console.log('🏪 Loaded theme data:', themeData)
 
       if (themeData.theme) {
         // Convert string numbers to actual numbers
@@ -248,8 +246,6 @@ export const useThemeStore = () => {
           loadedTheme.symbolBorderWidth = 
parseFloat(loadedTheme.symbolBorderWidth)
         }
 
-        console.log('🏪 Before applying theme:', { ...theme })
-
         // Apply the complete theme configuration property by property to 
ensure reactivity
         // This ensures Vue's reactive system properly detects changes
         Object.keys(loadedTheme).forEach(key => {
@@ -268,16 +264,12 @@ export const useThemeStore = () => {
         // Update axis settings based on axisSeperateSetting
         updateAxisSetting()
 
-        console.log('🏪 After applying theme:', theme)
-        console.log('🏪 Theme name set to:', themeName.value)
-
         // Force trigger reactive update by modifying a dummy property
         ;(theme as any).__forceUpdate = Date.now()
       }
     } catch (error) {
-      console.error('❌ Error loading predefined theme:', error)
+      console.error('Error loading predefined theme:', error)
       // Fallback to basic theme loading
-      console.log('🏪 Using fallback theme loading')
       theme.backgroundColor = preTheme.background
       theme.color = [...preTheme.theme]
       themeName.value = preTheme.name
@@ -310,13 +302,15 @@ export const useThemeStore = () => {
 
   const exportTheme = () => {
     const exportData = { ...theme }
-    // 删除重复的 axis 选项,因为它已经包含在 theme.axes 中
+    // Remove duplicate axis options since they are already included in 
theme.axes
     const { axis, ...cleanedData } = exportData
     return cleanedData
   }
 
   const getEChartsTheme = (isToExport: boolean = false) => {
-    return generateEChartsTheme(theme, isToExport)
+    // Convert reactive object to plain object to ensure proper data passing
+    const plainTheme = JSON.parse(JSON.stringify(theme))
+    return generateEChartsTheme(plainTheme, isToExport)
   }
 
   const getThemeJsFile = () => {
@@ -342,3 +336,10 @@ export const useThemeStore = () => {
     getThemeConfigForDownload
   }
 }
+
+export const useThemeStore = () => {
+  if (!themeStoreInstance) {
+    themeStoreInstance = createThemeStore()
+  }
+  return themeStoreInstance
+}
diff --git a/src/types/theme.ts b/src/types/theme.ts
index fe65437..708e09f 100644
--- a/src/types/theme.ts
+++ b/src/types/theme.ts
@@ -1,4 +1,4 @@
-// ECharts 主题类型定义
+// ECharts theme type definitions
 export interface ThemeAxis {
   type: string
   name: string
@@ -15,7 +15,7 @@ export interface ThemeAxis {
 }
 
 export interface ThemeData {
-  // 基础配置
+  // Basic configuration
   seriesCnt: number
   backgroundColor: string
   titleColor: string
@@ -24,38 +24,38 @@ export interface ThemeData {
   textColor: string
   markTextColor: string
 
-  // 主色板
+  // Main color palette
   color: string[]
 
-  // 边框
+  // Border
   borderColor: string
   borderWidth: number
 
-  // 视觉映射
+  // Visual mapping
   visualMapColor: string[]
 
-  // 图例
+  // Legend
   legendTextColor: string
 
-  // K线图
+  // Candlestick chart
   kColor: string
   kColor0: string
   kBorderColor: string
   kBorderColor0: string
   kBorderWidth: number
 
-  // 线条
+  // Line chart
   lineWidth: number
   symbolSize: number
   symbol: string
   symbolBorderWidth: number
   lineSmooth: boolean
 
-  // 关系图
+  // Graph/Network chart
   graphLineWidth: number
   graphLineColor: string
 
-  // 地图
+  // Map
   mapLabelColor: string
   mapLabelColorE: string
   mapBorderColor: string
@@ -65,20 +65,20 @@ export interface ThemeData {
   mapAreaColor: string
   mapAreaColorE: string
 
-  // 坐标轴
+  // Coordinate axis
   axes: ThemeAxis[]
   axisSeperateSetting: boolean
   axis: ThemeAxis[] | null
 
-  // 工具箱
+  // Toolbox
   toolboxColor: string
   toolboxEmphasisColor: string
 
-  // 提示框
+  // Tooltip
   tooltipAxisColor: string
   tooltipAxisWidth: number
 
-  // 时间轴
+  // Timeline
   timelineLineColor: string
   timelineLineWidth: number
   timelineItemColor: string
diff --git a/src/utils/themeGenerator.ts b/src/utils/themeGenerator.ts
index 28e3973..b9dc843 100644
--- a/src/utils/themeGenerator.ts
+++ b/src/utils/themeGenerator.ts
@@ -7,11 +7,6 @@ import type { ThemeData } from '../types/theme'
  * @returns ECharts theme configuration object
  */
 export function generateEChartsTheme(themeData: ThemeData, isToExport: boolean 
= false) {
-  console.log('🎨 generateEChartsTheme called with:', themeData)
-  console.log('🎨 Theme backgroundColor:', themeData.backgroundColor)
-  console.log('🎨 Theme colors:', themeData.color)
-  console.log('🎨 Theme titleColor:', themeData.titleColor)
-
   // Halloween pumpkin symbol path
   const pumpkin = 
'path://M237.062,81.761L237.062,81.761c-12.144-14.24-25.701-20.1-40.68-19.072 
c-10.843,0.747-20.938,5.154-30.257,13.127c-9.51-5.843-19.8-9.227-30.859-10.366c0.521-3.197,1.46-6.306,2.85-9.363
 
c3.458-7.038,8.907-12.741,16.331-17.296c-5.609-3.384-11.227-6.799-16.854-10.279c-16.257,8.104-25.06,20.601-26.463,38.417
 
c-7.599,1.705-14.685,4.486-21.247,8.437c-9.164-7.677-18.996-11.917-29.496-12.632c-14.819-0.998-28.467,4.787-40.938,18.827
 C6.445,96.182,0,114.867,0,136.242c-0.007 [...]
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to