@topmindspace/tms-skills 0.1.3 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +39 -0
- package/README.md +6 -6
- package/package.json +2 -2
- package/top-ppt-html/README.md +5 -5
- package/top-ppt-html/SKILL.md +15 -12
- package/top-ppt-html/agents/openai.yaml +2 -2
- package/top-ppt-html/assets/examples/2026-09-09-architecture-graphite-dark.html +72 -27
- package/top-ppt-html/assets/examples/2026-09-09-presentation-business-blue.html +72 -27
- package/top-ppt-html/assets/examples/2026-09-09-research-mckinsey.html +72 -27
- package/top-ppt-html/assets/pptx-export.js +69 -25
- package/top-ppt-html/assets/style-gallery.html +1 -1
- package/top-ppt-html/assets/templates/architecture.html +70 -25
- package/top-ppt-html/assets/templates/presentation.html +70 -25
- package/top-ppt-html/assets/templates/research.html +70 -25
- package/top-ppt-html/package-lock.json +2 -2
- package/top-ppt-html/package.json +2 -2
- package/top-ppt-html/references/default-surface.md +1 -1
- package/top-ppt-html/references/modes.md +1 -1
- package/top-ppt-html/references/playbook.md +9 -8
- package/top-ppt-html/references/pptx-export.md +1 -1
- package/top-ppt-html/references/presentation-craft.md +4 -3
- package/top-ppt-html/references/tech-design.md +1 -1
- package/top-ppt-html/scripts/audit_skill.py +11 -0
- package/top-ppt-html/scripts/build_pptx.js +24 -10
- package/top-ppt-html/scripts/cross_verify.py +1 -1
- package/top-ppt-html/scripts/negative_tests.py +65 -9
- package/top-ppt-html/scripts/quality_gate.py +30 -19
- package/top-ppt-html/scripts/render_from_model.py +1 -1
- package/top-ppt-html/scripts/sync_runtime.py +10 -4
- package/top-ppt-html/scripts/test_feedback_gates.py +180 -0
- package/top-ppt-html/scripts/validate_pptx.py +157 -0
- package/top-ppt-html/scripts/validate_report.py +31 -1
|
@@ -3577,6 +3577,7 @@ window.REPORT_MODEL = {
|
|
|
3577
3577
|
|
|
3578
3578
|
/* __TOPPPT_RUNTIME_START__ */
|
|
3579
3579
|
/* ══ PPTX 导出运行时(assets/pptx-export.js 的内联副本 · 由 scripts/sync_runtime.py 注入,禁止手改) ══ */
|
|
3580
|
+
/* __TOPPPT_RUNTIME_SHA__:68c55206c33160af */
|
|
3580
3581
|
/* ═══════════════════════════════════════════════════════════════════════════
|
|
3581
3582
|
* TopPPT HTML· 浏览器端 PPTX 预览运行时
|
|
3582
3583
|
* 零依赖、随报告单文件分发;OOXML 序列化器(仅供预览,页面不导出文件)。
|
|
@@ -3658,11 +3659,11 @@ var STYLE_DATA_COLORS = {"business-blue":["1a73e8","3526bb","21a199","b77148","9
|
|
|
3658
3659
|
var STYLE_DATA_COLORS_DARK = {"business-blue":["8ab4f8","7966e0","88e7e5","d4ad91","cbce83"],"apple-mono":["f5f5f7","2997ff","2dd4bf","ff9f0a","bf5af2"],"mckinsey":["7fb2e5","6f6bdb","8ce3d8","d1a694","cbc586"],"brand-red":["ff5a66","e09e66","e788cb","91d4c2","83b4ce"],"warm-sand":["d9b36a","c2d571","df9391","97b5ce","8e89c7"],"deep-teal":["4fc3b0","7aaecd","97d8a4","c99cac","c29c8f"],"graphite-dark":["4da3ff","6c66e0","88e7dc","d4a691","cec983"],"indigo-violet":["a5a4f0","a967e0","89c3e7","d3c792","aece83"],"spectrum":["8ba0f8","9066e0","88d6e7","d4ba91","bdce83"]};
|
|
3659
3660
|
var GRID = {"columns":12,"gutter":0.16,"colW":0.8644,"x":[0.6,1.6244,2.6488,3.6732,4.6976,5.722,6.7464,7.7708,8.7952,9.8196,10.844,11.8684,12.733],"y":[2.35,3.27,4.19,5.11,6.03,6.9],"safe":{"top":0.4,"bottom":0.4,"left":0.6,"right":0.6}};
|
|
3660
3661
|
var TYPO = {"levels":[{"id":"C0","name":"封面/章节幕标题","role":"coverTitle","usage":"封面主标题、章节幕标题"},{"id":"T1","name":"页码/章节徽章","role":"caption","usage":"页码徽章、章节编号"},{"id":"T2","name":"页面主标题/结论标题","role":"h1","usage":"每页顶部结论句(research 行动标题)"},{"id":"T3","name":"副标题/语境说明","role":"lead","usage":"主标题下方导语"},{"id":"T4","name":"模块标题/图表标题","role":"h2","usage":"卡片标题、图表标题、面板标题"},{"id":"T5","name":"证据编号/轻量标签","role":"micro","usage":"Exhibit 编号、状态标签"},{"id":"T6","name":"证据块标题/小节标题","role":"h2","usage":"分栏小标题、证据块标题"},{"id":"T7","name":"正文解释段落","role":"body","usage":"证据解释、管理解读正文、表格正文"},{"id":"T8","name":"结论条文字","role":"body","usage":"so-what 结论条、核心结论框"},{"id":"T9","name":"SO WHAT 标签","role":"caption","usage":"so-what 标签行"},{"id":"T10","name":"SO WHAT 正文/业务含义","role":"body","usage":"so-what 正文、行动含义、表格行动项"},{"id":"T11","name":"图表轴/图例/刻度/微标签","role":"micro","usage":"坐标轴、图例、刻度、单位(禁用于表格正文与完整短句)"},{"id":"T12","name":"图表数据标签","role":"caption","usage":"折线点值、柱形标签、百分比标注"},{"id":"T13","name":"关键 KPI 大数字","role":"h1","usage":"KPI 大数字、hero 数值"},{"id":"T14","name":"注释/口径/来源/页脚","role":"micro","usage":"footnote、来源行、页脚、小页码"}],"tableSemanticRule":{"body":["T7","T10"],"microAllowed":["T11"],"microForbiddenFor":["表格正文","行动项","风险项","解释句","建议句","长项目符号","完整短句"]}};
|
|
3661
|
-
var CONT = {"pad":{"card":0.18,"panel":0.2,"cell":0.08,"band":0.16,"soWhat":0.16,"kpi":0.18,"chart":0.1,"head":0.05,"footer":0.05,"node":0.06},"minPad":0.06,"textMetrics":{"lineFactor":1.45,"emAsciiRatio":0.52},"overflowRule":"
|
|
3662
|
+
var CONT = {"pad":{"card":0.18,"panel":0.2,"cell":0.08,"band":0.16,"soWhat":0.16,"kpi":0.18,"chart":0.1,"head":0.05,"footer":0.05,"node":0.06},"minPad":0.06,"textMetrics":{"lineFactor":1.45,"emAsciiRatio":0.52},"overflowRule":"溢出处置优先级(禁静默截断):① 重构承载(列表/卡片/表/图/组合版式)→ ② 拆页/分章(议程→主张→证据卡→明细;01a/01b;信息须完整)→ ③ 换布局形态(V1–V4/多列/卡栅格)→ ④ 有限 fontShrink(阶梯内、模式 floor 以上、最多 4 档)→ ⑤ 禁止:静默截断、砍 so-what/证据/口径、为审美稀疏删决策必需信息。单页字数预算是预警不是删字许可证。","fontShrink":{"ladder":[15,14,13.5,13,12.5,12,11.5,11,10.5,10,9.5,9,8.5],"maxShrinkSteps":4,"floorPt":{"presentation":10,"research":9,"architecture":10},"preferContentFirst":true,"warnBelow":9.5},"continuousTextRule":"语义连续的一句话 / so-what 主句 / 结论句 / 表格单元格正文不得拆成多个独立文本框(避免异常空格、断句、基线漂移);局部加粗高亮必须用同一文本框内富文本。"};
|
|
3662
3663
|
var REG = {"bar":{"html":"svg-bars","pptx":"native","nativeType":"bar","dataTable":"notes","min":{"vbHeightMin":160}},"hbar":{"html":"svg-hbars","pptx":"native","nativeType":"bar","dataTable":"notes","min":{"vbHeightMin":100}},"stack":{"html":"svg-stack","pptx":"native","nativeType":"bar","dataTable":"notes","min":{"vbHeightMin":160},"nativeOpt":{"barGrouping":"stacked"}},"stackline":{"html":"svg-stackline","pptx":"native","nativeType":"bar","dataTable":"notes","min":{"vbHeightMin":40},"nativeOpt":{"barGrouping":"percentStacked"}},"line":{"html":"svg-line","pptx":"native","nativeType":"line","dataTable":"notes","min":{"vbHeightMin":160}},"dualline":{"html":"svg-dualline","pptx":"native","nativeType":"line","dataTable":"notes","min":{"vbHeightMin":160}},"area":{"html":"svg-area","pptx":"native","nativeType":"area","dataTable":"notes","min":{"vbHeightMin":160}},"donut":{"html":"svg-donut","pptx":"native","nativeType":"doughnut","dataTable":"notes","min":{"pxWidthMin":140}},"multidonut":{"html":"svg-mdonut","pptx":"native","nativeType":"doughnut","dataTable":"notes","min":{"pxWidthMin":140}},"pie":{"html":"svg-pie","pptx":"native","nativeType":"pie","dataTable":"notes","min":{"pxWidthMin":140}},"radar":{"html":"svg-radar","pptx":"native","nativeType":"radar","dataTable":"notes","min":{"pxWidthMin":220}},"scatter":{"html":"svg-scatter","pptx":"native","nativeType":"scatter","dataTable":"notes","min":{"vbHeightMin":180}},"bubble":{"html":"svg-bubble","pptx":"native","nativeType":"bubble","dataTable":"notes","min":{"vbHeightMin":180}},"waterfall":{"html":"svg-wf","pptx":"native","nativeType":"bar","dataTable":"notes","min":{"vbHeightMin":170},"nativeTrick":"stacked+hiddenBase+connector"},"gauge":{"html":"svg-gauge","pptx":"native","nativeType":"doughnut","dataTable":"notes","min":{"pxWidthMin":180},"nativeTrick":"doughnut+firstSliceAng+hiddenRemainder"},"pareto":{"html":"svg-pareto","pptx":"native","nativeType":"bar","dataTable":"notes","min":{"vbHeightMin":180},"nativeTrick":"multiType+bar+line"},"gantt":{"html":"svg-gantt","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":130},"path":{"forbidPresetShapes":true}},"vsbar":{"html":"svg-vsbar","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":100},"path":{"forbidPresetShapes":true}},"progress":{"html":"svg-progress","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":100},"path":{"forbidPresetShapes":true}},"sparkline":{"html":"svg-spark","pptx":"shape","dataTable":"off","min":{"vbHeightMin":20},"path":{"forbidPresetShapes":true}},"funnel":{"html":"svg-funnel","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":160},"path":{"minSamplePoints":8,"forbidPresetShapes":true}},"treemap":{"html":"svg-treemap","pptx":"shape","dataTable":"appendix","min":{"vbHeightMin":170},"path":{"forbidPresetShapes":true}},"marimekko":{"html":"svg-marimekko","pptx":"shape","dataTable":"appendix","min":{"vbHeightMin":160},"path":{"forbidPresetShapes":true}},"boxplot":{"html":"svg-boxplot","pptx":"shape","dataTable":"appendix","min":{"vbHeightMin":180},"path":{"forbidPresetShapes":true}},"network":{"html":"svg-network","pptx":"shape","dataTable":"appendix","min":{"vbHeightMin":200},"path":{"forbidPresetShapes":true}},"sankey":{"html":"svg-sankey","pptx":"shape","dataTable":"appendix","min":{"vbHeightMin":200},"path":{"minSamplePoints":16,"trackBothEdges":true,"forbidPresetShapes":true}},"streamgraph":{"html":"svg-stream","pptx":"shape","dataTable":"appendix","min":{"vbHeightMin":160},"path":{"minSamplePoints":24,"trackBothEdges":true,"forbidPresetShapes":true}},"slope":{"html":"svg-slope","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":180},"path":{"forbidPresetShapes":true}},"dumbbell":{"html":"svg-dumbbell","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":160},"path":{"forbidPresetShapes":true}},"lollipop":{"html":"svg-lollipop","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":140},"path":{"forbidPresetShapes":true}},"dotplot":{"html":"svg-dotplot","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":120},"path":{"forbidPresetShapes":true}},"bulletchart":{"html":"svg-bullet","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":140},"path":{"forbidPresetShapes":true}},"waffle":{"html":"svg-waffle","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":160},"path":{"forbidPresetShapes":true}},"radialbar":{"html":"svg-radialbar","pptx":"shape","dataTable":"notes","min":{"pxWidthMin":200},"path":{"minSamplePoints":16,"forbidPresetShapes":true}},"rose":{"html":"svg-rose","pptx":"shape","dataTable":"notes","min":{"pxWidthMin":180},"path":{"minSamplePoints":16,"forbidPresetShapes":true}},"candlestick":{"html":"svg-candle","pptx":"shape","dataTable":"appendix","min":{"vbHeightMin":180},"path":{"forbidPresetShapes":true}}};
|
|
3663
3664
|
var DEEP = {"triggers":["高保真","1:1","一比一","精确还原","按图还原","正式交付","不能偏移","像素级","严格对照","逐页验收"],"complexCharts":["sankey","streamgraph","treemap","marimekko","boxplot","network","rose","radialbar","candlestick","funnel"],"checks":{"anchors":true,"containerOverflow":true,"renderCompare":true,"manifest":true},"renderCompare":{"engine":"soffice","fallback":"powerpoint-com","skipIfMissing":true,"dpi":96}};
|
|
3664
3665
|
var IMG = {"layouts":["full","half","bleed","grid","compare","wall"],"multiLayouts":["grid","compare","wall"],"fitEnum":["cover","contain"],"fitDefault":"cover","formats":["png","jpeg","jpg","webp","svg"],"ratioDefault":{"full":"3:1","half":"4:3","bleed":"21:9","grid":"4:3","compare":"4:3","wall":"1:1"},"ratioCssClass":{"full":"media--r3-1","half":"media--r4-3","bleed":"media--r21-9","grid":"media--r4-3","compare":"media--r4-3","wall":"media--r1-1"},"recommendedSizePx":{"full":"2400×800","half":"1400×1050","bleed":"2560×1100","grid":"900×675","compare":"1400×1050","wall":"480×480"},"maxInlineBytes":1572864,"maxTotalInlineBytes":8388608,"maxPerPage":6,"placeholderLabel":"配图占位","placeholderHintPrefix":"建议 ","placeholderHintSuffix":"px","zeroExternal":true,"qualityRule":"位图优先提供 ≥2× 显示尺寸;截图用 16:9 或 4:3 锁定比例;数据图不要用截图(应用内联 SVG 图表,可随主题变色)。"};
|
|
3665
|
-
var LAYOUT_SLOTS = {"version":"
|
|
3666
|
+
var LAYOUT_SLOTS = {"version":"0.1","pageTypes":{"points":{"mode":["presentation","research","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".grid.g-2 / .card / .ul","pptx":"points columns","minUnits":1},{"id":"annotation","role":"annotation","required":false,"html":".sowhat / .note","pptx":"soWhatBar / footnoteLine"}]},"metrics":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".metric","pptx":"metric row","minUnits":4},{"id":"annotation","role":"annotation","required":false,"html":"口径行 / .sowhat","pptx":"footnoteLine / soWhatBar"}]},"kpi":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"hero","role":"primary","required":true,"html":".t-metric hero","pptx":"hero number"},{"id":"metrics","role":"secondary","required":false,"html":".metric","pptx":"support metrics"},{"id":"annotation","role":"annotation","required":false,"html":".sowhat / .note","pptx":"soWhatBar"}]},"exhibit":{"mode":["research","presentation"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead / .exhibit__hd","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"svg[data-chart] / .exhibit","pptx":"nativeChart | shapeChart","channel":"registry"},{"id":"secondary","role":"secondary","required":false,"html":"要点列表","pptx":"side bullets"},{"id":"annotation","role":"annotation","required":true,"html":".exhibit__src / .sowhat","pptx":"footnoteLine / soWhatBar / notes"}]},"split":{"mode":["presentation","research","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"left","role":"primary","required":true,"html":"左区(points/table/image/chart)","pptx":"left zone"},{"id":"right","role":"secondary","required":true,"html":"右区(points/table/image/chart)","pptx":"right zone"},{"id":"annotation","role":"annotation","required":false,"html":".sowhat / .note","pptx":"soWhatBar"}]},"table":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".tbl-wrap table","pptx":"addTable","maxRows":{"presentation":8,"research":16}},{"id":"annotation","role":"annotation","required":false,"html":".sowhat / .note","pptx":"soWhatBar / footnoteLine"}]},"bar":{"mode":["presentation","research","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"svg[data-chart]","pptx":"nativeChart | shapeChart","channel":"registry"},{"id":"annotation","role":"annotation","required":true,"html":"note / dataTable","pptx":"footnoteLine / notes / inline table"}]},"donut":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"svg[data-chart=donut]","pptx":"addChart doughnut"},{"id":"annotation","role":"annotation","required":false,"html":"中心合计 / 图例 / .note","pptx":"center label / legend / notes"}]},"twocol":{"mode":["research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".cols-2","pptx":"two text columns"},{"id":"annotation","role":"annotation","required":false,"html":".sowhat","pptx":"soWhatBar"}]},"threecol":{"mode":["research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".cols-3","pptx":"three text columns"},{"id":"annotation","role":"annotation","required":false,"html":".sowhat","pptx":"soWhatBar"}]},"halftable":{"mode":["research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"左表","pptx":"addTable left"},{"id":"secondary","role":"secondary","required":true,"html":"右图","pptx":"chart right"},{"id":"annotation","role":"annotation","required":false,"html":".sowhat","pptx":"soWhatBar"}]},"matrix":{"mode":["research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".matrix","pptx":"matrix cells"},{"id":"annotation","role":"annotation","required":false,"html":".sowhat","pptx":"soWhatBar"}]},"comparison":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"left","role":"primary","required":true,"html":"左面板","pptx":"left panel"},{"id":"right","role":"secondary","required":true,"html":"右面板","pptx":"right panel"},{"id":"annotation","role":"annotation","required":false,"html":"verdict / .sowhat","pptx":"verdict bar"}]},"quote":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"金句正文","pptx":"quote text"}]},"timeline":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".tl","pptx":"timeline axis"}]},"steps":{"mode":["presentation","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".steps","pptx":"step row"}]},"cards":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".card grid","pptx":"card grid"}]},"heatmap":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".heat","pptx":"heat cells"}]},"bullet":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".bul","pptx":"bullet rows"}]},"pyramid":{"mode":["presentation","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".pyr","pptx":"pyramid layers"}]},"image":{"mode":["presentation","research","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".media*","pptx":"imageLayoutShapes"}]},"diagram":{"mode":["architecture","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".arch / layers","pptx":"layered nodes + edges","maxNodes":24,"maxLayers":4},{"id":"annotation","role":"annotation","required":false,"html":".arch__legend / .note","pptx":"legend chips / notes"}]},"lane":{"mode":["architecture","research"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":".lane","pptx":"lanes + steps"}]},"sankey":{"mode":["research","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"svg[data-chart=sankey]","pptx":"infoSankey","maxNodes":12},{"id":"annotation","role":"annotation","required":true,"html":"dataTable / .note","pptx":"notes"}]},"treemap":{"mode":["research","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"svg[data-chart=treemap]","pptx":"infoTreemap"},{"id":"annotation","role":"annotation","required":true,"html":"dataTable / .note","pptx":"notes"}]},"boxplot":{"mode":["research","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"svg[data-chart=boxplot]","pptx":"infoBoxplot"},{"id":"annotation","role":"annotation","required":true,"html":"dataTable / .note","pptx":"notes"}]},"network":{"mode":["research","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"svg[data-chart=network]","pptx":"infoNetwork"},{"id":"annotation","role":"annotation","required":true,"html":"dataTable / .note","pptx":"notes"}]},"marimekko":{"mode":["research","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"svg[data-chart=marimekko]","pptx":"infoMarimekko"},{"id":"annotation","role":"annotation","required":true,"html":"dataTable / .note","pptx":"notes"}]},"streamgraph":{"mode":["research","architecture"],"slots":[{"id":"head","role":"chrome","required":true,"html":".shead","pptx":"head()"},{"id":"primary","role":"primary","required":true,"html":"svg[data-chart=streamgraph]","pptx":"infoStreamgraph"},{"id":"annotation","role":"annotation","required":true,"html":"dataTable / .note","pptx":"notes"}]}}};
|
|
3666
3667
|
|
|
3667
3668
|
/* regionOf(pageType, slotId, opts) — 页型布局区域 IR(与 scripts/lib_layout_regions.js 同源) */
|
|
3668
3669
|
function regionOf(pageType, slotId, opts) {
|
|
@@ -3796,7 +3797,7 @@ function regionOf(pageType, slotId, opts) {
|
|
|
3796
3797
|
/* __TOPPPT_SCHEMA_START__ */
|
|
3797
3798
|
/* ── 由 scripts/sync_runtime.py 从 scripts/model-schema.json 注入 · 禁止手改 ── */
|
|
3798
3799
|
/* DSL schema 单源:浏览器端 validateModel 与 scripts/extract_model.py 消费同一份定义 */
|
|
3799
|
-
var MODEL_SCHEMA = {"version":"
|
|
3800
|
+
var MODEL_SCHEMA = {"version":"0.1","modes":["presentation","research","architecture"],"model":{"required":["title","sections:array","closing.title","closing.points:array"],"optional":["mode","style","theme","subtitle","meta","agenda:array"],"agendaMin":{"presentation":3,"research":3,"architecture":0},"sectionsMin":1,"sectionsRecommended":3,"agendaComfortMax":16},"commonSectionFields":["eyebrow","title","lead","soWhat","footnote","flags","image","exhibitNo","layoutPreset"],"flagsHint":"flags = 待核实/待二次修改条目字符串数组(如 '2027 增速 xx%(口径未定)');渲染为 accent 强调色标注行,提示用户核对。","imageHint":"image = 素材图片/配图占位对象。三选一必填:src(用户图,data: 内联或相对路径,零外链铁律禁 http(s))|items(多图版式:grid/compare/wall,元素 {src?, alt?, caption?, placeholder?})|placeholder:true(无图时出配图占位,原生形状渲染、pictures 不增)。其余可选:layout(full/half/bleed/grid/compare/wall,见 layout-constants.json imageSpec.layouts)、fit(cover 默认 / contain)、caption、alt、hint、ratio。","imageLayoutHint":"layout 与 HTML 版式对应:full=版心全宽图|half=左图右注(points 为右栏注解)|bleed=通栏出血|grid=多图网格(items 2/3/4/6 张)|compare=双图 A/B 对比(items 2 张)|wall=Logo 墙(items 3–12 张小图)。占位符标签文本由双引擎按 imageSpec 拼同一串,保证 A/B 通道逐页文本一致。","chartTypes":["bar","hbar","stack","stackline","line","dualline","area","donut","multidonut","pie","radar","scatter","bubble","waterfall","gauge","pareto","funnel","gantt","vsbar","progress","sparkline","slope","dumbbell","lollipop","dotplot","bulletchart","waffle","radialbar","rose","candlestick"],"chartTypesHint":"chart.type 可取值 = 本表(30 类:16 原生 + 14 形状还原)。其余 6 类复杂信息图(sankey/treemap/boxplot/network/marimekko/streamgraph)是**专属页型**而非 chart.type——它们要按列/段/节点等结构化载荷表达,故走 sections[].type。不变量:charts.registry.types == chartTypes ∪ 上述 6 类页型(sync_runtime.py 校验)。","chartDataTable":{"enum":["notes","inline","appendix","off"],"default":"notes","rule":"非原生图表(registry.pptx=shape)的 dataTable 不得为 off;缺失时按 registry 默认值补齐。"},"pageTypes":{"points":{"label":"要点列表页","modes":["presentation","research","architecture"],"required":["points:array"],"optional":["metrics:array"]},"metrics":{"label":"指标带页(4–6 个核心数字)","modes":["presentation","research"],"required":["metrics:array"]},"kpi":{"label":"大数指标页(hero 大数字 + 支撑指标行)","modes":["presentation","research"],"required":["hero:array"],"optional":["metrics:array"]},"table":{"label":"对比表页","modes":["presentation","research","architecture"],"required":["table.head:array","table.rows:array"],"optional":["table.colW:array"]},"timeline":{"label":"时间线 / 路线页","modes":["presentation","research"],"required":["phases:array"]},"steps":{"label":"步骤条页(N 步横排 + 箭头,可分组)","modes":["presentation","research","architecture"],"required":["steps:array"],"optional":["groups:array","note"]},"bar":{"label":"图表页(chart.type 见 chartTypes;native 通道走原生数据图表,shape 通道走高保真形状还原 + 数据表)","modes":["presentation","research"],"required":["chart.labels:array","chart.values:array"],"optional":["chart.type","chart.series:array","chart.points:array","chart.max","chart.unit","chart.colors:array","chart.start:array","chart.target:array","chart.dataTable","note"]},"donut":{"label":"环形图页(原生 pie 楔形 + 图例)","modes":["presentation","research"],"required":["chart.labels:array","chart.values:array"],"optional":["chart.unit","chart.centerLabel","chart.colors:array","chart.dataTable","note"]},"heatmap":{"label":"热力矩阵页(行 × 列 + 强度色阶)","modes":["presentation","research"],"required":["rowHeads:array","colHeads:array","cells:array"],"optional":["unit","scaleLabel:array","note"]},"bullet":{"label":"达成对比页(实际 vs 目标条)","modes":["presentation","research"],"required":["items:array"],"optional":["unit","max","note"]},"pyramid":{"label":"金字塔页(层级递进,顶层最窄)","modes":["presentation","research","architecture"],"required":["levels:array"],"optional":["note"]},"image":{"label":"素材图片页(full/half/bleed/grid/compare/wall,效果与位置锁定;支持配图占位)","modes":["presentation","research","architecture"],"required":["anyof:image.src:str|image.items:array|image.placeholder"],"optional":["image.caption","image.alt","image.layout","image.fit","image.ratio","image.hint","points:array","note"]},"cards":{"label":"卡片网格页(cards 元素须为 {title, points:[[k,v]…]},不接受元组)","modes":["presentation","research"],"required":["cards:array"],"optional":["columns"]},"split":{"label":"双区组合页(left / right 各可为 要点|图表|表格|图片:type = points(默认)| table | image | 图表类型名;图表/表格字段直接挂在对应侧)","modes":["presentation","research"],"required":["anyof:left.points:array|left.type:str"],"optional":["left.cap","left.image","left.labels:array","left.values:array","left.series:array","left.points:array","left.max","left.unit","left.colors:array","left.dataTable","left.head:array","left.rows:array","left.colW:array","right.type","right.cap","right.image","right.labels:array","right.values:array","right.series:array","right.points:array","right.max","right.unit","right.colors:array","right.dataTable","right.head:array","right.rows:array","right.colW:array"]},"comparison":{"label":"对比页(左右双栏 + 可选结论条)","modes":["presentation","research"],"required":["left.title","left.points:array","right.title","right.points:array"],"optional":["verdict"]},"quote":{"label":"引用 / 金句页(深色全幅)","modes":["presentation","research"],"required":["quote","author"],"optional":["context"]},"diagram":{"label":"分层架构页(architecture 模式走全幅几何)","modes":["presentation","research","architecture"],"required":["layers:array"],"optional":["legend:array"]},"exhibit":{"label":"Exhibit 编号图表页(research R2)","modes":["research"],"required":["chart.labels:array","chart.values:array"],"optional":["exhibitNo","chart.type","chart.series:array","chart.points:array","chart.max","chart.unit","chart.colors:array","chart.dataTable","note"]},"twocol":{"label":"双栏论证页(research R1)","modes":["research"],"required":["paragraphs:array"]},"threecol":{"label":"三栏证据页(research R6)","modes":["research"],"required":["paragraphs:array"]},"halftable":{"label":"半表半图页(research R7)","modes":["research"],"required":["table.head:array","table.rows:array","chart.labels:array","chart.values:array"],"optional":["table.colW:array","chart.type","chart.series:array","chart.points:array","chart.max","chart.unit","chart.colors:array","chart.dataTable","note"]},"matrix":{"label":"矩阵图页(research R8)","modes":["research"],"required":["rowHeads:array","colHeads:array","cells:array"]},"lane":{"label":"泳道页(architecture A2)","modes":["architecture"],"required":["lanes:array"]},"sankey":{"label":"桑基图页(节点-流带,流向与流量)","modes":["research","architecture"],"required":["flows:array"],"optional":["unit","chart.dataTable","note"]},"treemap":{"label":"树图页(面积编码的层级构成)","modes":["research","architecture"],"required":["items:array"],"optional":["unit","chart.dataTable","note"]},"boxplot":{"label":"箱线图页(分布对比:min/q1/median/q3/max)","modes":["research","architecture"],"required":["groups:array"],"optional":["unit","chart.dataTable","note"]},"network":{"label":"关系网络页(节点-边拓扑)","modes":["research","architecture"],"required":["nodes:array","edges:array"],"optional":["chart.dataTable","note"]},"marimekko":{"label":"马赛克图页(列宽 × 列高双重编码)","modes":["research","architecture"],"required":["cols:array","cells:array"],"optional":["unit","chart.dataTable","note"]},"streamgraph":{"label":"流带图页(时间上的构成演变)","modes":["research","architecture"],"required":["series:array"],"optional":["labels:array","chart.dataTable","note"]}}};
|
|
3800
3801
|
/* __TOPPPT_SCHEMA_END__ */
|
|
3801
3802
|
|
|
3802
3803
|
var _mode = 'presentation'; /* 当前模式(slidesOf 里按 model.mode 设置) */
|
|
@@ -3855,6 +3856,16 @@ function modeFloorPtA(mode) {
|
|
|
3855
3856
|
var m = String(mode || 'presentation');
|
|
3856
3857
|
return (floors[m] != null) ? floors[m] : 10;
|
|
3857
3858
|
}
|
|
3859
|
+
function snapFont(pt, ladder, floor) {
|
|
3860
|
+
var lad = (ladder || FONT_LADDER).filter(function (v) { return v >= (floor == null ? 0 : floor); });
|
|
3861
|
+
if (!lad.length) return floor == null ? pt : Math.max(floor, pt);
|
|
3862
|
+
var best = lad[0], bd = Math.abs(lad[0] - pt);
|
|
3863
|
+
for (var i = 1; i < lad.length; i++) {
|
|
3864
|
+
var d = Math.abs(lad[i] - pt);
|
|
3865
|
+
if (d < bd) { bd = d; best = lad[i]; }
|
|
3866
|
+
}
|
|
3867
|
+
return best;
|
|
3868
|
+
}
|
|
3858
3869
|
function fitFont(items, widthIn, availIn, opts) {
|
|
3859
3870
|
opts = opts || {};
|
|
3860
3871
|
var max = (opts.max == null) ? 99 : opts.max, lf = opts.lineFactor || 1.45;
|
|
@@ -4199,7 +4210,7 @@ function imageLayoutShapes(sh, S, layout, img, items, points, isPh, fit, y0, y1)
|
|
|
4199
4210
|
sh.push(shape('rect', rxI, lyI + rowHI / 2 - 0.06, 0.12, 0.12, S.accent));
|
|
4200
4211
|
sh.push(txSp(rxI + 0.26, lyI, rwI - 0.3, rowHI - 0.04,
|
|
4201
4212
|
[[{ t: (pt[0] || '') + ' ', sz: fzI, b: 1, col: S.ink, font: S.font },
|
|
4202
|
-
{ t: pt[1] || '', sz: fzI - 1, col: S.body, font: S.font }]], { anchor: 't' }));
|
|
4213
|
+
{ t: pt[1] || '', sz: snapFont(fzI - 1), col: S.body, font: S.font }]], { anchor: 't' }));
|
|
4203
4214
|
});
|
|
4204
4215
|
capY = iy + Math.max(ihh, ih * 0.5);
|
|
4205
4216
|
} else if (layout === 'bleed') {
|
|
@@ -4248,24 +4259,55 @@ function hbarRows(sh, ec, S, y0, y1, dcols, x0, w) {
|
|
|
4248
4259
|
}
|
|
4249
4260
|
/* 竖柱 / 堆叠柱 */
|
|
4250
4261
|
function vbarShapes(sh, ec, S, x, y, w, h, dcols) {
|
|
4251
|
-
|
|
4262
|
+
/* Multi-series aware (mirrors lineShapes): ec.series[{name,values}] or single ec.values. */
|
|
4263
|
+
var labels = ec.labels || [];
|
|
4264
|
+
var series = (ec.series && ec.series.length)
|
|
4265
|
+
? ec.series
|
|
4266
|
+
: [{ name: '数值', values: ec.values || [] }];
|
|
4252
4267
|
var nb = Math.max(1, labels.length);
|
|
4268
|
+
var ns = Math.max(1, series.length);
|
|
4253
4269
|
var baseY = y + h, plotW = w, step = plotW / nb;
|
|
4254
|
-
var
|
|
4255
|
-
var
|
|
4256
|
-
var
|
|
4270
|
+
var cluster = Math.min(1.1, step * (ns > 1 ? 0.78 : 0.55));
|
|
4271
|
+
var bw = cluster / ns;
|
|
4272
|
+
var all = [];
|
|
4273
|
+
series.forEach(function (se) {
|
|
4274
|
+
(se.values || []).forEach(function (v) { all.push(Number(v) || 0); });
|
|
4275
|
+
});
|
|
4276
|
+
var vmax = ec.max || Math.max.apply(null, all.concat([1]));
|
|
4277
|
+
var top = all.length ? Math.max.apply(null, all) : 0;
|
|
4257
4278
|
sh.push(shape('rect', x, baseY, plotW, 0.02, S.line));
|
|
4258
|
-
|
|
4259
|
-
var
|
|
4260
|
-
var
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4279
|
+
series.forEach(function (se, si) {
|
|
4280
|
+
var vals = se.values || [];
|
|
4281
|
+
var col = dcols ? dcols[si % 5] : (si === 0 ? S.accent : S.faint);
|
|
4282
|
+
vals.forEach(function (v, i) {
|
|
4283
|
+
var num = Number(v) || 0;
|
|
4284
|
+
var hh = Math.max(0.05, num / vmax * (h - 0.5));
|
|
4285
|
+
var bx = x + i * step + (step - cluster) / 2 + si * bw;
|
|
4286
|
+
var hot = ns === 1 && num === top;
|
|
4287
|
+
sh.push(shape('roundRect', bx, baseY - hh, Math.max(0.04, bw * 0.92), hh,
|
|
4288
|
+
hot ? (dcols ? dcols[i % 5] : S.accent) : col, { adj: 6000 }));
|
|
4289
|
+
if (ns === 1) {
|
|
4290
|
+
sh.push(txSp(bx - 0.3, baseY - hh - 0.4, bw + 0.6, 0.32,
|
|
4291
|
+
[[{ t: valText(num, ec.unit), sz: 12.5, b: 1, col: hot ? S.accent : S.body, font: S.font }]], { align: 'ctr' }));
|
|
4292
|
+
}
|
|
4293
|
+
});
|
|
4268
4294
|
});
|
|
4295
|
+
labels.forEach(function (lb, i) {
|
|
4296
|
+
var lx = x + i * step;
|
|
4297
|
+
sh.push(txSp(lx, baseY + 0.08, step, 0.32,
|
|
4298
|
+
[[{ t: lb, sz: 10.5, col: S.faint, font: S.font }]], { align: 'ctr' }));
|
|
4299
|
+
});
|
|
4300
|
+
/* Multi-series legend along top of plot (keeps category labels; avoids blank chart). */
|
|
4301
|
+
if (ns > 1) {
|
|
4302
|
+
var lx2 = x;
|
|
4303
|
+
series.forEach(function (se, si) {
|
|
4304
|
+
var col2 = dcols ? dcols[si % 5] : (si === 0 ? S.accent : S.faint);
|
|
4305
|
+
sh.push(shape('rect', lx2, y, 0.12, 0.12, col2));
|
|
4306
|
+
sh.push(txSp(lx2 + 0.16, y - 0.02, 1.4, 0.24,
|
|
4307
|
+
[[{ t: String(se.name || ('系列' + (si + 1))), sz: 10, col: S.body, font: S.font }]]));
|
|
4308
|
+
lx2 += 1.6;
|
|
4309
|
+
});
|
|
4310
|
+
}
|
|
4269
4311
|
}
|
|
4270
4312
|
/* 折线 / 双折线 / 面积 */
|
|
4271
4313
|
function lineShapes(sh, ec, S, x, y, w, h, dcols) {
|
|
@@ -4672,8 +4714,11 @@ function infoApprox(sh, sec, S, y0, y1) {
|
|
|
4672
4714
|
totals.push(tt);
|
|
4673
4715
|
}
|
|
4674
4716
|
var maxTot = Math.max.apply(null, totals.concat([1]));
|
|
4675
|
-
|
|
4676
|
-
var
|
|
4717
|
+
/* Reserve legend INSIDE the plot box so 6-series pages do not crush the annotation band. */
|
|
4718
|
+
var legH = Math.min(1.2, Math.max(0.28, series.length * 0.22 + 0.08));
|
|
4719
|
+
var plotBottom = P.y1 - legH;
|
|
4720
|
+
var plotH3 = Math.max(0.6, plotBottom - P.y0);
|
|
4721
|
+
var cyMid = P.y0 + plotH3 / 2;
|
|
4677
4722
|
var base = totals.map(function (tv) { return cyMid - tv / maxTot * plotH3 / 2; });
|
|
4678
4723
|
series.forEach(function (se, si) {
|
|
4679
4724
|
var upper = base.map(function (bv, i3) { return bv + (values[si][i3] || 0) / maxTot * plotH3 / 2; });
|
|
@@ -4683,12 +4728,12 @@ function infoApprox(sh, sec, S, y0, y1) {
|
|
|
4683
4728
|
sh.push(shape('rect', MX + i4 * stepX, (base[i4] + base[i4 + 1]) / 2, stepX, hgt, palette[si % palette.length]));
|
|
4684
4729
|
}
|
|
4685
4730
|
base = upper;
|
|
4686
|
-
sh.push(shape('rect', MX,
|
|
4687
|
-
sh.push(txSp(MX + 0.16,
|
|
4731
|
+
sh.push(shape('rect', MX, plotBottom + 0.04 + si * 0.2, 0.12, 0.12, palette[si % palette.length]));
|
|
4732
|
+
sh.push(txSp(MX + 0.16, plotBottom + 0.02 + si * 0.2, 1.5, 0.2,
|
|
4688
4733
|
[[{ t: String(se.name || ('系列' + (si + 1))), sz: 10, col: S.body, font: S.font }]], { anchor: 'ctr' }));
|
|
4689
4734
|
});
|
|
4690
4735
|
labels.forEach(function (lb, i5) {
|
|
4691
|
-
sh.push(txSp(MX + (nPts > 1 ? i5 / (nPts - 1) : 0.5) * CW - 0.4,
|
|
4736
|
+
sh.push(txSp(MX + (nPts > 1 ? i5 / (nPts - 1) : 0.5) * CW - 0.4, plotBottom - 0.22, 0.8, 0.2,
|
|
4692
4737
|
[[{ t: String(lb), sz: 9.5, col: S.faint, font: S.font }]], { align: 'ctr' }));
|
|
4693
4738
|
});
|
|
4694
4739
|
}
|
|
@@ -4880,8 +4925,8 @@ function slidesOf(model, S) {
|
|
|
4880
4925
|
var iy = iR.y;
|
|
4881
4926
|
var capH2 = img.caption ? 0.32 : 0;
|
|
4882
4927
|
var ih = Math.max(1.2, iR.h);
|
|
4883
|
-
imageLayoutShapes(sh, S, layout, img, items, sec.points || [], isPh, fit, iy, iy + ih);
|
|
4884
|
-
if (img.caption) sh.push(txSp(MX,
|
|
4928
|
+
var capYImg = imageLayoutShapes(sh, S, layout, img, items, sec.points || [], isPh, fit, iy, iy + ih);
|
|
4929
|
+
if (img.caption) sh.push(txSp(MX, capYImg + 0.04, CW, capH2, [[{ t: img.caption, sz: 10.5, col: S.faint, font: S.font }]]));
|
|
4885
4930
|
} else if (type === 'donut') {
|
|
4886
4931
|
var dcn = sec.chart || {};
|
|
4887
4932
|
if (dcn.labels && dcn.values) donutChart(sh, dcn, S, dcn.colors || donutColors(model.style, S, model.theme));
|
|
@@ -5198,7 +5243,7 @@ function slidesOf(model, S) {
|
|
|
5198
5243
|
sh.push(shape('rect', x, ly2 + rowHP / 2 - 0.06, 0.12, 0.12, S.accent));
|
|
5199
5244
|
sh.push(txSp(x + 0.28, ly2, w - 0.4, rowHP - 0.04,
|
|
5200
5245
|
[[{ t: pt[0] + ' ', sz: fzP, b: 1, col: S.ink, font: S.font },
|
|
5201
|
-
{ t: pt[1], sz: fzP - 1, col: S.body, font: S.font }]]));
|
|
5246
|
+
{ t: pt[1], sz: snapFont(fzP - 1), col: S.body, font: S.font }]]));
|
|
5202
5247
|
});
|
|
5203
5248
|
};
|
|
5204
5249
|
if (lt2 === 'table') {
|
|
@@ -5319,7 +5364,7 @@ function slidesOf(model, S) {
|
|
|
5319
5364
|
sh.push(shape('rect', ptsR.x, y11 + rowHPt / 2 - P2.markSize / 2, P2.markSize, P2.markSize, S.accent));
|
|
5320
5365
|
sh.push(txSp(ptsR.x + 0.32, y11, textW, rowHPt - 0.04,
|
|
5321
5366
|
[[{ t: p[0] + ' ', sz: fzP, b: 1, col: S.ink, font: S.font },
|
|
5322
|
-
{ t: p[1], sz: fzP - 1, col: S.body, font: S.font }]]));
|
|
5367
|
+
{ t: p[1], sz: snapFont(fzP - 1), col: S.body, font: S.font }]]));
|
|
5323
5368
|
});
|
|
5324
5369
|
if (hasM) {
|
|
5325
5370
|
var gx2 = PW - MX - nm2 * mw2;
|
|
@@ -79,7 +79,7 @@ var STYLE_DATA_COLORS = {"business-blue":["1a73e8","3526bb","21a199","b77148","9
|
|
|
79
79
|
var STYLE_DATA_COLORS_DARK = {"business-blue":["8ab4f8","7966e0","88e7e5","d4ad91","cbce83"],"apple-mono":["f5f5f7","2997ff","2dd4bf","ff9f0a","bf5af2"],"mckinsey":["7fb2e5","6f6bdb","8ce3d8","d1a694","cbc586"],"brand-red":["ff5a66","e09e66","e788cb","91d4c2","83b4ce"],"warm-sand":["d9b36a","c2d571","df9391","97b5ce","8e89c7"],"deep-teal":["4fc3b0","7aaecd","97d8a4","c99cac","c29c8f"],"graphite-dark":["4da3ff","6c66e0","88e7dc","d4a691","cec983"],"indigo-violet":["a5a4f0","a967e0","89c3e7","d3c792","aece83"],"spectrum":["8ba0f8","9066e0","88d6e7","d4ba91","bdce83"]};
|
|
80
80
|
var GRID = {"columns":12,"gutter":0.16,"colW":0.8644,"x":[0.6,1.6244,2.6488,3.6732,4.6976,5.722,6.7464,7.7708,8.7952,9.8196,10.844,11.8684,12.733],"y":[2.35,3.27,4.19,5.11,6.03,6.9],"safe":{"top":0.4,"bottom":0.4,"left":0.6,"right":0.6}};
|
|
81
81
|
var TYPO = {"levels":[{"id":"C0","name":"封面/章节幕标题","role":"coverTitle","usage":"封面主标题、章节幕标题"},{"id":"T1","name":"页码/章节徽章","role":"caption","usage":"页码徽章、章节编号"},{"id":"T2","name":"页面主标题/结论标题","role":"h1","usage":"每页顶部结论句(research 行动标题)"},{"id":"T3","name":"副标题/语境说明","role":"lead","usage":"主标题下方导语"},{"id":"T4","name":"模块标题/图表标题","role":"h2","usage":"卡片标题、图表标题、面板标题"},{"id":"T5","name":"证据编号/轻量标签","role":"micro","usage":"Exhibit 编号、状态标签"},{"id":"T6","name":"证据块标题/小节标题","role":"h2","usage":"分栏小标题、证据块标题"},{"id":"T7","name":"正文解释段落","role":"body","usage":"证据解释、管理解读正文、表格正文"},{"id":"T8","name":"结论条文字","role":"body","usage":"so-what 结论条、核心结论框"},{"id":"T9","name":"SO WHAT 标签","role":"caption","usage":"so-what 标签行"},{"id":"T10","name":"SO WHAT 正文/业务含义","role":"body","usage":"so-what 正文、行动含义、表格行动项"},{"id":"T11","name":"图表轴/图例/刻度/微标签","role":"micro","usage":"坐标轴、图例、刻度、单位(禁用于表格正文与完整短句)"},{"id":"T12","name":"图表数据标签","role":"caption","usage":"折线点值、柱形标签、百分比标注"},{"id":"T13","name":"关键 KPI 大数字","role":"h1","usage":"KPI 大数字、hero 数值"},{"id":"T14","name":"注释/口径/来源/页脚","role":"micro","usage":"footnote、来源行、页脚、小页码"}],"tableSemanticRule":{"body":["T7","T10"],"microAllowed":["T11"],"microForbiddenFor":["表格正文","行动项","风险项","解释句","建议句","长项目符号","完整短句"]}};
|
|
82
|
-
var CONT = {"pad":{"card":0.18,"panel":0.2,"cell":0.08,"band":0.16,"soWhat":0.16,"kpi":0.18,"chart":0.1,"head":0.05,"footer":0.05,"node":0.06},"minPad":0.06,"textMetrics":{"lineFactor":1.45,"emAsciiRatio":0.52},"overflowRule":"
|
|
82
|
+
var CONT = {"pad":{"card":0.18,"panel":0.2,"cell":0.08,"band":0.16,"soWhat":0.16,"kpi":0.18,"chart":0.1,"head":0.05,"footer":0.05,"node":0.06},"minPad":0.06,"textMetrics":{"lineFactor":1.45,"emAsciiRatio":0.52},"overflowRule":"溢出处置优先级(禁静默截断):① 重构承载(列表/卡片/表/图/组合版式)→ ② 拆页/分章(议程→主张→证据卡→明细;01a/01b;信息须完整)→ ③ 换布局形态(V1–V4/多列/卡栅格)→ ④ 有限 fontShrink(阶梯内、模式 floor 以上、最多 4 档)→ ⑤ 禁止:静默截断、砍 so-what/证据/口径、为审美稀疏删决策必需信息。单页字数预算是预警不是删字许可证。","fontShrink":{"ladder":[15,14,13.5,13,12.5,12,11.5,11,10.5,10,9.5,9,8.5],"maxShrinkSteps":4,"floorPt":{"presentation":10,"research":9,"architecture":10},"preferContentFirst":true,"warnBelow":9.5},"continuousTextRule":"语义连续的一句话 / so-what 主句 / 结论句 / 表格单元格正文不得拆成多个独立文本框(避免异常空格、断句、基线漂移);局部加粗高亮必须用同一文本框内富文本。"};
|
|
83
83
|
var REG = {"bar":{"html":"svg-bars","pptx":"native","nativeType":"bar","dataTable":"notes","min":{"vbHeightMin":160}},"hbar":{"html":"svg-hbars","pptx":"native","nativeType":"bar","dataTable":"notes","min":{"vbHeightMin":100}},"stack":{"html":"svg-stack","pptx":"native","nativeType":"bar","dataTable":"notes","min":{"vbHeightMin":160},"nativeOpt":{"barGrouping":"stacked"}},"stackline":{"html":"svg-stackline","pptx":"native","nativeType":"bar","dataTable":"notes","min":{"vbHeightMin":40},"nativeOpt":{"barGrouping":"percentStacked"}},"line":{"html":"svg-line","pptx":"native","nativeType":"line","dataTable":"notes","min":{"vbHeightMin":160}},"dualline":{"html":"svg-dualline","pptx":"native","nativeType":"line","dataTable":"notes","min":{"vbHeightMin":160}},"area":{"html":"svg-area","pptx":"native","nativeType":"area","dataTable":"notes","min":{"vbHeightMin":160}},"donut":{"html":"svg-donut","pptx":"native","nativeType":"doughnut","dataTable":"notes","min":{"pxWidthMin":140}},"multidonut":{"html":"svg-mdonut","pptx":"native","nativeType":"doughnut","dataTable":"notes","min":{"pxWidthMin":140}},"pie":{"html":"svg-pie","pptx":"native","nativeType":"pie","dataTable":"notes","min":{"pxWidthMin":140}},"radar":{"html":"svg-radar","pptx":"native","nativeType":"radar","dataTable":"notes","min":{"pxWidthMin":220}},"scatter":{"html":"svg-scatter","pptx":"native","nativeType":"scatter","dataTable":"notes","min":{"vbHeightMin":180}},"bubble":{"html":"svg-bubble","pptx":"native","nativeType":"bubble","dataTable":"notes","min":{"vbHeightMin":180}},"waterfall":{"html":"svg-wf","pptx":"native","nativeType":"bar","dataTable":"notes","min":{"vbHeightMin":170},"nativeTrick":"stacked+hiddenBase+connector"},"gauge":{"html":"svg-gauge","pptx":"native","nativeType":"doughnut","dataTable":"notes","min":{"pxWidthMin":180},"nativeTrick":"doughnut+firstSliceAng+hiddenRemainder"},"pareto":{"html":"svg-pareto","pptx":"native","nativeType":"bar","dataTable":"notes","min":{"vbHeightMin":180},"nativeTrick":"multiType+bar+line"},"gantt":{"html":"svg-gantt","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":130},"path":{"forbidPresetShapes":true}},"vsbar":{"html":"svg-vsbar","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":100},"path":{"forbidPresetShapes":true}},"progress":{"html":"svg-progress","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":100},"path":{"forbidPresetShapes":true}},"sparkline":{"html":"svg-spark","pptx":"shape","dataTable":"off","min":{"vbHeightMin":20},"path":{"forbidPresetShapes":true}},"funnel":{"html":"svg-funnel","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":160},"path":{"minSamplePoints":8,"forbidPresetShapes":true}},"treemap":{"html":"svg-treemap","pptx":"shape","dataTable":"appendix","min":{"vbHeightMin":170},"path":{"forbidPresetShapes":true}},"marimekko":{"html":"svg-marimekko","pptx":"shape","dataTable":"appendix","min":{"vbHeightMin":160},"path":{"forbidPresetShapes":true}},"boxplot":{"html":"svg-boxplot","pptx":"shape","dataTable":"appendix","min":{"vbHeightMin":180},"path":{"forbidPresetShapes":true}},"network":{"html":"svg-network","pptx":"shape","dataTable":"appendix","min":{"vbHeightMin":200},"path":{"forbidPresetShapes":true}},"sankey":{"html":"svg-sankey","pptx":"shape","dataTable":"appendix","min":{"vbHeightMin":200},"path":{"minSamplePoints":16,"trackBothEdges":true,"forbidPresetShapes":true}},"streamgraph":{"html":"svg-stream","pptx":"shape","dataTable":"appendix","min":{"vbHeightMin":160},"path":{"minSamplePoints":24,"trackBothEdges":true,"forbidPresetShapes":true}},"slope":{"html":"svg-slope","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":180},"path":{"forbidPresetShapes":true}},"dumbbell":{"html":"svg-dumbbell","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":160},"path":{"forbidPresetShapes":true}},"lollipop":{"html":"svg-lollipop","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":140},"path":{"forbidPresetShapes":true}},"dotplot":{"html":"svg-dotplot","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":120},"path":{"forbidPresetShapes":true}},"bulletchart":{"html":"svg-bullet","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":140},"path":{"forbidPresetShapes":true}},"waffle":{"html":"svg-waffle","pptx":"shape","dataTable":"notes","min":{"vbHeightMin":160},"path":{"forbidPresetShapes":true}},"radialbar":{"html":"svg-radialbar","pptx":"shape","dataTable":"notes","min":{"pxWidthMin":200},"path":{"minSamplePoints":16,"forbidPresetShapes":true}},"rose":{"html":"svg-rose","pptx":"shape","dataTable":"notes","min":{"pxWidthMin":180},"path":{"minSamplePoints":16,"forbidPresetShapes":true}},"candlestick":{"html":"svg-candle","pptx":"shape","dataTable":"appendix","min":{"vbHeightMin":180},"path":{"forbidPresetShapes":true}}};
|
|
84
84
|
var DEEP = {"triggers":["高保真","1:1","一比一","精确还原","按图还原","正式交付","不能偏移","像素级","严格对照","逐页验收"],"complexCharts":["sankey","streamgraph","treemap","marimekko","boxplot","network","rose","radialbar","candlestick","funnel"],"checks":{"anchors":true,"containerOverflow":true,"renderCompare":true,"manifest":true},"renderCompare":{"engine":"soffice","fallback":"powerpoint-com","skipIfMissing":true,"dpi":96}};
|
|
85
85
|
var IMG = {"layouts":["full","half","bleed","grid","compare","wall"],"multiLayouts":["grid","compare","wall"],"fitEnum":["cover","contain"],"fitDefault":"cover","formats":["png","jpeg","jpg","webp","svg"],"ratioDefault":{"full":"3:1","half":"4:3","bleed":"21:9","grid":"4:3","compare":"4:3","wall":"1:1"},"ratioCssClass":{"full":"media--r3-1","half":"media--r4-3","bleed":"media--r21-9","grid":"media--r4-3","compare":"media--r4-3","wall":"media--r1-1"},"recommendedSizePx":{"full":"2400×800","half":"1400×1050","bleed":"2560×1100","grid":"900×675","compare":"1400×1050","wall":"480×480"},"maxInlineBytes":1572864,"maxTotalInlineBytes":8388608,"maxPerPage":6,"placeholderLabel":"配图占位","placeholderHintPrefix":"建议 ","placeholderHintSuffix":"px","zeroExternal":true,"qualityRule":"位图优先提供 ≥2× 显示尺寸;截图用 16:9 或 4:3 锁定比例;数据图不要用截图(应用内联 SVG 图表,可随主题变色)。"};
|
|
@@ -276,6 +276,16 @@ function modeFloorPtA(mode) {
|
|
|
276
276
|
var m = String(mode || 'presentation');
|
|
277
277
|
return (floors[m] != null) ? floors[m] : 10;
|
|
278
278
|
}
|
|
279
|
+
function snapFont(pt, ladder, floor) {
|
|
280
|
+
var lad = (ladder || FONT_LADDER).filter(function (v) { return v >= (floor == null ? 0 : floor); });
|
|
281
|
+
if (!lad.length) return floor == null ? pt : Math.max(floor, pt);
|
|
282
|
+
var best = lad[0], bd = Math.abs(lad[0] - pt);
|
|
283
|
+
for (var i = 1; i < lad.length; i++) {
|
|
284
|
+
var d = Math.abs(lad[i] - pt);
|
|
285
|
+
if (d < bd) { bd = d; best = lad[i]; }
|
|
286
|
+
}
|
|
287
|
+
return best;
|
|
288
|
+
}
|
|
279
289
|
function fitFont(items, widthIn, availIn, opts) {
|
|
280
290
|
opts = opts || {};
|
|
281
291
|
var max = (opts.max == null) ? 99 : opts.max, lf = opts.lineFactor || 1.45;
|
|
@@ -620,7 +630,7 @@ function imageLayoutShapes(sh, S, layout, img, items, points, isPh, fit, y0, y1)
|
|
|
620
630
|
sh.push(shape('rect', rxI, lyI + rowHI / 2 - 0.06, 0.12, 0.12, S.accent));
|
|
621
631
|
sh.push(txSp(rxI + 0.26, lyI, rwI - 0.3, rowHI - 0.04,
|
|
622
632
|
[[{ t: (pt[0] || '') + ' ', sz: fzI, b: 1, col: S.ink, font: S.font },
|
|
623
|
-
{ t: pt[1] || '', sz: fzI - 1, col: S.body, font: S.font }]], { anchor: 't' }));
|
|
633
|
+
{ t: pt[1] || '', sz: snapFont(fzI - 1), col: S.body, font: S.font }]], { anchor: 't' }));
|
|
624
634
|
});
|
|
625
635
|
capY = iy + Math.max(ihh, ih * 0.5);
|
|
626
636
|
} else if (layout === 'bleed') {
|
|
@@ -669,24 +679,55 @@ function hbarRows(sh, ec, S, y0, y1, dcols, x0, w) {
|
|
|
669
679
|
}
|
|
670
680
|
/* 竖柱 / 堆叠柱 */
|
|
671
681
|
function vbarShapes(sh, ec, S, x, y, w, h, dcols) {
|
|
672
|
-
|
|
682
|
+
/* Multi-series aware (mirrors lineShapes): ec.series[{name,values}] or single ec.values. */
|
|
683
|
+
var labels = ec.labels || [];
|
|
684
|
+
var series = (ec.series && ec.series.length)
|
|
685
|
+
? ec.series
|
|
686
|
+
: [{ name: '数值', values: ec.values || [] }];
|
|
673
687
|
var nb = Math.max(1, labels.length);
|
|
688
|
+
var ns = Math.max(1, series.length);
|
|
674
689
|
var baseY = y + h, plotW = w, step = plotW / nb;
|
|
675
|
-
var
|
|
676
|
-
var
|
|
677
|
-
var
|
|
690
|
+
var cluster = Math.min(1.1, step * (ns > 1 ? 0.78 : 0.55));
|
|
691
|
+
var bw = cluster / ns;
|
|
692
|
+
var all = [];
|
|
693
|
+
series.forEach(function (se) {
|
|
694
|
+
(se.values || []).forEach(function (v) { all.push(Number(v) || 0); });
|
|
695
|
+
});
|
|
696
|
+
var vmax = ec.max || Math.max.apply(null, all.concat([1]));
|
|
697
|
+
var top = all.length ? Math.max.apply(null, all) : 0;
|
|
678
698
|
sh.push(shape('rect', x, baseY, plotW, 0.02, S.line));
|
|
679
|
-
|
|
680
|
-
var
|
|
681
|
-
var
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
699
|
+
series.forEach(function (se, si) {
|
|
700
|
+
var vals = se.values || [];
|
|
701
|
+
var col = dcols ? dcols[si % 5] : (si === 0 ? S.accent : S.faint);
|
|
702
|
+
vals.forEach(function (v, i) {
|
|
703
|
+
var num = Number(v) || 0;
|
|
704
|
+
var hh = Math.max(0.05, num / vmax * (h - 0.5));
|
|
705
|
+
var bx = x + i * step + (step - cluster) / 2 + si * bw;
|
|
706
|
+
var hot = ns === 1 && num === top;
|
|
707
|
+
sh.push(shape('roundRect', bx, baseY - hh, Math.max(0.04, bw * 0.92), hh,
|
|
708
|
+
hot ? (dcols ? dcols[i % 5] : S.accent) : col, { adj: 6000 }));
|
|
709
|
+
if (ns === 1) {
|
|
710
|
+
sh.push(txSp(bx - 0.3, baseY - hh - 0.4, bw + 0.6, 0.32,
|
|
711
|
+
[[{ t: valText(num, ec.unit), sz: 12.5, b: 1, col: hot ? S.accent : S.body, font: S.font }]], { align: 'ctr' }));
|
|
712
|
+
}
|
|
713
|
+
});
|
|
689
714
|
});
|
|
715
|
+
labels.forEach(function (lb, i) {
|
|
716
|
+
var lx = x + i * step;
|
|
717
|
+
sh.push(txSp(lx, baseY + 0.08, step, 0.32,
|
|
718
|
+
[[{ t: lb, sz: 10.5, col: S.faint, font: S.font }]], { align: 'ctr' }));
|
|
719
|
+
});
|
|
720
|
+
/* Multi-series legend along top of plot (keeps category labels; avoids blank chart). */
|
|
721
|
+
if (ns > 1) {
|
|
722
|
+
var lx2 = x;
|
|
723
|
+
series.forEach(function (se, si) {
|
|
724
|
+
var col2 = dcols ? dcols[si % 5] : (si === 0 ? S.accent : S.faint);
|
|
725
|
+
sh.push(shape('rect', lx2, y, 0.12, 0.12, col2));
|
|
726
|
+
sh.push(txSp(lx2 + 0.16, y - 0.02, 1.4, 0.24,
|
|
727
|
+
[[{ t: String(se.name || ('系列' + (si + 1))), sz: 10, col: S.body, font: S.font }]]));
|
|
728
|
+
lx2 += 1.6;
|
|
729
|
+
});
|
|
730
|
+
}
|
|
690
731
|
}
|
|
691
732
|
/* 折线 / 双折线 / 面积 */
|
|
692
733
|
function lineShapes(sh, ec, S, x, y, w, h, dcols) {
|
|
@@ -1093,8 +1134,11 @@ function infoApprox(sh, sec, S, y0, y1) {
|
|
|
1093
1134
|
totals.push(tt);
|
|
1094
1135
|
}
|
|
1095
1136
|
var maxTot = Math.max.apply(null, totals.concat([1]));
|
|
1096
|
-
|
|
1097
|
-
var
|
|
1137
|
+
/* Reserve legend INSIDE the plot box so 6-series pages do not crush the annotation band. */
|
|
1138
|
+
var legH = Math.min(1.2, Math.max(0.28, series.length * 0.22 + 0.08));
|
|
1139
|
+
var plotBottom = P.y1 - legH;
|
|
1140
|
+
var plotH3 = Math.max(0.6, plotBottom - P.y0);
|
|
1141
|
+
var cyMid = P.y0 + plotH3 / 2;
|
|
1098
1142
|
var base = totals.map(function (tv) { return cyMid - tv / maxTot * plotH3 / 2; });
|
|
1099
1143
|
series.forEach(function (se, si) {
|
|
1100
1144
|
var upper = base.map(function (bv, i3) { return bv + (values[si][i3] || 0) / maxTot * plotH3 / 2; });
|
|
@@ -1104,12 +1148,12 @@ function infoApprox(sh, sec, S, y0, y1) {
|
|
|
1104
1148
|
sh.push(shape('rect', MX + i4 * stepX, (base[i4] + base[i4 + 1]) / 2, stepX, hgt, palette[si % palette.length]));
|
|
1105
1149
|
}
|
|
1106
1150
|
base = upper;
|
|
1107
|
-
sh.push(shape('rect', MX,
|
|
1108
|
-
sh.push(txSp(MX + 0.16,
|
|
1151
|
+
sh.push(shape('rect', MX, plotBottom + 0.04 + si * 0.2, 0.12, 0.12, palette[si % palette.length]));
|
|
1152
|
+
sh.push(txSp(MX + 0.16, plotBottom + 0.02 + si * 0.2, 1.5, 0.2,
|
|
1109
1153
|
[[{ t: String(se.name || ('系列' + (si + 1))), sz: 10, col: S.body, font: S.font }]], { anchor: 'ctr' }));
|
|
1110
1154
|
});
|
|
1111
1155
|
labels.forEach(function (lb, i5) {
|
|
1112
|
-
sh.push(txSp(MX + (nPts > 1 ? i5 / (nPts - 1) : 0.5) * CW - 0.4,
|
|
1156
|
+
sh.push(txSp(MX + (nPts > 1 ? i5 / (nPts - 1) : 0.5) * CW - 0.4, plotBottom - 0.22, 0.8, 0.2,
|
|
1113
1157
|
[[{ t: String(lb), sz: 9.5, col: S.faint, font: S.font }]], { align: 'ctr' }));
|
|
1114
1158
|
});
|
|
1115
1159
|
}
|
|
@@ -1301,8 +1345,8 @@ function slidesOf(model, S) {
|
|
|
1301
1345
|
var iy = iR.y;
|
|
1302
1346
|
var capH2 = img.caption ? 0.32 : 0;
|
|
1303
1347
|
var ih = Math.max(1.2, iR.h);
|
|
1304
|
-
imageLayoutShapes(sh, S, layout, img, items, sec.points || [], isPh, fit, iy, iy + ih);
|
|
1305
|
-
if (img.caption) sh.push(txSp(MX,
|
|
1348
|
+
var capYImg = imageLayoutShapes(sh, S, layout, img, items, sec.points || [], isPh, fit, iy, iy + ih);
|
|
1349
|
+
if (img.caption) sh.push(txSp(MX, capYImg + 0.04, CW, capH2, [[{ t: img.caption, sz: 10.5, col: S.faint, font: S.font }]]));
|
|
1306
1350
|
} else if (type === 'donut') {
|
|
1307
1351
|
var dcn = sec.chart || {};
|
|
1308
1352
|
if (dcn.labels && dcn.values) donutChart(sh, dcn, S, dcn.colors || donutColors(model.style, S, model.theme));
|
|
@@ -1619,7 +1663,7 @@ function slidesOf(model, S) {
|
|
|
1619
1663
|
sh.push(shape('rect', x, ly2 + rowHP / 2 - 0.06, 0.12, 0.12, S.accent));
|
|
1620
1664
|
sh.push(txSp(x + 0.28, ly2, w - 0.4, rowHP - 0.04,
|
|
1621
1665
|
[[{ t: pt[0] + ' ', sz: fzP, b: 1, col: S.ink, font: S.font },
|
|
1622
|
-
{ t: pt[1], sz: fzP - 1, col: S.body, font: S.font }]]));
|
|
1666
|
+
{ t: pt[1], sz: snapFont(fzP - 1), col: S.body, font: S.font }]]));
|
|
1623
1667
|
});
|
|
1624
1668
|
};
|
|
1625
1669
|
if (lt2 === 'table') {
|
|
@@ -1740,7 +1784,7 @@ function slidesOf(model, S) {
|
|
|
1740
1784
|
sh.push(shape('rect', ptsR.x, y11 + rowHPt / 2 - P2.markSize / 2, P2.markSize, P2.markSize, S.accent));
|
|
1741
1785
|
sh.push(txSp(ptsR.x + 0.32, y11, textW, rowHPt - 0.04,
|
|
1742
1786
|
[[{ t: p[0] + ' ', sz: fzP, b: 1, col: S.ink, font: S.font },
|
|
1743
|
-
{ t: p[1], sz: fzP - 1, col: S.body, font: S.font }]]));
|
|
1787
|
+
{ t: p[1], sz: snapFont(fzP - 1), col: S.body, font: S.font }]]));
|
|
1744
1788
|
});
|
|
1745
1789
|
if (hasM) {
|
|
1746
1790
|
var gx2 = PW - MX - nm2 * mw2;
|