Files
Fu-Jie_openwebui-extensions/plugins/actions/infographic/debug_styles.html

342 lines
14 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>信息图样式调试</title>
<script src="https://registry.npmmirror.com/@antv/infographic/0.2.1/files/dist/infographic.min.js"></script>
<style>
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 20px;
background: #f0f0f0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}
.debug-container {
display: flex;
gap: 20px;
max-width: 1400px;
margin: 0 auto;
}
.controls {
width: 300px;
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
height: fit-content;
position: sticky;
top: 20px;
}
.controls h2 {
margin-top: 0;
font-size: 16px;
}
.controls label {
display: block;
margin: 12px 0 4px;
font-size: 14px;
color: #666;
}
.controls input,
.controls select {
width: 100%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
}
.controls button {
width: 100%;
padding: 10px;
margin-top: 16px;
background: #6366f1;
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
}
.controls button:hover {
background: #4f46e5;
}
.preview {
flex: 1;
background: white;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
overflow: hidden;
}
#infographic-container {
min-height: 500px;
padding: 24px;
}
/* ========== 可调试的样式 ========== */
/* 这些样式可以直接在这里修改,刷新页面即可看到效果 */
/* 基础字体 */
#infographic-container svg text {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif !important;
}
#infographic-container svg foreignObject {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif !important;
line-height: 1.4 !important;
}
/* 标题样式 - 根据需要调整 */
#infographic-container svg foreignObject h1,
#infographic-container svg foreignObject [class*="title"] {
font-size: 0.8em !important;
white-space: nowrap !important;
overflow: hidden !important;
text-overflow: ellipsis !important;
}
#infographic-container svg foreignObject h2,
#infographic-container svg foreignObject [class*="subtitle"] {
font-size: 0.85em !important;
white-space: nowrap !important;
overflow: hidden !important;
text-overflow: ellipsis !important;
}
/* ========== 调试样式结束 ========== */
</style>
</head>
<body>
<div class="debug-container">
<div class="controls">
<h2>🔧 样式调试面板</h2>
<label>一级标题字体大小</label>
<input type="text" id="h1-size" value="1.2em" placeholder="例如: 1.2em, 20px">
<label>二级标题字体大小</label>
<input type="text" id="h2-size" value="0.6em" placeholder="例如: 0.6em, 12px">
<label>标题换行设置</label>
<select id="title-wrap">
<option value="nowrap">不换行 (nowrap)</option>
<option value="normal">自动换行 (normal)</option>
</select>
<label>行高</label>
<input type="text" id="line-height" value="1.4" placeholder="例如: 1.4, 1.6">
<button onclick="applyStyles()">应用样式</button>
<button onclick="reRender()" style="background: #10b981; margin-top: 8px;">重新渲染</button>
<hr style="margin: 20px 0; border: none; border-top: 1px solid #eee;">
<label>自定义语法内容</label>
<textarea id="syntax-input" rows="10" style="width: 100%; font-size: 12px; font-family: monospace;">infographic list-grid
data
title 2025职业足球运动员成功要素解析
desc 在高度竞争的现代足球体系下,从天赋到职业的进化路径
items
- label 核心入场券:天赋与身体
desc 速度、爆发力及极佳的球感是底线。基本功必须化为肌肉记忆。
icon mdi/lightning-bolt
- label 决定上限:极度自律
desc 包含严苛的饮食、睡眠管理及强大的抗压心态。
icon mdi/shield-star
- label 现代智慧:球商 (IQ)
desc 复杂的战术理解力与阅读比赛能力。
icon mdi/brain
- label 隐形推手:机遇与平台
desc 专业的青训体系、能发掘你的伯乐。
icon mdi/star-shooting</textarea>
</div>
<div class="preview">
<div id="infographic-container"></div>
</div>
</div>
<script>
function applyStyles() {
console.log('[Debug] 应用样式到已渲染的元素...');
const h1Size = document.getElementById('h1-size').value;
const h2Size = document.getElementById('h2-size').value;
const titleWrap = document.getElementById('title-wrap').value;
const lineHeight = document.getElementById('line-height').value;
const container = document.getElementById('infographic-container');
// 直接操作 SVG 内的所有文本元素
const allTexts = container.querySelectorAll('svg text');
allTexts.forEach(text => {
text.style.setProperty('font-size', h1Size, 'important');
});
// 操作 foreignObject 内的所有元素
const foreignObjects = container.querySelectorAll('svg foreignObject');
let mainTitleCount = 0;
let itemLabelCount = 0;
let itemDescCount = 0;
let otherCount = 0;
foreignObjects.forEach(fo => {
// 检查 foreignObject 自身的 data-element-type 属性
const elementType = fo.getAttribute('data-element-type');
// 设置 foreignObject 本身的行高
fo.style.setProperty('line-height', lineHeight, 'important');
// 获取内部的第一个元素(通常是 span
const firstChild = fo.querySelector(':scope > *');
if (!firstChild) return;
// 根据 foreignObject 的类型设置样式
if (elementType === 'title') {
// 主标题
mainTitleCount++;
firstChild.style.setProperty('font-size', h1Size, 'important');
firstChild.style.setProperty('font-weight', 'bold', 'important');
firstChild.style.setProperty('line-height', lineHeight, 'important');
if (titleWrap === 'nowrap') {
firstChild.style.setProperty('white-space', 'nowrap', 'important');
firstChild.style.setProperty('overflow', 'hidden', 'important');
firstChild.style.setProperty('text-overflow', 'ellipsis', 'important');
} else {
firstChild.style.setProperty('white-space', 'normal', 'important');
firstChild.style.setProperty('overflow', 'visible', 'important');
firstChild.style.setProperty('text-overflow', 'clip', 'important');
}
} else if (elementType === 'desc') {
// 页面副标题(主标题下方的描述)
itemLabelCount++; // 归入副标题计数
firstChild.style.setProperty('font-size', h2Size, 'important');
firstChild.style.setProperty('line-height', lineHeight, 'important');
if (titleWrap === 'nowrap') {
firstChild.style.setProperty('white-space', 'nowrap', 'important');
firstChild.style.setProperty('overflow', 'hidden', 'important');
firstChild.style.setProperty('text-overflow', 'ellipsis', 'important');
} else {
firstChild.style.setProperty('white-space', 'normal', 'important');
firstChild.style.setProperty('overflow', 'visible', 'important');
firstChild.style.setProperty('text-overflow', 'clip', 'important');
}
} else if (elementType === 'item-label') {
// 卡片标题
itemLabelCount++;
firstChild.style.setProperty('font-size', h2Size, 'important');
firstChild.style.setProperty('line-height', lineHeight, 'important');
if (titleWrap === 'nowrap') {
firstChild.style.setProperty('white-space', 'nowrap', 'important');
firstChild.style.setProperty('overflow', 'hidden', 'important');
firstChild.style.setProperty('text-overflow', 'ellipsis', 'important');
} else {
firstChild.style.setProperty('white-space', 'normal', 'important');
firstChild.style.setProperty('overflow', 'visible', 'important');
firstChild.style.setProperty('text-overflow', 'clip', 'important');
}
} else if (elementType === 'item-desc') {
// 卡片描述
itemDescCount++;
firstChild.style.setProperty('line-height', lineHeight, 'important');
firstChild.style.setProperty('white-space', 'normal', 'important');
} else {
// 其他元素
otherCount++;
firstChild.style.setProperty('line-height', lineHeight, 'important');
firstChild.style.setProperty('white-space', 'normal', 'important');
}
});
console.log('[Debug] foreignObject 处理:', '主标题:', mainTitleCount, '卡片标题:', itemLabelCount, '卡片描述:', itemDescCount, '其他:', otherCount);
console.log('[Debug] 样式已应用到', allTexts.length, '个文本元素和', foreignObjects.length, '个 foreignObject');
}
function reRender() {
const container = document.getElementById('infographic-container');
container.innerHTML = '';
let syntaxContent = document.getElementById('syntax-input').value.trim();
if (typeof AntVInfographic === 'undefined') {
container.innerHTML = '<div style="color: red; padding: 20px;">⚠️ AntV Infographic 库未加载</div>';
return;
}
// 应用模板映射(与插件保持一致)
const TEMPLATE_MAPPING = {
'list-grid': 'list-grid-compact-card',
'list-vertical': 'list-column-simple-vertical-arrow',
'tree-vertical': 'hierarchy-tree-tech-style-capsule-item',
'tree-horizontal': 'hierarchy-tree-lr-tech-style-capsule-item',
'mindmap': 'hierarchy-mindmap-branch-gradient-capsule-item',
'sequence-roadmap': 'sequence-roadmap-vertical-simple',
'sequence-zigzag': 'sequence-horizontal-zigzag-simple',
'sequence-horizontal': 'sequence-horizontal-zigzag-simple',
'relation-sankey': 'relation-sankey-simple',
'relation-circle': 'relation-circle-icon-badge',
'compare-binary': 'compare-binary-horizontal-simple-vs',
'compare-swot': 'compare-swot',
'compare-table': 'compare-table-simple',
'quadrant-quarter': 'quadrant-quarter-simple-card',
'statistic-card': 'list-grid-compact-card',
'chart-bar': 'chart-bar-plain-text',
'chart-column': 'chart-column-simple',
'chart-line': 'chart-line-plain-text',
'chart-area': 'chart-area-simple',
'chart-pie': 'chart-pie-plain-text',
'chart-doughnut': 'chart-pie-donut-plain-text'
};
for (const [key, value] of Object.entries(TEMPLATE_MAPPING)) {
const regex = new RegExp(`infographic\\s+${key}(?=\\s|$)`, 'i');
if (regex.test(syntaxContent)) {
console.log(`[Debug] 模板映射: ${key} -> ${value}`);
syntaxContent = syntaxContent.replace(regex, `infographic ${value}`);
break;
}
}
try {
const { Infographic } = AntVInfographic;
const instance = new Infographic({
container: '#infographic-container',
padding: 24,
});
instance.render(syntaxContent);
console.log('[Debug] 渲染完成');
// 渲染完成后应用样式
setTimeout(() => {
applyStyles();
}, 300);
} catch (error) {
container.innerHTML = '<div style="color: red; padding: 20px;">⚠️ 渲染错误: ' + error.message + '</div>';
console.error(error);
}
}
// 页面加载后自动渲染
window.onload = function () {
setTimeout(reRender, 500);
};
</script>
</body>
</html>