update at 2026-02-14 13:16:10
This commit is contained in:
@@ -75,6 +75,18 @@ function getBaseNameFromPath(filePath) {
|
|||||||
return segments[segments.length - 1] || '';
|
return segments[segments.length - 1] || '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传框文案只显示文件名,不展示路径和统计信息。
|
||||||
|
* 详细信息统一放到“信息日志”区域,避免主界面过长文本挤压。
|
||||||
|
*/
|
||||||
|
function buildUploadMessage(fileName, sourceType) {
|
||||||
|
const baseName = getBaseNameFromPath(fileName) || '未知文件';
|
||||||
|
if (sourceType === 'default') {
|
||||||
|
return `默认加载:${baseName}`;
|
||||||
|
}
|
||||||
|
return `已加载:${baseName}`;
|
||||||
|
}
|
||||||
|
|
||||||
const FALLBACK_THEME_COLORS = ['#9b6bc2', '#7e95f7', '#4cc9f0', '#f4a261'];
|
const FALLBACK_THEME_COLORS = ['#9b6bc2', '#7e95f7', '#4cc9f0', '#f4a261'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -755,7 +767,7 @@ Page({
|
|||||||
DEFAULT_THEME_INDEX,
|
DEFAULT_THEME_INDEX,
|
||||||
Array.isArray(themePresets) ? themePresets.length : 0
|
Array.isArray(themePresets) ? themePresets.length : 0
|
||||||
),
|
),
|
||||||
uploadMessage: '默认加载 data/sankey.xlsx 中...',
|
uploadMessage: buildUploadMessage(DEFAULT_SANKEY_FILE_NAME, 'default'),
|
||||||
parseError: '',
|
parseError: '',
|
||||||
buildError: '',
|
buildError: '',
|
||||||
columnHeaders: [],
|
columnHeaders: [],
|
||||||
@@ -778,6 +790,12 @@ Page({
|
|||||||
infoLogs: ['解析信息: 正在加载默认数据文件 data/sankey.xlsx'],
|
infoLogs: ['解析信息: 正在加载默认数据文件 data/sankey.xlsx'],
|
||||||
sankeyLinks: [],
|
sankeyLinks: [],
|
||||||
sankeyNodes: [],
|
sankeyNodes: [],
|
||||||
|
loadedFileName: '',
|
||||||
|
loadedFilePath: '',
|
||||||
|
loadedFileSourceType: '',
|
||||||
|
// 同步 canvas 逻辑分辨率,避免默认 300x150 被拉伸后出现裁剪。
|
||||||
|
previewCanvasWidth: 300,
|
||||||
|
previewCanvasHeight: 150,
|
||||||
gapOptions: GAP_OPTIONS,
|
gapOptions: GAP_OPTIONS,
|
||||||
gapOptionIndex: 1,
|
gapOptionIndex: 1,
|
||||||
nodeGap: GAP_OPTIONS[1],
|
nodeGap: GAP_OPTIONS[1],
|
||||||
@@ -1051,7 +1069,10 @@ Page({
|
|||||||
success(readRes) {
|
success(readRes) {
|
||||||
try {
|
try {
|
||||||
const table = parseTableByFileName(fileName, readRes.data);
|
const table = parseTableByFileName(fileName, readRes.data);
|
||||||
that.applyParsedTable(table, fileName);
|
that.applyParsedTable(table, fileName, {
|
||||||
|
sourceType: 'upload',
|
||||||
|
fullPath: filePath
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
that.setData({
|
that.setData({
|
||||||
parseError: toFriendlyParseError(error, '文件解析失败')
|
parseError: toFriendlyParseError(error, '文件解析失败')
|
||||||
@@ -1093,7 +1114,10 @@ Page({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
that.applyParsedTable(defaultSankeyTable, `${DEFAULT_SANKEY_FILE_NAME}(内置回退)`);
|
that.applyParsedTable(defaultSankeyTable, DEFAULT_SANKEY_FILE_NAME, {
|
||||||
|
sourceType: 'default',
|
||||||
|
fullPath: 'miniapp/data/sankey.default.js(内置回退)'
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const tryReadByIndex = (index, lastErrorMessage) => {
|
const tryReadByIndex = (index, lastErrorMessage) => {
|
||||||
@@ -1108,7 +1132,10 @@ Page({
|
|||||||
success(readRes) {
|
success(readRes) {
|
||||||
try {
|
try {
|
||||||
const table = parseTableByFileName(DEFAULT_SANKEY_FILE_NAME, readRes.data);
|
const table = parseTableByFileName(DEFAULT_SANKEY_FILE_NAME, readRes.data);
|
||||||
that.applyParsedTable(table, DEFAULT_SANKEY_FILE_NAME);
|
that.applyParsedTable(table, DEFAULT_SANKEY_FILE_NAME, {
|
||||||
|
sourceType: 'default',
|
||||||
|
fullPath: candidatePath
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
that.setData({
|
that.setData({
|
||||||
uploadMessage: '点击上传或将csv/xls文件拖到这里上传',
|
uploadMessage: '点击上传或将csv/xls文件拖到这里上传',
|
||||||
@@ -1164,9 +1191,14 @@ Page({
|
|||||||
/**
|
/**
|
||||||
* 应用解析结果,并按 Web 规则设置默认映射后触发重建。
|
* 应用解析结果,并按 Web 规则设置默认映射后触发重建。
|
||||||
*/
|
*/
|
||||||
applyParsedTable(table, fileName) {
|
applyParsedTable(table, fileName, options) {
|
||||||
const headers = table.headers || [];
|
const headers = table.headers || [];
|
||||||
const rows = table.rows || [];
|
const rows = table.rows || [];
|
||||||
|
const sourceType = options && options.sourceType === 'default' ? 'default' : 'upload';
|
||||||
|
const fullPath =
|
||||||
|
options && typeof options.fullPath === 'string' && options.fullPath
|
||||||
|
? options.fullPath
|
||||||
|
: '';
|
||||||
const sourceByName = findHeaderIndex(headers, ['data', 'value', '数据', '值']);
|
const sourceByName = findHeaderIndex(headers, ['data', 'value', '数据', '值']);
|
||||||
const sourceBySecondRow = findNumericColumnFromSecondRow(rows);
|
const sourceBySecondRow = findNumericColumnFromSecondRow(rows);
|
||||||
const sourceDescByName = findHeaderIndex(headers, ['source', '源']);
|
const sourceDescByName = findHeaderIndex(headers, ['source', '源']);
|
||||||
@@ -1179,9 +1211,12 @@ Page({
|
|||||||
|
|
||||||
this.setData(
|
this.setData(
|
||||||
{
|
{
|
||||||
uploadMessage: `已加载: ${fileName}(${rows.length} 行)`,
|
uploadMessage: buildUploadMessage(fileName, sourceType),
|
||||||
parseError: '',
|
parseError: '',
|
||||||
buildError: '',
|
buildError: '',
|
||||||
|
loadedFileName: getBaseNameFromPath(fileName) || fileName || '',
|
||||||
|
loadedFilePath: fullPath,
|
||||||
|
loadedFileSourceType: sourceType,
|
||||||
columnHeaders: headers.length > 0 ? headers : [],
|
columnHeaders: headers.length > 0 ? headers : [],
|
||||||
tableRows: rows,
|
tableRows: rows,
|
||||||
sourceDataColumn,
|
sourceDataColumn,
|
||||||
@@ -1344,6 +1379,20 @@ Page({
|
|||||||
const logs = [];
|
const logs = [];
|
||||||
const rows = this.data.tableRows || [];
|
const rows = this.data.tableRows || [];
|
||||||
const headers = this.data.columnHeaders || [];
|
const headers = this.data.columnHeaders || [];
|
||||||
|
const loadedFileName = this.data.loadedFileName || '';
|
||||||
|
const loadedFilePath = this.data.loadedFilePath || '';
|
||||||
|
const loadedFileSourceType = this.data.loadedFileSourceType || '';
|
||||||
|
|
||||||
|
if (loadedFileName) {
|
||||||
|
logs.push(`解析信息: 当前文件 ${loadedFileName}`);
|
||||||
|
}
|
||||||
|
if (loadedFileSourceType) {
|
||||||
|
logs.push(`解析信息: 数据来源 ${loadedFileSourceType === 'default' ? '默认文件' : '用户上传'}`);
|
||||||
|
}
|
||||||
|
if (loadedFilePath) {
|
||||||
|
logs.push(`解析信息: 文件路径 ${loadedFilePath}`);
|
||||||
|
}
|
||||||
|
|
||||||
if (rows.length > 0) {
|
if (rows.length > 0) {
|
||||||
logs.push(`解析信息: 已加载 ${rows.length} 行,${headers.length} 列`);
|
logs.push(`解析信息: 已加载 ${rows.length} 行,${headers.length} 列`);
|
||||||
logs.push(`解析信息: 已生成 ${this.data.nodesCount} 个节点,${this.data.linksCount} 条连线`);
|
logs.push(`解析信息: 已生成 ${this.data.nodesCount} 个节点,${this.data.linksCount} 条连线`);
|
||||||
@@ -1388,8 +1437,25 @@ Page({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const width = rect.width;
|
const width = Math.max(1, Math.round(rect.width));
|
||||||
const height = rect.height;
|
const height = Math.max(1, Math.round(rect.height));
|
||||||
|
|
||||||
|
// 小程序 canvas 默认逻辑尺寸是 300x150。
|
||||||
|
// 若不把逻辑尺寸同步到容器尺寸,超过 300/150 的坐标会被裁剪,
|
||||||
|
// 视觉上会出现“节点明明应在最右侧,却停在约 2/3 位置”的问题。
|
||||||
|
if (this.data.previewCanvasWidth !== width || this.data.previewCanvasHeight !== height) {
|
||||||
|
this.setData(
|
||||||
|
{
|
||||||
|
previewCanvasWidth: width,
|
||||||
|
previewCanvasHeight: height
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
this.drawSankey();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const ctx = wx.createCanvasContext('sankeyCanvas', this);
|
const ctx = wx.createCanvasContext('sankeyCanvas', this);
|
||||||
ctx.clearRect(0, 0, width, height);
|
ctx.clearRect(0, 0, width, height);
|
||||||
ctx.setFillStyle('#f7f8fa');
|
ctx.setFillStyle('#f7f8fa');
|
||||||
|
|||||||
@@ -76,7 +76,13 @@
|
|||||||
|
|
||||||
<text wx:if="{{buildError}}" class="error-text" user-select>{{buildError}}</text>
|
<text wx:if="{{buildError}}" class="error-text" user-select>{{buildError}}</text>
|
||||||
<text wx:if="{{parseError}}" class="error-text" user-select>{{parseError}}</text>
|
<text wx:if="{{parseError}}" class="error-text" user-select>{{parseError}}</text>
|
||||||
<canvas class="preview-canvas" canvas-id="sankeyCanvas" id="sankeyCanvas" />
|
<canvas
|
||||||
|
class="preview-canvas"
|
||||||
|
canvas-id="sankeyCanvas"
|
||||||
|
id="sankeyCanvas"
|
||||||
|
width="{{previewCanvasWidth}}"
|
||||||
|
height="{{previewCanvasHeight}}"
|
||||||
|
/>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="bottom-panels" style="height: {{bottomPanelsHeightPx}}px;">
|
<view class="bottom-panels" style="height: {{bottomPanelsHeightPx}}px;">
|
||||||
|
|||||||
Reference in New Issue
Block a user