Compare commits
2 Commits
2cafdbb8fe
...
b2af1cab83
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b2af1cab83 | ||
|
|
d93e2c812f |
@@ -3,6 +3,7 @@
|
|||||||
当前目录已从骨架升级为可用版,支持以下能力:
|
当前目录已从骨架升级为可用版,支持以下能力:
|
||||||
|
|
||||||
- 顶部 Logo / 主题 / 上传 / 导出区域
|
- 顶部 Logo / 主题 / 上传 / 导出区域
|
||||||
|
- 启动默认加载:`data/sankey.xlsx`(位于小程序包内 `miniapp/data/sankey.xlsx`)
|
||||||
- 文件上传与解析:`csv / xls / xlsx`
|
- 文件上传与解析:`csv / xls / xlsx`
|
||||||
- 默认列映射:
|
- 默认列映射:
|
||||||
- 源数据列优先匹配 `data/value/数据/值`
|
- 源数据列优先匹配 `data/value/数据/值`
|
||||||
@@ -18,4 +19,5 @@
|
|||||||
|
|
||||||
注意事项:
|
注意事项:
|
||||||
- `xlsx` 解析依赖 npm 包,若在微信开发者工具中提示模块缺失,请先执行“工具 -> 构建 npm”。
|
- `xlsx` 解析依赖 npm 包,若在微信开发者工具中提示模块缺失,请先执行“工具 -> 构建 npm”。
|
||||||
|
- 当默认文件或上传文件未加载成功时,“数据选择”仅显示空状态提示,不展示占位列名。
|
||||||
- SVG 文件导出后是否可直接预览,取决于当前系统与微信版本对 SVG 文档的支持。
|
- SVG 文件导出后是否可直接预览,取决于当前系统与微信版本对 SVG 文档的支持。
|
||||||
|
|||||||
BIN
miniapp/data/sankey.xlsx
Normal file
BIN
miniapp/data/sankey.xlsx
Normal file
Binary file not shown.
@@ -129,6 +129,8 @@ const TARGET_ALIGN_OPTIONS = [
|
|||||||
{ value: 'top', label: '顶部' },
|
{ value: 'top', label: '顶部' },
|
||||||
{ value: 'bottom', label: '底部' }
|
{ value: 'bottom', label: '底部' }
|
||||||
];
|
];
|
||||||
|
const DEFAULT_SANKEY_FILE_NAME = 'data/sankey.xlsx';
|
||||||
|
const DEFAULT_SANKEY_FILE_PATHS = ['/data/sankey.xlsx', 'data/sankey.xlsx'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数值限制,避免 UI 参数导致布局异常。
|
* 数值限制,避免 UI 参数导致布局异常。
|
||||||
@@ -141,6 +143,32 @@ function clampNumber(value, min, max, fallback) {
|
|||||||
return Math.min(max, Math.max(min, normalized));
|
return Math.min(max, Math.max(min, normalized));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统一错误文案:
|
||||||
|
* - xlsx 解析能力缺失时,固定提示用户去“构建 npm”
|
||||||
|
* - 其他错误返回原始 message,便于定位
|
||||||
|
*/
|
||||||
|
function toFriendlyParseError(error, fallbackMessage) {
|
||||||
|
const message = error && error.message ? String(error.message) : '';
|
||||||
|
if (message.indexOf('xlsx 解析') >= 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 时对连线做镜像翻转。
|
* 方向切换:target->source 时对连线做镜像翻转。
|
||||||
*/
|
*/
|
||||||
@@ -384,10 +412,10 @@ Page({
|
|||||||
data: {
|
data: {
|
||||||
selectedThemeIndex: 1,
|
selectedThemeIndex: 1,
|
||||||
showThemeSheet: false,
|
showThemeSheet: false,
|
||||||
uploadMessage: '点击上传或将csv/xls文件拖到这里上传',
|
uploadMessage: '默认加载 data/sankey.xlsx 中...',
|
||||||
parseError: '',
|
parseError: '',
|
||||||
buildError: '',
|
buildError: '',
|
||||||
columnHeaders: ['列1', '列2', '列3'],
|
columnHeaders: [],
|
||||||
tableRows: [],
|
tableRows: [],
|
||||||
sourceDataColumn: null,
|
sourceDataColumn: null,
|
||||||
sourceDescriptionColumns: [],
|
sourceDescriptionColumns: [],
|
||||||
@@ -396,7 +424,7 @@ Page({
|
|||||||
linksCount: 0,
|
linksCount: 0,
|
||||||
droppedRows: 0,
|
droppedRows: 0,
|
||||||
buildWarnings: [],
|
buildWarnings: [],
|
||||||
infoLogs: ['解析信息: 尚未加载数据文件'],
|
infoLogs: ['解析信息: 正在加载默认数据文件 data/sankey.xlsx'],
|
||||||
sankeyLinks: [],
|
sankeyLinks: [],
|
||||||
sankeyNodes: [],
|
sankeyNodes: [],
|
||||||
gapOptions: GAP_OPTIONS,
|
gapOptions: GAP_OPTIONS,
|
||||||
@@ -413,7 +441,68 @@ Page({
|
|||||||
targetAlignOptionLabels: TARGET_ALIGN_OPTIONS.map((item) => item.label),
|
targetAlignOptionLabels: TARGET_ALIGN_OPTIONS.map((item) => item.label),
|
||||||
targetAlignValues: TARGET_ALIGN_OPTIONS.map((item) => item.value),
|
targetAlignValues: TARGET_ALIGN_OPTIONS.map((item) => item.value),
|
||||||
targetAlignIndex: 0,
|
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() {
|
onReady() {
|
||||||
this.drawSankey();
|
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 filePath = picked.path;
|
||||||
const fileName = picked.name || 'unknown.csv';
|
const fileName = picked.name || 'unknown.csv';
|
||||||
const extension = getFileExtension(fileName);
|
that.readAndApplyFile(filePath, 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);
|
|
||||||
},
|
},
|
||||||
fail(err) {
|
fail(err) {
|
||||||
if (err && String(err.errMsg || '').indexOf('cancel') >= 0) {
|
if (err && String(err.errMsg || '').indexOf('cancel') >= 0) {
|
||||||
@@ -601,7 +744,7 @@ Page({
|
|||||||
uploadMessage: `已加载: ${fileName}(${rows.length} 行)`,
|
uploadMessage: `已加载: ${fileName}(${rows.length} 行)`,
|
||||||
parseError: '',
|
parseError: '',
|
||||||
buildError: '',
|
buildError: '',
|
||||||
columnHeaders: headers.length > 0 ? headers : ['列1', '列2', '列3'],
|
columnHeaders: headers.length > 0 ? headers : [],
|
||||||
tableRows: rows,
|
tableRows: rows,
|
||||||
sourceDataColumn,
|
sourceDataColumn,
|
||||||
sourceDescriptionColumns,
|
sourceDescriptionColumns,
|
||||||
|
|||||||
@@ -90,61 +90,64 @@
|
|||||||
<canvas class="preview-canvas" canvas-id="sankeyCanvas" id="sankeyCanvas" />
|
<canvas class="preview-canvas" canvas-id="sankeyCanvas" id="sankeyCanvas" />
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="bottom-panels">
|
<view class="bottom-panels" style="height: {{bottomPanelsHeightPx}}px;">
|
||||||
<view class="panel data-panel">
|
<view class="panel data-panel">
|
||||||
<image class="panel-title" src="../../assets/icons/data-select.svg" mode="widthFix" />
|
<image class="panel-title" src="../../assets/icons/data-select.svg" mode="widthFix" />
|
||||||
|
<scroll-view class="data-scroll" scroll-y enhanced show-scrollbar="true">
|
||||||
|
<text wx:if="{{columnHeaders.length === 0}}" class="empty-tip">未加载文件,暂无列信息</text>
|
||||||
|
|
||||||
<view class="field-group">
|
<view class="field-group">
|
||||||
<view class="field-title">
|
<view class="field-title">
|
||||||
<image src="../../assets/icons/expand.svg" mode="aspectFit" />
|
<image src="../../assets/icons/expand.svg" mode="aspectFit" />
|
||||||
<text>源数据(link value)</text>
|
<text>源数据(link value)</text>
|
||||||
|
</view>
|
||||||
|
<view class="row" wx:for="{{columnHeaders}}" wx:key="*this" data-index="{{index}}" bindtap="onSelectSourceData">
|
||||||
|
<image src="../../assets/icons/data.svg" mode="aspectFit" />
|
||||||
|
<text class="label">{{item}}</text>
|
||||||
|
<image
|
||||||
|
src="{{sourceDataColumn === index ? '../../assets/icons/radiobutton.svg' : '../../assets/icons/radiobutton-no.svg'}}"
|
||||||
|
mode="aspectFit"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="row" wx:for="{{columnHeaders}}" wx:key="*this" data-index="{{index}}" bindtap="onSelectSourceData">
|
|
||||||
<image src="../../assets/icons/data.svg" mode="aspectFit" />
|
|
||||||
<text class="label">{{item}}</text>
|
|
||||||
<image
|
|
||||||
src="{{sourceDataColumn === index ? '../../assets/icons/radiobutton.svg' : '../../assets/icons/radiobutton-no.svg'}}"
|
|
||||||
mode="aspectFit"
|
|
||||||
/>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view class="field-group">
|
<view class="field-group">
|
||||||
<view class="field-title">
|
<view class="field-title">
|
||||||
<image src="../../assets/icons/expand.svg" mode="aspectFit" />
|
<image src="../../assets/icons/expand.svg" mode="aspectFit" />
|
||||||
<text>源标签(Source label)</text>
|
<text>源标签(Source label)</text>
|
||||||
|
</view>
|
||||||
|
<view class="row" wx:for="{{columnHeaders}}" wx:key="*this" data-index="{{index}}" bindtap="onToggleSourceDesc">
|
||||||
|
<image src="../../assets/icons/description.svg" mode="aspectFit" />
|
||||||
|
<text class="label">{{item}}</text>
|
||||||
|
<image
|
||||||
|
src="{{sourceDescriptionColumns.indexOf(index) > -1 ? '../../assets/icons/checkbox.svg' : '../../assets/icons/checkbox-no.svg'}}"
|
||||||
|
mode="aspectFit"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="row" wx:for="{{columnHeaders}}" wx:key="*this" data-index="{{index}}" bindtap="onToggleSourceDesc">
|
|
||||||
<image src="../../assets/icons/description.svg" mode="aspectFit" />
|
|
||||||
<text class="label">{{item}}</text>
|
|
||||||
<image
|
|
||||||
src="{{sourceDescriptionColumns.indexOf(index) > -1 ? '../../assets/icons/checkbox.svg' : '../../assets/icons/checkbox-no.svg'}}"
|
|
||||||
mode="aspectFit"
|
|
||||||
/>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view class="field-group">
|
<view class="field-group">
|
||||||
<view class="field-title">
|
<view class="field-title">
|
||||||
<image src="../../assets/icons/expand.svg" mode="aspectFit" />
|
<image src="../../assets/icons/expand.svg" mode="aspectFit" />
|
||||||
<text>目标标签(target label)</text>
|
<text>目标标签(target label)</text>
|
||||||
|
</view>
|
||||||
|
<view class="row" wx:for="{{columnHeaders}}" wx:key="*this" data-index="{{index}}" bindtap="onToggleTargetDesc">
|
||||||
|
<image src="../../assets/icons/description.svg" mode="aspectFit" />
|
||||||
|
<text class="label">{{item}}</text>
|
||||||
|
<image
|
||||||
|
src="{{targetDescriptionColumns.indexOf(index) > -1 ? '../../assets/icons/checkbox.svg' : '../../assets/icons/checkbox-no.svg'}}"
|
||||||
|
mode="aspectFit"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="row" wx:for="{{columnHeaders}}" wx:key="*this" data-index="{{index}}" bindtap="onToggleTargetDesc">
|
</scroll-view>
|
||||||
<image src="../../assets/icons/description.svg" mode="aspectFit" />
|
|
||||||
<text class="label">{{item}}</text>
|
|
||||||
<image
|
|
||||||
src="{{targetDescriptionColumns.indexOf(index) > -1 ? '../../assets/icons/checkbox.svg' : '../../assets/icons/checkbox-no.svg'}}"
|
|
||||||
mode="aspectFit"
|
|
||||||
/>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="panel log-panel">
|
<view class="panel log-panel">
|
||||||
<image class="panel-title panel-title-log" src="../../assets/icons/information.svg" mode="widthFix" />
|
<image class="panel-title panel-title-log" src="../../assets/icons/information.svg" mode="widthFix" />
|
||||||
<view class="log-list">
|
<scroll-view class="log-list" scroll-y enhanced show-scrollbar="true">
|
||||||
<text class="log-item" wx:for="{{infoLogs}}" wx:key="index">{{item}}</text>
|
<text class="log-item" wx:for="{{infoLogs}}" wx:key="index">{{item}}</text>
|
||||||
</view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
.page {
|
.page {
|
||||||
min-height: 100vh;
|
height: 100vh;
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
background: #f3f4f6;
|
background: #f3f4f6;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
@@ -10,6 +13,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
@@ -31,6 +35,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
padding-left: 6px;
|
padding-left: 6px;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tool-icon {
|
.tool-icon {
|
||||||
@@ -101,6 +106,11 @@
|
|||||||
background: #fff;
|
background: #fff;
|
||||||
padding: 3.2px;
|
padding: 3.2px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
flex: 1;
|
||||||
|
min-height: 220px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.preview-head {
|
.preview-head {
|
||||||
@@ -227,7 +237,9 @@
|
|||||||
.preview-canvas {
|
.preview-canvas {
|
||||||
margin-top: 3px;
|
margin-top: 3px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 371px;
|
height: auto;
|
||||||
|
flex: 1;
|
||||||
|
min-height: 120px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
background: #f7f8fa;
|
background: #f7f8fa;
|
||||||
}
|
}
|
||||||
@@ -237,6 +249,9 @@
|
|||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr 1fr;
|
grid-template-columns: 1fr 1fr;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
|
height: 300px;
|
||||||
|
min-height: 180px;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.panel {
|
.panel {
|
||||||
@@ -245,18 +260,37 @@
|
|||||||
background: #fff;
|
background: #fff;
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.data-panel {
|
.data-panel {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-scroll {
|
||||||
|
margin-top: 12px;
|
||||||
|
flex: 1;
|
||||||
|
height: 0;
|
||||||
|
min-height: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.empty-tip {
|
||||||
|
color: #86909c;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
.log-panel {
|
.log-panel {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.panel-title {
|
.panel-title {
|
||||||
@@ -316,11 +350,11 @@
|
|||||||
|
|
||||||
.log-list {
|
.log-list {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
height: 0;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
overflow: auto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.log-item {
|
.log-item {
|
||||||
@@ -334,6 +368,7 @@
|
|||||||
color: #86909c;
|
color: #86909c;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 1.3;
|
line-height: 1.3;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-sheet-mask {
|
.theme-sheet-mask {
|
||||||
|
|||||||
@@ -1,4 +1,24 @@
|
|||||||
{
|
{
|
||||||
|
<<<<<<< HEAD
|
||||||
|
"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": {}
|
||||||
|
}
|
||||||
|
=======
|
||||||
"setting": {
|
"setting": {
|
||||||
"es6": true,
|
"es6": true,
|
||||||
"postcss": true,
|
"postcss": true,
|
||||||
@@ -22,4 +42,5 @@
|
|||||||
},
|
},
|
||||||
"appid": "wxcf0f89b6eb65759e",
|
"appid": "wxcf0f89b6eb65759e",
|
||||||
"editorSetting": {}
|
"editorSetting": {}
|
||||||
}
|
}
|
||||||
|
>>>>>>> 2cafdbb8fe6909bf187472a961427bb67e990218
|
||||||
|
|||||||
Reference in New Issue
Block a user