图表(Chart):运行时、Chart.js 绘制、设计器的"系列和图例"

- System.Windows.Forms.DataVisualization.Charting:ChartAreas、Legends、Titles、Series
  (ChartType、Points.AddXY、图例文字等),DataSource + DataBind(DataTable / DataView / DataSet,
  按 XValueMember、YValueMembers 取列);数据变化时把各系列的点发给浏览器
- 浏览器用 Chart.js 画:SeriesChartType 对应折线、柱形、饼图等,WinForms 默认的 BrightPastel 配色,不要动画
- 设计器工具箱加"图表",和 VS 一样带 ChartArea1、Legend1、Series1;属性窗口"系列和图例"对话框
  编辑系列(名称、图表类型、图例、图例文字、X / Y 值字段)和图例,按 VS 的格式和顺序写回 Designer.cs,
  对话框不管的属性原样保留,教材项目 8 的图表读入再写出逐字节不变;删除图表时一起删掉局部变量;
  设计时用示例数据预览

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
xuyueandClaude Opus 5.5 committed 2026-10-23 15:14:49 +08:00
1 parent d60868d912
commit 2cd0111967
13 files changed
+1227 -4

No files matched your search

+5 -1
View File
@@ -1,6 +1,7 @@
// 对 Designer.cs 文档的编辑操作。每个操作返回新文档,不修改传入的文档。
// 修改过的语句清掉原文(text),生成时按 VS 格式重写;其余语句原样保留。
import { type ControlDef, controlDef, isContainerType } from './catalog'
import { CHART_TYPE, DEFAULT_CHART, removeChartDeclarations, writeChart } from './chart'
import type { Block, DesignerDocument, Stmt } from './document'
import { renderValue, type Value } from './values'
@@ -180,7 +181,8 @@ export function addControl(
if (!def.component) insertChild(next, parent, name)
next.tail = addField(next.tail, def.type, name, next.eol)
syncLayout(next)
return { doc: next, name }
// 图表和 VS 一样带一个图表区、一个图例、一个系列
return { doc: def.type === CHART_TYPE ? writeChart(next, name, DEFAULT_CHART) : next, name }
}
/** 新加入的子控件在最上层:Controls.Add 放在已有的 Controls.Add 之前 */
@@ -201,6 +203,8 @@ export function removeControl(doc: DesignerDocument, name: string): DesignerDocu
for (const child of childrenOf(next, n)) collect(child)
}
collect(name)
// 图表的图表区、图例、系列是 InitializeComponent 开头的局部变量,一起删掉
for (const n of doomed) if (typeOf(next, n) === CHART_TYPE) next.prologue = removeChartDeclarations(next, n).prologue
const keep = (s: Stmt) =>
!(
(s.kind === 'create' && doomed.has(s.name)) ||