From d93e2c812fbe5bc294392731b01271b65cee6073 Mon Sep 17 00:00:00 2001 From: "douboer@gmail.com" Date: Fri, 13 Feb 2026 22:40:22 +0800 Subject: [PATCH] update at 2026-02-13 22:40:22 --- miniapp/README.md | 2 + miniapp/data/sankey.xlsx | Bin 0 -> 10966 bytes miniapp/pages/index/index.js | 207 ++++++++++++++++++++++++++++----- miniapp/pages/index/index.wxml | 87 +++++++------- miniapp/pages/index/index.wxss | 41 ++++++- miniapp/project.config.json | 19 +++ 6 files changed, 279 insertions(+), 77 deletions(-) create mode 100644 miniapp/data/sankey.xlsx create mode 100644 miniapp/project.config.json diff --git a/miniapp/README.md b/miniapp/README.md index 99f3dc3..4c3ec1d 100644 --- a/miniapp/README.md +++ b/miniapp/README.md @@ -3,6 +3,7 @@ 当前目录已从骨架升级为可用版,支持以下能力: - 顶部 Logo / 主题 / 上传 / 导出区域 +- 启动默认加载:`data/sankey.xlsx`(位于小程序包内 `miniapp/data/sankey.xlsx`) - 文件上传与解析:`csv / xls / xlsx` - 默认列映射: - 源数据列优先匹配 `data/value/数据/值` @@ -18,4 +19,5 @@ 注意事项: - `xlsx` 解析依赖 npm 包,若在微信开发者工具中提示模块缺失,请先执行“工具 -> 构建 npm”。 +- 当默认文件或上传文件未加载成功时,“数据选择”仅显示空状态提示,不展示占位列名。 - SVG 文件导出后是否可直接预览,取决于当前系统与微信版本对 SVG 文档的支持。 diff --git a/miniapp/data/sankey.xlsx b/miniapp/data/sankey.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..f76dbaaed11ebd4b4584af75673cb16b2c36c244 GIT binary patch literal 10966 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 0) { + return '当前环境未启用 xlsx 解析,请先在开发者工具执行“构建 npm”'; + } + return message || fallbackMessage; +} + +/** + * 兼容 onWindowResize 不同回调结构,提取 windowHeight。 + */ +function getWindowHeightFromResizePayload(payload) { + if (payload && payload.size && Number.isFinite(payload.size.windowHeight)) { + return payload.size.windowHeight; + } + if (payload && Number.isFinite(payload.windowHeight)) { + return payload.windowHeight; + } + return null; +} + /** * 方向切换:target->source 时对连线做镜像翻转。 */ @@ -384,10 +412,10 @@ Page({ data: { selectedThemeIndex: 1, showThemeSheet: false, - uploadMessage: '点击上传或将csv/xls文件拖到这里上传', + uploadMessage: '默认加载 data/sankey.xlsx 中...', parseError: '', buildError: '', - columnHeaders: ['列1', '列2', '列3'], + columnHeaders: [], tableRows: [], sourceDataColumn: null, sourceDescriptionColumns: [], @@ -396,7 +424,7 @@ Page({ linksCount: 0, droppedRows: 0, buildWarnings: [], - infoLogs: ['解析信息: 尚未加载数据文件'], + infoLogs: ['解析信息: 正在加载默认数据文件 data/sankey.xlsx'], sankeyLinks: [], sankeyNodes: [], gapOptions: GAP_OPTIONS, @@ -413,7 +441,68 @@ Page({ targetAlignOptionLabels: TARGET_ALIGN_OPTIONS.map((item) => item.label), targetAlignValues: TARGET_ALIGN_OPTIONS.map((item) => item.value), targetAlignIndex: 0, - targetAlignMode: TARGET_ALIGN_OPTIONS[0].value + targetAlignMode: TARGET_ALIGN_OPTIONS[0].value, + bottomPanelsHeightPx: 300 + }, + + /** + * 页面加载时: + * 1) 根据窗口高度计算底部双窗口的目标高度(默认 300,低高度窗口自动压缩) + * 2) 监听窗口变化,保持整体布局稳定 + */ + onLoad() { + this.updateBottomPanelsHeight(); + if (typeof wx.onWindowResize === 'function') { + this._handleWindowResize = (payload) => { + const nextWindowHeight = getWindowHeightFromResizePayload(payload); + this.updateBottomPanelsHeight(nextWindowHeight); + }; + wx.onWindowResize(this._handleWindowResize); + } + }, + + /** + * 页面卸载时移除窗口变化监听,避免重复绑定。 + */ + onUnload() { + if (this._handleWindowResize && typeof wx.offWindowResize === 'function') { + wx.offWindowResize(this._handleWindowResize); + } + }, + + /** + * 计算底部双窗口高度: + * - 优先保持 300px + * - 在小高度窗口中自动收缩到 180~300 区间,避免挤压主预览区 + */ + updateBottomPanelsHeight(windowHeight) { + let resolvedWindowHeight = Number(windowHeight); + if (!Number.isFinite(resolvedWindowHeight)) { + try { + if (typeof wx.getWindowInfo === 'function') { + resolvedWindowHeight = wx.getWindowInfo().windowHeight; + } else { + resolvedWindowHeight = wx.getSystemInfoSync().windowHeight; + } + } catch (error) { + resolvedWindowHeight = 760; + } + } + + const remainForBottomPanels = resolvedWindowHeight - 360; + const nextHeight = clampNumber(remainForBottomPanels, 180, 300, 300); + if (nextHeight === this.data.bottomPanelsHeightPx) { + return; + } + + this.setData( + { + bottomPanelsHeightPx: nextHeight + }, + () => { + this.drawSankey(); + } + ); }, /** @@ -522,6 +611,86 @@ Page({ */ onReady() { this.drawSankey(); + this.loadDefaultSankeyFile(); + }, + + /** + * 统一读取并解析文件。 + * - CSV 按 utf8 文本读取 + * - XLS/XLSX 按二进制读取 + */ + readAndApplyFile(filePath, fileName, onReadFailPrefix) { + const that = this; + const extension = getFileExtension(fileName); + const isCsvFile = extension === 'csv'; + const readOptions = { + filePath, + success(readRes) { + try { + const filePayload = isCsvFile ? String(readRes.data || '') : readRes.data; + const table = parseTableByFileName(fileName, filePayload); + that.applyParsedTable(table, fileName); + } catch (error) { + that.setData({ + parseError: toFriendlyParseError(error, '文件解析失败') + }); + that.refreshInfoLogs(); + } + }, + fail(err) { + that.setData({ + parseError: `${onReadFailPrefix}: ${err && err.errMsg ? err.errMsg : '未知错误'}` + }); + that.refreshInfoLogs(); + } + }; + if (isCsvFile) { + readOptions.encoding = 'utf8'; + } + wx.getFileSystemManager().readFile(readOptions); + }, + + /** + * 默认加载项目内置数据:data/sankey.xlsx + * 说明: + * - 多路径兜底,兼容不同开发者工具路径解析差异 + * - 加载失败不展示占位列,保持“未加载文件”状态 + */ + loadDefaultSankeyFile() { + const that = this; + const tryReadByIndex = (index, lastErrorMessage) => { + if (index >= DEFAULT_SANKEY_FILE_PATHS.length) { + that.setData({ + uploadMessage: '点击上传或将csv/xls文件拖到这里上传', + parseError: `默认文件加载失败: ${lastErrorMessage || `未找到 ${DEFAULT_SANKEY_FILE_NAME}`}` + }); + that.refreshInfoLogs(); + return; + } + + const candidatePath = DEFAULT_SANKEY_FILE_PATHS[index]; + wx.getFileSystemManager().readFile({ + filePath: candidatePath, + success(readRes) { + try { + const table = parseTableByFileName(DEFAULT_SANKEY_FILE_NAME, readRes.data); + that.applyParsedTable(table, DEFAULT_SANKEY_FILE_NAME); + } catch (error) { + that.setData({ + uploadMessage: '点击上传或将csv/xls文件拖到这里上传', + parseError: toFriendlyParseError(error, '默认文件解析失败') + }); + that.refreshInfoLogs(); + } + }, + fail(err) { + const errorMessage = err && err.errMsg ? err.errMsg : '未知错误'; + tryReadByIndex(index + 1, errorMessage); + } + }); + }; + + tryReadByIndex(0, ''); }, /** @@ -540,33 +709,7 @@ Page({ } const filePath = picked.path; const fileName = picked.name || 'unknown.csv'; - const extension = getFileExtension(fileName); - const isCsvFile = extension === 'csv'; - const readOptions = { - filePath, - success(readRes) { - try { - const filePayload = isCsvFile ? String(readRes.data || '') : readRes.data; - const table = parseTableByFileName(fileName, filePayload); - that.applyParsedTable(table, fileName); - } catch (error) { - that.setData({ - parseError: error && error.message ? error.message : '文件解析失败' - }); - that.refreshInfoLogs(); - } - }, - fail(err) { - that.setData({ - parseError: `读取文件失败: ${err && err.errMsg ? err.errMsg : '未知错误'}` - }); - that.refreshInfoLogs(); - } - }; - if (isCsvFile) { - readOptions.encoding = 'utf8'; - } - wx.getFileSystemManager().readFile(readOptions); + that.readAndApplyFile(filePath, fileName, '读取文件失败'); }, fail(err) { if (err && String(err.errMsg || '').indexOf('cancel') >= 0) { @@ -601,7 +744,7 @@ Page({ uploadMessage: `已加载: ${fileName}(${rows.length} 行)`, parseError: '', buildError: '', - columnHeaders: headers.length > 0 ? headers : ['列1', '列2', '列3'], + columnHeaders: headers.length > 0 ? headers : [], tableRows: rows, sourceDataColumn, sourceDescriptionColumns, diff --git a/miniapp/pages/index/index.wxml b/miniapp/pages/index/index.wxml index 6e90231..6956633 100644 --- a/miniapp/pages/index/index.wxml +++ b/miniapp/pages/index/index.wxml @@ -90,61 +90,64 @@ - + + + 未加载文件,暂无列信息 - - - - 源数据(link value) + + + + 源数据(link value) + + + + {{item}} + + - - - {{item}} - - - - - - - 源标签(Source label) + + + + 源标签(Source label) + + + + {{item}} + + - - - {{item}} - - - - - - - 目标标签(target label) + + + + 目标标签(target label) + + + + {{item}} + + - - - {{item}} - - - + - + {{item}} - + diff --git a/miniapp/pages/index/index.wxss b/miniapp/pages/index/index.wxss index c850bcc..c2cf72d 100644 --- a/miniapp/pages/index/index.wxss +++ b/miniapp/pages/index/index.wxss @@ -1,8 +1,11 @@ .page { - min-height: 100vh; + height: 100vh; padding: 8px; background: #f3f4f6; box-sizing: border-box; + display: flex; + flex-direction: column; + overflow: hidden; } .header { @@ -10,6 +13,7 @@ display: flex; align-items: center; gap: 8px; + flex-shrink: 0; } .logo { @@ -31,6 +35,7 @@ align-items: center; gap: 6px; padding-left: 6px; + flex-shrink: 0; } .tool-icon { @@ -101,6 +106,11 @@ background: #fff; padding: 3.2px; box-sizing: border-box; + flex: 1; + min-height: 220px; + display: flex; + flex-direction: column; + overflow: hidden; } .preview-head { @@ -227,7 +237,9 @@ .preview-canvas { margin-top: 3px; width: 100%; - height: 371px; + height: auto; + flex: 1; + min-height: 120px; border-radius: 4px; background: #f7f8fa; } @@ -237,6 +249,9 @@ display: grid; grid-template-columns: 1fr 1fr; gap: 8px; + height: 300px; + min-height: 180px; + flex-shrink: 0; } .panel { @@ -245,18 +260,37 @@ background: #fff; padding: 8px; box-sizing: border-box; + height: 100%; + overflow: hidden; } .data-panel { + display: flex; + flex-direction: column; + min-height: 0; +} + +.data-scroll { + margin-top: 12px; + flex: 1; + height: 0; + min-height: 0; display: flex; flex-direction: column; gap: 12px; } +.empty-tip { + color: #86909c; + font-size: 12px; + line-height: 1.4; +} + .log-panel { display: flex; flex-direction: column; gap: 8px; + min-height: 0; } .panel-title { @@ -316,11 +350,11 @@ .log-list { flex: 1; + height: 0; min-height: 0; display: flex; flex-direction: column; gap: 6px; - overflow: auto; } .log-item { @@ -334,6 +368,7 @@ color: #86909c; font-size: 14px; line-height: 1.3; + flex-shrink: 0; } .theme-sheet-mask { diff --git a/miniapp/project.config.json b/miniapp/project.config.json new file mode 100644 index 0000000..967484a --- /dev/null +++ b/miniapp/project.config.json @@ -0,0 +1,19 @@ +{ + "description": "sankey miniapp standalone config", + "packOptions": { + "ignore": [] + }, + "setting": { + "es6": true, + "enhance": true, + "postcss": true, + "minified": true + }, + "compileType": "miniprogram", + "libVersion": "trial", + "appid": "wxcf0f89b6eb65759e", + "projectname": "sankey-miniapp", + "miniprogramRoot": "./", + "srcMiniprogramRoot": "./", + "condition": {} +}