马一丁

Update the test renderer

@@ -364,6 +364,68 @@ def build_chapters() -> list[dict]: @@ -364,6 +364,68 @@ def build_chapters() -> list[dict]:
364 ], 364 ],
365 } 365 }
366 366
  367 + pest_block = {
  368 + "type": "pestTable",
  369 + "title": "宏观环境脉冲扫描(PEST)",
  370 + "summary": "模拟四大维度的外部约束与机会,验证 pestTable 的渲染样式。",
  371 + "political": [
  372 + {
  373 + "title": "地方条例征求意见",
  374 + "detail": "短视频发布需实名溯源,平台合规沟通窗口期开启",
  375 + "trend": "正面利好",
  376 + "impact": 7,
  377 + },
  378 + {
  379 + "title": "监管关注情绪煽动",
  380 + "detail": "对夸大矛盾的账号重点巡查,舆论阈值下调",
  381 + "trend": "持续观察",
  382 + "impact": 6,
  383 + },
  384 + ],
  385 + "economic": [
  386 + {
  387 + "title": "周边商户营收波动",
  388 + "detail": "客流短期下滑 12%,但直播带货订单上升",
  389 + "trend": "中性",
  390 + "impact": 5,
  391 + },
  392 + {
  393 + "title": "品牌赞助谨慎",
  394 + "detail": "赞助延期观察声誉风险,对官宣节奏有压力",
  395 + "trend": "不确定",
  396 + "impact": 4,
  397 + },
  398 + ],
  399 + "social": [
  400 + {
  401 + "title": "核心群体情绪分化",
  402 + "detail": "本地居民关注安全,外地游客关注体验与退款",
  403 + "trend": "负面影响",
  404 + "impact": 8,
  405 + },
  406 + {
  407 + "title": "高校社群自发求证",
  408 + "detail": "校媒与学生会组织“以图搜图”科普贴,情绪趋稳",
  409 + "trend": "正面利好",
  410 + "impact": 6,
  411 + },
  412 + ],
  413 + "technological": [
  414 + {
  415 + "title": "AI 生成内容被混入",
  416 + "detail": "局部画面被放大后再传播,需水印溯源工具辅助鉴伪",
  417 + "trend": "负面影响",
  418 + "impact": 7,
  419 + },
  420 + {
  421 + "title": "多模态检索上线",
  422 + "detail": "平台试行“视频反诈”模型,自动提示剪辑痕迹",
  423 + "trend": "正面利好",
  424 + "impact": 5,
  425 + },
  426 + ],
  427 + }
  428 +
367 callout_block = { 429 callout_block = {
368 "type": "callout", 430 "type": "callout",
369 "tone": "warning", 431 "tone": "warning",
@@ -422,6 +484,164 @@ def build_chapters() -> list[dict]: @@ -422,6 +484,164 @@ def build_chapters() -> list[dict]:
422 } 484 }
423 485
424 widget_block = build_widget_block() 486 widget_block = build_widget_block()
  487 + stacked_bar_chart_block = {
  488 + "type": "widget",
  489 + "widgetId": "demo-stacked-sentiment",
  490 + "widgetType": "chart.js/bar",
  491 + "props": {
  492 + "type": "bar",
  493 + "options": {
  494 + "responsive": True,
  495 + "plugins": {"legend": {"position": "bottom"}},
  496 + "scales": {
  497 + "x": {"stacked": True},
  498 + "y": {"stacked": True, "title": {"display": True, "text": "信息量"}},
  499 + },
  500 + },
  501 + },
  502 + "data": {
  503 + "labels": ["周一", "周二", "周三", "周四", "周五"],
  504 + "datasets": [
  505 + {"label": "正向", "data": [18, 22, 24, 19, 16], "backgroundColor": "#27ae60"},
  506 + {"label": "中性", "data": [22, 20, 18, 21, 23], "backgroundColor": "#f39c12"},
  507 + {"label": "负向", "data": [12, 14, 10, 9, 11], "backgroundColor": "#c0392b"},
  508 + ],
  509 + },
  510 + }
  511 + doughnut_chart_block = {
  512 + "type": "widget",
  513 + "widgetId": "demo-sentiment-share",
  514 + "widgetType": "chart.js/doughnut",
  515 + "props": {
  516 + "type": "doughnut",
  517 + "options": {"plugins": {"legend": {"position": "right"}, "tooltip": {"enabled": True}}},
  518 + },
  519 + "data": {
  520 + "labels": ["政策", "经济", "社会", "技术"],
  521 + "datasets": [
  522 + {
  523 + "label": "关注度占比",
  524 + "data": [24, 30, 28, 18],
  525 + "backgroundColor": ["#8e44ad", "#16a085", "#e67e22", "#2980b9"],
  526 + "hoverOffset": 6,
  527 + }
  528 + ],
  529 + },
  530 + }
  531 + radar_chart_block = {
  532 + "type": "widget",
  533 + "widgetId": "demo-response-radar",
  534 + "widgetType": "chart.js/radar",
  535 + "props": {
  536 + "type": "radar",
  537 + "options": {
  538 + "plugins": {"legend": {"position": "top"}},
  539 + "scales": {"r": {"beginAtZero": True, "max": 100}},
  540 + },
  541 + },
  542 + "data": {
  543 + "labels": ["透明度", "响应速度", "一致性", "互动度", "信息量"],
  544 + "datasets": [
  545 + {
  546 + "label": "官方渠道",
  547 + "data": [78, 88, 82, 66, 91],
  548 + "backgroundColor": "rgba(46,204,113,0.15)",
  549 + "borderColor": "#2ecc71",
  550 + "pointBackgroundColor": "#27ae60",
  551 + },
  552 + {
  553 + "label": "民间讨论",
  554 + "data": [64, 72, 58, 74, 63],
  555 + "backgroundColor": "rgba(52,152,219,0.12)",
  556 + "borderColor": "#3498db",
  557 + "pointBackgroundColor": "#2980b9",
  558 + },
  559 + ],
  560 + },
  561 + }
  562 + polar_area_chart_block = {
  563 + "type": "widget",
  564 + "widgetId": "demo-channel-polar",
  565 + "widgetType": "chart.js/polarArea",
  566 + "props": {"type": "polarArea"},
  567 + "data": {
  568 + "labels": ["短视频", "微博", "社区论坛", "新闻客户端", "线下反馈"],
  569 + "datasets": [
  570 + {
  571 + "label": "渠道渗透度",
  572 + "data": [62, 54, 38, 45, 28],
  573 + "backgroundColor": [
  574 + "rgba(231,76,60,0.65)",
  575 + "rgba(142,68,173,0.6)",
  576 + "rgba(52,152,219,0.55)",
  577 + "rgba(46,204,113,0.55)",
  578 + "rgba(241,196,15,0.6)",
  579 + ],
  580 + }
  581 + ],
  582 + },
  583 + }
  584 + scatter_chart_block = {
  585 + "type": "widget",
  586 + "widgetId": "demo-correlation-scatter",
  587 + "widgetType": "chart.js/scatter",
  588 + "props": {
  589 + "type": "scatter",
  590 + "options": {
  591 + "plugins": {"legend": {"position": "bottom"}},
  592 + "scales": {
  593 + "x": {"title": {"display": True, "text": "情绪极性"}, "min": -1, "max": 1},
  594 + "y": {"title": {"display": True, "text": "互动量"}, "beginAtZero": True},
  595 + },
  596 + },
  597 + },
  598 + "data": {
  599 + "datasets": [
  600 + {
  601 + "label": "帖子散点",
  602 + "data": [
  603 + {"x": -0.65, "y": 120},
  604 + {"x": -0.25, "y": 190},
  605 + {"x": 0.05, "y": 260},
  606 + {"x": 0.42, "y": 340},
  607 + {"x": 0.78, "y": 410},
  608 + ],
  609 + "backgroundColor": "rgba(52,152,219,0.7)",
  610 + }
  611 + ],
  612 + },
  613 + }
  614 + bubble_chart_block = {
  615 + "type": "widget",
  616 + "widgetId": "demo-impact-bubble",
  617 + "widgetType": "chart.js/bubble",
  618 + "props": {
  619 + "type": "bubble",
  620 + "options": {
  621 + "plugins": {"legend": {"position": "bottom"}},
  622 + "scales": {
  623 + "x": {"title": {"display": True, "text": "曝光量 (万)"}, "beginAtZero": True},
  624 + "y": {"title": {"display": True, "text": "情绪强度"}, "min": -100, "max": 100},
  625 + },
  626 + },
  627 + },
  628 + "data": {
  629 + "datasets": [
  630 + {
  631 + "label": "渠道分布",
  632 + "data": [
  633 + {"x": 8, "y": 35, "r": 12},
  634 + {"x": 12, "y": -28, "r": 10},
  635 + {"x": 18, "y": 22, "r": 14},
  636 + {"x": 25, "y": 48, "r": 16},
  637 + {"x": 6, "y": -12, "r": 8},
  638 + ],
  639 + "backgroundColor": "rgba(192,57,43,0.55)",
  640 + "borderColor": "#c0392b",
  641 + }
  642 + ],
  643 + },
  644 + }
425 645
426 chapter_1 = { 646 chapter_1 = {
427 "chapterId": "S1", 647 "chapterId": "S1",
@@ -469,7 +689,9 @@ def build_chapters() -> list[dict]: @@ -469,7 +689,9 @@ def build_chapters() -> list[dict]:
469 { 689 {
470 "type": "paragraph", 690 "type": "paragraph",
471 "inlines": [ 691 "inlines": [
472 - {"text": "以下内容逐一覆盖 paragraph/list/table/swot/table/widget 等全部块类型。"} 692 + {
  693 + "text": "以下内容逐一覆盖 paragraph/list/table/swot/pest/widget 等全部块类型。",
  694 + }
473 ], 695 ],
474 }, 696 },
475 { 697 {
@@ -484,14 +706,35 @@ def build_chapters() -> list[dict]: @@ -484,14 +706,35 @@ def build_chapters() -> list[dict]:
484 { 706 {
485 "type": "heading", 707 "type": "heading",
486 "level": 3, 708 "level": 3,
487 - "text": "2.2 高阶块与富媒体", 709 + "text": "2.2 图表组件演示",
  710 + "anchor": "charts-demo",
  711 + },
  712 + {
  713 + "type": "paragraph",
  714 + "inlines": [
  715 + {
  716 + "text": "折线/柱状/饼图/雷达/极区/散点/气泡等多类型图表,用于验证 Chart.js 兼容性。",
  717 + }
  718 + ],
  719 + },
  720 + widget_block,
  721 + stacked_bar_chart_block,
  722 + doughnut_chart_block,
  723 + radar_chart_block,
  724 + polar_area_chart_block,
  725 + scatter_chart_block,
  726 + bubble_chart_block,
  727 + {
  728 + "type": "heading",
  729 + "level": 3,
  730 + "text": "2.3 高阶块与富媒体",
488 "anchor": "advanced-blocks", 731 "anchor": "advanced-blocks",
489 }, 732 },
490 blockquote_block, 733 blockquote_block,
491 callout_block, 734 callout_block,
492 engine_quote_block, 735 engine_quote_block,
493 swot_block, 736 swot_block,
494 - widget_block, 737 + pest_block,
495 code_block, 738 code_block,
496 math_block, 739 math_block,
497 figure_block, 740 figure_block,
@@ -554,16 +797,16 @@ def main() -> int: @@ -554,16 +797,16 @@ def main() -> int:
554 report_id = f"all-blocks-demo-{timestamp}" 797 report_id = f"all-blocks-demo-{timestamp}"
555 metadata = { 798 metadata = {
556 "title": "社会公共热点事件渲染测试", 799 "title": "社会公共热点事件渲染测试",
557 - "subtitle": "覆盖全部 IR 块类型的示例数据",  
558 - "query": "公共事件渲染能力自检", 800 + "subtitle": "覆盖全部 IR 块类型的示例数据,含多种图表与 PEST 演示",
  801 + "query": "公共事件渲染能力自检 / Chart & PEST",
559 "toc": {"title": "目录", "depth": 3}, 802 "toc": {"title": "目录", "depth": 3},
560 "hero": { 803 "hero": {
561 - "summary": "用于验证 Report Engine 在 HTML / PDF 渲染时对各类区块的兼容性。", 804 + "summary": "用于验证 Report Engine 在 HTML / PDF 渲染时对各类区块、Chart.js 组件与 PEST 模块的兼容性。",
562 "kpis": [ 805 "kpis": [
563 - {"label": "示例块数量", "value": "14", "delta": "+100%", "tone": "up"},  
564 - {"label": "图表数", "value": "1", "delta": "安全检查", "tone": "neutral"}, 806 + {"label": "示例块数量", "value": "20+", "delta": "含 PEST", "tone": "up"},
  807 + {"label": "图表数", "value": "7", "delta": "新增多类型", "tone": "neutral"},
565 ], 808 ],
566 - "highlights": ["覆盖全部 block", "含行内/块级公式", "Chart.js 数据有效"], 809 + "highlights": ["覆盖全部 block", "含行内/块级公式", "Chart.js 多类型", "PEST + SWOT"],
567 "actions": ["重新生成", "导出 PDF"], 810 "actions": ["重新生成", "导出 PDF"],
568 }, 811 },
569 } 812 }