From 96ed255014bbf04baf987cc0906cea53a3dd22b1 Mon Sep 17 00:00:00 2001 From: Dongcheng Lin Date: Sun, 25 Oct 2026 12:33:51 +0900 Subject: [PATCH] docs: rewrite the manual around reader tasks Rewrite the figure, data, AI assistant and interface reference pages, split the MCP reference into topic pages, and group the sidebar by data type. --- docs/README.md | 15 + docs/astro.config.mjs | 89 +- docs/src/content/docs/ai/connect.md | 70 + .../src/content/docs/ai/control-and-review.md | 132 + docs/src/content/docs/ai/working-with-ai.md | 94 + .../docs/getting-started/first-figure.md | 62 +- .../docs/getting-started/installation.md | 2 +- .../docs/getting-started/quick-tour.md | 3 +- docs/src/content/docs/guides/annotations.md | 26 +- docs/src/content/docs/guides/automation.md | 481 +--- docs/src/content/docs/guides/axes.md | 143 + .../content/docs/guides/choosing-a-tool.md | 5 +- docs/src/content/docs/guides/dosy.md | 35 +- .../content/docs/guides/electrophysiology.md | 2 +- docs/src/content/docs/guides/exporting.md | 14 +- docs/src/content/docs/guides/images.md | 77 + .../src/content/docs/guides/importing-data.md | 347 +-- .../content/docs/guides/layout-and-export.md | 536 ---- .../content/docs/guides/legends-and-lines.md | 100 + .../content/docs/guides/mass-spectrometry.md | 92 + .../docs/guides/multi-panel-figures.md | 260 ++ .../content/docs/guides/organizing-data.md | 5 +- .../content/docs/guides/plots-and-charts.md | 158 ++ docs/src/content/docs/guides/processing.md | 41 +- .../content/docs/guides/supported-formats.md | 270 ++ docs/src/content/docs/guides/tables.md | 124 +- .../content/docs/guides/themes-and-styles.md | 108 + docs/src/content/docs/index.mdx | 20 +- docs/src/content/docs/reference/cli.md | 15 +- .../content/docs/reference/command-palette.md | 4 +- .../content/docs/reference/file-formats.md | 202 +- docs/src/content/docs/reference/mcp.md | 2468 ----------------- .../content/docs/reference/mcp/discovery.md | 249 ++ docs/src/content/docs/reference/mcp/index.md | 137 + docs/src/content/docs/reference/mcp/layout.md | 338 +++ docs/src/content/docs/reference/mcp/plots.md | 279 ++ docs/src/content/docs/reference/mcp/review.md | 373 +++ .../docs/reference/mcp/save-and-export.md | 180 ++ .../content/docs/reference/mcp/scientific.md | 125 + .../src/content/docs/reference/mcp/styling.md | 367 +++ docs/src/content/docs/reference/mcp/tables.md | 404 +++ .../src/content/docs/reference/preferences.md | 13 +- .../content/docs/reference/settings-ids.md | 221 ++ .../content/docs/reference/troubleshooting.md | 58 +- .../src/content/docs/reference/ui-overview.md | 44 +- docs/src/content/docs/zh-cn/ai/connect.md | 59 + .../docs/zh-cn/ai/control-and-review.md | 109 + .../content/docs/zh-cn/ai/working-with-ai.md | 79 + .../zh-cn/getting-started/first-figure.md | 53 +- .../zh-cn/getting-started/installation.md | 2 +- .../docs/zh-cn/getting-started/quick-tour.md | 3 +- .../content/docs/zh-cn/guides/annotations.md | 21 +- .../content/docs/zh-cn/guides/automation.md | 365 +-- docs/src/content/docs/zh-cn/guides/axes.md | 111 + .../docs/zh-cn/guides/choosing-a-tool.md | 7 +- docs/src/content/docs/zh-cn/guides/dosy.md | 25 +- .../content/docs/zh-cn/guides/exporting.md | 12 +- docs/src/content/docs/zh-cn/guides/images.md | 59 + .../docs/zh-cn/guides/importing-data.md | 261 +- .../docs/zh-cn/guides/layout-and-export.md | 408 --- .../docs/zh-cn/guides/legends-and-lines.md | 75 + .../docs/zh-cn/guides/mass-spectrometry.md | 74 + .../docs/zh-cn/guides/multi-panel-figures.md | 207 ++ .../docs/zh-cn/guides/organizing-data.md | 2 +- .../docs/zh-cn/guides/plots-and-charts.md | 125 + .../content/docs/zh-cn/guides/processing.md | 30 +- .../docs/zh-cn/guides/supported-formats.md | 219 ++ docs/src/content/docs/zh-cn/guides/tables.md | 97 +- .../docs/zh-cn/guides/themes-and-styles.md | 86 + docs/src/content/docs/zh-cn/index.mdx | 17 +- docs/src/content/docs/zh-cn/reference/cli.md | 13 +- .../docs/zh-cn/reference/command-palette.md | 2 +- .../docs/zh-cn/reference/file-formats.md | 146 +- docs/src/content/docs/zh-cn/reference/mcp.md | 1979 ------------- .../docs/zh-cn/reference/mcp/discovery.md | 199 ++ .../content/docs/zh-cn/reference/mcp/index.md | 111 + .../docs/zh-cn/reference/mcp/layout.md | 263 ++ .../content/docs/zh-cn/reference/mcp/plots.md | 225 ++ .../docs/zh-cn/reference/mcp/review.md | 298 ++ .../zh-cn/reference/mcp/save-and-export.md | 145 + .../docs/zh-cn/reference/mcp/scientific.md | 93 + .../docs/zh-cn/reference/mcp/styling.md | 301 ++ .../docs/zh-cn/reference/mcp/tables.md | 327 +++ .../docs/zh-cn/reference/preferences.md | 9 +- .../docs/zh-cn/reference/settings-ids.md | 204 ++ .../docs/zh-cn/reference/troubleshooting.md | 39 +- .../docs/zh-cn/reference/ui-overview.md | 23 +- 87 files changed, 8427 insertions(+), 7244 deletions(-) create mode 100644 docs/src/content/docs/ai/connect.md create mode 100644 docs/src/content/docs/ai/control-and-review.md create mode 100644 docs/src/content/docs/ai/working-with-ai.md create mode 100644 docs/src/content/docs/guides/axes.md create mode 100644 docs/src/content/docs/guides/images.md delete mode 100644 docs/src/content/docs/guides/layout-and-export.md create mode 100644 docs/src/content/docs/guides/legends-and-lines.md create mode 100644 docs/src/content/docs/guides/mass-spectrometry.md create mode 100644 docs/src/content/docs/guides/multi-panel-figures.md create mode 100644 docs/src/content/docs/guides/plots-and-charts.md create mode 100644 docs/src/content/docs/guides/supported-formats.md create mode 100644 docs/src/content/docs/guides/themes-and-styles.md delete mode 100644 docs/src/content/docs/reference/mcp.md create mode 100644 docs/src/content/docs/reference/mcp/discovery.md create mode 100644 docs/src/content/docs/reference/mcp/index.md create mode 100644 docs/src/content/docs/reference/mcp/layout.md create mode 100644 docs/src/content/docs/reference/mcp/plots.md create mode 100644 docs/src/content/docs/reference/mcp/review.md create mode 100644 docs/src/content/docs/reference/mcp/save-and-export.md create mode 100644 docs/src/content/docs/reference/mcp/scientific.md create mode 100644 docs/src/content/docs/reference/mcp/styling.md create mode 100644 docs/src/content/docs/reference/mcp/tables.md create mode 100644 docs/src/content/docs/reference/settings-ids.md create mode 100644 docs/src/content/docs/zh-cn/ai/connect.md create mode 100644 docs/src/content/docs/zh-cn/ai/control-and-review.md create mode 100644 docs/src/content/docs/zh-cn/ai/working-with-ai.md create mode 100644 docs/src/content/docs/zh-cn/guides/axes.md create mode 100644 docs/src/content/docs/zh-cn/guides/images.md delete mode 100644 docs/src/content/docs/zh-cn/guides/layout-and-export.md create mode 100644 docs/src/content/docs/zh-cn/guides/legends-and-lines.md create mode 100644 docs/src/content/docs/zh-cn/guides/mass-spectrometry.md create mode 100644 docs/src/content/docs/zh-cn/guides/multi-panel-figures.md create mode 100644 docs/src/content/docs/zh-cn/guides/plots-and-charts.md create mode 100644 docs/src/content/docs/zh-cn/guides/supported-formats.md create mode 100644 docs/src/content/docs/zh-cn/guides/themes-and-styles.md delete mode 100644 docs/src/content/docs/zh-cn/reference/mcp.md create mode 100644 docs/src/content/docs/zh-cn/reference/mcp/discovery.md create mode 100644 docs/src/content/docs/zh-cn/reference/mcp/index.md create mode 100644 docs/src/content/docs/zh-cn/reference/mcp/layout.md create mode 100644 docs/src/content/docs/zh-cn/reference/mcp/plots.md create mode 100644 docs/src/content/docs/zh-cn/reference/mcp/review.md create mode 100644 docs/src/content/docs/zh-cn/reference/mcp/save-and-export.md create mode 100644 docs/src/content/docs/zh-cn/reference/mcp/scientific.md create mode 100644 docs/src/content/docs/zh-cn/reference/mcp/styling.md create mode 100644 docs/src/content/docs/zh-cn/reference/mcp/tables.md create mode 100644 docs/src/content/docs/zh-cn/reference/settings-ids.md diff --git a/docs/README.md b/docs/README.md index b252bc5f..e5229689 100644 --- a/docs/README.md +++ b/docs/README.md @@ -11,6 +11,21 @@ page automatically falls back to the English version with a notice banner. - `src/content/docs/zh-cn/` — Chinese translations (same filenames) - `astro.config.mjs` — site title, locales, and sidebar structure +## Writing conventions + +- Each page is one of three kinds: a task guide (how to do something), a + concept page (why it works that way), or a reference (a complete list or + contract). Keep each section to one kind. +- Property IDs, JSON, and error codes belong only in the Setting IDs and MCP + pages. A guide links there in at most one line. +- Write a new feature into the page and section that own its task, not at the + end of the page edited most recently. +- State each fact in one place and link to it from elsewhere. +- A task page that an AI client can also perform ends with a "With an AI + client" section in the format used by the existing pages. +- When adding or moving a page, update its Simplified Chinese counterpart and + the sidebar in `astro.config.mjs` in the same change. + ## Commands Run from this directory: diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index a8875327..cc6ab12d 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -29,14 +29,30 @@ export default defineConfig({ ], }, { - label: 'Working with Data', + label: 'AI Assistant', + translations: { 'zh-CN': 'AI 助手' }, + items: [ + { slug: 'ai/connect' }, + { slug: 'ai/working-with-ai' }, + { slug: 'ai/control-and-review' }, + ], + }, + { + label: 'Data', translations: { 'zh-CN': '准备数据' }, items: [ { slug: 'guides/importing-data' }, - { slug: 'guides/organizing-data' }, + { slug: 'guides/supported-formats' }, { slug: 'guides/tables' }, + { slug: 'guides/organizing-data' }, + ], + }, + { + label: 'Processing', + translations: { 'zh-CN': '处理' }, + items: [ { slug: 'guides/processing' }, - { slug: 'guides/craft' }, + { slug: 'guides/templates' }, ], }, { @@ -49,38 +65,49 @@ export default defineConfig({ { slug: 'guides/custom-models' }, { slug: 'guides/statistics' }, { slug: 'guides/spectrum-tools' }, + ], + }, + { + label: 'By data type', + translations: { 'zh-CN': '按数据类型' }, + items: [ { - label: 'By technique', - translations: { 'zh-CN': '按数据类型' }, + label: 'NMR', items: [ + { slug: 'guides/craft' }, { slug: 'guides/pseudo-2d' }, { slug: 'guides/dosy' }, { slug: 'guides/2d-integration' }, { slug: 'guides/symmetry-review' }, - { slug: 'guides/electrophysiology' }, - { slug: 'guides/xps' }, ], }, + { slug: 'guides/mass-spectrometry' }, + { slug: 'guides/xps' }, + { slug: 'guides/electrophysiology' }, ], }, { - label: 'Figures and Export', - translations: { 'zh-CN': '图形与导出' }, + label: 'Figures', + translations: { 'zh-CN': '图形' }, items: [ - { slug: 'guides/layout-and-export' }, + { slug: 'guides/plots-and-charts' }, + { slug: 'guides/axes' }, + { slug: 'guides/legends-and-lines' }, + { slug: 'guides/themes-and-styles' }, + { slug: 'guides/multi-panel-figures' }, + { slug: 'guides/images' }, + { slug: 'guides/annotations' }, { slug: 'guides/contour-levels' }, { slug: 'guides/heatmap-range' }, - { slug: 'guides/annotations' }, { slug: 'guides/exporting' }, { slug: 'guides/present-mode' }, ], }, { - label: 'Batch and Automation', - translations: { 'zh-CN': '批量与自动化' }, + label: 'Batch and Scripting', + translations: { 'zh-CN': '批量与脚本' }, items: [ { slug: 'guides/automation' }, - { slug: 'guides/templates' }, { slug: 'reference/cli' }, ], }, @@ -88,16 +115,42 @@ export default defineConfig({ label: 'Reference', translations: { 'zh-CN': '参考' }, items: [ - { slug: 'reference/shortcuts' }, - { slug: 'reference/command-palette' }, { slug: 'reference/ui-overview' }, { slug: 'reference/ribbon' }, + { slug: 'reference/command-palette' }, + { slug: 'reference/shortcuts' }, { slug: 'reference/preferences' }, - { slug: 'reference/mcp' }, { slug: 'reference/file-formats' }, - { slug: 'reference/updates' }, + ], + }, + { + label: 'Setting IDs and MCP', + translations: { 'zh-CN': '设置 ID 与 MCP' }, + items: [ + { slug: 'reference/settings-ids' }, + { + label: 'MCP', + items: [ + { slug: 'reference/mcp' }, + { slug: 'reference/mcp/discovery' }, + { slug: 'reference/mcp/tables' }, + { slug: 'reference/mcp/plots' }, + { slug: 'reference/mcp/styling' }, + { slug: 'reference/mcp/layout' }, + { slug: 'reference/mcp/review' }, + { slug: 'reference/mcp/save-and-export' }, + { slug: 'reference/mcp/scientific' }, + ], + }, + ], + }, + { + label: 'Help', + translations: { 'zh-CN': '帮助' }, + items: [ { slug: 'reference/troubleshooting' }, { slug: 'reference/reporting-problems' }, + { slug: 'reference/updates' }, ], }, ], diff --git a/docs/src/content/docs/ai/connect.md b/docs/src/content/docs/ai/connect.md new file mode 100644 index 00000000..8571306a --- /dev/null +++ b/docs/src/content/docs/ai/connect.md @@ -0,0 +1,70 @@ +--- +title: Connect an AI client +description: Connect Codex, Claude Code or Claude Desktop to Plotium so it can work with your open project. +--- + +An AI client connected to Plotium can look at your open project, build and +adjust figures, and run supported analyses while you keep working in the +desktop app. You talk to it in the client (Codex, Claude Code or Claude +Desktop); Plotium has no built-in chat window. The connection runs on your own +computer and uses the Model Context Protocol (MCP). + +## Before you start + +- Install the AI client you want to use. +- Keep the Plotium installation complete. The macOS app already contains the + connector; for a ZIP installation keep `plotium-mcp` (`plotium-mcp.exe` on + Windows) beside the main program. + +## Connect + +1. Open Plotium. +2. Open **Preferences → AI connections (MCP)**. You can also click the robot + icon beside Operation history in the Ribbon, or choose **File → AI + connections (MCP)…**. +3. Turn on **Enable MCP**. +4. Under **Access**, choose **Read only** to let the AI look without changing + anything, or **Read and modify** to allow supported edits. The default is + **Read and modify**; [Access, review and undo](/ai/control-and-review/) + explains both. +5. Add your client: + +| Client | In Plotium | In the client | +| --- | --- | --- | +| Codex | Press **Add** in the Codex card | Reload MCP configuration or restart the client if needed | +| Claude Code | Press **Add** in the Claude Code card | Reload MCP configuration or restart the client if needed | +| Claude Desktop (macOS and Windows) | Press **Add to Claude Desktop…** | Confirm installation of the extension, then reload or restart if needed | + +Each client only needs to be added once. Plotium remembers **Enable MCP** and +the access level across restarts. + +## Check the connection + +Start your AI client yourself; Plotium does not launch it. **Configured** on a +card only means the settings were added. To check that the client can reach +Plotium, send this first request: + +> Use Plotium to list the datasets and figures in my current project. Do not +> change anything. + +The client should describe your project, and the robot icon in Plotium turns +green while the client is active. Opening the Claude Desktop extension package +alone does not confirm a working connection. If nothing happens, see +[If the connection does not work](/ai/control-and-review/#if-the-connection-does-not-work). + +Next, see [Working with an AI client](/ai/working-with-ai/) for what to ask. + +## Other MCP clients + +For another MCP client on the same computer, expand **Manual configuration and +diagnostics** and press **Copy stable stdio configuration**, then paste the +copied configuration into your client. The connection works only for clients +on the same computer and user account; remote connections and access between +Windows and WSL are not supported. +[MCP setup and permissions](/reference/mcp/) has the manual registration +commands and the technical reference. + +## After updating Plotium + +Restart the Plotium connection in your AI client (or restart the client) so it +loads the updated tools. You do not need to add the client again. diff --git a/docs/src/content/docs/ai/control-and-review.md b/docs/src/content/docs/ai/control-and-review.md new file mode 100644 index 00000000..7a28b551 --- /dev/null +++ b/docs/src/content/docs/ai/control-and-review.md @@ -0,0 +1,132 @@ +--- +title: Access, review and undo +description: Control what an AI client can do, follow and undo its changes, and fix connection problems. +--- + +You stay in charge of what an AI client does in Plotium: you choose whether it +may change anything, every change can be undone, and nothing is written to disk +without your confirmation in Plotium. + +## Choose what the AI may do + +Set this in **Preferences → AI connections (MCP)**, or click the robot icon in +the Ribbon. + +| Setting | Effect | +| --- | --- | +| **Access → Read only** | The AI can look at data, tables and figures, including images of the current figures, but cannot prepare, preview or apply changes. Switching to Read only also blocks changes it has prepared but not yet applied | +| **Access → Read and modify** | The AI can also make supported changes. This is the default | +| **Enable MCP** off | Stops all access immediately and discards changes the AI prepared but did not apply. Your client setup is kept | + +The access level applies to every connected client and every project you open, +and Plotium remembers it across restarts. Closing Preferences or switching +projects keeps the connection running; exiting Plotium stops it. After a +restart you can continue in the same AI conversation without adding the client +again. After you switch projects, ask the AI to look at the current project +before it continues editing. + +Your AI client may also ask you to approve its tool calls. That approval is +the client's own and separate from Plotium's access level: approving a call in +the client never bypasses **Read only** or the save and export confirmations. + +## Review and undo changes + +- Every change appears in Plotium immediately and is one step in **Undo** and + **Redo**, however many items it touched. A save or export is not a change to + the project and cannot be undone. +- Values you set by hand, such as a colour you chose in the Object inspector or + a legend you dragged, are kept when the AI restyles a figure or applies a + theme, unless you ask it to change them. +- Looking, previewing and checking do not change the project and do not mark + it as unsaved. +- **Operation history** (the clock-arrow button in the Ribbon) lists the results + of recent AI operations under **Results**, with links to view them. + +## Save and export confirmation + +When the AI asks to save or export, Plotium shows **Allow AI to save this +project?** or **Allow AI to export this figure?** with the exact file paths. + +- Press **Allow save** or **Allow export** to go ahead, or **Deny** to write + nothing. +- Replacing an existing file needs its own checkbox in the same prompt. +- Each confirmation covers that one request. A changed path needs a new one. +- This confirmation is needed even with **Read and modify** access, and the AI + can ask for it even in **Read only**. + +A save captures the project at the moment you allow it; later edits are still +unsaved. Export does not change the project or mark it as saved. + +## Follow AI results + +By default, the workspace follows the AI: it shows the canvas affected by the +latest completed operation. Results that touch several canvases are shown +together, and a canvas already in view keeps its zoom. Requests that only look +at the project, and empty canvases, do not move the workspace. + +The follow button beside the robot icon shows whether following is active, +paused or off. Working yourself pauses following: opening or selecting other +content, panning, zooming or editing. Hovering and reading operation details do +not. In Operation history's **Results**, use **Pause**, **Resume**, **Stop +following** or **View latest**. + +While following is paused: + +- A badge on the follow button counts new or updated results you have not + viewed. Repeated changes to the same object count once. Viewing a result marks + it as seen; **View latest** shows the latest result but leaves older ones in + the count, and does not turn following back on. Resuming clears the count. + Open **Results** to review them without resuming. +- Updates to the object in view also show a brief notification you can close. +- A reminder offers **Resume following**, **Dismiss** and **Don't remind + again**. It closes after about eight seconds. **Dismiss** hides it without + marking results as seen; further changes to the same object do not bring it + back, but a new result object can. **Don't remind again** turns reminders off across restarts; + turn them back on in **Preferences → General → Remind me about results while + following is paused**. Result counts and error notifications stay available. + +Pausing freezes the view at once, including an unfinished automatic zoom. +Resuming, or viewing the latest result, shows the latest operation's results +only. Changing projects or losing the connection +stops following; resume it yourself when you are ready. Following never cancels +a running task. + +A spinner on the robot icon means a scientific task is running. Hover over it +for the operation, progress when known, and whether editing now could stop the +result from being applied. It shows Plotium's own running work, not whether the +AI has finished your request. + +## The robot icon + +Hover over the robot for the project, access level and last activity. Click it +to open the connection settings; it stays available when the Ribbon is +collapsed. + +| Appearance | Status | What it means | +| --- | --- | --- | +| Gray, short slash | Off | Turn on **Enable MCP** when you want to connect | +| Blue, hollow dot | Starting / Ready | Wait for startup, or send a request from your client | +| Green, filled dot | Active | A client was active in the last 30 seconds; this does not mean its task is finished | +| Orange, exclamation | Needs attention | Open the connection settings, read the error and follow the suggested action | + +## If the connection does not work + +| What you see | What to try | +| --- | --- | +| Plotium cannot find Codex or Claude Code | Use **Installation help** to install the client, or **Choose executable…** to select it, then press **Add** | +| An error mentions Node.js | Check the client's Node.js installation, or select a standalone client executable, then try again | +| A different server named `plotium` already exists | Review the existing entry. Choose **Back up and replace this entry** only if you want to replace it; Plotium backs it up and leaves other servers unchanged | +| **Configured**, but no client activity | Reload the client's MCP configuration or restart it, then send the [first request](/ai/connect/#check-the-connection). Check whether the client has disabled or blocked the server | +| The AI says the project has changed or its information is out of date | Ask it to look at the current project again before continuing | +| Another Plotium instance owns the connection | Use the instance providing the connection, or exit it so this one can connect. Switching window focus does not switch the AI's target | +| Windows reports that the connector is in use during an update | Exit AI clients using Plotium, then press **Retry** in the connection settings | +| The connector or Claude Desktop extension is missing | Extract the complete Plotium release again and keep its files together | + +Startup failures retry automatically. The connection settings show recent +operations and errors; press **Retry** when offered after fixing the cause. + +If the connection breaks while the AI is changing something, look at the +project before asking it to try again: the change may already have been made, +and repeating it could create duplicate content. The same applies to saves and +exports: ask the AI to check what happened to the request rather than sending +it again. diff --git a/docs/src/content/docs/ai/working-with-ai.md b/docs/src/content/docs/ai/working-with-ai.md new file mode 100644 index 00000000..4ac740f7 --- /dev/null +++ b/docs/src/content/docs/ai/working-with-ai.md @@ -0,0 +1,94 @@ +--- +title: Working with an AI client +description: What an AI client can do in Plotium, how to ask, and how to preview, apply and check its work. +--- + +Once [connected](/ai/connect/), an AI client works on the project open in +Plotium. Everything it changes appears in the desktop app at once, as ordinary +Plotium content you can keep editing by hand. + +## What it can do + +| Area | Examples | +| --- | --- | +| Look | List datasets and figures, read table values, look at a figure as an image, check a figure for clipped or overlapping text, a legend covering data, unreadable axes or misaligned panels | +| Data | Import data files Plotium opens and CSV, TSV or XLSX tables, add calculated columns, filter and sort into a new table, correct cells and refresh tables derived from them | +| Plots | Create line, scatter, bar, box and violin plots from table columns, add or swap curves | +| Styling | Colours, line widths and styles, markers, axes, legends, font sizes, built-in themes and your saved canvas styles | +| Layout | Page size, panel positions and grids, panel labels, stacked plots with a shared x axis, text, images, annotations, arrows and reference lines, deleting chosen items | +| Analysis | NMR processing steps and recipes, diffusion inputs, region fitting and DOSY maps | +| Files | Save the project and export figures, after you confirm in Plotium | + +General curve fitting, statistics and Preferences are not +available to an AI client; use Plotium's interface for those. Each task page in +this manual ends with a **With an AI client** section where the AI can help, +for example [Legends and lines](/guides/legends-and-lines/) or +[Tables](/guides/tables/). + +## How to ask + +Plain language works. A few habits make the result predictable: + +- **Name what to change.** “The left panel”, “the curve named Current” or “the + figure on page 2” is clearer than “this”. If you have selected something in + Plotium, the AI can see the selection and use it as “this”. +- **Say what to keep.** “Keep my axis ranges and colours” protects choices the + AI cannot guess. Values you set by hand in Plotium, including a legend you + dragged, are kept anyway unless you ask for them to change; see + [Place a legend by hand](/guides/legends-and-lines/#place-a-legend-by-hand). +- **Give files as absolute paths and state units.** “Import + `/Users/me/data/run3.csv`, time in s, current in mA.” Plotium never guesses + units. +- **Ask to look first.** “Do not change anything” keeps a request read-only; + switching access to **Read only** guarantees it. + +Before creating a plot the AI asks what the plot should show and the one point +it should support, and for error bars, what they represent. See +[Plots and charts](/guides/plots-and-charts/). + +## Preview, apply, check + +For any change you care about, ask the AI to work in three steps: + +1. **Preview.** The AI prepares the change and shows you an image of the + result before anything changes in your project. For a style choice, ask for + two or three options; it previews each and applies only the one you pick. + Your AI client must support receiving images to show previews. +2. **Apply.** The change appears in Plotium as one Undo step. +3. **Check.** Ask it to look at the real figure again, and to run a figure + check at the size you will publish, for example “At 180 × 90 mm, check for + clipped text and legends covering data.” It reports problems; it does not + fix them on its own, and it should not shrink text or hide data just to + clear a warning. + +A request that combines the steps might read: + +> Look at this figure and suggest the smallest fix for the overlapping labels. +> Show me a preview of each change before you apply it, then check the real +> figure again. Keep my data, units and axis ranges. + +If you edit the figure while the AI is preparing a change, it has to prepare +the change again. Previewing a prepared change needs **Read and modify** access but does not +change the project; looking at the current figure works in **Read only**. + +## Save and export + +The AI can save the project and export figures, but Plotium asks you first: + +> Save this project to `/Users/me/figures/fig2.plotium`. Then export this +> canvas at 180 × 90 mm to `/Users/me/figures/fig2.svg`, a matching PDF and a +> 300 DPI PNG. Do not overwrite existing files. + +Plotium shows **Allow AI to save this project?** or **Allow AI to export this +figure?** with the exact paths. Replacing an existing file needs its own +checkbox. Ask the AI to confirm that every file finished and to open the +results; a request that is still running is not finished. Saving and exporting +cannot be undone. See [Access, review and undo](/ai/control-and-review/#save-and-export-confirmation). + +A good habit before you send a figure off is to save, reopen the `.plotium` +file in Plotium and check that curves, text and images are still editable. + +## Build your own client + +To call Plotium's tools from your own program, see the +[MCP reference](/reference/mcp/). diff --git a/docs/src/content/docs/getting-started/first-figure.md b/docs/src/content/docs/getting-started/first-figure.md index b93de047..f3f5366b 100644 --- a/docs/src/content/docs/getting-started/first-figure.md +++ b/docs/src/content/docs/getting-started/first-figure.md @@ -1,13 +1,20 @@ --- title: Your first figure -description: From a raw dataset to an exported, publication-ready figure in one sitting. +description: From a spectrum or a table to an exported, publication-ready figure in one sitting. --- -This walkthrough takes one 1D NMR dataset from import to an exported figure. -Every step generalizes: the same flow works for a Bruker folder, a JCAMP-DX -file, a patch-clamp recording, or a plain CSV table. +This walkthrough takes you from your data to an exported figure. Start from a +spectrum if your data comes from an instrument such as an NMR spectrometer, or +from a table if it is a CSV or Excel file. Both routes end with the same layout, +export, and save steps. -## 1. Import +You can also ask an AI client connected to Plotium to make a first draft for you +and then refine it yourself on the board; see +[Connect an AI client](/ai/connect/). + +## Start from a spectrum + +### 1. Import Drag your data file — for example a JEOL `.jdf` — onto the Plotium window, or choose **Open File…** from the **File** menu. For a Bruker TopSpin experiment, @@ -16,7 +23,7 @@ use **Open Folder…** and pick the experiment directory instead. The dataset appears in the Primary Side Bar and is placed on the board automatically, already plotted on its own page. -## 2. Process +### 2. Process Open the **Process** tab of the Ribbon. A new 1D dataset already carries the standard pipeline — apodization, zero filling, FFT, phase correction, and @@ -31,9 +38,9 @@ be undone. Two edits cover most sessions: - If the automatic phase is off, open the **Phase correction** step and adjust φ0 / φ1 with live preview. -See [Processing](/guides/processing/) for the full list of steps. +See [Processing pipeline](/guides/processing/) for the full list of steps. -## 3. Analyze +### 3. Analyze Press `P` to select the **Peaks** tool, then drag the threshold line on the plot: peaks above it are detected when you release. Add, move, or delete peak @@ -44,7 +51,38 @@ linked to the spectrum. This walkthrough stops at peaks; the [analysis tool overview](/guides/choosing-a-tool/) shows what else is available and when to reach for it. -## 4. Lay out the page +Continue with [Lay out the page](#lay-out-the-page). + +## Start from a table + +### 1. Import the table + +Choose **Import Table…** on the **Data** tab and pick a CSV, TSV, or XLSX file, +or paste a copied table with `Ctrl` + `Shift` + `V`. The **Review table import** +dialog shows each column's detected type and unit; check them, then choose +**Import table**. See [Import a table](/guides/importing-data/#import-a-table) +for how column types are decided. + +The table appears on the board as a sheet, beside a new page with an empty plot. + +### 2. Choose the columns + +Click the plot to select it. In the Object inspector, open **Data → Curve +columns**, choose the **X** and **Y** columns, and optionally a **Y error** +column, then choose **Apply curve binding**. The curve appears on the plot. + +To plot another column on the same axes, open **Add curve**, choose the table +and its **X** and **Y** columns, pick **Line** or **Scatter**, and choose +**Append curve**. + +### 3. Pick a chart type + +The plot starts as a line chart. To show the data as bars, a histogram, box +plots, or another chart, choose **Chart** on the **Figure** tab and pick from +the **Chart type** gallery. See [Plots and chart types](/guides/plots-and-charts/) +for which chart answers which question. + +## Lay out the page Click the size chip above the page's top-left corner (or **Canvas Size & Settings…** on the **Figure** Ribbon tab) and pick your target journal's @@ -54,7 +92,7 @@ specification; axis text is already at printed size. Add a panel label or annotation if you need one — press `T` for the Text tool and click the canvas. See [Annotations](/guides/annotations/). -## 5. Export +## Export Use the **Figure** tab's **Output** group (or **File → Export**) and choose a vector format — SVG for further editing, PDF for manuscripts — or a raster preset such as @@ -64,8 +102,8 @@ sizes or line widths violate the chosen preset before anything is written. For a quick paste into a document, `Ctrl` + `C` copies the selected frame to the clipboard as bitmap and vector at once. -## 6. Save the project +## Save the project `Ctrl` + `S` saves everything — data, processing, analysis, and layout — as a single `.plotium` file you can reopen later or send to a colleague. See -[File formats](/reference/file-formats/). +[Plotium files](/reference/file-formats/). diff --git a/docs/src/content/docs/getting-started/installation.md b/docs/src/content/docs/getting-started/installation.md index 67c863d6..99be74cb 100644 --- a/docs/src/content/docs/getting-started/installation.md +++ b/docs/src/content/docs/getting-started/installation.md @@ -38,7 +38,7 @@ Desktop extension. Keep the app intact; do not move files out of its Contents. For portable ZIP installations, keep `plotium-mcp` (`plotium-mcp.exe` on Windows) beside the main executable. macOS and Windows ZIPs also include `plotium.mcpb`. -When you are ready, follow [Connect your AI client](/guides/automation/#connect-your-ai-client). +When you are ready, follow [Connect an AI client](/ai/connect/). Each client only needs to be added once. ## First launch diff --git a/docs/src/content/docs/getting-started/quick-tour.md b/docs/src/content/docs/getting-started/quick-tour.md index 68a2d1fd..641d3928 100644 --- a/docs/src/content/docs/getting-started/quick-tour.md +++ b/docs/src/content/docs/getting-started/quick-tour.md @@ -91,7 +91,8 @@ multi-selection, and saved board views. 4. **Arrange** plots on the board and **export** the figure. [Your first figure](/getting-started/first-figure/) walks through these four -steps with a real dataset. +steps with a real dataset. You can also ask an AI client connected to Plotium +to carry out any of them; see [Connect an AI client](/ai/connect/). ## Navigation diff --git a/docs/src/content/docs/guides/annotations.md b/docs/src/content/docs/guides/annotations.md index c4087d6e..306dc52d 100644 --- a/docs/src/content/docs/guides/annotations.md +++ b/docs/src/content/docs/guides/annotations.md @@ -30,7 +30,7 @@ Drag on the canvas to create a shape, then move or resize it like any frame. ## Labels inside plots Text annotations and reference-line labels that belong to a plot (for example -those an agent adds through [automation](/guides/automation/)) place +those an AI client adds) place themselves clear of the data: - A reference-line label starts at the top of a vertical line or the right end @@ -45,8 +45,8 @@ themselves clear of the data: Drag a label to place it yourself; `Esc` during the drag puts it back, and the move is one Undo step. A dragged text keeps its distance from its anchor and a dragged reference label keeps its place along the line, so both follow axis -range changes, zoom and pan. Agent edits to the text or size keep your -placement, and an agent moves a label you placed only when you ask it to. +range changes, zoom and pan. Edits an AI client makes to the text or size keep +your placement, and it moves a label you placed only when you ask it to. Right-click the label and choose **Automatic position** to return it to automatic placement. @@ -62,8 +62,8 @@ automatic placement. label is one line, saved with `Enter`. `Esc` cancels. - **Move**: drag an arrow to move it, or drag one of its ends to move only that end; drag a reference line across itself to change its value. Arrow keys - nudge the selected annotation. Agents keep an arrow or line you moved where - you put it unless you ask them to move it. + nudge the selected annotation. An AI client keeps an arrow or line you moved + where you put it unless you ask it to move it. - **Style**: click an annotation to select it; the Object inspector shows its size and color (text), color, width, and style (reference lines), or color, width, and head (arrows). @@ -76,7 +76,7 @@ After styling an object, you can set its look as the default for new objects of that kind ("set as default for new …"), so a series of labels comes out consistent without restyling each one. These defaults last for the session; axis and title text sizes are a document-level setting instead — see -[Figure Typography](/guides/layout-and-export/#plot-styling-and-typography). +[Figure typography](/guides/themes-and-styles/#figure-typography). ## Selecting, grouping, and locking @@ -89,4 +89,16 @@ axis and title text sizes are a document-level setting instead — see - `Delete` or `Backspace` removes the selected annotation objects. Alignment, distribution, and z-ordering for annotations work exactly as for -plot frames — see [the board](/guides/layout-and-export/). +plot frames — see [the board](/guides/multi-panel-figures/#the-board). + +## With an AI client + +You can ask an AI client connected to Plotium to do this for you, for example: + +> On the plot named Kinetics, add a dashed vertical line at 30 s labelled +> Injection, and an arrow pointing at the peak near 45 s. Show me a preview. + +The new labels place themselves clear of the data, a label you placed by hand +stays where you put it, and the change is one Undo step. Check the preview +before you agree. See +[Access, review and undo](/ai/control-and-review/). diff --git a/docs/src/content/docs/guides/automation.md b/docs/src/content/docs/guides/automation.md index b5effa53..addc0eb1 100644 --- a/docs/src/content/docs/guides/automation.md +++ b/docs/src/content/docs/guides/automation.md @@ -1,27 +1,36 @@ --- title: Automation -description: Apply one action to many datasets or figures, or run a saved workflow. +description: Apply one action to many datasets or figures, run a read-only scientific script, or run a saved workflow. --- When the same operation has to happen to a whole series of experiments, automation replaces the click-per-dataset routine with one reviewed batch. Open **File → Automation…** (also on the command palette). The window has two -tabs: +tabs: **Current Project** works on what is already open, and **External +Inputs** runs a saved workflow that starts from files on disk. + +To have an AI client do this kind of work from a plain-language request +instead, see [Working with an AI client](/ai/working-with-ai/). ## Current Project -Works on what is already open. Search for datasets or figures and check the -ones you want — or press **Current selection** to pull in your current -selection — then pick a tool and press **Preflight** to see which targets it -will affect and which will be skipped. **Confirm and execute** applies -it, and the whole batch collapses into a single **Undo automation** step. +Search for datasets or figures and check the ones you want, or press **Current +selection** to check what is selected in the workspace. Then choose one of the +two modes below the list: **Scientific Script** or **Registered Tool**. + +### Apply a tool to the checked items -### Settings +In **Registered Tool**, pick a tool from the list. The window shows what the +tool does and the parameters it accepts; fill them in under **Parameters +(JSON)**. Press **Preflight** to see which targets the tool will affect and +which it will skip, then **Confirm and execute**. The whole batch collapses +into a single **Undo automation** step. -Three tools reach the settings the **Object inspector** and the processing -steps edit, so one level, colour, width, type size or window function can be -applied across a whole project as a single reviewed batch: +Three of the tools reach the settings that the **Object inspector**, the +processing steps and Preferences edit, so one contour level, colour, line +width, type size or window function can be applied across a whole project in +one batch: | Tool | What it does | | --- | --- | @@ -29,138 +38,81 @@ applied across a whole project as a single reviewed batch: | **Set a property** | Writes a value | | **Reset a property** | Re-derives the value from the current data, as the panel's reset button does | -Name the setting in **Parameters (JSON)** by its id: -`{"key": "series.contour.count", "value": 12}` for **Set a property**, and -`{"key": "series.contour.count"}` for the other two. - -The three tools reach every setting the panels edit: object and series styling, -processing-step parameters, document and canvas settings, and application -preferences. Which resource to name follows from the setting — a contour or -line setting lives on a plot object, an apodization setting on a dataset, -figure typography on the document (listed as **Plotium document**), a page size -on a canvas, and a preference on the application (listed as **Plotium -application**). - -| Setting in the Object inspector | id | Accepts | -| --- | --- | --- | -| **Lowest level** | `series.contour.base.magnitude` | a number above 0; what it measures depends on the anchor | -| **Anchor** | `series.contour.base.policy` | `absolute`, `noise_floor`, `background_scale`, `fraction_of_range` | -| **Levels** | `series.contour.count` | 1 to 256 | -| **Level ratio** | `series.contour.ratio` | above 1, at most 10 | -| **Negative contours** | `series.contour.negative.enabled` | `true` or `false` | -| **Positive colour** | `series.contour.positive_color` | `"#rrggbb"` | -| **Negative colour** | `series.contour.negative_color` | `"#rrggbb"` | -| **Line width** | `series.contour.line_width` | 0.05 to 10 pt; default 0.5 | -| **Stroke width**, in the **Line** section | `series.line.stroke_width` | 0.05 to 10 pt; default 0.5 | -| **Tick-label size**, in the **Figure typography** section | `document.figure.typography.tick_pt` | 1 to 72 | - -Application preferences take the same three tools. For -`settings.appearance.accent.color`, **Set a property** accepts `"#rrggbb"` and -pins the canvas accent to that colour; **Reset a property** clears it, and the -accent follows the theme again. - -| Setting on an apodization step | id | Accepts | -| --- | --- | --- | -| **Window** | `dataset.processing.apodization.kind` | `none`, `cosine_bell`, `exponential`, `gaussian` | -| **LB** | `dataset.processing.apodization.lb_hz` | −10000 to 10000 | -| **GB** | `dataset.processing.apodization.gb_hz` | greater than 0, at most 10000 | - -[Contour levels](/guides/contour-levels/) explains what each contour setting -does and which data each anchor needs; [Processing](/guides/processing/) does -the same for the apodization rows. - -#### What a checked target expands to - -The resource you check is rarely the thing that is written — the setting decides -what inside it is. A plot object expands to its series, a dataset to its -processing steps, and the document to itself. Preflight and the result list show -one row per component, so a plot holding three series produces three rows, -naming the object and the series inside it. - -A component the setting does not reach is listed as **Skipped** with the reason, -and the rest still apply: a heatmap drawn under a contour, a zero-fill step when -the setting belongs to apodization, or a **GB** asked of a step whose window is -*Exponential*. A resource with nothing to address at all — a text box, a dataset -with no pipeline — is skipped the same way. - -Result rows and the run record name the component beside the resource: - -```json -{ - "resource": { "id": "…", "kind": "plotium.dataset" }, - "component": { "kind": "processing_step", "id": 3 } +Name the setting by its ID. [Setting IDs](/reference/settings-ids/#reading-and-writing-settings) +lists the IDs, the parameter format, which item each one lives on, and how +results report skipped targets. + +A value outside the range is refused at **Preflight**, before you confirm. +Past that point either every listed target takes the value or none does. A +target that already holds the value is reported as skipped; if every target +does, nothing is written and nothing is added to the undo stack. + +### Run a scientific script + +A scientific script reads LC–MS data and returns its own summary, for example +the peaks it found in each chromatogram. It cannot change the project, open +other files or reach the network. + +1. Check the LC–MS datasets to analyse. Checking a canvas includes the datasets + it shows. +2. Choose **Scientific Script**, press **Open script…** and pick a + `.plotiumscript` file. The window shows how many checked LC–MS datasets the + script will process. +3. Press **Run Scientific Script**. The datasets are processed one after + another, with a progress bar. +4. Each dataset gets a result card. If the script returns a `summary`, its + fields appear as a table; **Technical details** shows the complete result. + A dataset the script could not process shows the error instead, and the + others still run. +5. Press **Save results…** to write all results to one JSON file. + +**Run Scientific Script** in the command palette opens this mode and runs the +chosen script on the checked datasets. Only LC–MS datasets, such as mzML and +Waters MassLynx imports, are passed to a script, and the command is unavailable +until one is loaded. + +Scripts are written in [Rhai](https://rhai.rs/). `load_input()` returns the +dataset as a map: its `source` and `instrument`, the `chromatograms` stored in +the file, the total-ion and base-peak `stream_chromatograms`, a summary of every +scan under `scans`, and for Waters data the LC method under `lc_method`. +Retention times are in minutes. The script's last expression is its result. +These helpers are available: + +| Function | Returns | +| --- | --- | +| `moving_average(values, width)` | The values smoothed with a centred window of `width` points | +| `rolling_percentile(values, width, q)` | The `q` quantile (0–1) in a centred window, for example as a baseline | +| `estimate_noise(values)` | A noise estimate for the trace | +| `detect_peaks(x, y, options)` | Peaks as maps with `index`, `x`, `y` and `prominence`; `options` may set `min_height`, `min_prominence`, `min_spacing` and `max_count` | +| `format_number(value, decimals)` | The number as text with up to 12 decimals | + +For example, this script reports the five most prominent peaks of the first +total-ion or base-peak chromatogram: + +```rust +let input = load_input(); +let trace = input.stream_chromatograms[0]; +let peaks = detect_peaks(trace.time_min, trace.values, #{ min_prominence: 1000.0, max_count: 5 }); +#{ + summary: #{ "Peaks found": peaks.len() }, + peaks: peaks } ``` -Series components read `{"kind": "series", "id": 2}`. Both ids are local to the -resource they travel with, so a step id means nothing next to a different -dataset. - -#### Why a target was skipped - -Every skipped row carries a sentence written to be read. Rows the write itself -passed over also carry `skip_reason`, a stable token a workflow can branch on -without matching on wording: - -| `skip_reason` | Means | -| --- | --- | -| `already_at_value` | The target already held that value, so nothing was written | -| `not_applicable` | The setting does not apply to this target | -| `target_missing` | The address no longer names anything in the document | - -Rows already ruled out at preflight carry the sentence alone. They are never -same-value no-ops, so the absence of the token is itself the distinction. - -A **Set a property** whose every target already stores the requested value and -override state writes nothing: each target is reported as skipped, the document revision does not move, -and nothing is added to the undo stack. Setting an inherited value as an explicit -override still records that author choice. - -A value outside the range is refused at **Preflight**, before you confirm, and -names both the value you gave and the limit that rejected it. Past that point -either every listed component takes the value or none does, and what is written -collapses into one **Undo automation** step. - -**Inspect a property** returns its readings to whoever ran it: run it as a -workflow step and the values land in the run record, which is also what -[the command line](/reference/cli/) writes to its manifest file. In the window -the numbers appear under **Result value (JSON)**, below the per-component rows: -one reading per component, each with its current value, its default and the -range it accepts. - -#### What a reading contains - -Each reading names its `target` and carries the current `value`, a -`default_value` where the setting has one, `modified` — whether the value -differs from that default — an `availability`, and the `schema` that bounds it. - -A setting the current state does not allow you to write is still read back: -`availability` is `"disabled"` and `disabled_reason` names what has to change -first, such as switching the phase mode to *Manual* before φ0 can be set. - -Schemas are tagged by `type`: `bool`, `text`, `int`, `stepped_int`, `float`, -`enum`, `color`, `unit_code`, or `axis_range`. - -- `int` and `stepped_int` carry `min` and `max`, plus a `unit` where the setting - has one. `stepped_int` also carries the `step` its values must land on — a - Savitzky-Golay window, for instance, runs from 3 to 201 in steps of 2. -- `float` carries `min`, `max` and `exclusive_min`, and where a setting refuses - particular values, `excluded` (one value) or `excluded_magnitude` (everything - at or below that magnitude). Its `display` — `linear`, `degrees` or `log10` — - is how the panel shows the number; the `unit` and `log` fields beside it - restate the same thing. -- `enum` lists its variants, each with a stable id and a label. - -Bounds and values are always in the setting's own units, whatever `display` -says: a phase whose `display` is `degrees` is radians on the wire. +A script stops with an error when it runs too long, builds arrays or text that +are too large, or returns more than 10 MB of results. Results stay in the window +until you run a script again, so save them if you need them later. ## External Inputs -Runs a saved workflow that starts from files on disk — for example: import -every experiment in a folder, apply a processing recipe, and export each -figure. Press **Open workflow…** to load it, **Validate** to check it, then -**Confirm and run workflow**. Progress is reported step by step and a long run -can be cancelled. +Runs a saved workflow that starts from files on disk, for example: import every +experiment in a folder, apply a processing recipe, and export each figure. +Press **Open workflow…** to load it, **Validate** to check it, then **Confirm +and run workflow**. Progress is reported step by step and a long run can be +cancelled. + +The window runs workflow files; it does not create them. A workflow is a plain +JSON file, described under [Workflow file anatomy](/reference/cli/#workflow-file-anatomy). ## What is recorded @@ -168,251 +120,14 @@ A workflow run leaves a record of the workflow and its hash, the Plotium version and every step's targets, parameters and results. Run it here and that record is kept in the project; run it from [the command line](/reference/cli/) and the same record is written to a file. A batch from **Current Project** leaves no -such record — it is an ordinary edit, in the document and on the undo stack. - -Native workflow operations that write outside the project — exporting figures, for -instance — is also listed under **Help → Operation and Diagnostic History**, -with each file's path, size and SHA-256 checksum. An export that fails partway -still names the files it had already written, so nothing reaches disk -unaccounted for. - -Workflow files are plain JSON and can also be run without the desktop app — -see [the command line](/reference/cli/), which executes the same workflows -headlessly. [File formats](/reference/file-formats/) describes the workflow -and run-record files themselves. - -## Local agent connections (MCP) - -Connect an AI client to ask questions about your open project, inspect a figure, -or make supported edits in Plotium. MCP is the connection that lets the client -use Plotium's tools; you continue chatting in Codex, Claude Code or Claude Desktop. - -### Discover capabilities when needed - -Ask the agent to read `plotium_get_state` for current permissions and project -context, and call `plotium_capabilities_get` only when it needs static contracts -or sees a different capability fingerprint. It returns a compact index; the agent -fetches detailed schemas and limits one section at a time. State includes project counts, -a bounded selection page and retained save receipt IDs; detailed targets and -receipts have their own queries. Cached capabilities do not authorize edits or -retry, and each save/export still requires desktop confirmation. -See [state and discovery](/reference/mcp/#read-state-and-discover-capabilities-on-demand). - -### Connect your AI client - -Keep the complete Plotium release folder, including `plotium-mcp` -(`plotium-mcp.exe` on Windows). Install the AI client you want to use before -adding it to Plotium. - -1. Open Plotium. -2. Open **Preferences → AI connections (MCP)**. You can also click the robot - beside Operation history in the Ribbon, or use **File → AI connections (MCP)…**. -3. Turn on **Enable MCP**. Under **Access**, choose **Read only** to explore - without allowing edits, or **Read and modify** to allow supported changes. - The default is **Read and modify**. -4. Add your client using the matching option below. - -| Client | What to do in Plotium | What to do in the client | -| --- | --- | --- | -| Codex | Press **Add** in the Codex card | Reload MCP configuration or restart the client if needed | -| Claude Code | Press **Add** in the Claude Code card | Reload MCP configuration or restart the client if needed | -| Claude Desktop (macOS and Windows) | Press **Add to Claude Desktop…** | Confirm installation of the extension, then reload or restart if needed | - -Start your AI client yourself; Plotium does not launch it. For Codex and Claude -Code, **Configured** means the connection settings have been added. To check that -the client can actually reach Plotium, send this first request: - -> Use Plotium to list the datasets and figures in my current project. Do not -> change anything. - -The client should describe your project, and Plotium should show recent client -activity. The robot turns green while the connection is active. Opening the -Claude Desktop extension package alone does not confirm a working connection. - -New AI results appear in the workspace by default. Browsing or editing pauses -following so incoming results do not interrupt your work; resume it when ready. -Use Operation history to inspect results at any time. See -[following results](/reference/ui-overview/#window-regions) for the controls and behavior. - -### Try a task - -Use plain language in your AI client. For example: - -- **Inspect a figure:** “Use Plotium to preview my canvas and describe the curves - and labels. Do not change anything.” Your client must support receiving images. -- **Diagnose without editing:** “At 180 × 90 mm, locate text overflow and potential legend occlusion. Report coverage limits and inspect the native PNG. Keep intentional overlap and manual axis ranges.” See [figure diagnostics](/reference/mcp/#diagnose-figure-geometry-at-an-output-size). -- **Adjust a line:** “Find the curve named Current, check its line width, then - change only that curve to 1.5 pt.” This requires **Read and modify** access. -- **Arrange a figure:** “Make this page 180 × 90 mm, arrange these two panels - horizontally with 4 mm margins and a 5 mm gutter, label them a/b, add the - caption and my local PNG/JPEG, then show a preview. Leave other panels alone.” - Specify the target panels and absolute image paths. Continue editing each - native plot, text item and image in Plotium; Undo restores an entire layout batch. -- **Update data:** “Change only this source cell, show which derived tables are out of date, then refresh this table’s saved recipe. Keep my colors, axis ranges and layout.” Patch and refresh have separate Undo steps. -- **Create a plot:** “Import the CSV at `/absolute/path/experiment.csv`. Use time - as X and current as Y, with units s and mA. Create an editable line plot and - show me a preview.” Replace the path with your file's absolute path and state - the columns and units you want. - -The connection can import CSV/TSV tables, read table values, inspect project -structure, preview canvases, create multiple native line or scatter panels, -set page/panel geometry, align/distribute/grid explicitly chosen panels, add -editable text and local PNG/JPEG images, change a curve's -source columns, derive tables with supported native plans, patch existing cells, -explicitly refresh saved recipes, apply built-in themes or saved canvas styles to canvases, and rename datasets, -canvases or objects. Display edits cover exact-curve color, width, stroke style, markers, visibility -and legend text; axis titles, display units and auto/manual ranges; plot-local -tick, axis-title and legend sizes; and the existing contour/document font controls. Processing parameters, fitting and other -computations beyond supported table transforms, other import formats are not available through this connection. Use Plotium's interface for -those tasks. There is no built-in chat window. - -To save, ask “Save this desktop project to `/absolute/path/figure.plotium`.” -Review the exact path in Plotium's **Allow AI to save this project?** prompt; -existing files also need explicit replacement confirmation. Saving has separate, -one-use authorization, is not undoable, and finishes only when the agent receives -a completed save receipt. Later edits and reads may still be unsaved. - -### Refine a legend without changing the data - -Ask “On the left panel only, move the legend to its available bottom-left corner, -keep it vertical and title it Samples. Keep all curves, units and manual ranges. -Show me the before/after preview; report if the legend cannot fit.” The agent -should discover the exact plot ID rather than match a duplicate plot name, then -inspect the native PNG. You can continue dragging the legend in the GUI; -double-click restores automatic placement. Check Undo/Redo before saving. -See [guide coordinates and reset rules](/reference/mcp/#position-a-plots-legend-precisely). - -### Remove only an explicitly chosen item - -Ask “Delete this duplicate note and this exact redundant Series, keeping the -other curve with the same name, its units and my manual ranges. Show the deletion -list before executing, then show the actual PNG.” The agent must discover stable -IDs, not use names or the current selection. One Undo restores the batch. Empty -parents and source data remain; removing the last Series is rejected. An empty -panel can be deleted explicitly, but nonempty panels cannot cascade through MCP. -See [exact deletion and refusal rules](/reference/mcp/#delete-exact-content-or-selected-series). - -### Inspect a proposed correction before applying it - -Ask “Discover the exact objects, read diagnostics and the actual PNG, then propose -the smallest local correction. For **every** plan, show and inspect its candidate -PNG before explicitly executing that same plan; afterward read the real PNG and -fresh diagnostics. Preserve my data, units, manual ranges, other same-name objects, -and intentional clipping or overlap. Do not shrink text or hide data to clear warnings.” - -Candidate preview supports display property edits such as colours, line widths, -axes, legends and typography, as well as content geometry, image replacement, -text updates and exact deletion. It needs **Read and modify**, but leaves authored -state, Undo/Redo, dirty state and edit generation untouched, and adds no project -audit record. If you edit while the agent is reviewing a candidate, its old plan must be -replaced. One execution remains one native Undo step. See the [support matrix and -candidate metadata](/reference/mcp/#preview-a-plan-before-committing-it). - -For a style choice such as a palette, line widths or the legend position, ask -the AI to show two or three options. It previews each without changing your -project, and applies only the one you pick. - -### Deliver the editable project and final figures - -Have the agent import CSV/TSV and check explicit units, then create line-with-error -and scatter panels, native text and PNG/JPEG images. Ask it to actually inspect -the preview before making one local correction. Derive a new curve, then append -it to the existing plot. You can take over colors, axis ranges and panel positions -in the GUI; ask the agent to patch a precise source cell, inspect stale derived -data, then explicitly refresh it. Use Undo/Redo to check patch and refresh -separately while retaining your design. - -Save and reopen the `.plotium` file in the GUI to check that curves, text and -images remain editable. Then ask: “Export this 180 × 90 mm canvas to -`/absolute/path/figure.svg`, matching PDF and 300 DPI PNG. Do not overwrite files.” -Review paths in **Allow AI to export this figure?** and approve; replacing existing -outputs needs another explicit checkbox. Have the agent read every file's final -receipt and actually open the results, rather than treating queued work as success. -The PNG should be 2126 × 1063 pixels. Export does not replace the project or mark -it saved. MCP export results live in this process's export receipts; after -reconnecting inspect the original receipt instead of replaying unknown calls. - -### Control access and review changes - -**Access** applies to all clients using this Plotium connection and to every -project you open. Plotium remembers both the permission and **Enable MCP** across -restarts. Choose **Read only** to block further edits, including edits that have -been prepared but not yet applied. You can still inspect data and preview figures. - -Supported changes appear in the desktop immediately and use Plotium's normal -**Undo** and **Redo**. Ordinary queries, previews and diagnostics leave project -audit records, dirty state, edit generation and automation revision unchanged. - -Turn off **Enable MCP** to stop access immediately. Your client setup is retained. -Closing Preferences or switching projects keeps the connection running; exiting -Plotium stops access. After restarting Plotium or turning MCP back on, you can -continue in the same AI session without adding the client again. After a project -switch, ask the AI to inspect the current project before continuing edits. - -MCP tool annotations describe tool effects and may inform client approval policy. -They grant no Plotium permissions and do not remove desktop file confirmation. -The mixed planning/execution tools use conservative hints. Keep client approval -scoped to the intended tools and follow the -[annotation and authorization guidance](/reference/mcp/#tool-annotations-and-client-approval). - -Before the AI creates a plot, Plotium asks it to check with you what the plot -should show (compare groups, a trend, a distribution, a relationship, parts of a -whole, a change or ratio, or a local detail) and the one claim it should -support. Answer in your own words, or let the AI propose a reading and correct -it. The intent is saved with the plot and never changes the drawing; edit it -later under **Chart › Advanced** in the Object inspector. When you ask the AI to -check the figure, it compares the chart with this purpose and suggests forms -that fit better; it never switches them on its own. For curves with error bars -it also asks how many replicates each value summarises and whether the bars -show SD, SEM or a 95 % CI. See -[plot creation](/reference/mcp/#create-a-native-single-plot-from-an-imported-table). - -For different colours or labels across curves, ask for one atomic -`properties.set_many` plan with 1–200 exact target/property/value writes and one -Undo step. Reuse the complete targets returned by `plot.create`; see -[batch styling](/reference/mcp/#style-several-curves-in-one-plan). -Follow [recovery actions](/reference/mcp/#recovery-actions-and-uncertain-outcomes) -after errors. A queued task or save is still pending; inspect receipts before -claiming completion. Refusal, cancellation or disconnection never authorizes -automatic recomputation, file writes or replay of a consumed plan. Every new -file request still needs desktop approval for its exact paths and overwrite scope. - -### Understand the robot icon - -Hover over the robot for the project, permission and last activity. Click it to -open connection settings; it remains available when the Ribbon is collapsed. - -| Appearance | Status | What it means for you | -| --- | --- | --- | -| Gray, short slash | Off | Turn on **Enable MCP** when you want to connect | -| Blue, hollow dot | Starting / Ready | Wait for startup, or send a request from your client | -| Green, filled dot | Active | There has been client activity in the last 30 seconds; this does not confirm that a task has finished | -| Orange, exclamation | Needs attention | Open connection settings, read the error and follow the suggested action | - -### If the connection does not work - -| What you see | What to try | -| --- | --- | -| Plotium cannot find Codex or Claude Code | Use **Installation help** to install the client, or **Choose executable…** to select it, then press **Add** | -| An error mentions Node.js | Check the client's Node.js installation, or select a standalone client executable, then try again | -| A different server named `plotium` already exists | Review the existing entry. Choose **Back up and replace this entry** only if you want to replace it; Plotium backs it up and leaves other servers unchanged | -| **Configured**, but no client activity | Reload the client's MCP configuration or restart it, then send the first request above. Check whether the client has disabled or blocked the server | -| The client reports outdated project state | Ask it to read `plotium_get_state` again before continuing | -| Another Plotium instance owns the connection | Use the instance providing the connection, or exit it so this instance can connect. Switching window focus does not switch the AI's target | -| Windows reports that the connector is in use during an update | Exit AI clients using Plotium, then press **Retry** in connection settings | -| A connector or Claude Desktop extension is missing | Extract the complete Plotium release again; keep its files together | - -Startup failures retry automatically. Connection settings show recent operations -and errors; use **Retry** when offered after resolving the cause. If a connection -breaks during an edit, check the project before asking the AI to try again: the -edit may already have completed, and repeating it could create duplicate content. - -### Other clients and technical details +such record: it is an ordinary edit, in the document and on the undo stack. A +scientific script changes nothing and leaves no record. -For another local MCP client, expand **Manual configuration and diagnostics** and -press **Copy stable stdio configuration**. Use the copied configuration in your -client. This connection supports clients on the same machine and user account; -remote connections and access across Windows and WSL are not supported. +Native workflow operations that write outside the project, such as exporting +figures, are also listed under **Help → Operation and Diagnostic History**, with +each file's path, size and SHA-256 checksum. An export that fails partway still +names the files it had already written, so nothing reaches disk unaccounted for. -See the [MCP reference](/reference/mcp/) for manual registration commands, tool -parameters, examples and limits. +Workflow files can also be run without the desktop app; see +[the command line](/reference/cli/). [File formats](/reference/file-formats/) +describes the workflow and run-record files themselves. diff --git a/docs/src/content/docs/guides/axes.md b/docs/src/content/docs/guides/axes.md new file mode 100644 index 00000000..656945aa --- /dev/null +++ b/docs/src/content/docs/guides/axes.md @@ -0,0 +1,143 @@ +--- +title: Axes and ticks +description: Set axis titles and ranges, logarithmic and broken axes, a second y axis, and tick marks. +--- + +Plotium draws axes for print without any setup: clean bottom-and-left axes with +outward ticks, tick precision that follows the displayed range, and tick +density that thins as a panel narrows or shortens (a short panel still keeps +two y ticks wherever they fit). Select one plot and use **Axes** in the Object +inspector to change what you need. Charts without visible axes offer no axis +settings. + +## Titles and ranges + +Override the X and Y titles or numeric ranges in **Axes**. Leave a title blank, +or keep a range on **Auto**, to use the value derived from the data. A manual +range becomes that axis's full range: zooming and panning stay inside it, and a +double-click on the plot returns to it. Categorical axes have no range +controls. + +Axis titles use true superscripts and subscripts; see +[Superscripts and subscripts](/guides/legends-and-lines/#superscripts-and-subscripts). + +To hide text on one axis, use the **X text** and **Y text** rows: they toggle +**Tick labels** and **Title** individually, and **Automatic** returns that axis +to showing both. To hide inner axis text across a grid of panels at once, see +[Simplify inner axes](/guides/multi-panel-figures/#simplify-inner-axes). + +## Equal x/y scale + +**Equal x/y scale (1:1)** uses the same data units per screen unit on both +axes, for example for a Nyquist plot, an AFM image or a 2D NMR spectrum. The +plot area shrinks to that shape inside the frame; the axis ranges are kept. It +needs linear, non-categorical axes and no right y axis, and a plot in a +shared-x stack cannot turn it on. AFM images start with it on; for a true 2D NMR +spectrum Plotium sets its initial value when the spectrum is imported, and you +can change it afterward without changing the import preference. + +## Frame + +**Frame** in the same **Axes** section chooses *Left and bottom* or *All four +sides*. The four-sided frame adds top and right axis lines with the same stroke +as the other axes; ticks and labels stay on the left and bottom axes. Most plots +start with left and bottom axes; 2D maps such as contour plots and heatmaps +start with all four sides. + +## Logarithmic axes + +**X scale** and **Y scale**, under the more options of the **Axes** section, +switch a line, scatter or stick plot between *Linear* and *Logarithmic*. A +logarithmic axis labels powers of ten (10¹, 10², …), thins them when the axis +is short, and uses ordinary ticks when fewer than two powers of ten are visible; +minor ticks, when enabled, mark 2–9 × each decade. Its automatic range fits only +the positive data. Zero and negative values have no position: lines break +there, and error bars and sticks that reach below the axis end at its edge. A +manual range on a logarithmic axis must start above zero. Zooming and panning +move by decades. Logarithmic axes are not offered for categorical axes, 2D maps, +bars and distributions, or NMR spectra, whose integral, phase and cursor tools +measure in linear ppm. + +## Second y axis + +**Y axis** under the advanced controls of **Line** puts a line or scatter curve +on a second y axis at the right of the plot, for a quantity with a different +unit or magnitude. The right axis appears as soon as one curve uses it and goes +away when every curve is back on the left. It fits its own automatic range to +its curves and draws its own ticks, tick labels and title; the title reads +bottom to top like the left one and starts as the first right curve's column +name and unit. + +The **Right Y axis** section of the Object inspector, shown only while the plot +has a right axis, sets its title, range, logarithmic scale, tick labels, display +unit and major tick step. Scrolling, dragging and box zoom move both y axes by +the same fraction of their range, a double-click returns both to their full +range, and the **Inspect** cursor reads the pointer on x and on both y axes. One +legend lists every curve. Bars stay on the left axis, and reference lines, +annotations and arrows are placed in left-axis coordinates. In a table plot each +y axis keeps the unit of its first curve; a curve whose unit cannot convert to +it cannot join that axis. + +## Axis breaks + +**X break** and **Y break**, under the more options of the **Axes** section, +break a linear numeric axis: the values between the two endpoints are left out, +and the axis line opens with a pair of slanted marks. Untick **None** to start +from the middle third of the current range, then edit the endpoints; both must +lie inside the axis range. By default the two pieces keep the same scale; +**X lower share** or **Y lower share** sets how much of the axis length the +lower values get instead. + +Each piece gets its own ticks, and a tick right next to the break is left out so +the labels do not collide. Lines that cross the break leave at one side of the +gap and continue on the other; a bar that spans a y break is drawn cut. +Logarithmic, categorical and equal-scale axes, 2D maps and NMR spectra cannot be +broken, nor can the y axis of a plot with a right y axis. In a shared x stack, +an x break applies to every plot. + +## Tick positions and number format + +To choose where major ticks fall, set **X major tick step** or **Y major tick +step** under **Advanced** in the **Axes** section, or **Right Y major tick +step** in the **Right Y axis** section. Ticks then sit on the multiples of the +step in the axis's display unit — a step of 20 gives 80, 100, 120 — and minor +ticks divide those intervals. 0 returns to automatic ticks. The step does not +apply to logarithmic, category or broken axes, and a step that would draw fewer +than two or more than 100 ticks falls back to automatic ticks. Changing the +display unit clears the step. + +To write large tick values as `1,000` rather than `1000`, turn on **X thousands +separator** or **Y thousands separator** under **Advanced** in the same section. +When the axis reaches ±10,000, its labels are then written in full, such as +`15,000`, instead of using a shared ×10ⁿ multiplier. An axis that reaches 10¹⁵ +or more, or whose largest value is below 0.001, keeps the multiplier. + +## Tick marks and axis lines + +Tick marks and axis lines are set once for every plot in the document, in the +advanced controls of the **Figure typography** section (see +[Typography, themes and styles](/guides/themes-and-styles/#figure-typography)): + +- **Axis line width** — axis lines and tick marks, 0.05 to 10 pt, default + 1 pt. +- **Tick length** — 0 to 20 pt, default 3 pt. +- **Tick direction** — *Outward*, the default, or *Inward*. Inward ticks point + into the plot, so the tick labels move up to the axis line. +- **Minor ticks** — that many unlabelled ticks between neighbouring major ticks + on both axes (0 to 9, default 0, which hides them). Minor ticks are half the + tick length and use the same width and direction. Categorical axes, and axes + showing fewer than two major ticks, have no minor ticks. + +## With an AI client + +You can ask an AI client connected to Plotium to do this for you, for example: + +> On the plot named Kinetics, make the y axis logarithmic and set the x range to +> 0–120 s. Show me a preview before you apply it. + +> Put the Temperature curve on a second y axis on the right and title that axis +> Temperature (K). + +Values you set by hand are kept unless you ask the AI to change them, and the +change is one Undo step. Check the preview before you agree. See +[Access, review and undo](/ai/control-and-review/). diff --git a/docs/src/content/docs/guides/choosing-a-tool.md b/docs/src/content/docs/guides/choosing-a-tool.md index 26d2f217..7af7d6b8 100644 --- a/docs/src/content/docs/guides/choosing-a-tool.md +++ b/docs/src/content/docs/guides/choosing-a-tool.md @@ -18,6 +18,8 @@ what you want to measure: | Fit x-y data to a mathematical model | **Fit Curves** | Data tables (including series tables) | Parameters with uncertainties and diagnostics | | Build a chemical-shift × diffusion map | **DOSY…** | Frequency-domain spectrum stacks with valid diffusion input | Per-column or ILT DOSY map | | Compare groups, test correlation or normality | **Statistics** | Data tables | Saved statistical results | +| Fit the complex FID directly to resonances | **CRAFT…** (Process menu) | 1D NMR acquisitions with their original FID | Component frequencies, amplitudes, linewidths, and phases | +| Pull a mass spectrum or ion chromatogram out of an LC–MS run | **Extract Mass Spectrum** | LC–MS runs (Waters, WIFF, mzML) | Extracted spectra and XICs | Rules of thumb when two tools seem to apply: @@ -40,5 +42,6 @@ Where to go next: [Peaks and regions](/guides/peaks-and-regions/), [Homonuclear 2D symmetry review](/guides/symmetry-review/), [Curve fitting](/guides/curve-fitting/), [Statistics](/guides/statistics/), and the per-technique guides for [pseudo-2D](/guides/pseudo-2d/), -[DOSY](/guides/dosy/), and +[DOSY](/guides/dosy/), [CRAFT](/guides/craft/), +[mass spectrometry](/guides/mass-spectrometry/), [XPS](/guides/xps/), and [electrophysiology](/guides/electrophysiology/). diff --git a/docs/src/content/docs/guides/dosy.md b/docs/src/content/docs/guides/dosy.md index b7184b30..833fcb06 100644 --- a/docs/src/content/docs/guides/dosy.md +++ b/docs/src/content/docs/guides/dosy.md @@ -75,9 +75,11 @@ available, you must provide valid input again. 1. Display the **Stack**, then choose **Analyze → Draw Regions** and draw regions over the peaks of interest. -2. In the Regions task card, choose **View extracted curves**. Each region - becomes a point series with b on the x axis; an auxiliary gradient column - is retained when available. +2. In the Regions task card, choose **Extract curves** to prepare the table; + the button is unavailable while the source computation runs. When it is + ready, choose **View extracted curves**. Each region becomes a point series + with b on the x axis; an auxiliary gradient column is retained when + available. Completion does not switch panels on its own. 3. In **Curve Fit**, check that **Diffusion (b values)** is selected and choose **Run Fit**. The model fits `I = I₀ exp(−Db)`, with D in `m²/s`. 4. Inspect the fitted curve, parameter uncertainty, and diagnostics. Use @@ -169,19 +171,18 @@ settings, and finally a verified acquisition suggestion. This preserves the input used for a result rather than silently substituting a later default. -## Automation interface +## With an AI client -Desktop, CLI and MCP reuse native processing and scientific computation semantics. -See [MCP scientific operations and tasks](/reference/mcp/#scientific-operations-and-tasks) -for operations and parameter schemas, or use CLI -[`tool run`](/reference/cli/#single-step-scientific-operations). Pipeline edits, -schemes, region extraction, diffusion fitting and DOSY/ILT return process-owned -task receipts; wait for termination before consuming results. Background commits -form one Undo step and Redo reuses results. Document edits during computation make -work stale. Diffusion inspection reports SI units and source evidence; result -inspection provides paginated diagnostics. `empty` does not establish a scientific -conclusion. +You can ask an AI client connected to Plotium to run this analysis, for example: -In desktop region tools, select **Extract curves** to prepare the table. While the -source computation runs, extraction is disabled. Once ready, select **View -extracted curves** to open it; completion does not switch panels automatically. +> Check the diffusion inputs of this DOSY experiment and tell me what is +> missing. Then fit the regions I drew and build a DOSY map. Report D with its +> standard error and R² before plotting anything. + +Plotium does not fill in missing diffusion parameters for the AI: it reports +what is missing and waits for values you confirm. A finished calculation is +not a valid result by itself, so check the fit diagnostics it reports. Each +computation is one Undo step. See [Access, review and undo](/ai/control-and-review/); +scripts can use the same operations through +[MCP scientific operations](/reference/mcp/scientific/) and +[`plotium-cli tool run`](/reference/cli/#single-step-scientific-operations). diff --git a/docs/src/content/docs/guides/electrophysiology.md b/docs/src/content/docs/guides/electrophysiology.md index afecaf0f..097a9b7a 100644 --- a/docs/src/content/docs/guides/electrophysiology.md +++ b/docs/src/content/docs/guides/electrophysiology.md @@ -101,7 +101,7 @@ value with the peak and average response. Voltage stimuli require a current response; current stimuli require a voltage response. A unit mismatch is reported and calculation is stopped. Ramp protocols do not support IV analysis: the stimulus varies continuously within a sweep, so there is no -single stimulus value to plot against. In the data browser the table stays +single stimulus value to plot against. In the Data browser the table stays listed under the recording it came from, and its stimulus source remains part of the saved dataset. diff --git a/docs/src/content/docs/guides/exporting.md b/docs/src/content/docs/guides/exporting.md index cfc86c4e..4e45ba5d 100644 --- a/docs/src/content/docs/guides/exporting.md +++ b/docs/src/content/docs/guides/exporting.md @@ -62,7 +62,8 @@ the receiving app chooses a format it supports. With a dataset selected, choose **Export Data…** from the File menu, the Data Ribbon tab, or the command palette. The dialog shows only content that exists for that dataset and offers **Save CSV…**, **Save TSV…**, **Save XLSX…**, and -**Copy TSV**. +**Copy TSV**. Empty cells stay empty, while `NaN`, `+Inf`, and `-Inf` are +written as those literal tokens because they are real values, not blanks. Processed NMR data can export Real, Imaginary, or Magnitude intensity. For true 2D and pseudo-2D data, **Matrix** puts F2/ppm across the first row and F1/ppm or @@ -85,3 +86,14 @@ hidden worksheet. The visible columns open normally in Excel, Origin, or Prism, while the companion lets Plotium later reopen the table with its column types, units, and error bars intact. Exported XLSX files hold plain values, with no formulas to recalculate. + +## With an AI client + +You can ask an AI client connected to Plotium to do this for you, for example: + +> Export this 180 × 90 mm canvas to /Users/me/figures/figure.svg, plus a +> matching PDF and a 300 DPI PNG. Do not overwrite existing files. + +Plotium asks you to confirm the exact file paths before writing anything; +replacing a file needs its own checkbox. Exporting does not save the project. +See [Access, review and undo](/ai/control-and-review/). diff --git a/docs/src/content/docs/guides/images.md b/docs/src/content/docs/guides/images.md new file mode 100644 index 00000000..c89af9e7 --- /dev/null +++ b/docs/src/content/docs/guides/images.md @@ -0,0 +1,77 @@ +--- +title: Images in figures +description: Add micrographs, photos, and other images to figure pages and panels. +--- + +## Add images + +To place each image on its own fitted page, choose **Add Images…** from the File +menu, Ribbon, or command palette. You can select multiple PNG, JPEG, TIFF, WebP, +or BMP files. Plotium recognizes the format from the file's contents, not its +extension. GIF and SVG images are not supported. You can also drop files onto +the board; each image gets a new page even if you drop it over an existing one. + +Plotium asks for confirmation before importing an image above 100 megapixels +or an estimated 512 MiB when decoded, and rejects images above 500 megapixels or +2 GiB. + +To add an image inside an existing Panel, select or enter an unlocked Panel, +then drop the file inside the green outline. To paste an image or a copied list +of image files, use **Paste Image** or press `Ctrl`/`Cmd` + `V`. On Windows, you +can copy files from File Explorer or copy image pixels from an application such +as Paint. Pasting in a text field continues to paste text normally. + +When Plotium creates a page for an image, it uses the image's physical size when +DPI information is available and assumes 96 DPI otherwise. The page is at most +89 mm wide, and its height follows the image's aspect ratio. The image fills the +page without distortion. Importing several images is one undoable action; a +failed or cancelled import leaves the project unchanged. + +For formats that need special handling, use these commands: + +- **Add Animated Image First Frame…** imports the first frame of an animated + PNG or WebP. **Add Images…** tells you when an image is animated. +- **Add Images Without Metadata…** removes metadata by converting the image to + PNG before adding it. +- **Add All TIFF Pages…** adds every readable page of a multi-page TIFF. The + standard **Add Images…** command adds only its first page. + +## Adjust an image + +Select an image and use **Image** in the Object inspector to crop or rotate it, adjust its +opacity, or choose how it is interpolated. These changes do not alter the +embedded source image. Images are stored in the `.plotium` project; duplicating +an image does not duplicate its stored source, and each copy keeps its own crop, +rotation, opacity, fit, and interpolation. + +The board uses a bounded proxy for responsive editing, but SVG, PDF, EMF, +PNG, JPEG, TIFF, and **Copy Figure** sample the embedded source. Crop, +quarter-turn rotation, opacity, fit, interpolation, Panel clipping, and layer +order therefore match the authored page without depending on the source file's +original path. + +## Missing or damaged images + +Plotium checks every embedded image when a project opens. If one is missing, +damaged, or does not match its record, the project still opens and keeps +the image item in place as a labelled placeholder. Use **Replace Image…** in +the Object inspector to repair it. Normal save and publication export stop +until it is replaced; the Export dialog can explicitly allow labelled +placeholders when a review copy is still useful. + +For the image checks the Export dialog runs, see +[Exporting](/guides/exporting/#export-a-figure). + +## With an AI client + +You can ask an AI client connected to Plotium to do this for you, for example: + +> Add the micrograph at /Users/me/images/sem.png to panel b, fitted to the +> panel. Show me a preview. + +The AI can add local PNG and JPEG files of up to 1 MiB each (and at most 4 MiB +when decoded); give it the file's full path. Add larger images yourself with +**Add Images…**. The +change appears in Plotium right away and is one Undo step. Check the preview +before you agree. See +[Access, review and undo](/ai/control-and-review/). diff --git a/docs/src/content/docs/guides/importing-data.md b/docs/src/content/docs/guides/importing-data.md index bc06b83f..c48d7a84 100644 --- a/docs/src/content/docs/guides/importing-data.md +++ b/docs/src/content/docs/guides/importing-data.md @@ -1,31 +1,11 @@ --- title: Importing data -description: Supported file formats and how to open them. +description: Open instrument files, folders, and tables, follow import progress, and review how table columns are typed. --- -Plotium reads vendor LC–MS, NMR, XPS, AFM, and electrophysiology formats directly — -no conversion step is needed. - -## Supported formats - -| Format | Extension | Notes | -| --- | --- | --- | -| JEOL Delta | `.jdf` | Raw and processed 1D/2D and parameter series; experimental support | -| Bruker TopSpin | `fid` / `ser` / `pdata` | Raw and processed 1D/2D; NUS support is experimental | -| Varian/Agilent VnmrJ | `.fid` directory | Raw 1D, 2D with `phase=[1,2]`, or a series varying one parameter | -| Waters MassLynx RAW | `.raw` directory | Validated low-resolution runs, including SQD2 data | -| SCIEX legacy WIFF | `.wiff` + `.wiff.scan` | Single- and multi-sample legacy runs; both files must remain together | -| Rigaku powder XRD | `.rasx`, FI `.raw`, RAS_RAW `.txt` | Diffraction pattern, acquisition metadata, and attenuation when available | -| mzML | `.mzML` | Centroided/profile spectra and TIC, BPC, SIM, or SRM chromatograms with 32-bit or 64-bit arrays | -| Bruker NanoScope AFM | `.spm` / `.pfc` | Images, force curves, force-volume and PeakForce Capture cubes | -| JCAMP-DX | `.dx` / `.jdx` / `.jcamp` | 1D frequency-domain NMR spectra | -| Axon Binary Format 2 | `.abf` | int16/float32, multiple channels and sweeps, embedded DAC/epoch stimuli | -| VAMAS XPS | `.vms` | ISO 14976 `NORM` / `REGULAR` XPS blocks, including multiple measurement positions and regions | -| CasaXPS text | `.txt` | Structured eight-line export with raw spectrum, background, envelope, components, and fitted parameters | -| Tabular data | `.csv`, `.tsv`, `.txt`, `.xlsx` | Column types and empty cells preserved; one table per XLSX worksheet | -| Origin project (experimental) | `.opj`, `.opju` | Worksheets from the verified Origin 7.0552 and Origin 9.51 OPJ profiles; graphs are not imported, and `.opju` is detection-only. See [compatibility details](/reference/file-formats/). | -| Zip archive | `.zip` | An archived dataset folder | -| Plotium project | `.plotium` | Full project: data, processing, and layout | +Plotium reads instrument files and tables directly, with no conversion step. +For the full list of formats and what each importer reads, see +[Supported formats](/guides/supported-formats/). ## Opening files @@ -35,16 +15,16 @@ TopSpin, Varian/Agilent VnmrJ, and Waters MassLynx RAW), *Open Project…*, or *Import Table…*. Each imported dataset appears in the Primary Side Bar and is placed on the board automatically. -The file picker accepts several ABF files at once. Opening a folder recursively + +The file picker accepts several files at once. Opening a folder recursively imports every `.abf`, `.spm`, `.pfc`, `.vms`, `.wiff`, structured CasaXPS -`.txt`, and recognized `.raw` bundle below it. A `.wiff.scan` companion is -never imported as a separate dataset. -A `.raw` directory is imported once as a complete run; its internal files are -not treated as separate datasets. For ABF files, each immediate parent folder -becomes the initial, editable cell ID. -CasaXPS `.txt` files are recognized from their structured header, not from the -extension alone. Other `.txt` files continue through table import. See the -[XPS workflow](/guides/xps/) for energy-axis and fitting details. +`.txt`, and recognized `.raw` bundle below it. Companion files, such as a +`.wiff.scan` file or the internal files of a `.raw` directory, are not imported +as separate datasets. + +Where extensions are shared, Plotium identifies the format from the file's +content: a `.txt` file opens as CasaXPS or Rigaku XRD only when its header says +so, and otherwise goes to [table import](#import-a-table). ## Follow import progress @@ -60,191 +40,11 @@ NMR import includes default processing. NUS reconstruction can take substantiall longer than reading the file. Project files, table previews, ZIP files, and imports with a manually supplied sampling table use separate import workflows. -## Supplying a missing NMR sampling table - -Use this option for supported 2D Bruker NUS or JEOL acquisitions that sampled only -part of the indirect grid. You need the original sampling table and acquisition -files with enough grid and calibration information to check it. - -1. Choose **File → Import NMR with Sampling Table…** (also available in the - command palette), then select the Bruker `ser` or JEOL `.jdf` file. -2. Enter the table's source or an explanation, and the full original indirect - grid size, including unsampled points. -3. Enter **Lanes per observation**: the number of component records acquired at - each listed indirect point. Use the acquisition's value, not the number of - points in the table. -4. Select **Zero-based** or **One-based** to match the original table. Enter one - indirect index per line, in acquisition order. Each line represents all lanes - for that observation; keep repeated observations. -5. Click **Validate and import**. If validation fails, check the reported mismatch - against the acquisition records. Conflicts with an existing sampling list, - incorrect observation or lane counts, and missing grid or calibration information - prevent import. - -Vendor files are not modified. Save the project to retain the table and its source; -reopening the project does not require the original files. Repeated coordinates -can be imported but currently prevent [NUS reconstruction](/guides/processing/#reconstruct-a-non-uniformly-sampled-spectrum). -For scripts, see the [CLI declaration format](/reference/cli/#sampling-declarations). +## Import a table -## Varian/Agilent VnmrJ - -To import a raw 1D or conventional 2D acquisition, choose **Open Folder…** and -select its `.fid` directory. You can instead choose **Open File…** and select -the `fid` file inside. Keep the `fid` and `procpar` files together in the same -directory. - -You can also import a series varying one ungrouped parameter. Supported 2D data -requires `phase=[1,2]`. Grouped or multiple parameter arrays, other phase orders, -Varian NUS, processed spectra, and more than two dimensions are unsupported. -See [File formats](/reference/file-formats/#nmr-data-and-projects) for calibration -requirements and format limitations. - -## mzML - -Open or drop a `.mzML` file. Plotium imports the spectra into the same LC–MS -dataset and chart workflow used for Waters runs. Spectra are grouped by MS -level and polarity, while each scan retains acquisition-function metadata such -as its mzML instrument configuration, preset scan configuration, and filter -string when present. Scan times recorded in seconds or minutes are displayed -in minutes. Plotium prefers -each spectrum's file-supplied TIC and base-peak summaries over values derived -from profile samples, and retains whether each summary came from the source or -was derived. Plotium also imports file-supplied TIC, BPC, SIM, and SRM -chromatograms, including chromatogram-only acquisitions. Transition -precursor/product m/z, polarity, collision energy, and activation method are -retained when present. -For MS2 and higher spectra, Plotium separately retains the precursor spectrum -reference, selected-ion m/z, selected-ion intensity and charge, isolation-window -target and offsets, collision energy, and activation method. This distinction -preserves DIA isolation targets even when a selected ion is not present. The -current data model stores one precursor and one selected ion per spectrum; an -import warning identifies spectra with additional values and states that only -the first was retained. Scientific Script scan snapshots expose the summary -provenance, instrument configuration, source event or preset, and filter string. - -TIC and BPC provenance is kept separate. A file-supplied TIC or BPC channel is -marked as a source chromatogram and is used for its bound acquisition stream -before any fallback. When that channel is absent, Plotium uses the per-spectrum -source summary when available; otherwise it deterministically derives TIC from -the intensity array or BPC from the largest non-negative peak. A mixed run can -therefore report both source summaries and array-derived points. An unbound -source chromatogram in a multi-stream run is kept as its own channel rather -than guessed as a replacement for a stream's TIC or BPC. Field metadata, -Scientific Summary, and Scientific Script expose the selected provenance. - -For runs with many chromatogram channels, open **Dataset tools → Mass -spectrometry** from **Extract Mass Spectrum** or the command palette. The -**Chromatogram channels** browser lists a stable count and ordering, with TIC -and BPC ahead of SIM/SRM transitions. Search matches channel names and native -IDs. Structured transitions can also be filtered by precursor m/z, product -m/z, polarity, collision energy, and activation method. Numeric fields accept -an exact value, comparisons such as `>=400`, or a range such as `400..500`. - -Selecting a row replaces the series on the current LC–MS chromatogram plot with -that single channel through the normal Plotium field and binding workflow. Mass- -spectrum plots are never retargeted. The choice is undoable and is saved with -the page in a `.plotium` project. Chromatogram-only runs use the same browser. -The panel reports when a run has no plottable channels, no structured transition -metadata, or no channels matching the current filters. The list is virtualized, -so only visible rows are created for large scheduled-MRM runs. - -The importer accepts little-endian 32-bit and 64-bit floating-point m/z, time, -and intensity arrays with no compression or zlib compression. Numpress, -big-endian arrays, and spectra or chromatograms without their required arrays -stop the import with an error. - -## SCIEX legacy WIFF - -Open or drop the `.wiff` file. Keep the paired file with `.scan` appended to -the full filename beside it, for example `sample.wiff` and -`sample.wiff.scan`. Plotium imports native scan IDs, retention times, m/z and -intensity arrays, precursor details when available, polarity, instrument and -acquisition-start metadata, and a separate TIC for each verified experiment. -Spectra are grouped into independent sample/experiment acquisition streams and -retain cycle order, including zero-TIC and empty DDA slots. Duplicate sample -names remain separate and are displayed with stable suffixes such as -`yjs_10ppm #1` and `yjs_10ppm #2`. - -Plotium rejects a missing companion, an empty container, or an unrecognized WIFF -layout rather than creating a partial dataset. SCIEX `.wiff2` and `.timeseries.data` are not supported; -convert those acquisitions to mzML before opening them in Plotium. - -## Rigaku powder XRD - -Open the `.rasx` file when it is available. Plotium reads the measured 2theta, -intensity, and attenuation columns together with the instrument name, X-ray -target, Kalpha1 wavelength, tube voltage/current, scan step, and scan speed. -The initial page is an XRD pattern. **Processing** provides optional SNIP -background subtraction, Savitzky-Golay smoothing, and normalization by maximum -intensity or integrated area; these settings and the original observations are -saved in the Plotium project. - -Rigaku `FI`-layout `.raw` files and profile `.txt` exports whose header identifies -`RAS_RAW` also open as XRD. The binary reader retains the scan ruler, intensity, -X-ray target, Kalpha1 wavelength, tube voltage/current, and scan speed. Other -`.raw` signatures are rejected explicitly because the extension is shared by -incompatible vendor formats. Other `.txt` files keep the normal table-import -preview, so a generic numeric table is not silently reclassified. - -## Waters MassLynx RAW - -Open or drop the `.raw` directory itself. Plotium imports its supported MS -functions and optical detector channels. Temperature, pressure, and other -readable auxiliary channels remain in the dataset but are not plotted by -default. - -When optical detector data is present, the initial page places its UV channels -above the active function's total ion chromatogram (TIC) on a shared retention- -time axis. Multiple UV channels are overlaid; their legend uses stored -wavelengths such as `214 nm`. Select the UV plot and use **Legend & scales** in -the Object inspector to hide, move, or lay out that legend. Without optical -data, the initial page contains only the TIC. - -Select the LC–MS dataset, then choose **Extract Mass Spectrum** on the -**Analyze** tab. Plotium opens **Dataset tools → Mass spectrometry** in the right -sidebar and activates retention-time range selection. - -Click a TIC or UV chromatogram to show the nearest MS scan under **Scan -preview**. The preview identifies its retention time and native scan number; it -is neither added to the page nor saved as a result. Choose **Extract current -scan** to add that scan as a stick spectrum. - -To extract from a time window, choose a **Method**, select **Select range**, and -drag across a TIC or UV chromatogram. **Extract spectrum** adds the peak-apex -scan, nearest scan, mean spectrum, or summed spectrum to the page. Each -extracted spectrum records its function, time range, and method. It does not -change when the preview cursor moves and appears under **Analysis** in the Data -browser. - -To create an extracted ion chromatogram (XIC; also called an EIC), open -**Dataset tools → Mass spectrometry** and choose **Select m/z range**. Drag -across the current mass-spectrum plot, confirm the displayed m/z interval and -acquisition stream, then choose **Extract ion chromatogram**. - -The resulting line plot contains one point per scan at its retention time in -minutes. Each point is the sum of intensities within the selected m/z interval, -including both endpoints. The result is saved and does not change when you move -the scan preview or select another acquisition stream. XIC extraction does not -integrate chromatographic peaks or calculate peak area. - -If the run contains several supported MS functions, use **Acquisition stream** -under **Dataset tools → Mass spectrometry**. The initial stream is the first -non-reference MS function. Stream changes, spectrum extractions, and XIC -extractions can be undone and redone with the standard Edit commands. - -Plotium supports the low-resolution MassLynx encoding validated with SQD2 runs. -If a required MS function uses another encoding, the import stops and -identifies the function and instrument. Unsupported optional or reference -functions produce an import warning when the rest of the run is readable. - -There is no LC–MS processing pipeline. The imported run, active acquisition -stream, detector channels, extracted spectra, extracted ion chromatograms, and -page layout are saved in the `.plotium` project. The scan preview is temporary -and is cleared when the project is reopened. - -Tables can also be pasted straight from the clipboard with -`Ctrl` + `Shift` + `V` — comma-, tab-, or semicolon-delimited text becomes a -new data table. +Choose **Import Table…** for a CSV, TSV, delimited `.txt`, or XLSX file. Tables +can also be pasted straight from the clipboard with `Ctrl` + `Shift` + `V` — +comma-, tab-, or semicolon-delimited text becomes a new data table. Importing a table, from a file or the clipboard, first opens a **Review table import** dialog. It shows each column's inferred type and unit, whether the @@ -252,7 +52,15 @@ column allows empty cells, a preview of the first rows, and any import diagnostics. Choose **Import table** to add it, or **Cancel** to leave your project and recent-file list untouched. An XLSX workbook with several sheets adds a **Table** selector so you can preview each worksheet; a single **Import -table** brings them all in as separate tables. +table** brings them all in as separate tables. While a preview is pending, +selecting a second table file is rejected; finish or cancel the current preview +first. + +The imported table appears on the board as a sheet beside a new page for its +plot. To choose which columns the plot shows, see +[Plots and chart types](/guides/plots-and-charts/). + +### How column types are decided Plotium keeps Boolean, whole-number, decimal, text, and empty cells distinct. A column that mixes kinds of value, or whose values are ambiguous, is kept as text @@ -267,6 +75,15 @@ when some columns end early; the diagnostics say how many. When the columns alternate as x/y pairs of different lengths, such as Source Data where each curve has its own x column, the diagnostics list the pairs. +### Error-bar columns + +To add error bars to your own data, put a column named `_sigma` immediately +after a y column in a CSV or TSV, holding each point's uncertainty (zero or +positive); on import Plotium links it to that y column as a symmetric standard +deviation. + +### Origin CSV exports + CSV files exported from Origin start with label rows (`Short Name`, `Long Name`, `Units`, `Comments`) and a row-number column. Plotium names each column from its Long Name (or its Comments, then its Short Name), appends the @@ -275,12 +92,19 @@ unit in parentheses, converts Origin's superscript, subscript and Greek markup row-number column. When Origin exported a single column without its x values, the row numbers are kept as the x column and the diagnostics warn about it. +Origin project files (`.opj`) open in the same preview; see +[Origin projects](/guides/supported-formats/#origin-projects-experimental). + +### Tables exported by Plotium + When Plotium exports a CSV or TSV, it writes a companion `.plotium-schema.json` file next to it, and Copy TSV puts the same information on the clipboard beside the plain text (on Windows). Reopening either restores the original column types, units, and error-bar relationships. Without that companion, Plotium infers the types on import and flags anything ambiguous in the review dialog. +### Excel workbooks + In an `.xlsx` workbook, each visible worksheet imports as its own table, and Plotium keeps its type information on a hidden worksheet. Plotium reads the value Excel cached for each formula but does not recalculate formulas itself; a @@ -288,52 +112,41 @@ formula cell with no cached value imports as empty and is listed in the diagnostics. Exported XLSX files hold plain values, so they never depend on Excel recalculating them. -## Origin project import (experimental) - -Origin `.opj` and `.opju` files appear in the file picker for both *Open -File…* and *Import Table…*. Both routes identify the format from file -content and signatures rather than relying only on the extension. - -When a supported `.opj` yields worksheets, Plotium opens the existing **Review -table import** preview so you can inspect every candidate table. Confirm once -to import all candidates, or cancel to leave the current project and recent-file -list unchanged. While a preview is pending, selecting a second table path is -rejected with a clear message; finish or cancel the current preview first. - -Origin does not need to be installed or launched, and Plotium does not automate -or invoke it. See [File formats](/reference/file-formats/) for the exact, -evidence-limited compatibility boundary. - -## Pseudo-2D experiments - -DOSY, T1, and T2 experiments are detected automatically from the acquisition -parameters and get their own analysis tools — see -[Pseudo-2D analysis](/guides/pseudo-2d/) and -[DOSY diffusion analysis](/guides/dosy/). Missing diffusion parameters can be -supplied in the **DOSY** task card after import. - -For patch-clamp sweeps, filtering, time-window statistics, stimulus handling, -and IV analysis, see [Electrophysiology](/guides/electrophysiology/). - -## Bruker NanoScope AFM - -Plotium imports NanoScope `.spm` images, force curves, and force-volume grids, -plus PeakForce Capture `.pfc` data cubes. Image channels plot as maps at the -recorded scan size, in the file's physical units, with the aspect ratio locked. -Force curves plot as separate approach and retract branches; when the file -records a deflection sensitivity, the vertical axis is deflection in -nanometres, otherwise the curve stays in the unit stored in the file. Plotium -shows the acquired data as is — it does not infer a contact point, indentation, -or modulus, and does not fit a contact-mechanics model. - -A PeakForce Capture file usually has an AllImages `.spm` export saved beside -it. Plotium finds that companion, checks that its image grid matches the force -grid, and imports the pair as one dataset; opening a folder also imports the -pair once, not as two datasets. The default canvas places the channel map -beside a force curve from the centre pixel of the grid. If no companion is -found, or its grid does not match, the `.pfc` file still imports with its -force curves alone. - -PeakForce Capture curves are the per-pixel signals as acquired. Derived QNM -maps such as modulus arrive as their own image channels; Plotium does not -recompute them from the curves. +## Supplying a missing NMR sampling table + +Use this option for supported 2D Bruker NUS or JEOL acquisitions that sampled only +part of the indirect grid. You need the original sampling table and acquisition +files with enough grid and calibration information to check it. + +1. Choose **File → Import NMR with Sampling Table…** (also available in the + command palette), then select the Bruker `ser` or JEOL `.jdf` file. +2. Enter the table's source or an explanation, and the full original indirect + grid size, including unsampled points. +3. Enter **Lanes per observation**: the number of component records acquired at + each listed indirect point. Use the acquisition's value, not the number of + points in the table. +4. Select **Zero-based** or **One-based** to match the original table. Enter one + indirect index per line, in acquisition order. Each line represents all lanes + for that observation; keep repeated observations. +5. Click **Validate and import**. If validation fails, check the reported mismatch + against the acquisition records. Conflicts with an existing sampling list, + incorrect observation or lane counts, and missing grid or calibration information + prevent import. + +Vendor files are not modified. Save the project to retain the table and its source; +reopening the project does not require the original files. Repeated coordinates +can be imported but currently prevent [NUS reconstruction](/guides/processing/#reconstruct-a-non-uniformly-sampled-spectrum). +For scripts, see the [CLI declaration format](/reference/cli/#sampling-declarations). + +## With an AI client + +You can ask an AI client connected to Plotium to import data for you, for example: + +> Import the CSV at `/absolute/path/experiment.csv`. Time is in s and current +> is in mA. Show me its columns before you plot anything. + +The AI client can import instrument files and CSV, TSV or XLSX tables that you +name by their full path. Units are taken only from what you state; Plotium does not +guess them. The whole import is one Undo step, and a file that fails adds +nothing to the project. Check the columns and units it reports before you plot. +See [Access, review and undo](/ai/control-and-review/). diff --git a/docs/src/content/docs/guides/layout-and-export.md b/docs/src/content/docs/guides/layout-and-export.md deleted file mode 100644 index 4598debd..00000000 --- a/docs/src/content/docs/guides/layout-and-export.md +++ /dev/null @@ -1,536 +0,0 @@ ---- -title: The board and page layout -description: Arranging figures on the infinite board and sizing pages for journals. ---- - -## The board - -Plots live on an infinite board organized into pages. Dragging a frame snaps -it to the page grid, margins, and the edges of neighboring frames; snapping -can be toggled off on the **Arrange** tab. The **Arrange** tab also offers -alignment (with two or more frames selected), horizontal / vertical -distribution (three or more), z-ordering, and a *Tidy up frames* command. - -Drag over empty board space to marquee-select page and sheet frames. Hold -`Shift` to add the enclosed frames or `Ctrl` (`Cmd` on macOS) to toggle them. -Dragging the header of any selected frame moves the whole selection; the move -undoes as one step. In the Canvas list, `Shift`-click selects a continuous range -and `Ctrl`-click adds or removes one canvas. `Ctrl` + `A` selects every frame or -canvas according to the area you last used. - -## Scientific summary and notes - -Plotium shows an automatic summary of the plotted data below each page on the -board. On a multi-panel page, shared information appears once and the remaining -details follow the panel labels. - -Open **Canvas settings** to add a page note, or select a Panel and edit its -**Note**. Notes appear after the summary and are not included in exports. Use -**Show summary below page** to show or hide this whole board-only block. - -## Add external images - -To place each image on its own fitted page, choose **Add Images…** from the File -menu, Ribbon, or command palette. You can select multiple PNG, JPEG, TIFF, WebP, -or BMP files. You can also drop files onto the board; each image gets a new page -even if you drop it over an existing one. - -To add an image inside an existing Panel, select or enter an unlocked Panel, -then drop the file inside the green outline. To paste an image or a copied list -of image files, use **Paste Image** or press `Ctrl`/`Cmd` + `V`. On Windows, you -can copy files from File Explorer or copy image pixels from an application such -as Paint. Pasting in a text field continues to paste text normally. - -When Plotium creates a page for an image, it uses the image's physical size when -DPI information is available and assumes 96 DPI otherwise. The page is at most -89 mm wide, and its height follows the image's aspect ratio. The image fills the -page without distortion. Importing several images is one undoable action; a -failed or cancelled import leaves the project unchanged. - -For formats that need special handling, use these commands: - -- **Add Animated Image First Frame…** imports the first frame of an animated - PNG or WebP. -- **Add Images Without Metadata…** removes metadata by converting the image to - PNG before adding it. -- **Add All TIFF Pages…** adds every readable page of a multi-page TIFF. The - standard **Add Images…** command adds only its first page. - -Plotium asks for confirmation before importing a very large image. Select an -image and use **Image** in the Object inspector to crop or rotate it, adjust its -opacity, or choose how it is interpolated. These changes do not alter the -embedded source image. - -The board uses a bounded proxy for responsive editing, but SVG, PDF, EMF, -PNG, JPEG, TIFF, and **Copy Figure** sample the embedded source. Crop, -quarter-turn rotation, opacity, fit, interpolation, Panel clipping, and layer -order therefore match the authored page without depending on the source file's -original path. - -If an embedded image is missing or damaged, the project still opens and keeps -the image item in place as a labelled placeholder. Use **Replace Image…** in -the Object inspector to repair it. Normal save and publication export stop -until it is replaced; the Export dialog can explicitly allow labelled -placeholders when a review copy is still useful. - -## Work with figure panels - -Use the Panel commands in the Arrange menu or command palette to build a -multi-panel figure. You can create an empty Panel, turn selected objects into a -Panel, or duplicate, merge, split, dissolve, and delete Panels. Expand a Panel -in Layers to see the objects it contains. - -Click anywhere inside a Panel to select it, then drag to move it or use a corner -handle to resize it together with its contents. `Shift`-click selects multiple -Panels. To work with an object inside a Panel, double-click the Panel or press -`Enter`. Use the breadcrumb above the page or press `Esc` to return to the page. -You can also `Ctrl`/`Cmd`-click an object to select it without entering first. -A resize stops before any plot inside the Panel would lose the room for its -data to its axes, ticks and colour scale. While you move or resize a Panel or a -plot, its plot area also snaps to the plot-area edges of the other plots, so -axes line up even when their tick labels differ in width. - -With **Clip contents to panel** off, content can extend beyond its Panel and -the page; drag the visible content to bring it back. With clipping on, dragging -or resizing content keeps it reachable inside the Panel. Where objects overlap, -the topmost visible object receives the drag. - -To exchange two Panels on the same canvas, drag one over the other and release -when both slots are highlighted. The Panels exchange positions and sizes; their -contents scale with the destination slot. This is one undoable step. Hidden or -locked Panels cannot be swap targets, and multi-Panel drags remain group moves. - -Inside a Panel, objects snap to the Panel edge and to one another. To move an -object into another unlocked Panel, drag it over the Panel and release when the -target is highlighted. You can make the same move in Layers by dragging the -object's row onto the Panel's row. A Stack or Grid Panel rearranges its contents -after the move. Hidden objects remain selectable in Layers; locked objects can -be selected but not edited. - -Use the Panel inspector to control visibility, locking, clipping, labels, and -layout. **Vertical Stack**, **Horizontal Stack**, and **Grid** arrange the -contents using the selected gap, padding, and alignment. **Shared X Stack** -stacks plots on one x axis; see -[Stack plots on a shared x axis](#stack-plots-on-a-shared-x-axis). Automatic panel letters -appear only when a page has more than one visible Panel and follow reading order: -rows from top to bottom, left to right within a row. They update as soon as you -move or add a Panel. Choose **Locked auto** to keep a Panel's current -letter, or clear **Participates in sequence** to leave it unlettered. A letter -placed over an image automatically switches between black and white for -contrast, and a plot's y-axis title moves down when needed so the letter never -sits on it; on a plot too short for that, the plot moves right of the letter -instead. Manual and locked labels remain -visible on a page with one Panel. To hide every letter on a page at once, clear -**Show panel letters** in **Canvas settings**; the letters keep their sequence -and return unchanged when you turn it back on, and axis titles no longer make -room for them while they are hidden. - -Drag a single Panel completely clear of every canvas and keep it outside for -0.5 seconds to prepare a new canvas. The preview shows a progress bar, then a -green outline and **Release to create canvas**. Release to move the whole Panel -onto a new canvas fitted to its current size at that board position. Its contents, -labels, note, and internal layout are retained; the source canvas stays in place. -The move and canvas creation undo together. Returning any part of the Panel to a -canvas resets the timer. Resizing or dragging multiple Panels does not create a -canvas, and pressing `Esc` cancels the gesture. - -## Canvas size - -The active page shows a size chip above its top-left corner — the current -dimensions plus the matched preset (for example *89 × 60 mm · Nature · -Single column*). Click it, use **Canvas Size & Settings…** on the Figure -Ribbon tab, or run any "Canvas Size" entry in the command palette to change -the size. - -The preset list is searchable and grouped: journal figure widths (Nature, -Science, Cell Press, ACS, Elsevier, PNAS, and IEEE, taken from the -publishers' artwork guidelines), paper sizes with a portrait/landscape -toggle, presentation slides, recently used entries, and your own saved -custom sizes. Journal presets fix the page *width* — the height stays -content-driven up to the journal's maximum figure depth, and a warning -appears when the page grows past that depth. - -By default a size change never moves or resizes your content; if objects -end up outside the page, the chip row shows an overflow warning that scales -the content down to fit in one undoable click (font sizes keep their -physical pt values). Turn on **Scale content when applying sizes** to have -presets scale objects together with the page instead. - -Two helpers automate the rest: - -- **Auto height** keeps the width fixed and lets the page height follow the - content's depth, clamped to the journal's maximum. -- When the layout grid asks for two or more panel columns on a - single-column page, a dismissible hint offers the same journal's full - width in one click — it never resizes the page on its own. - -The export dialog pre-selects the matching journal preset, so a page -authored at a column width exports at that width by default. - -## Spacing between panels - -Panels of a multi-panel figure read best when their data areas are evenly -spaced — but each plot reserves a different amount of room for its tick -labels and axis titles, so equal frame gaps rarely look equal. -**Canvas Size & Settings…** sets both the spacing you want and how it is -measured. - -**Minimum spacing** is the gap itself, in the canvas unit; the **Tight** -(2 mm), **Normal** (5 mm), and **Spacious** (10 mm) presets fill in common -values. - -**Spacing basis** decides what that gap is measured between: - -- **Visual** (the default) measures between the data areas of neighboring - plots, counting the tick labels and axis titles that sit between them, so a - panel with a long y title is given the room it needs. The value is a - minimum: the gap you see can end up wider, never narrower, and frames never - overlap. The axis text of neighboring plots always keeps at least 8 pt - apart. -- **Frame** measures between the plot frames and ignores axis text. Frames - then sit exactly the requested distance apart, and the visible space between - data areas varies from pair to pair. - -A plot frame ends at its outermost text, tick, or axis line, with no blank -border of its own. A panel placed against the page edge therefore reaches the -edge of the exported figure, which suits journal sizes where the page is the -finished figure. - -The basis applies wherever Plotium places plots for you — **Apply grid**, and -dragging a plot onto a page that already holds one. - -Dragging a plot onto another page moves it there and re-tiles the destination. -During the drag the plot travels with the pointer, keeping the point you grabbed -under the cursor, and the destination page draws where every plot will sit once -you release. On a page that already holds two or more plots, the whole page -re-tiles into an even grid and the arriving plot takes the cell you are pointing -at. - -If the move leaves the source page empty, Plotium deletes that page as part of the -drop, so the move and the deletion undo together. Hold `Alt` as you release to -keep the empty page instead; the Operation history shows which way `Alt` will flip the -current drop. To keep empty source pages by default, turn on **Keep source canvas -when tiling its last object** in Preferences → General — `Alt` then removes them -for that one drop. - -With the Select tool active, each non-zero page margin is drawn as a dashed -line across the page, showing the content area you are laying out into; a -margin of zero draws no line. Turning on the layout grid adds the cell -outlines, and snapping guides appear in a contrasting color while you drag. - -## Simplify inner axes - -In a grid of panels that share the same axes, repeating the tick numbers and -axis titles on every panel wastes space. **Simplify inner axes** keeps the -x-axis text only on the bottom plot of each column and the y-axis text only on -the leftmost plot of each row. Axis lines and tick marks stay on every panel. - -There are two ways in: - -- Tick **Simplify inner axes** beside **Apply grid** in Canvas settings to - arrange and simplify as one undoable step. The frames are then measured - against the simplified axes, so the panels grow into the space the hidden - text used to take. -- Run **Simplify Inner Axes** — on the Arrange Ribbon tab, in the canvas - right-click Arrange menu, or from the command palette — to simplify plots - that are already in place. It needs at least two plots aligned in a grid; - otherwise the Operation history says what to fix. - -To bring text back on one panel, select it and use **Axes** in the Object -inspector: the **X text** and **Y text** rows toggle **Tick labels** and -**Title** individually, and **Automatic** returns that axis to showing both. - -To write large tick values as `1,000` rather than `1000`, open **Advanced** in -the same **Axes** section and turn on **X thousands separator** or **Y -thousands separator**. When the axis reaches ±10,000, its labels are then -written in full, such as `15,000`, instead of using a shared ×10ⁿ multiplier. -An axis that reaches 10¹⁵ or more, or whose largest value is below 0.001, keeps -the multiplier. Agents can set the same option through the -`object.axes.x_thousands_separator` and `object.axes.y_thousands_separator` -properties. - -To choose where major ticks fall, set **X major tick step** or **Y major tick -step** under **Advanced** in the same section, or **Right Y major tick step** -in the **Right Y axis** section. Ticks then sit on the multiples of the step in -the axis's display unit — a step of 20 gives 80, 100, 120 — and minor ticks -divide those intervals. 0 returns to automatic ticks. The step does not apply -to logarithmic, category or broken axes, and a step that would draw fewer than -two or more than 100 ticks falls back to automatic ticks. Changing the display -unit clears the step. Agents use -`object.axes.x_major_step`, `object.axes.y_major_step` and -`object.axes.y2_major_step`. - -## Stack plots on a shared x axis - -A Shared X Stack puts two or more plots in one Panel, one above the other, on a -common x axis — for example an XRD pattern above its reference-card sticks, or -several spectra kept apart. Each plot keeps its own y axis, legend and chart -type. - -There are two ways in: - -- Select a Panel that holds two or more plots and choose **Shared X Stack** in - the Panel inspector's **Layout** list, the **Edit ▸ Panel** menu or the - command palette. -- Select several Panels, each holding a plot, and run **Stack with Shared X**. - The Panels are merged into the first one and stacked top to bottom in their - page order, as one undoable step. - -In the stack: - -- The plots fill the Panel's width and touch at their inner edges. The gap - starts at 0 pt; raise **Gap** in the Panel inspector to separate them while - keeping them aligned. -- Plot areas share one left and one right edge, so the y-axis titles line up - whatever the width of the tick numbers. Each plot keeps or omits its own - right y axis, and the right-axis titles of the plots that have one line up - the same way. -- Only the bottom plot draws x tick numbers and the x-axis title, and only the - top plot draws a figure title. Where two plots meet, their x ticks point - inward; the bottom axis keeps the tick direction you chose. A ×10ⁿ multiplier - of a lower plot's y axis moves just inside its top-left corner, and a y tick - number that would sit on the shared edge is left out. -- The plots share one x window. Entering the stack sets an x range covering all - of their data and the top plot's x major tick step on every plot, so the - plots must use the same x scale (linear or logarithmic) first. Every plot follows the bottom plot's x direction: an - NMR spectrum, whose ppm axis runs right to left, stacked above an ascending - plot is drawn left to right. -- Zooming or panning x on one plot moves all of them. Changing the x range, - logarithmic scale, x display unit, thousands separator or major tick step on - one plot changes - every plot in the stack in one undoable step; a change that one of the plots - cannot take, such as a logarithmic axis on an NMR spectrum, is refused. -- The top-to-bottom order is the Panel's content order. Each plot's height sets - its share of the stack: drag a plot's bottom edge on the canvas to make it - taller or shorter than the others. -- The whole stack is one Panel with one panel letter. - -The canvas, the Operation-history checks and every export use the same stacked -geometry. To leave the stack, set the layout back to **Free** or **Vertical -Stack**; each plot then draws its own x axis and x direction again. The shared -x range stays until you set **X range** back to **Auto**. - -## Stacked and multi-dataset plots - -A single plot frame can display several 1D datasets — superimposed, or -stacked with adjustable vertical spacing and 3D shear. 2D datasets combine -as a color overlay. - -To align line series along x, select the plot and choose **Align Traces…** in -the **Align** group on the **Analyze** tab. The command is available when the -plot contains at least two visible line series with the same x-axis unit. You -can open the same dialog with **Align traces…** under **Data** in the Object -inspector. - -Choose a reference series, then align by **Trace start** (the first finite -plotted sample) or by a peak within an x window. For peak alignment, -**Positive** finds upward peaks, **Negative** finds downward peaks, and -**Magnitude** compares their prominence. Review the **Anchor**, **Delta**, and -**Result** columns before selecting **Apply**. Hidden series, incompatible -series, and series without a usable anchor are listed as **Skipped** and remain -unchanged. - -Alignment preserves the plot's current zoom. To adjust one line manually, edit -its **X shift** under **Data**. Automatic and manual shifts are undoable plot -settings and do not affect source data or data exports. - -## Plot styling and typography - -Plotium styles plots for print automatically: clean bottom-and-left axes with -outward ticks, tick precision that follows the displayed range, tick density -that thins as a panel narrows or shortens (a short panel still keeps two y -ticks wherever they fit), and NMR isotope numbers set as superscripts. -New dataset pages start at the 89 × 60 mm single-column size, so a plot -spanning the page already shows text at its printed journal size; assemble -multi-panel figures on a wider page later, keeping each panel at its natural -size. - -What you control directly: - -- Select one plot and use **Axes** in the Object inspector to override its X - and Y titles or numeric ranges, or to hide either axis's tick labels and - title. **Equal x/y scale (1:1)** uses the same data units per screen unit on - both axes, for example for a Nyquist plot, an AFM image or a 2D NMR - spectrum. The plot area shrinks to that shape inside the frame; the axis - ranges are kept. It needs linear, non-categorical axes and no right y axis, - and a plot in a shared-x stack cannot turn it on. AFM images start with it - on; for a true 2D NMR spectrum Plotium sets its initial value when the - spectrum is imported, and you can change it afterward without changing the - import preference. Leave a title blank, or keep a range on **Auto**, to use - the value derived from the data. A manual range becomes that axis's full - range: zooming and panning stay inside it, and a double-click on the plot - returns to it. Charts without visible axes offer no axis settings, and - categorical axes have no range controls. -- **Frame** in the same **Axes** section chooses *Left and bottom* or *All four - sides*. The four-sided frame adds top and right axis lines with the same - stroke as the other axes; ticks and labels stay on the left and bottom axes. - Most plots start with left and bottom axes; 2D maps such as contour plots and - heatmaps start with all four sides. -- **X scale** and **Y scale**, under the more options of the **Axes** section, - switch a line, scatter or stick plot between *Linear* and *Logarithmic*. A - logarithmic axis labels powers of ten (10¹, 10², …), thins them when the - axis is short, and uses ordinary ticks when fewer than two powers of ten are - visible; - minor ticks, when enabled, mark 2–9 × each decade. Its automatic range fits - only the positive data. Zero and negative values have no position: lines - break there, and error bars and sticks that reach below the axis end at its - edge. A manual range on a logarithmic axis must start above zero. Zooming and - panning move by decades. Logarithmic axes are not offered for categorical - axes, 2D maps, bars and distributions, or NMR spectra, whose integral, phase - and cursor tools measure in linear ppm. -- **Y axis** under the advanced controls of **Line** puts a line or scatter - curve on a second y axis at the right of the plot, for a quantity with a - different unit or magnitude. The right axis appears as soon as one curve - uses it and goes away when every curve is back on the left. It fits its own - automatic range to its curves and draws its own ticks, tick labels and - title; the title reads bottom to top like the left one and starts as the - first right curve's column name and unit. The **Right Y axis** section of the - Object inspector, shown only while the plot has a right axis, sets its - title, range, logarithmic scale, tick labels, display unit and major tick - step. Scrolling, - dragging and box zoom move both y axes by the same fraction of their range, - a double-click returns both to their full range, and the **Inspect** cursor - reads the pointer on x and on both y axes. One legend lists every curve. - Bars stay on the left axis, and reference lines, annotations and arrows are - placed in left-axis coordinates. In a table plot each y axis keeps the unit - of its first curve; a curve whose unit cannot convert to it cannot join that - axis. -- **X break** and **Y break**, under the more options of the **Axes** section, - break a linear numeric axis: the values between the two endpoints are left - out, and the axis line opens with a pair of slanted marks. Untick **None** to - start from the middle third of the current range, then edit the endpoints; - both must lie inside the axis range. By default the two pieces keep the same - scale; **X lower share** or **Y lower share** sets how much of - the axis length the lower values get instead. Each piece gets its own ticks, and a tick right next to - the break is left out so the labels do not collide. Lines that cross the - break leave at one side of the gap and continue on the other; a bar that - spans a y break is drawn cut. Logarithmic, categorical and equal-scale axes, - 2D maps and NMR spectra cannot be broken, nor can the y axis of a plot with a - right y axis. In a shared x stack, an x break applies to every plot. - Agents set it through `object.axes.x_break` and `object.axes.y_break` - (`{"mode":"manual","min":…,"max":…,"unit":…}`, or `{"mode":"auto"}` for no - break) and - `object.axes.x_break_lower_fraction`/`object.axes.y_break_lower_fraction`; - figure diagnosis reports data points that a break hides. -- Use **Legend & scales** in the Object inspector for any plot. With - **Visibility** on **Auto**, Plotium shows a categorical legend when the plot - has two or more named entries and shows a continuous colour scale for a - heatmap. **Show** also permits a one-entry legend; **Hide** removes the legend - or colour scale from that plot. **Position** on **Auto** places a legend - inside the plot in whichever corner or edge midpoint covers the fewest data - points and lines, preferring the roomier spot and then the upper right. When - every such spot covers data, Plotium extends **Auto** axis ranges on the - legend's side, by up to half their span, just far enough to clear one; - manual ranges, zoomed views and aspect-locked plots are never changed. - **Inside** keeps it in the upper right, and **Outside right** or **Outside - bottom** reserve space beside the plot. **Layout** switches a categorical - legend between a vertical list and a horizontal row; **Title** is available - under the section's advanced controls. -- Legends draw no border and no background, on screen and in every export - format; only their entries and title are drawn. -- With **Select** active, click a legend or colour scale to open its - **Legend & scales** settings. Drag a categorical legend to place it freely; - the custom position survives resizing and is used by every export format. - A clicked legend or plot label is outlined; the arrow keys then move it by - 0.5 pt (`Shift`: 5 pt). Double-click a legend or colour scale to restore its - automatic placement. -- Axis titles, legend entries and text use true superscripts and subscripts: - type `cm^{-2}` or `H_{2}O`. Characters such as `⁻²` and `₂` are drawn the - same way. EMF output falls back to those Unicode characters. -- By default, figure text is set in Arial on the canvas and in every export - format. Without Arial, Plotium uses Helvetica or a metric-compatible sans - such as Liberation Sans. SVG files name the typeface, so a vector editor - keeps the Arial that Nature-portfolio journals ask for. -- **Font** in the **Figure typography** section switches the text inside every - plot — tick labels, axis titles, the figure title, legends, colour scales - and plot annotations — between *Arial* (the default), *Helvetica* and - *Times New Roman*. Helvetica is drawn as Helvetica on macOS; Windows and - Linux draw it with Arial or Liberation Sans, which have the same character - widths, and SVG files still name Helvetica first. Without Times New Roman, - Plotium uses a metric-compatible serif such as Liberation Serif. **Font weight** (an advanced control) sets that text - *Regular* or *Bold*. Text boxes and panel letters on the canvas keep their - own Arial styling. Both settings travel with themes and saved styles; the - built-in themes set Arial Regular. -- **Figure typography** in the Figure Ribbon tab's **Style** group opens the - document-wide typography section; **Figure Typography…** in the command - palette shows the same section in its own window with a **Reset to - defaults** button. Either sets the text sizes (tick labels, axis titles, the - figure title, and legends) for every plot at once, in absolute points — a - document-level style, so resizing a panel never changes its type size. - These sizes accept 1 to 72 pt. Legends default to 7 pt. -- The same section's advanced controls set every plot's axis strokes: - **Axis line width** (axis lines and tick marks, 0.05 to 10 pt, default - 1 pt), **Tick length** (0 to 20 pt, default 3 pt) and **Tick direction** - (*Outward*, the default, or *Inward*). Inward ticks point into the plot, so - the tick labels move up to the axis line. -- **Minor ticks** in the same advanced controls draws that many unlabelled - ticks between neighbouring major ticks on both axes (0 to 9, default 0, - which hides them). Minor ticks are half the tick length and use the same - width and direction. Categorical axes, and axes showing fewer than two - major ticks, have no minor ticks. -- **Figure typography** in the Object inspector holds the same tick-label size - as **Tick-label size**, plus **Legend size** and **Legend text color**. - Changing a value in either surface changes the one document-wide value. - Because it belongs to the document rather than to a plot, the section is - shown whatever is selected — including when nothing is. -- **Line** in the Object inspector sets the **Stroke width** of the selected - plot's line series, in points. New line series are 0.5 pt; drag or type any - value from 0.05 to 10 pt, or take one from **Presets** — *Fine* 0.50 pt, - *Medium* 0.75 pt, *Bold* 1.25 pt. The section appears only when something in - the selection is drawn as a line, and its header counts the series it is - about to change. Select several plots and it edits them together; select - nothing and it follows the page's active plot. - - When the selected series do not all carry the same width the control shows an - em dash and the word *mixed* rather than presenting one of them as the - setting; setting the row is what makes them agree. A selected series that is - drawn as something else — a contour, say — is reported as skipped in the - Operation history, and the rest still take the value. A width that differs from the - one Plotium would choose for this data is marked with a dot, and the reset - button beside it re-derives that default. -- **Advanced** under **Line** holds each curve's marker colours, apart from its - line colour. **Marker fill** sets the inside of closed markers (circle, square, diamond, - triangles, star, pentagon, hexagon) and **Marker edge color** their outline; both follow the curve - colour until set. **Marker edge width** draws that outline, from 0 (no - outline, the default) to 5 pt. **Hollow marker** leaves closed markers - unfilled and keeps their outline, 0.5 pt when the edge width is 0; the - fill colour returns when it is turned off. **Marker every N points** draws - a marker on the first point and every N-th point after it, for dense data - such as hundreds of cycles; the line still runs through every point. Plus - and cross markers stay in the curve colour. The legend swatch shows the same - marker. Charts whose colours carry - meaning keep their marker colours. -- **Canvas themes** carry matching sizes — the Presentation Dark theme, for - example, enlarges the axis text for slides. The **Nature** theme follows the - Nature Portfolio final-artwork guidelines: 7 pt text with strokes scaled to - it — 0.3 pt axes, ticks, bar outlines and new reference lines and arrows, - 0.5 pt line series — outward 3 pt ticks, 3 pt markers without an outline and - the colour-blind-safe Okabe–Ito palette. Marker outlines you drew by hand - stay. Its sizes assume a Nature column - width, so applying it to a canvas that matches none of the Nature size presets - (89, 136 or 183 mm wide) adds a note to the status bar naming those widths; - the canvas keeps its size. A canvas already at one of those widths without a - size preset takes on that Nature preset, so the export precheck applies - Nature's minimums (5 pt text, 0.25 pt lines). The - line widths and marker sizes stay when you switch to a theme that does not - set them. Any theme keeps the values you set by hand: curve and marker - colours, line widths, marker sizes and outlines, text and shape colours and - the figure typography. The status bar says how many it kept; resetting a - value hands it back to the theme. -- **Values you set by hand** — in the property panels, by scrolling over a - control or by dragging a legend — are kept for you. Themes leave them alone, - and an AI agent connected through MCP skips them unless you ask it to change - them. Resetting a value (or double-clicking a dragged legend) releases it. - Values an agent sets are not counted as yours. -- **Save Canvas Style…** (View ▸ Canvas Theme, or **Save Style** in the - Figure Ribbon tab's Style group) saves the active canvas's look as a named - style: background, text colour and size, figure typography (including the - font and font weight), axis and tick - strokes, curve colours with their marker fills, outlines and hollow setting, - line width and marker size. **Canvas Styles…** lists saved styles to apply to the active canvas or - delete. Applying a style is one undoable step. To change a style, apply it, - adjust the canvas and save it again under the same name. Styles are stored - as `.plotiumstyle` files in the `styles` folder of Plotium's configuration - directory, so they can be copied to another computer. - -When the figure is ready, see [Exporting](/guides/exporting/). diff --git a/docs/src/content/docs/guides/legends-and-lines.md b/docs/src/content/docs/guides/legends-and-lines.md new file mode 100644 index 00000000..c567b16e --- /dev/null +++ b/docs/src/content/docs/guides/legends-and-lines.md @@ -0,0 +1,100 @@ +--- +title: Legends, lines and markers +description: Place and title legends, set line widths and marker styles, and write superscripts and subscripts. +--- + +## Legends and colour scales + +Use **Legend & scales** in the Object inspector for any plot. + +- With **Visibility** on **Auto**, Plotium shows a categorical legend when the + plot has two or more named entries and shows a continuous colour scale for a + heatmap. **Show** also permits a one-entry legend; **Hide** removes the legend + or colour scale from that plot. +- **Position** on **Auto** places a legend inside the plot in whichever corner + or edge midpoint covers the fewest data points and lines, preferring the + roomier spot and then the upper right. When every such spot covers data, + Plotium extends **Auto** axis ranges on the legend's side, by up to half their + span, just far enough to clear one; manual ranges, zoomed views and + aspect-locked plots are never changed. +- **Inside** keeps the legend in the upper right, and **Outside right** or + **Outside bottom** reserve space beside the plot. +- **Layout** switches a categorical legend between a vertical list and a + horizontal row; **Title** is available under the section's advanced controls. + +Legends draw no border and no background, on screen and in every export +format; only their entries and title are drawn. Legend text size and colour are +document-wide settings in +[Figure typography](/guides/themes-and-styles/#figure-typography). + +### Place a legend by hand + +With **Select** active, click a legend or colour scale to open its +**Legend & scales** settings. Drag a categorical legend to place it freely; the +custom position survives resizing and is used by every export format. A clicked +legend or plot label is outlined; the arrow keys then move it by 0.5 pt +(`Shift`: 5 pt). Double-click a legend or colour scale to restore its automatic +placement. + +## Line width + +**Line** in the Object inspector sets the **Stroke width** of the selected +plot's line series, in points. New line series are 0.5 pt; drag or type any +value from 0.05 to 10 pt, or take one from **Presets** — *Fine* 0.50 pt, +*Medium* 0.75 pt, *Bold* 1.25 pt. The section appears only when something in the +selection is drawn as a line, and its header counts the series it is about to +change. Select several plots and it edits them together; select nothing and it +follows the page's active plot. + +When the selected series do not all carry the same width the control shows an +em dash and the word *mixed* rather than presenting one of them as the setting; +setting the row is what makes them agree. A selected series that is drawn as +something else — a contour, say — is reported as skipped in the Operation +history, and the rest still take the value. A width that differs from the one +Plotium would choose for this data is marked with a dot, and the reset button +beside it re-derives that default. + +## Markers + +**Advanced** under **Line** holds each curve's marker colours, apart from its +line colour. + +- **Marker fill** sets the inside of closed markers (circle, square, diamond, + triangles, star, pentagon, hexagon) and **Marker edge color** their outline; + both follow the curve colour until set. +- **Marker edge width** draws that outline, from 0 (no outline, the default) to + 5 pt. +- **Hollow marker** leaves closed markers unfilled and keeps their outline, + 0.5 pt when the edge width is 0; the fill colour returns when it is turned + off. +- **Marker every N points** draws a marker on the first point and every N-th + point after it, for dense data such as hundreds of cycles; the line still runs + through every point. + +Plus and cross markers stay in the curve colour. The legend swatch shows the +same marker. Charts whose colours carry meaning keep their marker colours. + +## Superscripts and subscripts + +Axis titles, legend entries and text use true superscripts and subscripts: type +`cm^{-2}` or `H_{2}O`. Characters such as `⁻²` and `₂` are drawn the same way. +EMF output falls back to those Unicode characters. NMR isotope numbers are set +as superscripts automatically. + +## With an AI client + +You can ask an AI client connected to Plotium to do this for you, for example: + +> On the left panel only, move the legend to the bottom-left corner, keep it +> vertical and title it Samples. Show me a preview before you apply it. + +> Find the curve named Current and change only that curve's line width to +> 1.5 pt. + +> Give each curve in this plot its own colour and legend text: Control, 1 mM, +> 5 mM. Show me two or three palettes to choose from. + +Plotium changes only the plot or curve you name, keeps values you set by hand +(such as a legend you dragged), and applies the change as one Undo step. When +you ask for options, it previews each and applies only the one you pick. See +[Access, review and undo](/ai/control-and-review/). diff --git a/docs/src/content/docs/guides/mass-spectrometry.md b/docs/src/content/docs/guides/mass-spectrometry.md new file mode 100644 index 00000000..90b09caa --- /dev/null +++ b/docs/src/content/docs/guides/mass-spectrometry.md @@ -0,0 +1,92 @@ +--- +title: Mass spectrometry +description: Browse LC–MS runs, extract mass spectra and ion chromatograms, and choose chromatogram channels. +--- + +Waters MassLynx RAW, SCIEX legacy WIFF, and mzML runs open as one kind of LC–MS +dataset. To open a Waters run, choose **Open Folder…** and select the `.raw` +directory, or drop the directory onto the window. This page covers what you do +after import; for what each importer +reads, see [Supported formats](/guides/supported-formats/#mass-spectrometry). + +There is no LC–MS processing pipeline. The imported run, active acquisition +stream, detector channels, extracted spectra, extracted ion chromatograms, and +page layout are saved in the `.plotium` project. + +## The initial page + +The initial page shows the active stream's total ion chromatogram (TIC). When +a Waters run contains optical detector data, its UV channels are placed above +the TIC on a shared retention-time axis. Multiple UV channels are overlaid; their +legend uses stored wavelengths such as `214 nm`. Select the UV plot and use +**Legend & scales** in the Object inspector to hide, move, or lay out that +legend. + +## Preview and extract a mass spectrum + +Select the LC–MS dataset, then choose **Extract Mass Spectrum** on the +**Analyze** tab. Plotium opens **Dataset tools → Mass spectrometry** in the right +sidebar and activates retention-time range selection. + +Click a TIC or UV chromatogram to show the nearest MS scan under **Scan +preview**. The preview identifies its retention time and native scan number; it +is neither added to the page nor saved as a result, and it is cleared when the +project is reopened. Choose **Extract current scan** to add that scan as a stick +spectrum. + +To extract from a time window, choose a **Method**, select **Select range**, and +drag across a TIC or UV chromatogram. **Extract spectrum** adds the peak-apex +scan, nearest scan, mean spectrum, or summed spectrum to the page. Each +extracted spectrum records its function, time range, and method. It does not +change when the preview cursor moves and appears under **Analysis** in the Data +browser. + +## Extract an ion chromatogram (XIC) + +To create an extracted ion chromatogram (XIC; also called an EIC), open +**Dataset tools → Mass spectrometry** and choose **Select m/z range**. Drag +across the current mass-spectrum plot, confirm the displayed m/z interval and +acquisition stream, then choose **Extract ion chromatogram**. + +The resulting line plot contains one point per scan at its retention time in +minutes. Each point is the sum of intensities within the selected m/z interval, +including both endpoints. The result is saved and does not change when you move +the scan preview or select another acquisition stream. XIC extraction does not +integrate chromatographic peaks or calculate peak area. + +## Switch acquisition streams + +If the run contains several supported MS functions or experiments, use +**Acquisition stream** under **Dataset tools → Mass spectrometry**. For a +Waters run, the initial stream is the first non-reference MS function. Stream +changes, spectrum extractions, and XIC extractions can be undone and redone +with the standard Edit commands. + +## Browse chromatogram channels + +For runs with many chromatogram channels, open **Dataset tools → Mass +spectrometry** from **Extract Mass Spectrum** or the command palette. The +**Chromatogram channels** browser lists a stable count and ordering, with TIC +and BPC ahead of SIM/SRM transitions. Search matches channel names and native +IDs. Structured transitions can also be filtered by precursor m/z, product +m/z, polarity, collision energy, and activation method. Numeric fields accept +an exact value, comparisons such as `>=400`, or a range such as `400..500`. + +Selecting a row replaces the series on the current LC–MS chromatogram plot with +that single channel. Mass-spectrum plots are never retargeted. The choice is +undoable and is saved with the page in the project. Chromatogram-only runs use +the same browser. The panel reports when a run has no plottable channels, no +structured transition metadata, or no channels matching the current filters. +The list stays responsive for large scheduled-MRM runs. + +## Where TIC and BPC values come from + +A file-supplied TIC or BPC chromatogram is marked as a source chromatogram and +is used for its acquisition stream first. When that channel is absent, Plotium +uses each spectrum's file-supplied TIC or base-peak summary when available; +otherwise it derives TIC from the intensity array, or BPC from the largest +non-negative peak. A mixed run can therefore report both source summaries and +array-derived points. In a multi-stream run, a source chromatogram that is not +tied to a stream is kept as its own channel rather than guessed as a +replacement for a stream's TIC or BPC. The field metadata and the Scientific +Summary show which source was used. diff --git a/docs/src/content/docs/guides/multi-panel-figures.md b/docs/src/content/docs/guides/multi-panel-figures.md new file mode 100644 index 00000000..73058654 --- /dev/null +++ b/docs/src/content/docs/guides/multi-panel-figures.md @@ -0,0 +1,260 @@ +--- +title: Multi-panel figures +description: Arrange plots on the board, build figure panels, and size pages for journals. +--- + +## The board + +Plots live on an infinite board organized into pages. Dragging a frame snaps +it to the page grid, margins, and the edges of neighboring frames; snapping +can be toggled off on the **Arrange** tab. The **Arrange** tab also offers +alignment (with two or more frames selected), horizontal / vertical +distribution (three or more), z-ordering, and a *Tidy up frames* command. + +Drag over empty board space to marquee-select page and sheet frames. Hold +`Shift` to add the enclosed frames or `Ctrl` (`Cmd` on macOS) to toggle them. +Dragging the header of any selected frame moves the whole selection; the move +undoes as one step. In the Canvas list, `Shift`-click selects a continuous range +and `Ctrl`-click adds or removes one canvas. `Ctrl` + `A` selects every frame or +canvas according to the area you last used. + +## Scientific summary and notes + +Plotium shows an automatic summary of the plotted data below each page on the +board. On a multi-panel page, shared information appears once and the remaining +details follow the panel labels. + +Open **Canvas settings** to add a page note, or select a Panel and edit its +**Note**. Notes appear after the summary and are not included in exports. Use +**Show summary below page** to show or hide this whole board-only block. + +## Work with figure panels + +Use the Panel commands in the Arrange menu or command palette to build a +multi-panel figure. You can create an empty Panel, turn selected objects into a +Panel, or duplicate, merge, split, dissolve, and delete Panels. Expand a Panel +in Layers to see the objects it contains. + +Click anywhere inside a Panel to select it, then drag to move it or use a corner +handle to resize it together with its contents. `Shift`-click selects multiple +Panels. To work with an object inside a Panel, double-click the Panel or press +`Enter`. Use the breadcrumb above the page or press `Esc` to return to the page. +You can also `Ctrl`/`Cmd`-click an object to select it without entering first. +A resize stops before any plot inside the Panel would lose the room for its +data to its axes, ticks and colour scale. While you move or resize a Panel or a +plot, its plot area also snaps to the plot-area edges of the other plots, so +axes line up even when their tick labels differ in width. + +With **Clip contents to panel** off, content can extend beyond its Panel and +the page; drag the visible content to bring it back. With clipping on, dragging +or resizing content keeps it reachable inside the Panel. Where objects overlap, +the topmost visible object receives the drag. + +To exchange two Panels on the same canvas, drag one over the other and release +when both slots are highlighted. The Panels exchange positions and sizes; their +contents scale with the destination slot. This is one undoable step. Hidden or +locked Panels cannot be swap targets, and multi-Panel drags remain group moves. + +Inside a Panel, objects snap to the Panel edge and to one another. To move an +object into another unlocked Panel, drag it over the Panel and release when the +target is highlighted. You can make the same move in Layers by dragging the +object's row onto the Panel's row. A Stack or Grid Panel rearranges its contents +after the move. Hidden objects remain selectable in Layers; locked objects can +be selected but not edited. + +Use the Panel inspector to control visibility, locking, clipping, labels, and +layout. **Vertical Stack**, **Horizontal Stack**, and **Grid** arrange the +contents using the selected gap, padding, and alignment. **Shared X Stack** +stacks plots on one x axis; see +[Stack plots on a shared x axis](#stack-plots-on-a-shared-x-axis). Automatic panel letters +appear only when a page has more than one visible Panel and follow reading order: +rows from top to bottom, left to right within a row. They update as soon as you +move or add a Panel. Choose **Locked auto** to keep a Panel's current +letter, or clear **Participates in sequence** to leave it unlettered. A letter +placed over an image automatically switches between black and white for +contrast, and a plot's y-axis title moves down when needed so the letter never +sits on it; on a plot too short for that, the plot moves right of the letter +instead. Manual and locked labels remain +visible on a page with one Panel. To hide every letter on a page at once, clear +**Show panel letters** in **Canvas settings**; the letters keep their sequence +and return unchanged when you turn it back on, and axis titles no longer make +room for them while they are hidden. + +Drag a single Panel completely clear of every canvas and keep it outside for +0.5 seconds to prepare a new canvas. The preview shows a progress bar, then a +green outline and **Release to create canvas**. Release to move the whole Panel +onto a new canvas fitted to its current size at that board position. Its contents, +labels, note, and internal layout are retained; the source canvas stays in place. +The move and canvas creation undo together. Returning any part of the Panel to a +canvas resets the timer. Resizing or dragging multiple Panels does not create a +canvas, and pressing `Esc` cancels the gesture. + +## Canvas size + +The active page shows a size chip above its top-left corner — the current +dimensions plus the matched preset (for example *89 × 60 mm · Nature · +Single column*). Click it, use **Canvas Size & Settings…** on the Figure +Ribbon tab, or run any "Canvas Size" entry in the command palette to change +the size. + +The preset list is searchable and grouped: journal figure widths (Nature, +Science, Cell Press, ACS, Elsevier, PNAS, and IEEE, taken from the +publishers' artwork guidelines), paper sizes with a portrait/landscape +toggle, presentation slides, recently used entries, and your own saved +custom sizes. Journal presets fix the page *width* — the height stays +content-driven up to the journal's maximum figure depth, and a warning +appears when the page grows past that depth. + +By default a size change never moves or resizes your content; if objects +end up outside the page, the chip row shows an overflow warning that scales +the content down to fit in one undoable click (font sizes keep their +physical pt values). Turn on **Scale content when applying sizes** to have +presets scale objects together with the page instead. + +Two helpers automate the rest: + +- **Auto height** keeps the width fixed and lets the page height follow the + content's depth, clamped to the journal's maximum. +- When the layout grid asks for two or more panel columns on a + single-column page, a dismissible hint offers the same journal's full + width in one click — it never resizes the page on its own. + +The export dialog pre-selects the matching journal preset, so a page +authored at a column width exports at that width by default. + +## Spacing between panels + +Panels of a multi-panel figure read best when their data areas are evenly +spaced — but each plot reserves a different amount of room for its tick +labels and axis titles, so equal frame gaps rarely look equal. +**Canvas Size & Settings…** sets both the spacing you want and how it is +measured. + +**Minimum spacing** is the gap itself, in the canvas unit; the **Tight** +(2 mm), **Normal** (5 mm), and **Spacious** (10 mm) presets fill in common +values. + +**Spacing basis** decides what that gap is measured between: + +- **Visual** (the default) measures between the data areas of neighboring + plots, counting the tick labels and axis titles that sit between them, so a + panel with a long y title is given the room it needs. The value is a + minimum: the gap you see can end up wider, never narrower, and frames never + overlap. The axis text of neighboring plots always keeps at least 8 pt + apart. +- **Frame** measures between the plot frames and ignores axis text. Frames + then sit exactly the requested distance apart, and the visible space between + data areas varies from pair to pair. + +A plot frame ends at its outermost text, tick, or axis line, with no blank +border of its own. A panel placed against the page edge therefore reaches the +edge of the exported figure, which suits journal sizes where the page is the +finished figure. + +The basis applies wherever Plotium places plots for you — **Apply grid**, and +dragging a plot onto a page that already holds one. + +Dragging a plot onto another page moves it there and re-tiles the destination. +During the drag the plot travels with the pointer, keeping the point you grabbed +under the cursor, and the destination page draws where every plot will sit once +you release. On a page that already holds two or more plots, the whole page +re-tiles into an even grid and the arriving plot takes the cell you are pointing +at. + +If the move leaves the source page empty, Plotium deletes that page as part of the +drop, so the move and the deletion undo together. Hold `Alt` as you release to +keep the empty page instead; the Operation history shows which way `Alt` will flip the +current drop. To keep empty source pages by default, turn on **Keep source canvas +when tiling its last object** in Preferences → General — `Alt` then removes them +for that one drop. + +With the Select tool active, each non-zero page margin is drawn as a dashed +line across the page, showing the content area you are laying out into; a +margin of zero draws no line. Turning on the layout grid adds the cell +outlines, and snapping guides appear in a contrasting color while you drag. + +## Simplify inner axes + +In a grid of panels that share the same axes, repeating the tick numbers and +axis titles on every panel wastes space. **Simplify inner axes** keeps the +x-axis text only on the bottom plot of each column and the y-axis text only on +the leftmost plot of each row. Axis lines and tick marks stay on every panel. + +There are two ways in: + +- Tick **Simplify inner axes** beside **Apply grid** in Canvas settings to + arrange and simplify as one undoable step. The frames are then measured + against the simplified axes, so the panels grow into the space the hidden + text used to take. +- Run **Simplify Inner Axes** — on the Arrange Ribbon tab, in the canvas + right-click Arrange menu, or from the command palette — to simplify plots + that are already in place. It needs at least two plots aligned in a grid; + otherwise the Operation history says what to fix. + +To bring text back on one panel, select it and use **Axes** in the Object +inspector: the **X text** and **Y text** rows toggle **Tick labels** and +**Title** individually, and **Automatic** returns that axis to showing both. + +## Stack plots on a shared x axis + +A Shared X Stack puts two or more plots in one Panel, one above the other, on a +common x axis — for example an XRD pattern above its reference-card sticks, or +several spectra kept apart. Each plot keeps its own y axis, legend and chart +type. + +There are two ways in: + +- Select a Panel that holds two or more plots and choose **Shared X Stack** in + the Panel inspector's **Layout** list, the **Edit ▸ Panel** menu or the + command palette. +- Select several Panels, each holding a plot, and run **Stack with Shared X**. + The Panels are merged into the first one and stacked top to bottom in their + page order, as one undoable step. + +In the stack: + +- The plots fill the Panel's width and touch at their inner edges. The gap + starts at 0 pt; raise **Gap** in the Panel inspector to separate them while + keeping them aligned. +- Plot areas share one left and one right edge, so the y-axis titles line up + whatever the width of the tick numbers. Each plot keeps or omits its own + right y axis, and the right-axis titles of the plots that have one line up + the same way. +- Only the bottom plot draws x tick numbers and the x-axis title, and only the + top plot draws a figure title. Where two plots meet, their x ticks point + inward; the bottom axis keeps the tick direction you chose. A ×10ⁿ multiplier + of a lower plot's y axis moves just inside its top-left corner, and a y tick + number that would sit on the shared edge is left out. +- The plots share one x window. Entering the stack sets an x range covering all + of their data and the top plot's x major tick step on every plot, so the + plots must use the same x scale (linear or logarithmic) first. Every plot follows the bottom plot's x direction: an + NMR spectrum, whose ppm axis runs right to left, stacked above an ascending + plot is drawn left to right. +- Zooming or panning x on one plot moves all of them. Changing the x range, + logarithmic scale, x display unit, thousands separator or major tick step on + one plot changes + every plot in the stack in one undoable step; a change that one of the plots + cannot take, such as a logarithmic axis on an NMR spectrum, is refused. +- The top-to-bottom order is the Panel's content order. Each plot's height sets + its share of the stack: drag a plot's bottom edge on the canvas to make it + taller or shorter than the others. +- The whole stack is one Panel with one panel letter. + +The canvas, the Operation-history checks and every export use the same stacked +geometry. To leave the stack, set the layout back to **Free** or **Vertical +Stack**; each plot then draws its own x axis and x direction again. The shared +x range stays until you set **X range** back to **Auto**. + +## With an AI client + +You can ask an AI client connected to Plotium to do this for you, for example: + +> Make this page 180 × 90 mm and arrange these two panels side by side with +> 4 mm margins and a 5 mm gap. Label them a and b, and show me a preview. Leave +> the other panels alone. + +Plotium changes only the panels you name, and the whole layout is one Undo +step; you can keep editing every plot and text item afterwards. Check the +preview before you agree. See [Access, review and undo](/ai/control-and-review/). + +When the figure is ready, see [Exporting](/guides/exporting/). diff --git a/docs/src/content/docs/guides/organizing-data.md b/docs/src/content/docs/guides/organizing-data.md index a66b1037..50972911 100644 --- a/docs/src/content/docs/guides/organizing-data.md +++ b/docs/src/content/docs/guides/organizing-data.md @@ -3,7 +3,7 @@ title: Organizing data description: Browse datasets and their derived results, and save your work as a project. --- -## The data browser +## The Data browser Switch the Primary Side Bar to **Data** to see a searchable tree of everything in the project. Imported datasets are roots. Slices, projections, @@ -56,8 +56,7 @@ are hidden while browsing data. `Ctrl` + `S` opens the project save options. A `.plotium` project file stores the whole session — imported data, processing, analysis results, and layout — so it reopens exactly where you left off and can be shared as a single file. See -[File formats](/reference/file-formats/) for what the file contains and how -versions are handled. +[Plotium files](/reference/file-formats/) for what the file contains. Saving runs in the background. If you continue editing while it runs, the completed file contains the revision captured when saving began and Plotium diff --git a/docs/src/content/docs/guides/plots-and-charts.md b/docs/src/content/docs/guides/plots-and-charts.md new file mode 100644 index 00000000..da777e1a --- /dev/null +++ b/docs/src/content/docs/guides/plots-and-charts.md @@ -0,0 +1,158 @@ +--- +title: Plots and chart types +description: Turn a table into a plot, choose its columns and chart type, and combine several datasets in one plot. +--- + +Every imported dataset gets its own page with a plot. For spectra and other +instrument data, the plot is ready as soon as the import finishes. A plain table +needs one more step: you tell Plotium which columns to draw. + +## Plot a table + +When you [import a CSV, TSV, or XLSX table](/guides/importing-data/#import-a-table), Plotium opens it in the sheet and +creates a page with an empty line plot for it. To draw the data: + +1. Select the plot on the page. +2. In the Object inspector, open **Data → Curve columns**. +3. Choose the **X** column and the **Y** column. Only numeric columns are + listed. Plotium starts with the first numeric column as X and the second as + Y. +4. Optionally choose a **Y error** column to draw error bars (see + [Error bars](#error-bars)). +5. Press **Apply curve binding**. + +Plotium then reports how many rows were plotted and how many were left out +because a value was missing or not finite. + +To draw more columns in the same plot, open **Data → Add curve**, choose the +source table, its **X**, **Y**, and optional **Y error** columns, pick **Line** +or **Scatter**, and press **Append curve**. The source can be another table in +the project, so a derived table can join the plot it came from. A curve whose +units cannot convert to the plot's existing units is refused. + +To change the columns of an existing curve later, open **Curve columns** again, +choose new columns, and press **Apply curve binding**. Two plots can draw the +same table with different columns; changing one plot does not affect the other. + +Tables that Plotium creates itself, such as region integrals or fit results, +already know their x column and value columns and are plotted right away. If +such a plot draws several default curves, **Curve columns** first offers +**Expand default curves**: choose which curve keeps its identity, then edit each +curve's columns separately. + +## Chart types + +Select a plot made from a table and pick a chart in the **Chart type** gallery +of the Object inspector. **Chart** on the Ribbon's **Figure** tab jumps there +directly: it selects the table's plot and opens the inspector. + +Picking a chart is picking the question it answers: to follow values along an +axis, use **Line**; to compare quantities across categories, **Bar** or +**Grouped bars**; to show how one column's values are distributed, +**Histogram**; to compare distributions across several columns at a glance, +**Box** or **Violin**; to show parts of a whole, **Pie**; and to see an +entire matrix of values at once, **Heatmap** or **Surface 3D**. + +- **Line** — one point series per column against the x axis, with fitted + curves overlaid when present. +- **Bar** — one chosen column as filled bars on the numeric x axis. +- **Grouped bars** — every column side by side, one group per row; check + **Stacked** to pile the columns instead (positive values stack upward, + negative downward). +- **Histogram** — the value distribution of one chosen column. Bins follow the + Freedman–Diaconis rule; uncheck **Auto bins** to set a fixed **Bins** count + between 1 and 512. The count you inherit is the one the automatic rule just + produced, so unchecking the box leaves the histogram as it was. +- **Box** — one box per column: median, quartile box, 1.5 × IQR whiskers, and + individual outlier points. +- **Violin** — one kernel-density silhouette per column with an inner quartile + bar (columns need at least two distinct values; degenerate columns fall back + to raw points). +- **Heatmap** — the whole table as a colormapped matrix with rows reading + top-to-bottom; pick the colormap in the inspector. To set which values the + colours span, see [Heatmap colour range](/guides/heatmap-range/). +- **Pie** — one chosen column as wedges, one per row, labeled with + percentages. Negative and missing rows are excluded. +- **Surface 3D** — the table as a height field in a fixed orthographic view; + adjust the azimuth/elevation angles and the colormap in the inspector. + +Grouped bars, Box, Violin, Heatmap, and Surface 3D use all columns at once; +Bar, Histogram, and Pie read the single column selected next to the gallery. +Every chart renders identically on screen and in SVG/PDF/EMF export. + +**Purpose** and **Claim**, under **Chart › Advanced**, record what the plot +should show (for example a trend or a comparison between groups) and the one +statement it supports. They never change the drawing. An AI client that checks +the figure compares the chart with them and suggests better-fitting forms +without switching on its own. + +## Error bars + +Error bars come from a column that holds the uncertainty of another column. +Choose it as **Y error** in **Curve columns** or **Add curve**. Plotium checks +that the value column and its uncertainty have compatible units. Line, Bar and +unstacked Grouped-bar charts draw them as vertical error bars and widen the +y-axis range so the bars stay fully visible. Under **Line** in the Object +inspector, **Error bars show** records whether the bars are SD, SEM or a 95% CI, +and **Replicates (n)** how many measurements each value summarises; an AI client +asks you for both. + +Tables produced by Plotium's analysis tools already carry their +uncertainties, and an imported table keeps whichever its file describes — a +symmetric ±σ, separate lower and upper errors, or a confidence interval with its +level. To mark an uncertainty column in a CSV or TSV you write yourself, see +[Error-bar columns](/guides/importing-data/#error-bar-columns). + +## Several datasets in one plot + +A single plot can display several 1D datasets — superimposed, or stacked with +adjustable vertical spacing and 3D shear. 2D datasets combine as a color +overlay. Use **Add series…** under **Data** in the Object inspector to add +another dataset to the selected plot. + +To show related plots one above the other on a common x axis instead, use a +[Shared X Stack](/guides/multi-panel-figures/#stack-plots-on-a-shared-x-axis). + +## Align traces + +To align line series along x, select the plot and choose **Align Traces…** in +the **Overlay** group on the **Analyze** tab. The command is available when the +plot contains at least two visible line series with the same x-axis unit. You +can open the same dialog with **Align traces…** under **Data** in the Object +inspector. + +Choose a reference series, then align by **Trace start** (the first finite +plotted sample) or by a peak within an x window. For peak alignment, +**Positive** finds upward peaks, **Negative** finds downward peaks, and +**Magnitude** compares their prominence. Review the **Anchor**, **Delta**, and +**Result** columns before selecting **Apply**. Hidden series, incompatible +series, and series without a usable anchor are listed as **Skipped** and remain +unchanged. + +Alignment preserves the plot's current zoom. To adjust one line manually, edit +its **X shift** under **Data**. Automatic and manual shifts are undoable plot +settings and do not affect source data or data exports. + +## With an AI client + +You can ask an AI client connected to Plotium to do this for you, for example: + +> Import the CSV at /Users/me/data/experiment.csv. Use time as X and current as +> Y, with units s and mA. Create an editable line plot and show me a preview. + +> Delete this duplicate note and this exact curve, but keep the other curve with +> the same name. Show me what will be deleted first. + +Before creating a plot, the AI checks with you what it should show and records +the answer as the plot's **Purpose** and **Claim**. Units are taken only from +what you state, and only the items you name are deleted; source data stays, and +each change is one Undo step. Check the preview before you agree. See +[Access, review and undo](/ai/control-and-review/). + +## Next steps + +- [Axes and ticks](/guides/axes/): ranges, logarithmic and broken axes, a + second y axis. +- [Legends, lines and markers](/guides/legends-and-lines/). +- [Typography, themes and styles](/guides/themes-and-styles/): fonts, text + sizes, and journal themes. diff --git a/docs/src/content/docs/guides/processing.md b/docs/src/content/docs/guides/processing.md index aa9f7ca0..4dba1666 100644 --- a/docs/src/content/docs/guides/processing.md +++ b/docs/src/content/docs/guides/processing.md @@ -1,5 +1,5 @@ --- -title: Processing +title: Processing pipeline description: The ordered processing pipeline — apodization, FFT, phase, and baseline correction. --- @@ -14,7 +14,8 @@ appears moments later. XPS uses its own ordered recipe per spectrum region rather than the NMR pipeline. It contains an energy window, smoothing, and normalization, while charge correction is shared by all regions at one measurement position. See -[XPS](/guides/xps/). +[XPS](/guides/xps/). XRD patterns use the **XRD Processing** card instead; see +[Rigaku powder XRD](/guides/supported-formats/#rigaku-powder-xrd). ## A typical 1D spectrum @@ -225,7 +226,7 @@ button beside it to go back. A step you added yourself has no such default — nothing in the standard pipeline corresponds to it — so it carries no marker and no reset button. Asking for a -reset through [Automation](/guides/automation/) reports that step as skipped +reset through a script or AI client (see [Setting IDs](/reference/settings-ids/)) reports that step as skipped rather than turning a window you chose into *None*. ### While auto-recompute is paused @@ -266,7 +267,8 @@ places the pivot in ppm. φ0, φ1 and the pivot are editable only while **Mode** is *Manual*; under an automatic method each row says which switch to flip first. -Through [Automation](/guides/automation/) these values keep their own units: +When read or set through a script or AI client (see +[Setting IDs](/reference/settings-ids/)), these values keep their own units: phase angles in radians, the pivot as a fraction. For 2D data, the selected automatic method estimates a correction from the trace @@ -313,15 +315,24 @@ To reduce the original complex FID directly to fitted resonance parameters, see [CRAFT for 1D NMR](/guides/craft/). -## Automation interface +## With an AI client -Desktop, CLI and MCP reuse native processing and scientific computation semantics. -See [MCP scientific operations and tasks](/reference/mcp/#scientific-operations-and-tasks) -for operations and parameter schemas, or use CLI -[`tool run`](/reference/cli/#single-step-scientific-operations). Pipeline edits, -schemes, region extraction, diffusion fitting and DOSY/ILT return process-owned -task receipts; wait for termination before consuming results. Background commits -form one Undo step and Redo reuses results. Document edits during computation make -work stale. Diffusion inspection reports SI units and source evidence; result -inspection provides paginated diagnostics. `empty` does not establish a scientific -conclusion. +You can ask an AI client connected to Plotium to change processing for you, for +example: + +> On the spectrum named Sample A only, set the exponential window's LB to 0.3 Hz +> and keep every other step as it is. + +> Apply the recipe `/absolute/path/routine.plotiumproc` to the compatible +> datasets I selected and tell me which ones it skipped. + +Each processing change appears in Plotium when it finishes and is one Undo +step; editing the project while it computes makes the result stale instead of +applying it. Check the recomputed spectrum before you rely on it. See +[Access, review and undo](/ai/control-and-review/). + +## Scripting interface + +Scripts and AI clients run the same processing operations as the desktop; see +[MCP scientific operations](/reference/mcp/scientific/) and +[`plotium-cli tool run`](/reference/cli/#single-step-scientific-operations). diff --git a/docs/src/content/docs/guides/supported-formats.md b/docs/src/content/docs/guides/supported-formats.md new file mode 100644 index 00000000..014b6ce5 --- /dev/null +++ b/docs/src/content/docs/guides/supported-formats.md @@ -0,0 +1,270 @@ +--- +title: Supported formats +description: File formats Plotium can import, by instrument and data type, with what each importer reads and its limits. +--- + +Plotium reads vendor NMR, LC–MS, XRD, XPS, AFM, and electrophysiology formats +directly, with no conversion step. For how to open files and follow an import, +see [Importing data](/guides/importing-data/). + +## Overview + +| Format | Extension | Notes | +| --- | --- | --- | +| JEOL Delta | `.jdf` | Raw and processed 1D/2D and parameter series; experimental support | +| Bruker TopSpin | `fid` / `ser` / `pdata` | Raw and processed 1D/2D; NUS support is experimental | +| Varian/Agilent VnmrJ | `.fid` directory | Raw 1D, 2D with `phase=[1,2]`, or a series varying one parameter | +| JCAMP-DX | `.dx` / `.jdx` / `.jcamp` | 1D frequency-domain NMR spectra | +| Waters MassLynx RAW | `.raw` directory | Validated low-resolution runs, including SQD2 data | +| SCIEX legacy WIFF | `.wiff` + `.wiff.scan` | Single- and multi-sample legacy runs; both files must remain together | +| mzML | `.mzML` | Centroided/profile spectra and TIC, BPC, SIM, or SRM chromatograms with 32-bit or 64-bit arrays | +| Rigaku powder XRD | `.rasx`, FI `.raw`, RAS_RAW `.txt` | Diffraction pattern, acquisition metadata, and attenuation when available | +| VAMAS XPS | `.vms` | ISO 14976 `NORM` / `REGULAR` XPS blocks, including multiple measurement positions and regions | +| CasaXPS text | `.txt` | Structured eight-line export with raw spectrum, background, envelope, components, and fitted parameters | +| Bruker NanoScope AFM | `.spm` / `.pfc` | Images, force curves, force-volume and PeakForce Capture cubes | +| Axon Binary Format 2 | `.abf` | int16/float32, multiple channels and sweeps, embedded DAC/epoch stimuli | +| Tabular data | `.csv`, `.tsv`, `.txt`, `.xlsx` | Column types and empty cells preserved; one table per XLSX worksheet | +| Origin project (experimental) | `.opj`, `.opju` | Worksheets from two verified OPJ profiles; graphs are not imported, and `.opju` is detection-only | +| Zip archive | `.zip` | An archived dataset folder | +| Plotium project | `.plotium` | Full project: data, processing, and layout; see [Plotium files](/reference/file-formats/) | + +## NMR + +Plotium supports 1D and 2D NMR, including series with a parameter axis. +Choose the input that matches the data you want to work with: + +- **Bruker:** select an experiment directory for raw data, or a spectrum inside + `pdata` for processed data. If a directory contains ambiguous candidates, + select a specific file or processing directory. States 2D (`FnMODE=4`) is supported. + Processed spectra retain the real and imaginary components present in the files. +- **JEOL:** select a `.jdf` file containing a supported raw or processed acquisition. +- **JCAMP-DX:** ordinary XYDATA spectra with one intensity per coordinate, + version 5.00 or 5.01, are supported with Hz or ppm axes. LINK, NTUPLES, and + peak tables are not supported. + +Missing nucleus, frequency-reference, or digital-filter-delay information remains +unknown. Hz spectra can be displayed directly, but some analyses need additional +calibration. Raw data with unknown filter delay initially appears as an FID; +see [Group-delay correction](/guides/processing/#group-delay-correction) to view +an uncorrected spectrum, and [calibration requirements](/guides/processing/#check-calibration-before-analysis) +before choosing an analysis. Unknown coordinates or unsupported data arrangements +produce an import error or diagnostic. + +JEOL and Bruker NUS support is experimental and does not cover every instrument +or acquisition setting. Check import diagnostics and compare results with a trusted +reference before relying on an unfamiliar acquisition type. If a 2D NUS +acquisition lacks its sampling table, see +[Supplying a missing NMR sampling table](/guides/importing-data/#supplying-a-missing-nmr-sampling-table). + +DOSY, T1, and T2 experiments are detected automatically from the acquisition +parameters and get their own analysis tools; see +[Pseudo-2D analysis](/guides/pseudo-2d/) and +[DOSY diffusion analysis](/guides/dosy/). Missing diffusion parameters can be +supplied in the **DOSY** task card after import. + +Saving a `.plotium` project retains the imported NMR components, sampling order, +source information, warnings, and processing settings. Reopening recomputes spectra +from the saved settings without requiring the original vendor files. + +### Varian/Agilent VnmrJ + +Choose **Open Folder…** and select the `.fid` directory, or choose **Open +File…** and select the `fid` file inside it. Keep the `fid` and `procpar` files +together in the same directory. + +Supported acquisitions are raw 1D, a series varying one ungrouped parameter, +and 2D with `phase=[1,2]`. Samples may be big-endian 16-bit integers, 32-bit +integers, or 32-bit floating-point values. Grouped or multiple parameter +arrays, other phase orders, Varian NUS, more than two dimensions, and processed +spectra are unsupported. Import stops if the recorded dimensions or component +arrangement do not match the data. + +## Mass spectrometry + +All three LC–MS formats import into the same dataset and chart workflow. For +extracting spectra and ion chromatograms after import, see +[Mass spectrometry](/guides/mass-spectrometry/). + +### Waters MassLynx RAW + +Open or drop the `.raw` directory itself; its internal files are not treated as +separate datasets. Plotium imports its supported MS functions and optical +detector channels. Temperature, pressure, and other readable auxiliary channels +remain in the dataset but are not plotted by default. + +Plotium supports the low-resolution MassLynx encoding validated with SQD2 runs. +If a required MS function uses another encoding, the import stops and +identifies the function and instrument. Unsupported optional or reference +functions produce an import warning when the rest of the run is readable. + +### SCIEX legacy WIFF + +Open or drop the `.wiff` file. Keep the paired file with `.scan` appended to +the full filename beside it, for example `sample.wiff` and +`sample.wiff.scan`; the `.wiff.scan` file is never imported as a separate +dataset. SCIEX Analyst, SCIEX OS, or ProteoWizard does not need to be installed. + +Plotium imports native scan IDs, retention times, m/z and intensity arrays, +precursor details when available, polarity, instrument and acquisition-start +metadata, and a separate TIC for each of the 11 verified experiment slots. +Spectra are grouped into independent sample/experiment acquisition streams and +retain cycle order, including zero-TIC and empty DDA slots; experiments are not +merged or interpolated in time. Duplicate sample names remain separate and are +displayed with stable suffixes such as `yjs_10ppm #1` and `yjs_10ppm #2`. + +Only the validated legacy layout is supported. Plotium rejects a missing +companion, an empty container, or an unrecognized WIFF layout rather than +creating a partial dataset. Encrypted or newer `.wiff2` and `.timeseries.data` +acquisitions are not supported; convert them to mzML before opening them in +Plotium. + +### mzML + +Open or drop a `.mzML` file. Spectra are grouped by MS level and polarity, +while each scan retains acquisition-function metadata such as its mzML +instrument configuration, preset scan configuration, and filter string when +present. Scan times recorded in seconds or minutes are displayed in minutes. +Plotium also imports file-supplied TIC, BPC, SIM, and SRM chromatograms, +including chromatogram-only acquisitions. Transition precursor/product m/z, +polarity, collision energy, and activation method are retained when present. + +For MS2 and higher spectra, Plotium separately retains the precursor spectrum +reference, selected-ion m/z, selected-ion intensity and charge, isolation-window +target and offsets, collision energy, and activation method. This distinction +preserves DIA isolation targets even when a selected ion is not present. Plotium +stores one precursor and one selected ion per spectrum; an import warning +identifies spectra with additional values and states that only the first was +retained. + +The importer accepts little-endian 32-bit and 64-bit floating-point m/z, time, +and intensity arrays with no compression or zlib compression. Numpress, +big-endian arrays, and spectra or chromatograms without their required arrays +stop the import with an error. + +## Rigaku powder XRD + +Open the `.rasx` file when it is available. Plotium reads the measured 2theta, +intensity, and attenuation columns together with the instrument name, X-ray +target, Kalpha1 wavelength, tube voltage/current, scan step, and scan speed. +The initial page is an XRD pattern. To process it, select the pattern and choose +**Processing** on the **Process** tab. The **XRD Processing** card that opens +provides optional SNIP background subtraction, Savitzky-Golay smoothing, and +normalization by maximum intensity or integrated area; these settings and the +original observations are saved in the Plotium project. The NMR pipeline steps in +[Processing pipeline](/guides/processing/) do not apply to XRD. + +Rigaku `FI`-layout `.raw` files and profile `.txt` exports whose header identifies +`RAS_RAW` also open as XRD. The binary reader retains the scan ruler, intensity, +X-ray target, Kalpha1 wavelength, tube voltage/current, and scan speed. Other +`.raw` signatures are rejected explicitly because the extension is shared by +incompatible vendor formats. Other `.txt` files keep the normal table-import +preview, so a generic numeric table is not silently reclassified. + +## XPS + +VAMAS `.vms` support is limited to content-signed ISO 14976 `NORM` / +`REGULAR` XPS blocks with regular energy rulers. One file remains one +experiment with stable measurement and region identities. Plotium retains native +energy, counts, CPS, photon energy, dwell time, sweeps, position, acquisition +conditions, and free metadata. Non-XPS blocks can be skipped with warnings only +when their declared block boundaries are trusted; malformed XPS payloads reject +the file. Ordinate extrema are metadata rather than data points, and ordinate +labels plus signal mode determine whether pulse counts are converted to CPS. + +CasaXPS `.txt` files are recognized from their eight-line structured header, +not from the extension alone. Their source arrays and fitted parameters are +stored as an imported result. Other `.txt` files continue through table import. +See [XPS](/guides/xps/) for energy conversion, processing, and fitting. + +## Bruker NanoScope AFM + +Plotium imports NanoScope `.spm` images, force curves, and force-volume grids, +plus PeakForce Capture `.pfc` data cubes. Image channels plot as maps at the +recorded scan size, in the file's physical units, with the aspect ratio locked. +Force curves plot as separate approach and retract branches; when the file +records a deflection sensitivity, the vertical axis is deflection in +nanometres, otherwise the curve stays in the unit stored in the file. Plotium +shows the acquired data as is — it does not infer a contact point, indentation, +or modulus, and does not fit a contact-mechanics model. + +A PeakForce Capture file usually has an AllImages `.spm` export saved beside +it. Plotium finds that companion, checks that its image grid matches the force +grid, and imports the pair as one dataset; opening a folder also imports the +pair once, not as two datasets. The default canvas places the channel map +beside a force curve from the centre pixel of the grid. If no companion is +found, or its grid does not match, the `.pfc` file still imports with its +force curves alone. + +PeakForce Capture curves are the per-pixel signals as acquired. Derived QNM +maps such as modulus arrive as their own image channels; Plotium does not +recompute them from the curves. + +## Electrophysiology (ABF2) + +Plotium reads ABF 2.x files with int16 or float32 samples, multiple channels +and sweeps, and embedded DAC/epoch stimuli. ABF1 files and compressed ABF2 data +are not supported; re-export the recording as uncompressed ABF2 from your +acquisition software. The file picker accepts several ABF files at once, and +each file's immediate parent folder becomes its initial, editable cell ID. +For sweeps, filtering, time-window statistics, stimulus handling, and IV +analysis, see [Electrophysiology](/guides/electrophysiology/). + +## Tables + +CSV, TSV, delimited `.txt`, and XLSX files, as well as tables pasted from the +clipboard, go through the table import preview. Column typing, Origin CSV +headers, and XLSX worksheets are described in +[Import a table](/guides/importing-data/#import-a-table). + +## Origin projects (experimental) + +Origin `.opj` and `.opju` files can be chosen from both **Open File…** and +**Import Table…**; both routes identify the format from its content, not only +its extension. Worksheets from a supported `.opj` open in the +[table import preview](/guides/importing-data/#import-a-table). Origin does not +need to be installed, launched, or called during import. + +Successful import is limited to two exact, content-detected OPJ producer profiles: + +- Origin 7.0552 (`CPYA 4.2673 build 552`) imports verified `f64`, `f32`, signed + `i32`, signed `i16`, fixed-width ASCII text, mixed numeric/text cells, nulls, + and nonzero row offsets. Project parameters and notes are retained as source + metadata. +- Origin 9.51 build 195 W64 (`CPYA 4.3268 build 195 W64`) imports worksheet + names, column names, numeric `f64` values, nulls, and validated empty columns. + This profile does not yet import text cells, project parameters, or notes. + +Compatibility is limited to these profiles as tested; it does not extend to +other files merely because the extension or major Origin version is the same. + +Plotium preserves validated Origin window or group names and column names. Each +supported window is represented as one table under the generated worksheet +name `Sheet1`; original worksheet labels are not decoded. Mixed Origin 7 +columns are retained as text, and unequal column lengths are padded with nulls. +Long names, units, comments, column designations, dates, categorical values, +and unverified code pages are not guaranteed to import. + +An `.opju` file is recognized from its content signature, but `.opju` is not +importable in this release and Plotium creates no partial result. + +Unsupported content includes graphs, formulas, scripts, analysis +recomputation, saved analysis results as executable analyses, matrices, +embedded objects, modern OPJ text cells, non-ASCII text without a verified code +page, encrypted or protected projects, unverified OPJ versions or profiles, and +unverified OPJU containers. For the supported Origin 9.51 profile, Plotium stops +after the validated window list and warns that the remaining project objects +were not imported. + +Plotium never guesses an import. Corrupt or truncated files, files above the +current 128 MiB input cap, extension/signature mismatches, and malformed or +otherwise unsupported files produce a clear error before any table is +committed. Inside an otherwise supported OPJ, an unsupported worksheet column +may be omitted, or an unsupported non-table object skipped, only when each is +independently framed and its outer boundaries are trusted. Plotium shows a +warning for every such omission, so an imported worksheet may contain only the +supported columns. If framing is ambiguous, Plotium rejects the file rather +than shifting data. + +## Zip archives + +A `.zip` file is opened as an archived dataset folder. diff --git a/docs/src/content/docs/guides/tables.md b/docs/src/content/docs/guides/tables.md index 8552cdaa..79cf08c2 100644 --- a/docs/src/content/docs/guides/tables.md +++ b/docs/src/content/docs/guides/tables.md @@ -90,84 +90,46 @@ instead of guessing which row is which. These transforms can also run unattended as part of a batch job — see [Automation](/guides/automation/) and [the command line](/reference/cli/). -## Chart types - -Select a plot made from a table and pick a chart in the **Chart type** gallery -of the Object inspector. **Chart** on the Ribbon's **Figure** tab jumps there -directly: it selects the table's plot and opens the inspector. - -Picking a chart is picking the question it answers: to follow values along an -axis, use **Line**; to compare quantities across categories, **Bar** or -**Grouped bars**; to show how one column's values are distributed, -**Histogram**; to compare distributions across several columns at a glance, -**Box** or **Violin**; to show parts of a whole, **Pie**; and to see an -entire matrix of values at once, **Heatmap** or **Surface 3D**. - -- **Line** — one point series per column against the x axis, with fitted - curves overlaid when present. -- **Bar** — one chosen column as filled bars on the numeric x axis. -- **Grouped bars** — every column side by side, one group per row; check - **Stacked** to pile the columns instead (positive values stack upward, - negative downward). -- **Histogram** — the value distribution of one chosen column. Bins follow the - Freedman–Diaconis rule; uncheck **Auto bins** to set a fixed **Bins** count - between 1 and 512. The count you inherit is the one the automatic rule just - produced, so unchecking the box leaves the histogram as it was. -- **Box** — one box per column: median, quartile box, 1.5 × IQR whiskers, and - individual outlier points. -- **Violin** — one kernel-density silhouette per column with an inner quartile - bar (columns need at least two distinct values; degenerate columns fall back - to raw points). -- **Heatmap** — the whole table as a colormapped matrix with rows reading - top-to-bottom; pick the colormap in the inspector. -- **Pie** — one chosen column as wedges, one per row, labeled with - percentages. Negative and missing rows are excluded. -- **Surface 3D** — the table as a height field in a fixed orthographic view; - adjust the azimuth/elevation angles and the colormap in the inspector. - -Grouped bars, Box, Violin, Heatmap, and Surface 3D use all columns at once; -Bar, Histogram, and Pie read the single column selected next to the gallery. -Every chart renders identically on screen and in SVG/PDF/EMF export. - -## Plotting from tables - -Error bars come from a column holding the uncertainty of another column. Tables -produced by Plotium's analysis tools already carry these, and an imported table -carries whichever its file describes — a symmetric ±σ, separate lower and upper -errors, or a confidence interval with its level. To add error bars to your own -data, put a column named `_sigma` immediately after a y column in a CSV or -TSV, holding each point's uncertainty (zero or positive); on import Plotium links -it to that y column as a symmetric standard deviation. Before plotting, Plotium -checks that a value column and its uncertainty share compatible units. Line, -Bar, and unstacked Grouped-bar charts draw these as vertical error bars and -widen the y-axis range so the bars stay fully visible. - -To fit x-y values with a mathematical model, choose **Fit Curves** in the **Curve Fit** group of -the **Analyze** tab. A Curve Fit task card opens at the upper-right of the -canvas: choose a model, fit every curve or one selected curve, then choose -**Run Fit**. See [Curve fitting](/guides/curve-fitting/) for the built-in -models, custom models, shared (global) parameters, weighting and robust-loss -options, and fit diagnostics. The fitted curves and their results stay with the -table. -Use **Export Data…** and choose **Curve-fit parameters** to export parameters, -diagnostics, covariance, and point predictions/residuals. -A completed fit records exactly which rows it used, and which it excluded and -why, so later edits to the table cannot quietly change which points the result -was based on. The curve-fit export lists those included and excluded rows. - -**Export Data…** can also export the complete table as CSV, TSV, XLSX, or -clipboard TSV. Empty cells stay empty, while `NaN`, `+Inf`, and `-Inf` are -written as those literal tokens because they are real values, not blanks. Each -of these formats carries the table's column types, units, and error-bar -relationships alongside the data — in the `.plotium-schema.json` companion for -CSV and TSV, on a hidden worksheet for XLSX, or in the clipboard payload for -Copy TSV — so a `_sigma` column name is only needed when you hand-build a -file that has none. - -**Peak Fit** is a separate tool: use it when a plotted trace contains -overlapping spectral peaks that need to be deconvolved — see -[Choosing an analysis tool](/guides/choosing-a-tool/). - -To compare groups, test correlations, check normality, or run ANOVA on a -table's columns, choose **Statistics** in the **Analyze** tab. See -[Statistics](/guides/statistics/). +## Exporting a table + +**Export Data…** exports the complete table as CSV, TSV, XLSX, or clipboard +TSV. Empty cells stay empty, while `NaN`, `+Inf`, and `-Inf` are written as +those literal tokens because they are real values, not blanks. CSV, TSV and +XLSX carry the table's column types, units, and error-bar relationships +alongside the data (clipboard TSV does too on Windows), so the table can be +imported again without losing them; see +[Plotium files](/reference/file-formats/#table-schema-companions). For export +options, see [Export numerical data](/guides/exporting/#export-numerical-data). + +## Analyzing a table + +- To plot a table's columns and pick a chart type, see + [Plots and chart types](/guides/plots-and-charts/), including + [error bars](/guides/plots-and-charts/#error-bars). +- To fit x-y values with a mathematical model, choose **Fit Curves** in the + **Curve Fit** group of the **Analyze** tab; see + [Curve fitting](/guides/curve-fitting/). The fitted curves and their results + stay with the table. A completed fit records which rows it used, and which it + excluded and why, so later edits to the table cannot quietly change the points + the result was based on. To export parameters, diagnostics, covariance, and + point predictions/residuals, use **Export Data…** and choose **Curve-fit + parameters**; the export lists the included and excluded rows. +- To compare groups, test correlations, check normality, or run ANOVA, choose + **Statistics** in the **Analyze** tab; see [Statistics](/guides/statistics/). +- To separate overlapping spectral peaks in a plotted trace, use **Peak Fit** + instead; see [Choosing an analysis tool](/guides/choosing-a-tool/). + +## With an AI client + +You can ask an AI client connected to Plotium to change table data for you, for +example: + +> Change only this source cell, show which derived tables are out of date, then +> refresh this table. Keep my colors, axis ranges and layout. + +> Make a new table from this one with a column equal to current × 2, keep only +> rows where time is not 0, and sort by time descending. + +Editing a cell and refreshing a derived table are separate Undo steps, and your +plot styling stays. A derived table is a new table; its source is not changed. +Check the refreshed values before you rely on them. See [Access, review and undo](/ai/control-and-review/). diff --git a/docs/src/content/docs/guides/themes-and-styles.md b/docs/src/content/docs/guides/themes-and-styles.md new file mode 100644 index 00000000..29e84865 --- /dev/null +++ b/docs/src/content/docs/guides/themes-and-styles.md @@ -0,0 +1,108 @@ +--- +title: Typography, themes and styles +description: Set fonts and text sizes for every plot, apply canvas themes such as Nature, and save reusable styles. +--- + +Plotium styles plots for print automatically. New dataset pages start at the +89 × 60 mm single-column size, so a plot spanning the page already shows text at +its printed journal size; assemble multi-panel figures on a wider page later, +keeping each panel at its natural size. + +## Fonts + +By default, figure text is set in Arial on the canvas and in every export +format. Without Arial, Plotium uses Helvetica or a metric-compatible sans such +as Liberation Sans. SVG files name the typeface, so a vector editor keeps the +Arial that Nature-portfolio journals ask for. + +**Font** in the **Figure typography** section switches the text inside every +plot — tick labels, axis titles, the figure title, legends, colour scales and +plot annotations — between *Arial* (the default), *Helvetica* and *Times New +Roman*. Helvetica is drawn as Helvetica on macOS; Windows and Linux draw it with +Arial or Liberation Sans, which have the same character widths, and SVG files +still name Helvetica first. Without Times New Roman, Plotium uses a +metric-compatible serif such as Liberation Serif. **Font weight** (an advanced +control) sets that text *Regular* or *Bold*. Text boxes and panel letters on the +canvas keep their own Arial styling. Both settings travel with themes and saved +styles; the built-in themes set Arial Regular. + +## Figure typography + +**Figure typography** in the Figure Ribbon tab's **Style** group opens the +document-wide typography section; **Figure Typography…** in the command palette +shows the same section in its own window with a **Reset to defaults** button. +Either sets the text sizes (tick labels, axis titles, the figure title, and +legends) for every plot at once, in absolute points — a document-level style, so +resizing a panel never changes its type size. These sizes accept 1 to 72 pt. +Legends default to 7 pt. + +The same section's advanced controls set every plot's axis strokes and ticks; +see [Tick marks and axis lines](/guides/axes/#tick-marks-and-axis-lines). + +**Figure typography** in the Object inspector holds the same tick-label size as +**Tick-label size**, plus **Legend size** and **Legend text color**. Changing a +value in either surface changes the one document-wide value. Because it belongs +to the document rather than to a plot, the section is shown whatever is +selected — including when nothing is. + +## Canvas themes + +To apply a theme to the active canvas, choose **Paper**, **Nature**, **Dark** or +**Vibrant** in the **Style** group of the **Figure** tab, or pick it under +**View ▸ Canvas Theme**. Applying a theme is one undoable step. + +Canvas themes carry matching sizes — the Presentation Dark theme, for example, +enlarges the axis text for slides. + +The **Nature** theme follows the Nature Portfolio final-artwork guidelines: 7 pt +text with strokes scaled to it — 0.3 pt axes, ticks, bar outlines and new +reference lines and arrows, 0.5 pt line series — outward 3 pt ticks, 3 pt +markers without an outline and the colour-blind-safe Okabe–Ito palette. Marker +outlines you drew by hand stay. Its sizes assume a Nature column width, so +applying it to a canvas that matches none of the Nature size presets (89, 136 or +183 mm wide) adds a note to the status bar naming those widths; the canvas keeps +its size. A canvas already at one of those widths without a size preset takes on +that Nature preset, so the export precheck applies Nature's minimums (5 pt text, +0.25 pt lines). + +The line widths and marker sizes stay when you switch to a theme that does not +set them. + +## Values you set by hand + +Values you set by hand — in the Object inspector, by scrolling over a control or +by dragging a legend — are kept for you. Any theme leaves them alone: curve and +marker colours, line widths, marker sizes and outlines, text and shape colours +and the figure typography. The status bar says how many it kept. An AI client +connected to Plotium also skips them unless you ask it to change them; values +the AI sets are not counted as yours. Resetting a value (or double-clicking a +dragged legend) hands it back to the theme. + +## Saved styles + +**Save Canvas Style…** (View ▸ Canvas Theme, or **Save Style** in the Figure +Ribbon tab's Style group) saves the active canvas's look as a named style: +background, text colour and size, figure typography (including the font and font +weight), axis and tick strokes, curve colours with their marker fills, outlines +and hollow setting, line width and marker size. **Canvas Styles…** lists saved +styles to apply to the active canvas or delete. Applying a style is one undoable +step. To change a style, apply it, adjust the canvas and save it again under the +same name. + +Styles are stored as `.plotiumstyle` files in the `styles` folder of Plotium's +configuration directory, so they can be copied to another computer: on macOS +`~/Library/Application Support/plotium/styles`; for other platforms see +[Where Plotium keeps its settings](/getting-started/installation/#where-plotium-keeps-its-settings). + +## With an AI client + +You can ask an AI client connected to Plotium to do this for you, for example: + +> Apply the Nature theme to this canvas and show me a preview. Keep the colours +> I set by hand. + +> Apply my saved style Group meeting to every canvas in this project. + +Values you set by hand are kept unless you ask the AI to change them, and each +change is one Undo step. Check the preview before you agree. See +[Access, review and undo](/ai/control-and-review/). diff --git a/docs/src/content/docs/index.mdx b/docs/src/content/docs/index.mdx index 1f7969ce..e4ea75ce 100644 --- a/docs/src/content/docs/index.mdx +++ b/docs/src/content/docs/index.mdx @@ -1,13 +1,17 @@ --- title: Plotium -description: A desktop application for scientific data analysis and figure preparation. +description: A desktop application for scientific data analysis and figure preparation, on its own or with an AI client. template: splash hero: - tagline: Import, process, analyze, and publish scientific data — all in one desktop application. + tagline: Import, process, analyze, and publish scientific data in one desktop application, by hand or together with your AI client. actions: - text: Get started link: /getting-started/installation/ icon: right-arrow + - text: Connect an AI client + link: /ai/connect/ + icon: right-arrow + variant: secondary - text: View on GitHub link: https://github.com/nmrtist/plotium icon: external @@ -18,9 +22,15 @@ import { Card, CardGrid } from '@astrojs/starlight/components'; - Read NMR data from JEOL Delta (`.jdf`) and Bruker TopSpin, - patch-clamp recordings (ABF2), and tabular data from CSV or Excel — - no conversion step. + Read NMR (JEOL, Bruker, Varian/Agilent, JCAMP-DX), LC–MS (Waters, + SCIEX WIFF, mzML), powder XRD, XPS, AFM, and patch-clamp (ABF2) files, + plus CSV, TSV, Excel, and Origin tables, with no conversion step. + See [supported formats](/guides/supported-formats/). + + + Connect Claude Desktop or another MCP client and ask it to import data, + build and style plots, and lay out panels. Its edits appear on your + board, can be previewed first, and can be undone. Build an ordered processing pipeline: apodization, FFT, phase and diff --git a/docs/src/content/docs/reference/cli.md b/docs/src/content/docs/reference/cli.md index ef6a884a..5c7c0a8d 100644 --- a/docs/src/content/docs/reference/cli.md +++ b/docs/src/content/docs/reference/cli.md @@ -38,7 +38,7 @@ is not the number of acquired observations. A combination of time, frequency, or parameter axes is reported as `domain: "mixed"`. Check reported warnings before processing. Missing calibration or digital-filter -delay remains unknown; see [NMR format limitations](/reference/file-formats/#nmr-data-and-projects). +delay remains unknown; see [NMR format limitations](/guides/supported-formats/#nmr). Processing failures identify the failing step and return a nonzero exit code. `process` is the convenience path for a single import, one @@ -128,9 +128,10 @@ retains the declaration without changing the vendor files. plotium-cli batch --workflow --manifest ``` -`batch` runs a workflow file — the same JSON the in-app Automation window -uses, so the easiest way to get one is to build and validate it there first, -then hand the file to the command line for unattended runs. +`batch` runs a workflow file, the same JSON the in-app Automation window +runs. Write the file by hand (see [Workflow file anatomy](#workflow-file-anatomy)), +check it with **Validate** in the Automation window if you like, then hand it to +the command line for unattended runs. Every run writes a run-manifest record of what happened: the workflow and its hash, the Plotium version, the targets each step ran on, and every step's @@ -176,9 +177,9 @@ use `7`. Any other nonzero code indicates an internal error worth reporting. ## Workflow file anatomy -A workflow (`plotium.workflow.v1`) is a JSON graph of steps with no loops. You -rarely write one from scratch — the app produces them — but the format is -plain and editable. A minimal import → process → export workflow: +A workflow (`plotium.workflow.v1`) is a JSON graph of steps with no loops. The +app does not generate workflow files, so start from an example like this +minimal import → process → export workflow and edit it: ```json { diff --git a/docs/src/content/docs/reference/command-palette.md b/docs/src/content/docs/reference/command-palette.md index cb48c1a3..e55c2de8 100644 --- a/docs/src/content/docs/reference/command-palette.md +++ b/docs/src/content/docs/reference/command-palette.md @@ -87,11 +87,11 @@ Settings: thickness` all reach it. - **Tick-label size** in the Object inspector's **Figure typography** section. `font size`, `tick size`, `points` and `figure typography` reach it. See - [Layout and export](/guides/layout-and-export/). + [Typography, themes and styles](/guides/themes-and-styles/#figure-typography). - **Window**, **LB** and **GB** on an apodization step in Processing. `apodization`, `window function`, `exponential`, `gaussian`, `LB`, `line broadening`, `GB` and `gaussian broadening` reach them. See - [Processing](/guides/processing/). + [Processing pipeline](/guides/processing/). - **Raster resolution**, the pixel density bitmap exports start from, on the **Export** page of Preferences. `export DPI`, `bitmap DPI`, `bitmap resolution` and `raster resolution` reach it. It stays available whatever is diff --git a/docs/src/content/docs/reference/file-formats.md b/docs/src/content/docs/reference/file-formats.md index adcc9ec1..f9436e77 100644 --- a/docs/src/content/docs/reference/file-formats.md +++ b/docs/src/content/docs/reference/file-formats.md @@ -1,21 +1,25 @@ --- -title: File formats -description: Native Plotium files, imported formats, and their compatibility boundaries. +title: Plotium files +description: The files Plotium writes itself — projects, processing recipes, styles, fit models, workflows, run records, and table schema companions. --- +This page covers the files Plotium creates. For the instrument and table +formats it reads, see [Supported formats](/guides/supported-formats/). + ## `.plotium` projects A `.plotium` file stores the whole session in one file: imported data, -processing pipelines, analysis results, board layout, any saved workflows, and -a record of every automation run. That makes it self-contained — copy it to -another machine or send it to a colleague and it opens exactly as you saved -it, with no side files to remember. Keeping your original instrument data is -still good practice, as with any analysis software. +processing pipelines, analysis results, board layout, embedded images, any saved +workflows, and a record of every automation run. That makes it self-contained — +copy it to another machine or send it to a colleague and it opens exactly as you +saved it, with no side files to remember. Keeping your original instrument data +is still good practice, as with any analysis software. **Preferences → General → Project backup copies** keeps previous saves as hidden files beside the project, so an accidental overwrite can be recovered. Automatic crash-recovery checkpoints are separate internal files. They are -updated only after new edits and are not portable project copies. +updated only after new edits and are not portable project copies. See +[Saving projects](/guides/organizing-data/#saving-projects). For homonuclear 2D review, the project stores cross-peak marks, reciprocal pair links, and each mark's review state. The pinned cursor position and @@ -28,30 +32,10 @@ you on reopening if the map no longer matches the data the project reconstructs. The contour drawing is not stored — Plotium redraws it from the saved map when the project opens. -## Embedded images - -Plotium accepts PNG, JPEG, TIFF, WebP, and BMP images and stores them in the -`.plotium` project. Duplicating an image does not duplicate its stored source, but -each copy can have its own crop, rotation, opacity, fit, and interpolation. -Export and clipboard output sample the embedded pixels and preserve those -settings, Panel clipping, and z-order. SVG output embeds image data and never -depends on the original local path. - -SVG is not supported. For an animated PNG or WebP, **Add Images…** reports that -the image is animated; use **Add Animated Image First Frame…** to display its -first frame. **Add Images Without Metadata…** converts the pixels to PNG before -storing them. - -Plotium rejects images above 500 megapixels or an estimated 2 GiB when decoded. -It asks for confirmation above 100 megapixels or 512 MiB. For a multi-page TIFF, -**Add Images…** imports the first page and **Add All TIFF Pages…** imports every -page that Plotium can read. Each imported page can be edited independently. - -Plotium checks every embedded image when a project opens. A missing, damaged, or -mismatched resource produces a diagnostic and a replaceable placeholder -without discarding the page or image item. Plotium does not silently save that -degraded state. Publication export blocks by default; an explicit Export-dialog -option can emit a labelled placeholder for review. +Images added to a page are stored inside the project. Duplicating an image does +not duplicate its stored source. Plotium checks every embedded image when a +project opens; a missing or damaged one becomes a replaceable placeholder. See +[Images in figures](/guides/images/). ## `.plotiumproc` processing recipes @@ -59,63 +43,22 @@ A `.plotiumproc` file stores one processing pipeline, without any data — save recipe once and apply it to a whole series of similar experiments, on any machine. See [Recipes and templates](/guides/templates/). -## NMR data and projects - -Plotium supports 1D and 2D NMR, including series with a parameter axis. -Choose the input that matches the data you want to work with: - -- **Bruker:** select an experiment directory for raw data, or a spectrum inside - `pdata` for processed data. If a directory contains ambiguous candidates, - select a specific file or processing directory. States 2D (`FnMODE=4`) is supported. - Processed spectra retain the real and imaginary components present in the files. -- **JEOL:** select a `.jdf` file containing a supported raw or processed acquisition. -- **JCAMP-DX:** ordinary XYDATA spectra with one intensity per coordinate, - version 5.00 or 5.01, are supported with Hz or ppm axes. LINK, NTUPLES, and - peak tables are not supported. - -Missing nucleus, frequency-reference, or digital-filter-delay information remains -unknown. Hz spectra can be displayed directly, but some analyses need additional -calibration. Raw data with unknown filter delay initially appears as an FID; -see [Group-delay correction](/guides/processing/#group-delay-correction) to view -an uncorrected spectrum, and [calibration requirements](/guides/processing/#check-calibration-before-analysis) -before choosing an analysis. Unknown coordinates or unsupported data arrangements -produce an import error or diagnostic. - -JEOL and Bruker NUS support is experimental and does not cover every instrument -or acquisition setting. Check import diagnostics and compare results with a trusted -reference before relying on an unfamiliar acquisition type. - -Saving a `.plotium` project retains the imported NMR components, sampling order, -source information, warnings, and processing settings. Reopening recomputes spectra -from the saved settings without requiring the original vendor files. - -## Varian/Agilent VnmrJ raw NMR - -Select a `.fid` directory containing both `fid` and `procpar`, or the `fid` file -inside it. Supported acquisitions are raw 1D, a series varying one ungrouped -parameter, and 2D with `phase=[1,2]`. Samples may be big-endian 16-bit integers, -32-bit integers, or 32-bit floating-point values. - -Grouped or multiple parameter arrays, other phase orders, Varian NUS, more than -two dimensions, and processed spectra are unsupported. Import stops if the -recorded dimensions or component arrangement do not match the data. - -## SCIEX legacy WIFF - -Plotium reads a legacy `.wiff` OLE metadata container together with the -`.wiff.scan` payload whose name is formed by appending `.scan` to the complete -`.wiff` filename. The importer is pure Rust and does not require SCIEX Analyst, -SCIEX OS, or a ProteoWizard SDK installation. - -Only the validated legacy layout is supported. The native importer reads the -sample subtree/index streams, preserves duplicate sample names as independent -samples, and exposes each of the 11 verified experiment slots as its own -acquisition stream and TIC channel. Records remain in cycle order, including -zero-TIC and empty DDA slots; no cross-experiment time merging or interpolation -is performed. Unknown or structurally different WIFF variants are rejected -before a dataset is created. Encrypted or newer `.wiff2` and -`.timeseries.data` input is outside this boundary and must first be converted -to mzML. +Named processing templates are kept in the `templates` folder of Plotium's +[configuration directory](/getting-started/installation/#where-plotium-keeps-its-settings). + +## `.plotiumstyle` canvas styles + +**Save Canvas Style…** writes the active canvas's look as a `.plotiumstyle` +file in the `styles` folder of the configuration directory. Copy the file to the +same folder on another computer to use the style there. See +[Typography, themes and styles](/guides/themes-and-styles/). + +## Custom fit models + +Custom fit models are written in the `.plotiumfit` model language in the Curve +Fit editor and saved together in your model library, `fit-models.json` in the +configuration directory. A model is plain data and never runs code. See +[Custom fit models](/guides/custom-models/). ## Workflow and run-record files @@ -128,77 +71,10 @@ are covered in [the command line](/reference/cli/). A workflow is not a recipe: a recipe holds one processing pipeline, while a workflow describes a whole run and may reference a recipe as one of its steps. -## XPS import - -VAMAS `.vms` support is intentionally limited to content-signed ISO 14976 -`NORM` / `REGULAR` XPS blocks with regular energy rulers. One file remains one -experiment with stable measurement and region identities. Plotium retains native -energy, counts, CPS, photon energy, dwell time, sweeps, position, acquisition -conditions, and free metadata. Non-XPS blocks can be skipped with warnings only -when their declared block boundaries are trusted; malformed XPS payloads reject -the file. Ordinate extrema are metadata rather than data points, and ordinate -labels plus signal mode determine whether pulse counts are converted to CPS. - -CasaXPS `.txt` is recognized by its eight-line structure, not by `.txt` alone. -Its source arrays and fitted parameters are stored as an `Imported` result. -Unstructured text continues through table import. See [XPS](/guides/xps/) for -the energy conversion, processing, fitting, and export contract. - -## Origin project import (experimental) - -Origin project import is experimental. Successful import is limited to two -exact, content-detected OPJ producer profiles: - -- Origin 7.0552 (`CPYA 4.2673 build 552`) imports verified `f64`, `f32`, signed - `i32`, signed `i16`, fixed-width ASCII text, mixed numeric/text cells, nulls, - and nonzero row offsets. Project parameters and notes are retained as source - metadata. -- Origin 9.51 build 195 W64 (`CPYA 4.3268 build 195 W64`) imports worksheet - names, column names, numeric `f64` values, nulls, and validated empty columns. - This modern profile does not yet import text cells, project parameters, or - notes. - -Compatibility claims are limited to the committed Origin 7 regression fixture -and the exact Origin 9.51 profile checked against two real projects, companion -CSV exports, and an independent parser comparison. They do not extend to other -files merely because the extension or major Origin version is the same. - -Plotium preserves validated Origin window or group names and column names. Each -supported window is represented as one table under the generated worksheet -name `Sheet1`; this release does not claim to decode original worksheet labels. -Mixed Origin 7 columns are retained as text, and unequal column lengths are -padded with nulls. There is no verified-support claim for long names, units, -comments, column designations, dates, categorical values, or unverified code -pages. - -An `.opju` file is recognized from its CPYUA content signature, but `.opju` is -not importable in this release and Plotium creates no partial OPJU result. - -Unsupported content includes graphs, formulas, scripts, analysis -recomputation, saved analysis results as executable analyses, matrices, -embedded objects, modern OPJ text cells, non-ASCII text without a verified code -page, encrypted or protected projects, unverified OPJ versions or profiles, and -unverified OPJU containers. For the supported Origin 9.51 profile, Plotium stops -after the validated window-list boundary and warns that the remaining project -objects were not imported. - -Plotium never silently or heuristically guesses an import. Corrupt or truncated -files, files above the current 128 MiB input cap, extension/signature-family -mismatches, and malformed or otherwise unsupported files produce a clear error -before any table is committed. Inside an otherwise supported OPJ, an -unsupported worksheet column may be omitted, or an unsupported non-table object -skipped, only when each is independently framed and its outer boundaries are -trusted. Plotium shows warnings for every such omission; an imported worksheet -may therefore contain only the supported columns, not every source column. If -framing is ambiguous or untrusted, Plotium rejects the file rather than guessing -boundaries or silently shifting data. - -Origin need not be installed, launched, or called during import. - -## Data you import and export - -See [Importing data](/guides/importing-data/) for the supported instrument and -tabular formats, and [Exporting](/guides/exporting/) for figure and data -export — including the `.plotium-schema.json` companion that lets an exported -CSV/TSV round-trip back into Plotium with its column types, units, and error -bars intact. +## Table schema companions + +When Plotium exports a table as CSV or TSV, it writes a `.plotium-schema.json` +file next to it with the table's column types, units, and error-bar +relationships. XLSX exports keep the same information on a hidden worksheet, +and Copy TSV puts it on the clipboard (on Windows). Importing the table again restores those +details; see [Tables exported by Plotium](/guides/importing-data/#tables-exported-by-plotium). diff --git a/docs/src/content/docs/reference/mcp.md b/docs/src/content/docs/reference/mcp.md deleted file mode 100644 index add4d359..00000000 --- a/docs/src/content/docs/reference/mcp.md +++ /dev/null @@ -1,2468 +0,0 @@ ---- -title: MCP reference -description: Manual configuration, tool calls and limits for local Plotium MCP clients. ---- - -For connection setup and everyday tasks, start with [AI client connections](/guides/automation/#local-agent-connections-mcp). This reference is for custom clients and tool-level troubleshooting. - -## Manual configuration and diagnostics - -On Windows, Plotium finds standalone client executables on `PATH`. For Codex -installed with npm, it resolves the native executable inside the npm package, -using prefixes on `PATH` and the default `%APPDATA%\npm` prefix. Both x64 and -ARM64 installations are supported. For a custom npm prefix, add it to `PATH` and -restart Plotium, or use **Choose executable…** to select the package's -`codex.exe`. Adding a client requires the Codex CLI to be installed. - -In **Preferences → AI connections (MCP)**, expand **Manual configuration and diagnostics** -and press **Copy stable stdio configuration**. The copied JSON contains the actual -absolute connector path; the path below is a placeholder: - -```json -{"mcpServers":{"plotium":{"command":"/ABSOLUTE/USER/DATA/bin/plotium-mcp","args":[]}}} -``` - -Use the copied path for your platform (`plotium-mcp.exe` on Windows). Plotium -copies the connector to its user data directory when enabled and updates it on -application upgrades. Keep `plotium-mcp` beside the desktop executable in a release -installation. The official CLI registration forms are: - -```sh -codex mcp add plotium -- /ABSOLUTE/USER/DATA/bin/plotium-mcp -claude mcp add --transport stdio --scope user plotium -- /ABSOLUTE/USER/DATA/bin/plotium-mcp -``` - -See [Codex MCP](https://learn.chatgpt.com/docs/extend/mcp?surface=cli), -[Claude Code MCP](https://code.claude.com/docs/en/mcp) and the -[MCP Bundle manifest](https://github.com/modelcontextprotocol/mcpb/blob/main/MANIFEST.md). -Temporary HTTP diagnostics include a secret token and expire on service restart; -they are an advanced diagnostic entry, not the saved client configuration. -Discovery is private to the current user and local machine. Remote and cross-environment -WSL access are outside this interface. - -After upgrading Plotium, restart its MCP connection in your AI client to load -the updated tools. If connector installation fails, open -**AI connections (MCP)** to read the error and press **Retry**. - -## Permissions and supported operations - -Edits use Plotium's normal **Undo** and **Redo**. **Read only** prevents further -edit execution, including pending plans. Table reads and property preflight remain -available; import, native binding and creation and transform/patch/refresh preflight require Read and modify. -The selected permission persists until you change it. - -Project queries and plan creation require both `expected_revision` and -`expected_project_context`, using the `project_context` from `plotium_get_state`. -The examples below use `PROJECT_CONTEXT` as a placeholder for that value. -Every project open, new, close or recovery creates a new context, even when -revision numbers match. Switching clears plans and rejects queued work; -`busy` during a transition means wait until it finishes or is cancelled. -On `project_changed`, reread state and replan with newly discovered targets. -Never reuse old targets or plans. Executions bind the context of their saved plan. - -Project edits, scientific computations and data transformations retain durable run -provenance and mark the project as unsaved. Ordinary queries, including state, -resource/property/table/document browsing, scientific result inspection, previews -and diagnostics, do not append project audit records or change dirty state, edit -generation or automation revision. Query-only workflows also leave the project -unchanged; workflows containing modifying operations retain the complete run, -including query inputs needed to reproduce those operations. Handshakes, tool listing, authenticated status, five-second heartbeats, -the static property catalog and save coordination (planning, submission and -`plotium_save_status`), and export planning/submission/status do not add audit records. - -The connection supports native acquisition import and CSV/TSV/XLSX data-only import, native table queries, canvas previews, figure geometry diagnostics, -document structure, native plot creation and page/panel/text/local-image authoring, explicit numeric curve bindings, supported table transforms, cell patches, explicit saved-recipe refreshes and resource queries, renaming datasets, -canvases and canvas objects, applying built-in themes or saved canvas styles to canvases, and these display properties only: - -| Property ID | Target | Value | -| --- | --- | --- | -| `series.line.color` | Object + Series | `#RRGGBB` | -| `series.line.stroke_width` | Object + Series | 0.05–10 pt | -| `series.line.style` | Object + Series | `solid`, `dashed`, `dotted`, `dash_dot` | -| `series.line.marker` | Object + Series | `none`, `circle`, `square`, `diamond`, `triangle_up`, `triangle_down`, `star`, `pentagon`, `hexagon`, `plus`, `cross` | -| `series.line.marker_size` | Object + Series | 0.1–20 pt diameter | -| `series.line.marker_fill / series.line.marker_edge_color` | Object + Series | `#RRGGBB` | -| `series.line.marker_edge_width` | Object + Series | 0–5 pt; 0 draws no outline (0.5 pt while hollow) | -| `series.line.marker_hollow` | Object + Series | boolean | -| `series.line.marker_every` | Object + Series | 1–1000; markers on every n-th point from the first (default 1) | -| `series.bar.width` | Object + Series | 0.05–1, fraction of the bar's slot (bar curves; default 0.8) | -| `series.bar.edge_color` | Object + Series | `#RRGGBB` bar outline (bar curves; unset, a near-black shade of the fill's hue that follows color edits) | -| `series.bar.edge_width` | Object + Series | 0–5 pt bar outline; 0 draws none (bar curves; default 0.5 pt, or the theme's supporting-line width) | -| `series.y_axis` | Object + Series | `left`, `right` (line and scatter curves; bars stay left) | -| `series.points.spread` | Object + Series | 0–1 spread of replicate points across their mark (point and line curves; default 0) | -| `series.value_labels` | Object + Series | boolean; write each bar's or point's value (bar, point and line curves) | -| `series.replicates` | Object + Series | 0–100000 replicates behind each plotted value; 0 means not stated | -| `series.error_bars` | Object + Series | `unspecified`, `sd`, `sem`, `ci95`; what the y errors show (curves with a y error column) | -| `object.chart.orientation` | Object | `vertical`, `horizontal` (explicit-column plots) | -| `object.intent.purpose` | Object | `unspecified`, `compare`, `trend`, `distribution`, `relationship`, `composition`, `change`, `detail`; what the plot is meant to show | -| `object.intent.claim` | Object | string of at most 500 characters; the one claim the plot should support | -| `series.visible` | Object + Series | boolean | -| `series.label` | Object + Series | string | -| `object.axes.x_label / object.axes.y_label` | Object | string | -| `object.axes.x_show_label / object.axes.y_show_label` | Object | boolean; shows the axis title | -| `object.axes.x_show_tick_labels / object.axes.y_show_tick_labels` | Object | boolean | -| `object.axes.x_thousands_separator / object.axes.y_thousands_separator` | Object | boolean; groups digits in tick labels | -| `object.axes.x_major_step / object.axes.y_major_step` | Object | ≥ 0, distance between major ticks in the display unit; 0 chooses it automatically (linear axes without a break) | -| `object.axes.frame` | Object | `open` (left and bottom), `box` (all four sides) | -| `object.axes.equal_scale` | Object | boolean; same data units per length on x and y (linear, non-categorical axes without a right y axis) | -| `object.axes.x_scale / object.axes.y_scale` | Object | `linear`, `log` (line, scatter and stick plots; a manual range must stay above zero) | -| `object.axes.x_display_unit / object.axes.y_display_unit` | Object | compatible code from property inspection | -| `object.axes.x_range / object.axes.y_range` | Object | auto or manual range object | -| `object.axes.y2_label` | Object | string; right y axis title | -| `object.axes.y2_show_tick_labels / object.axes.y2_show_label` | Object | boolean | -| `object.axes.y2_scale` | Object | `linear`, `log` | -| `object.axes.y2_display_unit` | Object | compatible code from property inspection | -| `object.axes.y2_range` | Object | auto or manual range object | -| `object.axes.y2_major_step` | Object | as `y_major_step`, for the right y axis | -| `object.figure.typography.tick_pt / object.figure.typography.label_pt / object.figure.typography.legend_pt` | Object | 1–72 pt | -| `object.guides.visibility` | Object | `auto`, `show`, `hide` | -| `object.guides.placement` | Object | `auto`, `inside`, `outside_right`, `outside_bottom`, `custom` | -| `object.guides.layout` | Object | `auto`, `vertical`, `horizontal` | -| `object.guides.title` | Object | string | -| `object.guides.position` | Object | `[x,y]` in [0,1], or `null` | -| `series.contour.line_width` | Object + Series | 0.05–10 pt | -| `series.contour.count` | Object + Series | 1–256 | -| `document.figure.typography.tick_pt / document.figure.typography.label_pt` | document | 1–72 pt | -| `document.figure.typography.axis_line_pt` | document | 0.05–10 pt; axis lines and tick marks | -| `document.figure.typography.tick_length_pt` | document | 0–20 pt | -| `document.figure.typography.tick_direction` | document | `out`, `in` | -| `document.figure.typography.minor_ticks` | document | 0–9 minor ticks per major interval; 0 hides them | -| `document.figure.typography.typeface` | document | `arial`, `helvetica`, `times_new_roman`; text inside every plot | -| `document.figure.typography.font_weight` | document | `regular`, `bold`; text inside every plot | - -The `object.axes.y2_*` properties apply only while some curve of the plot has -`series.y_axis` `right`; on other plots they are not applicable. - -Scientific processing and task interfaces are described below. Preferences, new format parsers, automatic scientific-result plotting and built-in chat are outside this interface. - -### Tool annotations and client approval - -Every tool advertises MCP `annotations` in `tools/list`, independently of the -current **Access** setting. -`readOnlyHint` describes environment changes; `destructiveHint` distinguishes -potentially destructive writes from additive ones; `idempotentHint` describes -whether repeating identical arguments has additional effects; `openWorldHint` -describes interaction with external entities, including local input/output files. -Destructive and idempotent hints are meaningful only for non-read-only tools. -See the [MCP annotation definitions](https://modelcontextprotocol.io/specification/2025-11-25/schema#toolannotations). - -Queries, previews and receipt inspection are read-only and operate on native -project/application state. Diagnosis is also read-only, but continuation cursors -are single-use. `plotium_plan` is not read-only: each successful call retains a new -executable plan and can read external data, schema, processing-scheme or image -files and prepare computation. It does not commit the candidate or write -save/export outputs. `plotium_execute` covers edits, deletion, scientific tasks -and save/export requests, so the entire tool advertises potentially destructive, -non-idempotent, open-world behavior. Task cancellation is a potentially destructive -write to task state; repeating cancellation for the same retained task has no -additional effect. - -A client's policy may use trusted-server hints when deciding whether to ask for -approval; clients can still ask, and untrusted annotations must not authorize -calls. Client approval, Plotium **Access**, and desktop file consent are separate -decisions. Annotations grant no permission: revision/context checks, revocation -and one-use plans still apply. Every save/export request retains its own desktop -confirmation and exact file/overwrite scope, including in **Read only**. -Never replay a call after disconnection or an unknown outcome, even when marked -idempotent; inspect state or retained receipts instead. After upgrading Plotium -and its connector, reconnect the client to refresh the tool catalog. - -## Read state and discover capabilities on demand - -`plotium_get_state {}` reads the latest dynamic state. It returns -`project_context`, `revision`, `availability`, `permissions`, `save_state`, -`capability_fingerprint`, project counts and a bounded selection page. It does not -include the full capability catalog or project blueprint. Discover exact targets -with the revision-bound `plotium_document_inspect` pages or -`plotium_resources_search`, then inspect explicit IDs with -`plotium_resources_inspect`. Copy complete returned targets rather than names or -collection positions. - -Two short forms save copying. A resource reference may omit `parent_id` and -`local_id`; Plotium derives them from a nested ID such as `CANVAS_UUID/OBJECT_ID`. -A Series target may be written `{"plot":"CANVAS_UUID/OBJECT_ID","series":0}` in -plan and property-inspection targets and in curve-binding and `properties.set_many` -writes. Both expand to the full target before planning; plans, results and audit -records keep the full form. - -When idle, `selection` is `{items,total,next_offset}`. The default page contains -at most 16 stable resource references. Pass `selection_offset` (default 0) and -`selection_limit` (1–50) to read further pages, for example: - -```json -{"selection_offset":16,"selection_limit":50} -``` - -`selection.canvas` reports what the user selected on the active page: -`{items,total,part}`. `items` holds at most `selection_limit` summaries -(`target`, `kind`, `name`, `visible`) of the selected panels and items. `part` -is the legend, label or annotation the user clicked inside the lead plot, or `null`. A -legend reads `{target,part:"legend",property:"object.guides.position",value}`, -where a `null` value means automatic placement. A label reads -`{target,part:"label",kind,annotation_id,edit:"figure.edit annotation_set",…}` -with its current placement; an arrow or a reference line itself reads -`{target,part:"annotation",kind,annotation_id,edit,…}` with its position and -`hand_moved`. When the user says "this", edit that target or part. - -Every call reads the current selection; pages are not a frozen snapshot. GUI -selection can change without changing the document revision. Do not combine pages -as an atomic selection or use selection as execution authority. - -`hand_edits` lists the figure values the user set by hand in Plotium, as -`{items,total,next_offset}`. Each item has the `target`, the property `key`, its -`label` and current `value`. Pass `hand_edits_offset` and `hand_edits_limit` -(1–50, default 16) for further pages. Keep these values when you continue -editing; see [Values the user set by hand](#values-the-user-set-by-hand). - -While busy, `project`, `selection` and `hand_edits` are `null`; availability, -permissions, the capability fingerprint and save receipt IDs remain readable. - -Call `plotium_capabilities_get {}` to obtain a compact index, -`{capability_fingerprint,connection_capabilities}`. The index lists each tool's -operations and required permission, the editable operations grouped by preflight -and execute permission, the scientific operations, the recovery, revision and -property-batch contracts, the document root and `sections`. Tool descriptions, -input schemas and annotations are in `tools/list`; property definitions are in -`plotium_properties_list`. - -`sections` names each detail section with its size in bytes and whether it takes a -`key`. `operation_constraints` and `operation_details` list each key with a -one-line purpose, so you can match a task to an operation before fetching it. Fetch one detail with `{"section":...,"key":...}`, which returns -`{capability_fingerprint,section,key,contract}`: - -| Section | Key | Contract | -| --- | --- | --- | -| `tools` | optional tool name | result contract and target rules; a keyed request also includes the tool input schema | -| `operation_constraints` | required operation id | schema, permissions and result contract of one editable operation | -| `operation_details` | required operation/suboperation key, or `keys` | focused figure-edit schema, permissions, result contract and example | -| `scientific_operations` | required operation id | descriptor and required permission; editable operations link to their canonical input schema | -| `guide_contract` | none | legend and colorbar placement rules | -| `candidate_preview` | none | uncommitted plan preview contract | -| `limits` | optional limit name | connection budgets | - -For example, read the `figure.edit` schema with: - -```json -{"section":"operation_constraints","key":"figure.edit"} -``` - -Known operations can request their detail directly without first reading the index. -For a page edit, use `{"section":"operation_details","key":"figure.edit/page"}`. -For several edits, pass `keys` instead of `key`, for example -`{"section":"operation_details","keys":["figure.edit/panel_label","figure.edit/annotation_create.arrow"]}`. -The response has `keys` and a `contract` map keyed by the requested names. This -section accepts 1–32 unique keys per call; other sections accept only `key`. -Each detail holds one exact edit schema with only the restrictions and result -fields that apply to that edit. Replace example targets with -full stable references from document inspection. Use `operation_constraints` for -the complete mixed-edit schema. Editable scientific descriptors expose -`input_schema_ref: {section,key}` instead of duplicating that schema. - -An unknown section or key fails with `invalid_parameters`; `error.details.sections` -or `error.details.keys` lists the valid values. - -The fingerprint is SHA-256 of the complete static discovery contract (index, every -section, the MCP tool definitions and the property catalog) with canonical JSON -object ordering. Cache the index and fetched sections under the returned -fingerprint; fetch it again when the state -fingerprint differs. If state changes before discovery completes, use the -fingerprint returned with the discovered contract. Project edits, project changes, -selection changes and permission changes do not change static capabilities. - -Static discovery includes required permissions, not `currently_permitted` flags. -Always read current `permissions` and `availability` from state; execution still -checks server permissions, context, revision and single-use plans. Fingerprints, -cached schemas and annotations grant no permissions and never authorize retry. -Save and export still require fresh desktop confirmation for each exact request. -Update the desktop and connector together and reconnect clients to refresh the -tool catalog after upgrading. - -The advertised inputs for planning, property inspection, document inspection and -figure diagnostics list their fields directly so clients can display complete -signatures. Plotium still validates conditional rules: use exactly one nonempty -`ids` or `targets` selector where required, omit both for operations with embedded -targets, and supply one dataset ID for table operations. Only `properties.set` -and `properties.reset` accept Series targets. Document pagination applies only -to `view: "children"`; diagnostic continuation accepts only `cursor`, context and -revision, whereas an initial diagnostic request requires `canvas` and `output`. - -Committed synchronous `plotium_execute` results include `project_context`, -`before_revision` and `after_revision`. For known exact targets in that context, -use the returned context and `after_revision` for the next query or plan without -an extra state read. This does not refresh selection, hand edits, availability or -permissions. Read state initially, after desktop edits or Undo/Redo, when those -dynamic values are needed, and on stale/context errors or uncertain outcomes. -Execution still rechecks context, revision and permissions. - -Plans for figure edits, curve append/bind/expansion, scientific plots, renames, -themes and dataset deletion return `plan_id`, `project_context`, `basis_revision` -and a `preflight` without the echoed request or frozen target set. -`preflight.summary` counts compatible, skipped and failed targets, and -`preflight.targets` lists only the targets that will be skipped or fail. Their -execution results carry `summary` counts of succeeded, skipped and failed -targets, list only skipped or failed rows in `targets`, and report changed -resources in `produced` and `modified`. - -`plotium_apply` takes the same inputs as `plotium_plan` and plans and commits one -reversible edit in a single call, returning the `plotium_execute` result. It -accepts `properties.set`, `properties.set_many`, `properties.reset`, -`figure.edit` without deletions, `plot.create`, `plot.series.append`, -`plot.series.bind`, `plot.series.materialize_default`, `resource.rename` and -`figure.apply_theme`, and requires Read and modify. Preflight, revision and -permission checks, Undo and run records are those of the two-step form, and no -plan is retained. Saving, export, deletions, imports, table and scientific -operations still use `plotium_plan` and `plotium_execute`, as does previewing a -candidate. A rejected apply commits nothing. After a disconnection, read state: -a revision equal to the request's `expected_revision` means the edit was not -committed; otherwise inspect the targets. Never replay the call. - -A queued or submitted scientific task is not a committed edit; its immediate -`after_revision` must not be reused. Only a terminal `succeeded` receipt in the -known project context with `end_revision` permits reuse. Check scientific -validity/convergence separately: successful task completion alone does not prove -a valid fit. Failed, cancelled, stale, missing or uncertain receipts require the -existing recovery flow and never authorize automatic replay. Save/export receipts -describe file operations and do not provide a new document revision. - -## Import native data from the welcome page - -`plotium_get_state {}` works immediately after opening Plotium, including while -background work, recovery or saving blocks project access. It adds -`availability` entries for `project_read`, `project_modify` -and `native_import`; each has `available` and a nullable `{code,message}` reason. -You can import native data or tables directly from the welcome page. When idle, -`project` contains dataset and canvas counts, even before importing data. While busy, -`project` and `selection` are both `null`. Check `availability` before planning -an operation. Queries add no project audit entry or unsaved changes. -Connection capabilities remain discoverable through `plotium_capabilities_get {}` in every state. - -Enable **Read and modify**, copy `project_context` and `revision` from state, -then call `plotium_plan`: - -```json -{ - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 0, - "tool_id": "data.import", - "parameters": {"paths": ["C:/Data/experiment.jdf"]} -} -``` - -Use actual absolute paths. Native import accepts explicit data files and atomic -acquisition directories supported by the desktop loader, such as Bruker acquisition -or processed-data directories. It reads required companions without recursive batch -discovery or scanning adjacent experiments. ZIP archives, project files and new -formats are outside this operation. Optional `sampling_declaration` uses the core -import contract. Discover the shared schema with -`plotium_capabilities_get {"section":"operation_constraints","key":"data.import"}`. - -Preflight runs in the background and returns per-input format, dimensions, -warnings, failures and proposed dataset/canvas IDs in `import.items[].metadata`. -It creates no resources or document edits. Call `plotium_execute {"plan_id":"PLAN_ID"}` -to commit frozen data; changing or deleting the source after preflight does not -affect execution. Success adds native datasets and default canvases to the current -project, preserving its context and selection. - -Results report `succeeded`, `partial` or `failed`. All successful inputs commit -atomically in one Undo step. Undo leaves an empty project when the batch was its -first content; Redo restores the same resource IDs. If every input fails or the -import is cancelled, no resources, Undo entry or unsaved changes are added. -Successful imports retain scientific provenance. Permissions, context and revision -are checked again at submission. Plans are single-use even when execution is refused. After -`project_changed`, read state and preflight again. - -Native import allows 16 inputs per batch, one preflight in flight and four retained -prepared imports, shared with table import. Conservative native frozen-payload -reservations total at most 512 MiB across retained plans and the active preflight; -oversized batches fail with `import_budget_exceeded`. A call with more than 16 -paths fails with a message that gives the number received; import the rest in -further calls. Preflight responses are limited to 256 KiB. Scientific processing and DOSY use the separate shared scientific operations. -CSV, TSV and XLSX files are tables: import them with `mode: "table_data_only"`. -Native import rejects them with that hint. - -## Discover structure without relying on names - -Start with `plotium_get_state {}` for current context, revision and permissions. -Call `plotium_capabilities_get {}` when you need static contracts. Its index -describes this connection's tools, supported operations and their permissions; -fetch result contracts, operation schemas and limits by section. Standard MCP -`tools/list` lists tool input schemas, and `plotium_properties_list` lists property -definitions. Resource descriptors describe **core** data and -rendering capabilities; a capability listed on a resource -does not make that operation callable through this connection. Only -`project.save`, `figure.export`, `resource.rename`, `dataset.delete`, `figure.apply_theme`, `properties.set`, `properties.set_many`, `properties.reset` and the restricted -`data.import` / `data.transform` modes, `table.patch`, `table.refresh`, `figure.edit`, `plot.create` and `plot.series.append` / `plot.series.bind` / `plot.series.materialize_default` below can be planned here. Read-only access allows table reads -and existing property preflight, but refuses import/binding/creation/figure-edit/transform/patch/refresh preflight and all reversible edit execution. Saving and exporting use separate per-request desktop authorization, also in Read only mode. - -Use the returned revision to list the document's canvases: - -```json -{ - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 7, - "target": {"resource":{"id":"document","kind":"plotium.document"}}, - "view": "children", - "offset": 0, - "limit": 50 -} -``` - -Call `plotium_document_inspect` with this request. Copy a complete -`value.items[].target` into the next request to descend from canvas to panel, -content, and Series. A canvas lists its panels followed by loose content; -parented content appears only under its panel. `view: "self"`, with pagination -arguments omitted, reads one target's details, `ancestors` and `child_count`. -The content kinds are plot, text, shape and raster image; image pixels and data -rows are not returned. Frames use points: a panel is page-relative, while content -inside it is panel-local. Content details include its exact `parent`, `frame_space`, -converted `page_frame`, and `geometry` constraints/editability. Raster details retain -`asset_id` and add `image` attributes and replacement eligibility. Canvas dimensions are in millimetres. - -Series discovery uses the plot's current display binding, like property addressing. -Inactive channel or display-mode alternatives remain stored but are not listed or -addressable until reactivated. Authored hidden Series in the active binding are -still listed with `visible: false`. After switching channels or display modes, -fetch the current revision and discover the active targets again. - -`encoding` names the native encoding family: `line` includes both line and scatter -curves; `plot.create` reports the authored subtype in `series_defaults[].kind`. - -A Series detail includes its complete property-compatible target, encoding, -visibility, explicit label, and `source`: dataset and field resource references, -owner-local `field_id`, optional `item_id`, units and binding status. Use the -returned resource IDs with `plotium_resources_inspect` for field/column -descriptors. A missing field retains its `field_id` but has no resolvable field -reference. A source can report `resolved`, `missing_dataset`, `missing_field`, -`missing_item`, `incompatible_encoding`, `unbound` or `missing_column`. - -For tables, `binding_mode: "table_default"` reports the shared `x_column` and -all `series_columns` Y/error bindings. One logical Series may expand to several -rendered table traces; those traces do not gain separate Series IDs here. -Explicit sources report `binding_mode: "table_explicit"`, TableId, current table revision, -`x_column`, `y_column` and optional `error_column`, without reporting defaults as their source. -`coordinate_units` reports the plot coordinate contract. Names, including identical curve names, are display -text, never identity. Panels use `CANVAS_UUID/panels/PANEL_ID`; content and Series -retain the existing addresses shown below. - -Children queries default to 50 entries, accept 1–200, and return `total`, -`next_offset` and `truncated`. Follow `next_offset` with the **same revision and -target**, including when the 256 KiB structured-response budget shortens a page. -A detail or single entry that exceeds that budget returns `response_too_large`. -There is no recursive whole-project dump. Revision changes reject continuation; -read state and restart the listing. Missing targets and forged identities return -`invalid_parameters`, without using the current selection. - -`plotium_properties_list {}` browses every supported property, one compact row -each: `id`, `label`, value `type`, and where they apply `min`/`max`, `unit`, -`format`, enum `values`, the curve `encoding` and required field capabilities -(`requires`). An ID starting with `document.` has document scope; every other ID -has object scope, and `series.` IDs target a Series. Rows marked `requires_full` -(nested inputs and display-unit codes) need full detail. Fetch complete -definitions for the properties you need in one call: - -```json -{"keys":["series.line.stroke_width","series.line.color"],"detail":"full"} -``` - -Use `scope` with a scope name from the catalog, or `prefix` with the start of a -property ID such as `series.line` or `object.axes`, to filter the list. A prefix -that matches nothing fails with `error.details.prefixes`. `keys` must be -nonempty and unique; unsupported keys, unknown scopes and key/scope conflicts are -errors, rather than silently omitting requested properties. `detail: "full"` -without filters returns the complete catalog. Both forms are static, callable -while busy, and contain no current target values. Full details preserve complex -input constraints, colour format `#rrggbb` and every registered unit code. -Use `plotium_properties_inspect` for target-specific values, defaults, bounds and -applicability; an axis accepts only codes compatible with its coordinate unit. -Static applicability does not grant connection write permission. - -## Import CSV/TSV/XLSX data without creating a plot - -Ask the agent to import an explicitly named UTF-8 CSV or TSV, or an XLSX workbook, inspect its columns, -and read the whole table in pages. Start with `plotium_get_state {}`, then call -`plotium_plan`: - -```json -{ - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 7, - "tool_id": "data.import", - "parameters": { - "mode": "table_data_only", - "paths": ["/absolute/path/measurement.csv"], - "header": "present" - } -} -``` - -Do not supply `ids` or `targets` for import. `header` accepts `auto` (default), -`present` or `absent`; ambiguous auto detection fails. The `.csv` or `.tsv` -extension selects comma or tab; `format: "csv" | "tsv"` overrides it explicitly. -An `.xlsx` file (or `format: "xlsx"`) imports each visible worksheet that has -cells as its own table, named after the worksheet, or after the file when the -workbook holds a single table, the same way the desktop imports it. -`sheets: ["Figure 3", …]` imports only the named worksheets; an unknown name -fails that file and lists the visible worksheets. Each worksheet is prepared on -its own: one that holds no table or exceeds a limit fails as its own item and -the others still import. One file reads at most 8,000,000 worksheet cells, -counted over each worksheet's used range. `header`, `schema` and `schema_path` -apply to CSV/TSV only. If the summary of a batch with XLSX files would exceed -128 KiB, the preflight fails and lists each workbook's worksheets, so you can -import one workbook at a time and name fewer worksheets. -Only named regular files are read. There is no directory discovery, adjacent -sidecar lookup, source writeback, implicit plotting or X/Y binding. - -Preflight runs in the background and returns only when preparation finishes. -`import.items` reports each file, or each XLSX worksheet with its `sheet`, as -`prepared` or `failed`, with proposed native IDs, metadata and diagnostics. No -dataset exists yet. After reviewing the result, call -`plotium_execute {"plan_id":"RETURNED_PLAN_ID"}`. Execution uses those frozen -bytes and typed snapshots, even if a source file changed after preflight. It -rechecks revision and permission before one atomic commit of all prepared items. -`value.status` is `succeeded`, `partial` or `failed`; inspect every item and its -created IDs. Failed files leave no partial dataset. One Undo removes the batch's -successful items; Redo restores the same DatasetId, FieldId, ColumnId and RowId. -Existing GUI/CLI import entry points retain their original behavior. - -Metadata includes DatasetId, TableId, table RevisionId, field identities, stable -ColumnIds, logical types, nullable flags, units, total rows and diagnostics. -Fields and columns are distinct native identities. Missing cells remain null; -mixed numeric/text columns preserve text. Integer-looking tokens outside signed -64-bit range remain text rather than being rounded. Units are never inferred -from numbers or header spelling. Column `type_source` is `file`, `user`, -`inferred` or `unknown`; `unit_source` is `file`, `user` or `unknown`. - -Optional `schema` is an ordered native TableSchema with typed ColumnSchema IDs, -logical types, nullable flags and optional UnitSpec declarations. Alternatively, -`schema_path` names a v1 PlotiumDelimitedSchema JSON file explicitly. Its header -and order must match exactly; declarations are strict, with no inference fallback -for invalid values. Supported declared types are null, boolean, int64, float64, -utf8, date and timestamp. Uniqueness/business-key constraints and uncertainty -relations are not accepted by this import. Plain `_sigma` column names do not -assign scientific uncertainty meanings. New native IDs are allocated per import; -file/user schema IDs describe the source, not an existing project target. - -Limits are 16 files, 16 MiB per file, 64 MiB selected input bytes per batch, -256 columns and 1,000,000 rows per file. Explicit metadata files are limited to -256 KiB. The prepared item summary is limited to 128 KiB and the complete -preflight response to 256 KiB; reduce the batch/schema if either is exceeded. -At most four prepared imports and 32 total plans are retained per -connection; one import preflight runs at a time. Limits bound inputs, not total -process memory. Cancellation, a project transition, permission revocation or an -intervening edit prevents a pending preflight from becoming an executable plan. -Queued or running work is not completion. Failed/stale submissions consume their -plan; fetch state and preflight again instead of replaying a create request. - -## Read a complete table in bounded pages - -Copy DatasetId and table RevisionId from import metadata or the dataset resource -descriptor. Call `plotium_table_columns` with those IDs and `expected_revision` to -inspect metadata, then `plotium_table_read_rows`: - -```json -{ - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 8, - "dataset_id": "DATASET_UUID", - "table_revision": "TABLE_REVISION_UUID", - "offset": 0, - "limit": 200 -} -``` - -Replace the placeholders with returned IDs. Optional `column_ids` projects -columns by stable ColumnId, in the supplied order; omitted or empty selects all -columns in schema order. Rows follow immutable native snapshot order. The result -includes `column_ids`, `rows: [{row_id, values}]`, `total_rows`, `requested_rows`, -`returned_rows`, `next_offset` and `end`. Values are tagged by `kind`; null has no -value. Int64, time, timestamp and duration values use decimal strings to avoid -JSON number rounding. Date values are days since the Unix epoch; time, timestamp -and duration values use nanoseconds. Non-finite floats are explicit `NaN`, -`+Inf` or `-Inf` strings, not null. - -Follow `next_offset` with the same dataset, document revision, table revision -and projection until `end: true` and `next_offset: null`. The default page is -200 rows, maximum 1000 rows and 20000 projected cells; the complete structured -ToolResult is limited to 256 KiB. The byte limit can shorten a page, never a cell; -use the actual returned count and continuation. A single oversized row returns -`response_too_large`. An offset equal to total_rows returns an empty end page; -an offset beyond it fails. Invalid limits, duplicate/absent columns and oversized -requests fail rather than being silently clamped. - -Both revisions must still match on every read. Human edits, including Undo/Redo, -invalidate old document revisions: read state and restart rather than mixing -pages. Invalid IDs never use the current selection. Read-only connections can -query existing tables but cannot import them. Limits appear in the `limits` -capability section and the import permission condition in the index. - -## Derive a table without changing its source - -Ask the agent: “Calculate `signal_x2 = y_left * 2`, exclude rows whose -`x_left` equals zero, sort X descending, then bind the result to this existing -curve.” Table processing creates one native table, not a plot. Rebinding uses -[the existing curve-binding operation](#rebind-an-existing-curve-without-changing-another-plot). - -1. Read `plotium_get_state`, then `plotium_table_columns` with the DatasetId - and table revision. Copy the actual ColumnIds, `table_id`, `table_revision` - and `snapshot_fingerprint`; names and `source_column_id` are not identities. -2. Discover the native plan schema with - `plotium_capabilities_get {"section":"operation_constraints","key":"data.transform"}`. - Supply one DatasetId in `ids` and `mode: "table_data_only"`. The leaf must - pin exactly that dataset's current snapshot. Supply fresh UUIDs for - `operation_id` and each computed column's `id`. -3. Call `plotium_plan`, inspect `transform.status: "prepared"` and its - `output`, then submit the returned `plan_id` with `plotium_execute`. - Preparation does not insert data. A successful execution returns - `value.status: "succeeded"`, `value.output` and one `produced` dataset. - The prepared output identity is retained when committed. -4. Read the complete output with `plotium_table_read_rows`. Bind its actual - DatasetId, FieldId, TableId, revision and X/Y ColumnIds to an existing curve; - use `plotium_render_preview` to inspect the native result. To create a new plot, - pass the same output identities to [`plot.create`](#create-a-native-single-plot-from-an-imported-table) - instead, then preview the returned canvas. Processing and plot creation remain - separate, individually undoable operations. - -This complete native plan appends a Float64 column. Replace every placeholder -with a discovered identity or a fresh UUID. This example declares unknown units -with `unit: null`; when `y_left` has an explicit unit, copy its **whole UnitSpec** -to the output column for this dimensionless multiplication. - -```json -{ - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 7, - "tool_id": "data.transform", - "ids": ["DATASET_UUID"], - "parameters": { - "mode": "table_data_only", - "name": "Scaled signal", - "memory_limit_bytes": 16777216, - "plan": { - "version": 1, - "operation_id": "NEW_OPERATION_UUID", - "root": { - "op": "computed_column", - "input": { - "op": "snapshot_read", - "table": "TABLE_UUID", - "revision": "TABLE_REVISION_UUID", - "fingerprint": "SNAPSHOT_FINGERPRINT" - }, - "column": { - "id": "NEW_COLUMN_UUID", "name": "signal_x2", - "logical_type": {"kind": "float64"}, "nullable": true, "unit": null - }, - "expression": { - "expr": "call", "function": "multiply.v1", - "args": [ - {"expr": "cast", "input": {"expr": "column", "column": "Y_COLUMN_UUID"}, - "target": {"kind": "float64"}, "failure": "error"}, - {"expr": "literal", "value": {"type": "float64", - "value": {"kind": "finite", "value": 2.0}}} - ] - } - } - } - } -} -``` - -Supported relation nodes are `snapshot_read`, `project` (ordered ColumnIds), -`filter` (Boolean predicate), `stable_sort` (ordered keys with `column`, -`direction: ascending|descending`, `nulls: first|last`) and `computed_column` -(explicit column schema and expression). Wrap an earlier node in `input` to -compose them. For the task above, wrap the computed node in a filter using -`not.v1(eq.v1(column(X_COLUMN_UUID), literal(int64, 0)))`, then sort X descending, -then project X, Y and the new ColumnId. The schema defines the exact JSON forms. - -Expressions use `column`, `literal`, `cast` or versioned `call`. Available -functions are `is_null.v1`, `is_finite.v1`, `eq.v1`, `not.v1`, `and.v1`, `or.v1`, -`add.v1`, `subtract.v1`, `multiply.v1` and `divide.v1`; no arbitrary function, -SQL or script is accepted. Arithmetic requires Float64 operands. Casts are -explicit and may fail; `failure: error` rejects the transform, while `null` -produces a missing value. Native Int64-to-Float64 casts can lose precision. -Computed outputs support Boolean, Int64, Float64 and Utf8. Units are explicitly -declared, not inferred or converted by arithmetic. - -Filter keeps only true predicates; false and null are excluded. Sorting preserves -RowIds, resolves equal keys by RowId and places nulls independently of direction. -Non-null float order is `-Inf < finite < +Inf < NaN`. Projected columns retain -their IDs, types and units; computed columns retain the new IDs in the recipe. -Source values, table defaults, canvases and existing styles are unchanged. - -Output metadata includes the frozen native recipe, backend, input revisions and -fingerprints, column lineage and row-mapping contract. To inspect it later, call -`plotium_table_columns` with `include_provenance: true`. The same flag on -`plotium_table_read_rows` returns per-row `sources`: source DatasetId (when -recorded), TableId, revision, fingerprint, original RowId and zero-based -`input_position`. This decodes the stored native mapping for the returned page; -it does not follow the latest source revision. Imported rows have no derived -sources. Other relational lineage shapes are explicitly rejected for row-source -paging; ordinary reads without the flag retain their existing behavior. - -Preparation runs off the desktop thread. Planning and execution require **Read -and modify**. Permission, document revision and source snapshot are rechecked -when preparation finishes and immediately before commit. Each execution consumes -the plan, including a failed submission. Cancellation, stopping the connection, -project transitions and stale inputs discard uncommitted results. An already -started atomic commit is undone with normal Undo. One successful transform is -one Undo step; Redo restores the same table and column identities. - -There is one transform preflight in flight per connection. Parameters are limited -to 64 KiB, 64 relation/expression nodes and depth 16 (JSON nesting at most 48). -The memory budget defaults to and is capped at 512 MiB; it is the reference -executor's **materialized-result estimate**, checked after evaluation, not a -peak-process-memory limit. At most four prepared transforms share a 512 MiB -reservation budget, charged at each request's declared budget. Complete -responses are limited to 256 KiB; the prepared output summary is limited to -128 KiB, leaving room for the request and plan envelope. Limits are discoverable with -`plotium_capabilities_get {"section":"limits","key":"table_transform"}`. Budget failure returns -`transform_budget_exceeded`; cancellation returns `request_cancelled`. Neither -leaves a derived table or a successful execution result. Plan again after fixing -the input or budget. Use the separate cell-patch and explicit refresh operations below for subsequent updates. - - -## Patch cells, then explicitly refresh derived tables - -Use `table.patch` with exactly one DatasetId in top-level `ids`, no `targets`, -and the current table revision. Copy RowIds and ColumnIds from table reads; -page offsets, row numbers and names are not cell identities. For example: - -```json -{ - "tool_id": "table.patch", - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 12, - "ids": ["DATASET_UUID"], - "parameters": { - "table_revision": "TABLE_REVISION_UUID", - "edits": [{ - "row_id": "RETURNED_ROW_UUID", - "column_id": "RETURNED_COLUMN_UUID", - "value": {"kind": "float64", "value": 2.5} - }] - } -} -``` - -Values use the tagged `kind`/`value` representation returned by table reads. -Use decimal strings for Int64 and nanosecond temporal values, a JSON number or -`"NaN"`/`"+Inf"`/`"-Inf"` for Float64, and `{"kind":"null"}` for a missing cell. -Types and nullability must match exactly; a Float64 patch cannot silently widen -an Int64 column. Categorical values address existing level indices. Extension -values and live calculated region tables are not editable through this operation. - -A batch accepts 1–1000 distinct cells and at most 64 KiB of parameters. An absent -row/column, duplicate cell, invalid type or stale revision rejects the entire -patch. It cannot insert/delete rows, change schema, reimport files or write to the -original CSV/TSV. Preparation produces `update: {status:"prepared", output, -before_table_revision, changed}`; nothing is applied until execution. A no-op -returns `changed:false` without advancing the document revision or adding Undo. -Before a patch or refresh is committed, its values must remain valid for existing -curve bindings. For example, a column used as Y error cannot contain negative -amplitudes. A rejected update preserves the table, plots and Undo history. - -Table metadata, row pages and Series sources include -`freshness: {status, refreshable, reason, sources, mcp_refreshable, mcp_refresh_reason}`. -`refreshable` reports native refresh capability; `mcp_refreshable` additionally checks -the connection's supported recipe subset, not the current permission mode. Dataset -resource metadata exposes these as `table_refreshable`, `table_mcp_refreshable` and -`table_mcp_refresh_reason`, alongside `table_freshness` and its reason. `source` means no saved derived recipe; `current` means recorded input -revisions still match; `stale` means a direct or upstream input changed; -`unavailable` means sources or a supported recipe are missing. The data browser -marks affected relational tables **Out of date**, and their sheets explain why. -Stored results remain readable and drawable, with this explicit freshness state. -Editing a table invalidates its stored curve-fit analyses; Undo restores them. -A stale derived table's analyses describe its old result, not current source data. - -Refresh only when requested. Plan `table.refresh` with `ids:["DERIVED_DATASET_UUID"]` -and `parameters:{"table_revision":"CURRENT_DERIVED_REVISION"}`. It reruns the -persisted single-source `snapshot_read`/`project`/`filter`/`stable_sort`/`computed_column` -recipe, with the same expression and complexity limits as data-only transforms, -using current source snapshots and the existing reference executor/lineage path. -Other native recipes, including Pivot, are rejected by MCP refresh with a reason; -the native GUI/core refresh capabilities are unchanged. Before adoption, the output -must retain TableId and the column schema, including ColumnIds, types and units; -every output RowId must belong to the current input. A mismatch rejects the whole -refresh without changing tables, plot bindings or Undo. Refresh stale upstream tables first; -missing sources or recipes report a reason instead of recomputing unrelated data. -Existing manual cell edits on a derived table are rebased by stable RowId; missing -or ambiguous identities block the whole refresh, never fall back to row position. -Repeated refreshes retain those edits. `include_provenance:true` returns both the -current `operation` and the effective `refresh_recipe` through edit/rebase history. - -Optional `memory_limit_bytes` resolves the explicit value, then the saved recipe -budget, then 512 MiB; valid range is 1–536870912. This remains the executor's -materialized-result estimate, not a peak-memory limit. Patches, transforms and -refreshes share one background preflight, four prepared candidates and a 512 MiB -reservation limit; each patch reserves 64 KiB. Prepared summaries are at most -128 KiB and complete responses at most 256 KiB. Discover schemas and limits in the -`operation_constraints` and `limits` (`table_update`) capability sections. - -Both operations require **Read and modify** for preparation and execution. -Permission, document/table revisions and current inputs are rechecked before a -candidate can be adopted. Cancellation, project changes, connection stop or stale -inputs discard uncommitted work. Execute consumes the plan even when rejected. -After a lost response, inspect actual state; do not replay the submitted operation. - -Each patch or refresh is one independent Undo/Redo step. DatasetId, TableId, -ColumnId, existing RowId and native plot/Series identities remain intact; filters -can change which existing rows are present. Revisions and source mappings change, -while authored colors, axis ranges and panel frames stay untouched. Freshness is -computed from saved provenance and current revisions, so Undo/Redo restores the -corresponding freshness as well as values. Native sheet editing and refresh use -the same typed revision-adoption service. - -## Add a derived curve to an existing plot - -Use `plot.series.append` when a newly calculated table should appear beside the -existing curves, without replacing a plot. In the GUI, select the explicit plot, -open **Data → Add curve**, choose the source table, X/Y and optional Y-error -columns, then press **Append curve**. The old default-field **Add series** control -keeps its existing behavior for non-explicit plots. - -For MCP, omit top-level `ids`/`targets` and provide the exact whole plot target: - -```json -{ - "expected_project_context": "", - "expected_revision": 23, - "tool_id": "plot.series.append", - "parameters": { - "plot": {"resource": {"id": "/", "kind": "plotium.canvas.object", "parent_id": "", "local_id": ""}}, - "series": [{"kind": "line", "source": { - "dataset_id": "", "field_id": 0, - "table_id": "", "table_revision": "", - "x_column_id": "", "y_column_id": "", - "y_error_column_id": null - }}] - } -} -``` - -Copy targets, FieldId and all table/column IDs from discovery; labels are not -identity. The target must already have explicit coordinates. A batch adds -1–200 selected line/scatter/bar/box/violin curves, with at most 200 total curves in that plot. -Existing bars regroup to share their slots with appended bars. -The shared binding validator checks every source revision, complete curve data, -errors and units before one atomic commit. Compatible source units convert to -the plot's existing coordinate units; incompatible batches fail without adding -any curve. The binding service's 2,000,000 curve-row and pending-plan limits and -256 KiB response limit also apply, including existing curves in the affected plot. - -`preflight.binding_plan.appended` contains the proposed new Series targets; -`bindings` includes the unchanged existing and newly appended bindings. Execute -adopts those frozen IDs. One Undo removes the additions; Redo restores them. -Retired IDs are not reused by a different append after Undo. Existing Series -styles, coordinate meaning, authored axis ranges, plot/Panel identity and frames -remain unchanged. Preparation and execution require Read and modify; context, -revisions and permission use the same one-use-plan lifecycle as binding edits. -After response loss, inspect the proposed targets before making another plan. - -## Rebind an existing curve without changing another plot - -Two plots can use the same native table with different numeric X, Y and optional -symmetric Y-error columns. In the GUI, select a plot and expand **Data → Curve -columns** for its Series. Choose the columns and press **Apply curve binding**. -The table's shared default bindings are unchanged. - -For MCP, discover the exact Series target with `plotium_document_inspect` and -copy the DatasetId, TableId, FieldId, table revision and ColumnIds from -`plotium_table_columns`. Use project ColumnIds, not `source_column_id`, names, -trace positions or a guessed field resource address. Call `plotium_plan`: - -```json -{ - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 8, - "tool_id": "plot.series.bind", - "parameters": { - "edits": [{ - "target": { - "resource": {"id":"CANVAS_UUID/OBJECT_ID","kind":"plotium.canvas.object", - "parent_id":"CANVAS_UUID","local_id":"OBJECT_ID"}, - "component": {"kind":"series","id":0} - }, - "source": { - "dataset_id":"DATASET_UUID", "field_id":0, - "table_id":"TABLE_UUID", "table_revision":"TABLE_REVISION_UUID", - "x_column_id":"X_COLUMN_UUID", "y_column_id":"Y_COLUMN_UUID", - "y_error_column_id":null - } - }] - } -} -``` - -Replace every placeholder, including the numeric IDs, with discovered values. -Do not add top-level `ids` or `targets`: each edit carries its complete target. -`y_error_column_id` is a ColumnId, or null or omitted to remove the error binding. -Review `preflight.binding_plan.bindings`, including source mappings and row -diagnostics, then submit its one-use `plan_id` with `plotium_execute`. - -A default table Series can represent several displayed curves. First use -`plot.series.materialize_default` with -`parameters: {"edits":[{"target":EXACT_SERIES_TARGET, -"retain_y_column_id":"EXISTING_Y_COLUMN_UUID", -"table_revision":"TABLE_REVISION_UUID"}]}`. In the GUI, use **Expand default -curves** and choose the Y column that keeps the original SeriesId. The other -existing curves receive new owner-local SeriesIds, returned in the plan and -execution result. This expands existing content; it does not create a plot. -Fit overlays and normalized/offset multi-curve defaults cannot be expanded -losslessly and are rejected. Default drawing remains available without expansion. - -Only Int64 and Float64 columns are accepted. Integers that cannot be represented -exactly in f64 curve coordinates are rejected. X/Y nulls and non-finite values -create gaps, never zero values or connecting lines across a gap. A null error -keeps the valid point without its error bar; zero error is valid. Negative or -non-finite errors reject the entire batch, including on rows with missing X/Y. -Errors are non-negative absolute amplitudes; their names do not assign standard -deviation, standard error or confidence-interval meaning. Diagnostics count all -rows and include up to 20 affected RowIds per curve. No row sampling is used for -binding validation or native curve extraction. - -Compatible units are converted into the plot's persisted coordinate units. -Error amplitudes use scale only, not affine offsets. Known and unknown units -cannot be combined. Manual ranges and shifts retain their coordinate meaning -through rebinding, deletion of the first curve and reordering. An incompatible -binding is rejected rather than reinterpreting those numbers. Authored labels, -colors, line/point encoding, visibility, panel placement and axis settings stay -with their existing targets. Explicit plots retain line/point encodings rather -than switching to unrelated table chart types. - -A batch accepts 1–200 edits and at most 2,000,000 curve-row visits across the -affected plots. Pending MCP curve plans share that same row budget; complete -responses are limited to 256 KiB. All targets, columns, units, rows and revisions -are checked before one atomic commit and one Undo. There is no partial success -or skipped invalid target. Read-only connections reject binding preflight and -execution. Failed or stale execution consumes the plan; discover current state -and plan again. GUI save/reopen preserves the native bindings and units; MCP -`project.save` requires separate desktop approval; SVG/PDF/PNG exports require their own desktop approval. Use `plot.create` below to create a new plot. - -## Create a native single plot from an imported table - -Ask the agent: “Import this CSV, use time in s and current/error in mA, and create -one editable line plot with symmetric Y error bars. Preview it, then change only -that curve's line width to 1.5 pt and preview again.” Supply an absolute input path -and explicit units. The agent can discover the complete import and creation -schemas through the `operation_constraints` section of `plotium_capabilities_get`. - -After data-only import, read the actual DatasetId, FieldId, TableId, table revision -and ColumnIds from import results / table metadata. Plan `plot.create` without -top-level `ids` or `targets`: - -```json -{ - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 1, - "tool_id": "plot.create", - "parameters": { - "parent": {"resource": {"id": "document", "kind": "plotium.document"}}, - "name": "Current", - "series": [{ - "kind": "line", - "source": { - "dataset_id": "RETURNED_DATASET_UUID", - "field_id": 0, - "table_id": "RETURNED_TABLE_UUID", - "table_revision": "RETURNED_TABLE_REVISION_UUID", - "x_column_id": "RETURNED_TIME_COLUMN_UUID", - "y_column_id": "RETURNED_CURRENT_COLUMN_UUID", - "y_error_column_id": "RETURNED_ERROR_COLUMN_UUID" - } - }] - } -} -``` - -Replace every identity, including the example FieldId, with the actual returned -identity. `kind` is `line`, `scatter`, `bar`, `box` or `violin`; `y_error_column_id` is a -ColumnId, `null` or omitted for no error bars. A source can instead name columns: -`{"dataset_id":"DATASET_UUID","x":"time","y":"signal","y_error":"sd"}`. `x`, `y` -and optional `y_error` are exact, case-sensitive column names or ColumnIds; -Plotium fills in the default field, table and current table revision. A missing -or repeated name fails with `invalid_parameters`, the path in -`error.details.field` and the table's columns in `error.details.candidates`. -The plan response lists each source resolved this way in `resolved_sources`. -The same source forms apply to `plot.series.append` and `plot.series.bind`. A `bar` curve draws filled bars from zero with optional -error whiskers, filled in the curve color with a thin outline. Whiskers use the -outline's color and width, and their caps span 45% of the bar. A bar too small -for its outline on paper (narrower than 4 or shorter than 2 outline widths, such -as a near-zero value) is drawn as a plain fill, keeping its whiskers. On a numeric -x, a slot is the typical spacing between positions, narrowed only where -neighbours sit closer. Its x column may be numeric or a -Utf8 text column; text values become categories in table row order, and equal -texts share one slot. Bar curves that share a slot sit side by side within it; a -bar alone in its slot keeps the full width, so one bar curve per category gives -centred bars in their own colors. A `box` or `violin` curve summarises the raw y -samples that share each x (Tukey box: median, IQR and 1.5 × IQR whiskers with -outliers; violin: Gaussian kernel density with a quartile bar), takes no y error -column, and shares slots with bars. `line` and `scatter` curves may use a text x -too and overlay the slots: the k-th line or scatter curve sits on the k-th bar, -box or violin curve's position, so raw points line up with their bar. -`series.points.spread` spreads replicate points that share an x across that -mark (0–1 of its width, in row order), and `series.value_labels` writes each -bar's or point's value past its end (or whisker) in tick-label size. -`object.chart.orientation` `horizontal` turns an explicit plot on its side: -categories run down the vertical axis, first at the top, and values along the -horizontal one; error bars, labels and axis titles turn with it, and the view -resets. All series in one plot share a text or a numeric x. Plots with bars, -boxes or violins have no logarithmic axes. Optional `y_axis` -is `left` (default) or `right` for a line or scatter curve; `right` on a bar, -box or violin is rejected. Any right curve gives the plot a right y axis with its own automatic -range, scale and title, which starts as the first right curve's column name and -unit; that curve also fixes the right axis's unit. Reference lines, annotations -and arrows stay in left-axis coordinates. Multiple entries create independent native Series in this -one plot, not separate plots. Source extraction and all numeric, missing-value, -error and unit rules are the same as explicit curve binding above. Table-wide -X/Y defaults and other plots are untouched; no source table is copied. - -Optional `intent: {purpose, claim}` records what the plot is meant to show. -`purpose` is `compare`, `trend`, `distribution`, `relationship`, `composition`, -`change` (ratio or fold difference) or `detail` (zoom or inset); `claim` is one -sentence of at most 500 characters. Ask the user for both before creating a -plot instead of guessing; if they leave it open, propose your reading and let -them confirm or edit it. The intent never changes the drawing. It is saved with -the project, edited later through `object.intent.purpose` (`unspecified` clears -it) and `object.intent.claim`, and shown under **Chart › Advanced** in the Object inspector. - -The exact `parent` determines which objects are new: - -- Document root: create canvas, single panel and plot. Optional - `canvas: {name, size_mm: [width, height]}` sets the new canvas (10–1000 mm per - dimension), or `canvas: {name, size_preset}` uses a built-in page size such as - `nature-1col` (89 mm), `nature-1p5col` (136 mm) or `nature-2col` (183 mm) with - its default height and margins (0 mm for journal columns, 15 mm for paper, - 10 mm for slides); the result reports the applied `size_preset`. Omission freezes the native default size and - plot name. -- Existing canvas without a panel or plot: create panel and plot using native - GUI empty-page placement and the canvas's existing layout settings/margins. - Do not supply `canvas` options. -- Existing canvas with content: supply `panel_frame_pt: [x,y,width,height]` to - create another panel and plot at that exact page-relative pt frame. Existing - panels, curves and loose content stay in place; overlap is allowed. -- Its sole empty, visible, unlocked free-layout panel: create only the plot, - preserving the panel's page position and size. Omit `canvas`, `panel_name` and `panel_frame_pt`. - -`panel_name` optionally names a newly created panel; otherwise it uses the plot -name. Names must be nonblank and at most 1024 UTF-8 bytes. `panel_frame_pt` -sets only a newly created panel: X/Y are finite page pt, width/height are finite -and positive. Omission retains the original empty-page native placement contract; -an already plotted canvas requires the explicit frame. Existing content is never -retiled or rebuilt into a replacement plot. - -The MCP plan returns `plan_id`, `project_context` and `basis_revision`. -`preflight` includes `required_authority`, `created_target_count`, exceptional -`targets` and `outputs`. `preflight.binding_plan.creation` contains the exact -`parent`, proposed complete `canvas`, `panel`, `plot` and `created` targets -(including all Series), plus `size_mm`, any `size_preset`, `panel_frame_pt` -(page coordinates), `frame_pt` (panel-local coordinates), `coordinate_units` -and `series_defaults` (kind and line width in pt). Keep these frozen identities -when checking an uncertain execution outcome. - -`preflight.binding_plan.binding_count` counts curves, and `row_counts` sums -`total_rows` and `plotted_rows` across them. `binding_plan.bindings` includes only -curves with missing/non-finite data or missing errors, with each complete target -and full diagnostics including sample `affected_rows`. An empty list means no -such issues, not zero bindings. The response omits echoed requests, frozen-target -duplicates, source mappings and successful-target explanations; the stored plan -still retains the complete validated sources and candidate. - -Planning creates nothing. Executing the single-use plan returns -`value.creation` with the same canvas/panel/plot and layout, and `value.bindings` -with **every** Series target and its `total_rows`, `plotted_rows`, `missing_xy`, -`non_finite_xy` and `missing_error` counts. Defaults are disclosed only in -preflight. `produced` lists newly created resources; `summary` counts target -outcomes, while `targets` retains only exceptional rows. Diagnostics and -verification remain available. `project_context` and `after_revision` identify -the committed result. - -The creation is atomic: a bad source, incompatible units, invalid error or -changed parent/revision leaves no new canvas, panel or partial plot. Read-only -connections reject creation preflight and execution. There are 1–200 curves per -plot, at most 2,000,000 curve-row visits, a shared 2,000,000-row pending-plan -budget with binding edits, 32 pending plans and a 256 KiB structured-response -limit. Failed submissions consume their plan too. After a lost execute response, -query current state and the proposed targets before deciding what to do; do not -blindly make a new creation request. - -Use returned targets with document inspection and properties; preview the -returned whole-canvas target at the current revision. The result is selectable -and editable in the GUI. One Undo removes the created subtree but keeps existing -parents and imported data; Redo restores the same IDs. Existing native resize -and layout controls retain plot/Series identities and source bindings. Known exact -targets may reuse committed synchronous results; refresh state after desktop edits -or Undo/Redo. - -## Author page layout, text and local images atomically - -Plan `figure.edit` with `parameters: {canvas: EXACT_CANVAS_TARGET, edits: [...]}`; -omit top-level `ids`/`targets`. Discover the complete tagged edit schema with -`plotium_capabilities_get {"section":"operation_constraints","key":"figure.edit"}`. -One batch changes one canvas, in supplied edit order, with one Undo/Redo: - -| `op` | Required fields and meaning | -| --- | --- | -| `page` | At least one of `size_mm: [width,height]` or `size_preset`, `margin_mm: [top,right,bottom,left]`, `gutter_mm`; lengths in mm. A journal `size_preset` sets the column width and keeps the height of a page with content; paper and slide presets set both dimensions. Presets also replace the page margins (0 mm journal, 15 mm paper, 10 mm slides) unless `margin_mm` is given; the result reports `size_preset` | -| `panel_frame` | `target: EXACT_PANEL_TARGET`, `frame_pt: [x,y,width,height]` in page pt | -| `content_frame` | `target: EXACT_CONTENT_TARGET`, complete `frame_pt: [x,y,width,height]` in parent-local pt; changes only this item | -| `image_replace` | `target: EXACT_RASTER_TARGET`, `path`; replaces only its asset reference with frozen local PNG/JPEG | -| `content_delete` | `target: EXACT_CONTENT_TARGET`; removes this content, retaining its empty parent | -| `panel_delete` | `target: EXACT_PANEL_TARGET`; requires an originally empty panel | -| `series_delete` | `target: EXACT_SERIES_TARGET`; removes a non-final explicit Series | -| `panel_label` | `target`, `text`, `visible`; writes a native manual panel label, preserving its position/font | -| `panel_stack` | `panel: EXACT_PANEL_TARGET`, `shared_x: true\|false`; optional `gap_pt` (0–144) and `merge: [EXACT_PANEL_TARGET,...]`, both only with `shared_x: true`. Stacks the panel's plots on one shared x axis or returns it to free layout | -| `align` | `panels: [EXACT_PANEL_TARGET,...]`, `edge: left\|center\|right\|top\|middle\|bottom`; at least two panels | -| `distribute` | `panels`, `axis: horizontal\|vertical`; at least three panels | -| `grid` | `panels`, `rows`, `cols`; native Frame-basis cells in supplied target order | -| `text_create` | `parent: EXACT_CANVAS_OR_PANEL_TARGET`, `name`, `frame_pt`, `text`, `font_pt` | -| `text_set` | `target: EXACT_TEXT_TARGET`, `text`; optional `font_pt` | -| `image_create` | `parent`, `name`, `frame_pt`, `path: "/absolute/local/image.png"` (PNG or JPEG) | -| `annotation_create` | `target: EXACT_PLOT_TARGET`, `text`, `at: [x,y]` in the plot's data coordinates, `font_pt`; optional `kind: "text"`, `color: "#rrggbb"` | -| `annotation_create` (reference line) | `target: EXACT_PLOT_TARGET`, `kind: "reference_line"`, `orientation: vertical\|horizontal`, `value`; optional `label`, `font_pt`, `line: {color, width_pt, style}` | -| `annotation_create` (arrow) | `target: EXACT_PLOT_TARGET`, `kind: "arrow"`, tail `at: [x,y]`, head `to: [x,y]`; optional `head: none\|open\|filled\|double`, `line_width_pt`, `color: "#rrggbb"` | -| `annotation_set` | `target: EXACT_PLOT_TARGET`, `annotation_id`; at least one of `text`, `at`, `font_pt`, `color`, `offset_pt`, `placement` (text), `orientation`, `value`, `label`, `font_pt`, `line`, `placement` (reference line) or `at`, `to`, `head`, `line_width_pt`, `color` (arrow); optional `override_hand_edits` | -| `annotation_delete` | `target: EXACT_PLOT_TARGET`, `annotation_id` | - -For example, after creating two plots, set their page and selected-panel grid: - -```json -{ - "tool_id": "figure.edit", - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 3, - "parameters": { - "canvas": {"resource":{"id":"CANVAS_UUID","kind":"plotium.canvas"}}, - "edits": [ - {"op":"page","size_mm":[180,90],"margin_mm":[4,4,15,4],"gutter_mm":5}, - {"op":"grid","panels":[{"resource":{"id":"CANVAS_UUID/panels/PANEL_A_UUID","kind":"plotium.canvas.panel","parent_id":"CANVAS_UUID","local_id":"PANEL_A_UUID"}},{"resource":{"id":"CANVAS_UUID/panels/PANEL_B_UUID","kind":"plotium.canvas.panel","parent_id":"CANVAS_UUID","local_id":"PANEL_B_UUID"}}],"rows":1,"cols":2} - ] - } -} -``` - -Replace all identity placeholders with discovered complete targets, not names. The resulting frames are (4,4,83.5,71) and (92.5,4,83.5,71) mm. -A frame uses a top-left origin, X rightwards and Y downwards; 1 pt = 1/72 inch. -Panel frames use the existing **Object Geometry/drag authoring** semantics: -moving preserves child-local coordinates; resizing scales all child-local frames -proportionally, without changing curve IDs, bindings, styles, axis ranges or fonts. -This differs from the free Panel inspector's container-only dimensions. -New text/image frames are parent-local pt, or page pt for a canvas parent. - -`panel_stack` with `shared_x: true` needs at least two plots. `plot.create` -places each new plot in its own Panel, so list the other plots' Panels in -`merge`: they are merged into `panel` and their plots are stacked top to bottom -in their page order, like **Stack with Shared X** on the desktop. Without -`merge` the plots keep the Panel's content order. The stack fills the Panel's -inner width; -their heights keep the proportions of their current frames, so change one with -`content_frame` to give it a larger share. The gap defaults to 0 pt when the -stack is turned on. Only the bottom plot draws x tick labels and the x title, -only the top plot draws a figure title, inner boundaries touch with inward x -ticks, and the plot areas share left and right edges. Entering the stack writes -one x range covering every member's data (in its own coordinate unit) and the -top member's x major step (in the unit it displays) to each member, so members -must already share an x scale; every member draws the bottom -member's x direction without storing it. The plots share one x viewport, and -later x range, x scale, x display unit, x thousands-separator and x major step -edits on any -member apply to all of them in one Undo step; the write is rejected when any -member cannot take the value, and `applied` lists the member edits. A batch that -requests conflicting shared x settings is rejected without changes; equivalent -ranges expressed in compatible coordinate units are accepted. -`shared_x: false` returns the Panel to free layout and keeps -the frames. The result lists each operation in `panel_edits` with `layout`, -`gap_pt`, `members_top_to_bottom` and `merged_panels`. `plotium_document_inspect` reports every -Panel's `layout` (`free`, `vertical_stack`, `horizontal_stack`, `grid` or -`shared_x_stack`); a stack adds `shared_x_stack: {members_top_to_bottom, -gap_pt}`. `plotium_figure_diagnose` and plan previews use the stacked geometry. - -Plot annotations are anchored in data coordinates, not page pt: the label is -centred above its `at` point and follows the plot's axis ranges, zoom and pan, -in the canvas and in every export. When that spot covers data, the legend, a -value label or another label, the text moves to the nearest clear spot within -about three text heights; an arrow pointing at it does not count. -`offset_pt: [dx, dy]` (pt, x right, y up) pins the text there instead, with -`[0, 0]` exactly at `at`, and `placement: "auto"` returns it to automatic -placement. `color` (`#rrggbb`) sets the text colour, black by default. A label -the user dragged on the canvas keeps its place through edits of `text` and -`font_pt`; a new `at`, `offset_pt` or `placement` on it is rejected unless -`override_hand_edits: true` says the user asked. Each text in -`annotations` reports `placement` (`auto`, `fixed` or `hand`) and the drawn -`offset_pt`, and `plotium_get_state` lists dragged labels under `hand_edits` -with key `annotation.label_position`. An anchor outside the visible range is -clipped with the plot. `annotation_id` is local to the plot and never reused -after deletion; read it from `annotation_edits` in the result or from the plot's -`annotations` list in `plotium_document_inspect`. `at` uses the plot's source -units reported in `coordinate_units`, not a display unit chosen for the tick -labels. `\n` in `text` starts a new line. -Annotation text permits 1024 UTF-8 bytes (nonblank), and a plot holds at -most 256 annotations. The plot and its parent panel must be unlocked; Auto height -may stay on. - -A reference line is a plot annotation of `kind: "reference_line"`: a vertical -line at x = `value` or a horizontal line at y = `value`, in the same source -units as `at`, that spans the whole plot area. It follows the axis ranges, zoom -and pan, and disappears when `value` lies outside the visible range. `line` -sets `color` (`#rrggbb`), `width_pt` (0.1–20) and `style` (`solid`, `dashed`, -`dotted` or `dash_dot`); a new line defaults to `#000000`, 0.75 pt (or the -theme's supporting-line width, 0.3 pt under Nature), dashed, and -omitted `line` fields keep their value on `annotation_set`. The optional -`label` is drawn in the line colour near the top of a vertical line or the right -end of a horizontal one, or further along the line or on its other side when -that spot covers data, the legend or another label; inspection reports -`label_placement` and the drawn `label_position: {along, side}`, and -`placement: "auto"` returns a dragged label to automatic placement under the -same `override_hand_edits` rule. It uses the tick label size until `font_pt` sets an -explicit size, which then stays until changed. An empty `label` removes it. Reference lines and text -annotations share one id sequence and the 256-per-plot budget, and -`plotium_document_inspect` lists both under `annotations`, each with its `kind`. -Fields of the other kind are rejected rather than ignored; a reference line -takes its colour in `line.color`, not `color`. - -An arrow or reference line the user moved on the canvas reports -`hand_moved: true` and is listed under `hand_edits` with key -`annotation.position`. Restyling it is allowed, but a new `at` or `to` on such -an arrow, or a new `value` or `orientation` on such a line, is rejected unless -`override_hand_edits: true` says the user asked; the moved position then -becomes the agent's again. - -```json -{"op":"annotation_create","target":EXACT_PLOT_TARGET,"kind":"reference_line", - "orientation":"horizontal","value":0,"label":"baseline", - "line":{"color":"#7f7f7f","width_pt":0.5,"style":"dotted"}} -``` - -An arrow annotation (`kind: "arrow"`) draws a straight line from its tail `at` to -its head `to`, both in the same data coordinates, so it follows the axes and is -clipped to the plot area like a label. `head` defaults to `filled` (`double` -fills both ends, `none` draws a plain line); `line_width_pt` (0.1–20 pt) defaults to 1 pt, or the -theme's supporting-line width (0.3 pt under Nature); `color` defaults to black. The two ends must differ. An arrow carries no -text: label it with a separate text annotation, for example at its tail. Arrows -share the `annotation_id` sequence and 256-per-plot budget with the other kinds, -are listed under `annotations` with `kind: "arrow"`, and reject fields of the -other kinds. - -Align uses the selected bounding edges/centres. Distribution equalizes centres -between fixed endpoints, not edge gaps. Grid composes the existing native cell -algorithm with the authoring resize setter for an explicit subset; it does not -claim an existing GUI subset-grid button. Grid uses the current page margins and -gutter, but does not change saved grid preferences or simplify axes. Page size -and margin edits alone never rearrange content. Non-target panels and loose -content remain in place, including any resulting overlap or clipping. - -Panel layout-operation targets must be distinct, on this canvas, unlocked and -use free or shared-x stack layout; new text and images need a free-layout parent; -locked children reject a panel edit. Hidden explicit targets remain addressable. Turn off native Auto height before -exact page/layout authoring. -Dimensions must be finite/positive; page size is 10–1000 mm, margins/gutter are -nonnegative and must leave positive space. Grid is 1–16 rows/columns with enough -cells for every target; each cell must reach the native 1 pt minimum. Text permits 16384 UTF-8 bytes and 1–72 pt fonts; names -and manual labels permit 1024 bytes (nonblank). A batch permits 1–200 edits and -at most 200 panels per layout operation. - -Image preflight reads only explicitly named absolute regular files: at most 8 -image inputs (creation and replacement combined; duplicates still count), 1 MiB encoded per file, 4 MiB encoded per batch, and 4 MiB decoded RGBA8 -per image. PNG/JPEG probing and decoding reuse native image I/O; bytes are frozen -in the plan and embedded in the native asset store at commit. Identical encoded -assets are shared, not linked to the external path. Missing/damaged assets or -unsupported formats reject the entire batch with `invalid_parameters` and a -specific asset error. There is no directory scan, network fetch or source write. - -`preflight.figure_plan` reports proposed `created`/`modified` targets and `result` -with page dimensions, margins/gutter and exact `panel_frames`. Execute returns -that result in `ToolResult.value`. Preflight commits nothing; invalid targets, -geometry, assets or a stale revision leave no partial objects. Both planning and -execution require Read and modify. Plans are single-use, including failed -execution; the 32-plan and 256 KiB response limits apply. One Undo restores the -whole batch; Redo restores the same native content and asset IDs. After a lost -execute response, inspect the proposed targets before making another create call. - -Use the ordinary GUI Object Geometry, text and image inspectors to continue -editing. Preview the actual canvas PNG after layout changes; native text frames -can clip long text, and layout never silently shrinks fonts or resolves collisions. - -## Move existing content or replace an image in place - -To widen an existing caption or replace one of two images sharing an asset, first -inspect the exact content with `plotium_document_inspect`, `view: "self"`. Copy -its complete target, not its name, selection or collection position. Use the -current context/revision and plan `figure.edit` with edits such as: - -```json -[ - {"op":"content_frame","target":{"resource":{"id":"CANVAS_UUID/CONTENT_ID","kind":"plotium.canvas.object","parent_id":"CANVAS_UUID","local_id":"CONTENT_ID"}},"frame_pt":[12,18,140,30]}, - {"op":"image_replace","target":{"resource":{"id":"CANVAS_UUID/IMAGE_ID","kind":"plotium.canvas.object","parent_id":"CANVAS_UUID","local_id":"IMAGE_ID"}},"path":"/absolute/local/replacement.png"} -] -``` - -Place this array in `parameters.edits` alongside the discovered whole-canvas -`parameters.canvas`. Omit top-level `ids`/`targets`. The two targets above may be -different items; to move and replace the same image, repeat that image's target. -Existing text/font edits still use `text_set`. - -`content_frame` supports native plot, text, raster and existing rect/ellipse/line/ -arrow content, without creating or reparenting anything. It sets a **complete** -frame, not a relative delta. Coordinates use the parent's local pt, or page pt -for loose content: top-left origin, X rightwards, Y downwards. `parent` identifies -the actual canvas/panel; `page_frame` uses the native parent-origin translation. -Positions may extend beyond the panel or page and are not clamped or snapped. -All components and converted bounds must be finite, and width/height must be at -least 1 pt. This numeric minimum does not change the GUI drag minimum. - -Only the target item changes (in a shared-x stack its siblings reflow to the -new share): its parent and siblings otherwise keep their frames/order; -plot bindings, Series identities, sources, units, manual axis ranges and styles, -and text contents/fonts remain intact. The target and its parent must be unlocked; -a parent must use Free or Shared X Stack layout and Auto height must be off. In a -shared-x stack only the height counts: it sets the item's share of the stack, and -the stack reflows. A locked sibling does -not block this edit. `geometry.frame_editable` and `frame_edit_error` report these -native eligibility conditions, independent of connection modify permission. - -For a raster with `preserve_aspect: true`, dimensions preserve the **existing -frame ratio**, not the replacement's pixel ratio. The native aspect rule chooses -the width/height scale with the larger absolute departure from 1 (width wins a -tie), bounded by the 1 pt minimum. Requested X/Y remain the top-left anchor. -Preflight reports `requested_frame_pt` and `effective_frame_pt`; they may differ. -`geometry` exposes `min_size_pt`, `preserve_aspect` and `aspect_ratio`. -`fit` independently controls contain/cover/stretch rendering within the frame. - -`image_replace` sets only the target's AssetId. It retains ContentId, parent, -frame, z-order, name, visibility and all native image attributes: -`page_index`, crop, fit, quarter-turn rotation, opacity, interpolation and -preserve_aspect. Other references to the old asset remain unchanged. A retained -crop/fit can make the new image look different; settings are never reset to hide -that effect. PNG/JPEG replacement requires the existing `page_index` to be 0; -other pages reject the batch instead of silently changing page index. Replacement -requires the target/parent unlocked, but not Free layout or Auto height off. -`image.replaceable` and `replace_error` disclose that eligibility. - -Creation and replacement share the image budgets above, byte freezing, encoded -asset deduplication, embedding and Undo lifecycle. Changing or deleting the source -after preflight cannot alter the candidate or Redo. There is no source write or -asset garbage collection. Bad files, unsupported formats, wrong/stale targets, -locked targets and invalid geometry reject the whole batch, not just that edit. - -`preflight.figure_plan.result.content_edits` reports each new edit in input order: -`edit_index`, `op`, `target`, `parent`, `frame_space`, `before_frame_pt`, -`effective_frame_pt`, `page_frame` and `geometry`; frame edits add -`requested_frame_pt`, replacement adds `asset_change` with `before`/`after` -AssetIds, `format` and `pixel_size`. These are the state at that edit's step. -`result.content_frames` gives the final geometry for each distinct targeted -content after all edits, including any later explicit parent-panel resize. -Execute returns the same result in `ToolResult.value`. Both operations reuse the -same permission/context/revision checks and one-use plans as other figure edits; -one Undo restores the batch's frames and asset references, Redo restores the -same identities and frozen image. Inspect/render the committed state afterwards. - -## Delete exact content or selected Series - -Ask the agent: “Delete this duplicate note and this redundant curve, keeping the -other curve with the same name.” Discover the complete canvas/content targets -and plot-owned Series targets first. Do not identify them by name, row index, -visible trace number or the current GUI selection. - -Use a deletion-only `figure.edit` batch on one canvas: - -```json -{"tool_id":"figure.edit","expected_project_context":"PROJECT_CONTEXT","expected_revision":12,"parameters":{ - "canvas":{"resource":{"id":"CANVAS_UUID","kind":"plotium.canvas"}}, - "edits":[ - {"op":"content_delete","target":{"resource":{"id":"CANVAS_UUID/CONTENT_ID","kind":"plotium.canvas.object","parent_id":"CANVAS_UUID","local_id":"CONTENT_ID"}}}, - {"op":"series_delete","target":{"resource":{"id":"CANVAS_UUID/PLOT_ID","kind":"plotium.canvas.object","parent_id":"CANVAS_UUID","local_id":"PLOT_ID"},"component":{"kind":"series","id":2}}} - ] -}} -``` - -`content_delete` removes one whole native plot, text, raster or existing -rect/ellipse/line/arrow shape. Deleting a plot does not delete its source Dataset. -`panel_delete` takes a complete Panel target and requires it to be empty in the -original state. Deleting all its children in the same batch does not make a -nonempty panel eligible. Content deletion retains the empty parent panel and -does not reflow siblings. - -`series_delete` removes only the exact SeriesId inside its owning plot. It -supports line/scatter plots with explicit column bindings and an established -coordinate contract, including bindings to derived tables. The last Series -cannot be removed: use an explicit `content_delete` to remove the whole plot. -Table-default bindings and dynamic multi-channel displays are rejected; this -operation never materializes, rebinds or edits a Dataset. Remaining Series keep -their identities, sources, order, encodings, coordinate units and manual ranges, -including when the first Series is deleted. - -Duplicate targets, a whole plot plus any of its Series, cross-canvas targets, -locked targets/parents, and mixing deletion with non-deletion edits reject the -whole batch. Hidden exact targets remain eligible. A locked sibling is not a -reason to reject an unrelated deletion. Native automatic page height remains -enabled if it was enabled; its derived height is reported, not silently disabled. - -Read `preflight.figure_plan.deleted` and `result.deleted_targets` before executing. -`result.deletions` includes parent/order information and all owned Series removed -with a plot. `parent_changes`, `group_changes`, `viewport_link_changes` and -`selection_change` list necessary relationship updates; group/link changes retain -surviving members or remove a relationship that has fewer than two members. -`remaining_series` reports the surviving order and active Series identity, `retained_asset_ids` lists the -assets referenced by removed raster content, and `auto_height` reports derived -before/after heights when enabled. These are metadata, not a candidate image. -Execute returns the same deletion manifest in `ToolResult.value`. - -Planning commits nothing. One successful execute is one atomic Undo/Redo; -invalid batches leave no partial deletion. Undo restores exact identities, -parents, object/panel order, groups, links and necessary selection. Identity -allocator high-water marks never move backwards. No original file, Dataset or -asset is deleted. Runtime Undo retains embedded assets; saving uses the existing -reachable-asset policy, and reopening a project does not restore Undo history. - -The existing modify permission, project-context/revision checks and one-use -plan rules apply. A selection change that alters the reported deletion effect -also requires a new preflight, even though GUI selection does not advance the -revision. Up to 200 explicit deletion targets, 2,000,000 remaining curve-row -visits per Series candidate batch, 32 shared pending plans and the complete -256 KiB response budget apply. Oversized manifests fail rather than truncate. -Target/contract failures return `invalid_parameters` with the reason; -`stale_revision`, `project_changed`, `permission_denied`, `expired_plan`, -`plan_limit` and `response_too_large` retain their existing meanings. - -After an unknown execute outcome, rediscover the current context, revision and -exact targets before planning again; do not replay deletion automatically. View -the committed PNG, then use native Undo/Redo and save/reopen to check the result. - -## Diagnose figure geometry at an output size - -Ask: “At 180 × 90 mm, report out-of-page content, clipped geometry, text overflow, -intentional overlap between these two captions, and possible line/scatter occlusion -by legends. Do not edit anything. Inspect the returned targets and native PNG.” - -After discovering the canvas, call `plotium_figure_diagnose` directly (no edit plan): - -```json -{ - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 7, - "canvas": {"resource":{"id":"CANVAS_UUID","kind":"plotium.canvas"}}, - "output": {"size_mm":[180,90]}, - "checks": ["bounds","clipping","text_overflow","content_overlap","legend_occlusion","data_shape","layout_aesthetics","intent"], - "detail": "full", - "limit": 100 -} -``` - -Copy complete content or Series targets into optional `targets` to narrow the scan. -A Series target also includes its owning plot frame and guides as context. -Omission scans the canvas; it never uses GUI selection. `content_overlap` additionally -requires explicit whole-content `overlap_targets` (at least two). It compares visible, -page-clipped frames, not opaque pixels. `view` accepts `issues` (default) for -findings, `layout` for measured geometry rows instead, or `both`. `detail` is -`compact` (default) or `full`. Compact issue rows keep `target`, `component`, -`code`, `severity`, `message`, `measurement_basis` and any `suggestions`; their -`evidence` keeps only `other_target`, `other_component`, `point_range` and -`interpretation`, and coverage rows of checks that completed are left out. -`full` returns all evidence geometry and every coverage row. Coverage rows that -report a limit are always returned. - -`output.size_mm` must be positive and preserve the canvas aspect ratio (0.001 mm -height tolerance). Like native export, it uniformly scales the existing page without -reflow. Every initial query recalculates geometry. Results use `output_page_pt`: -72 points per inch, top-left origin, X right, Y down. `output` includes native size -and scale; text, stroke widths and bounds scale together. Panel-local frames are -converted through the native page-frame service. Plot data uses the actual plot -clip; a panel border is **not** a general content clip. Native raster frame and -`clip_children` clipping are reported separately. - -`ToolResult.value` contains `project_context`, `basis_revision`, `canvas`, `summary`, -`output`, `items`, `coverage`, `truncated` and `continuation`. In the default -compact detail, `output` has `size_mm` and `size_pt`, and `coverage` reports its -status, scan counts and unavailable or unsupported items. `detail: "full"` adds the -page coordinate description to `output`, the requested, supported and unsupported -check lists to `coverage`, and `budget`, `preview_request` and `read_policy`. `summary` -counts the issues on this page (`issues`, `by_code`, `by_severity`); add the -counts of every page of a continued scan. Each issue has a full native `target`, -an owner-relative `component`, `code`, `severity` and explanation; with -`detail: "full"` its evidence also carries bounds, clip and intersection geometry. Pass `target` to `plotium_document_inspect` -with `view: "self"`; names do not identify objects. `guide.legend` belongs to its -plot, not a new resource. A curve conflict points to the existing Series and its -owning plot's legend through `evidence.other_target` / `other_component`. - -- `out_of_canvas`, `partially_clipped`, `fully_clipped` and - `curve_primitives_clipped` / `shape_clipped` are informational facts, including intentional manual - range clipping. Curve evidence applies to the reported native run's point range. -- `text_container_overflow` is a warning based on native width/line-spacing - **estimates**, not exact glyph ink. Text does not automatically wrap or shrink. -- `content_frame_overlap` is informational; deliberate overlap is allowed. -- `axis_ticks_sparse` is a warning: at the output size an axis with shown tick - labels draws fewer than two ticks, so its scale cannot be read. Enlarge the - panel or lower `object.figure.typography.tick_pt`. -- `right_axis_untitled` is a warning: curves use the right y axis but it shows - no title. Set `object.axes.y2_label` (or turn `object.axes.y2_show_label` - back on). -- `legend_occlusion_potential` is a warning, not a claim that data is invisible. - The scan visits projected line segments and marker shapes after effective - clipping, retaining dash phase across batches. It does not use a whole-curve - bounding box or sample points. Stroke envelopes and the legend layout rectangle - are conservative; rounded corners, translucency and exact antialiasing can differ. - -The `data_shape`, `layout_aesthetics` and `intent` checks report issues with severity -`hint`: the figure could show its data more clearly, nothing is wrong. They are -included when `checks` is omitted. Hints never edit the document. Each carries -`suggestions`, a list of `{action, property, target, reason}`; `property` names a -property to set on `target`, or both are null. Lengths are measured at the -requested `output.size_mm`; the thresholds are provisional. A query narrowed to -Series reports Series hints for those Series only. - -| Code | Fires when | -| --- | --- | -| `small_values_invisible` | A bar's value is under 1 % of the value-axis span, or it prints under 0.5 mm, beside bars at least 5 mm long | -| `bars_too_narrow` | A bar prints narrower than 0.6 mm | -| `few_samples_hidden` | Every group of a box or violin Series, or of a bar Series with repeated rows per x, has fewer than 10 values, or a bar Series of one row per x has `series.replicates` of 1–9; and the plot has no scatter Series | -| `too_many_categories` | The category axis draws its labels but drops some, or neighbouring labels collide | -| `log_scale_candidate` | A plot without bars, boxes or violins has only positive line or scatter values on a linear value axis, spanning three or more decades | -| `bar_baseline_not_zero` | The value-axis range leaves out the bars' baseline | -| `labels_overlap` | Two text boxes on the canvas overlap by more than 0.2 mm in both directions; evidence names both and a direction to move the second. Entries of one legend and tick labels of one axis are not compared with each other | -| `text_over_data` | An annotation or value label overlaps a bar, box, violin, line or marker | -| `intent_mismatch` | The chart form does not suit the plot's `object.intent.purpose` (see below) | -| `panels_misaligned` | Two frames in one column (left edges within 1 mm) or row (bottom edges within 1 mm) have plot areas whose left or bottom edges differ by more than 0.5 mm, or the gaps between three or more frames in a row or column differ by more than 0.5 mm | - -Hints beyond 50 of one kind, and checks that hit a budget, add an `unavailable` -coverage row. - -The `intent` check weighs each plot built from explicit columns against the -purpose its author stated; `detail` is never reported. A plot without a purpose -gets a `not_applicable` coverage row, `no_purpose_stated`: ask the user what it -should show. Table chart types get `chart_type_not_covered`. `intent_mismatch` -evidence keeps the reason in `interpretation` and, with `detail: "full"`, adds -the purpose, the claim and the chart features it read. Its suggestions name -chart forms Plotium can draw; relay them and let the user choose. - -| Purpose | Reported when | -| --- | --- | -| `compare` | Lines join categories | -| `trend` | The category axis holds categories, or the plot draws bars | -| `distribution` | On a category axis, bars or lines without a box, violin or scatter Series | -| `relationship` | The category axis holds categories, or the plot draws bars, boxes or violins | -| `composition` | The plot draws lines or points but no bars | -| `change` | Two or more bar Series sit side by side, or positive bar values span tenfold or more; or, without bars, boxes or violins, positive left-axis line or scatter values span tenfold or more on a linear axis | - -Native guide layout includes estimated text widths. Font availability is checked -using native export font discovery; glyph coverage and cross-backend ink bounds -remain unverified. Raster viewport geometry uses header dimensions, integer crop, -rotation and fit; successful decoding and alpha-pixel coverage require the preview. -Non-line/scatter internal geometry, error-bar clipping/occlusion, derived scientific -annotations and opaque-pixel occlusion are not covered. Native rectangle, ellipse, line and arrow extrema use the actual page clip. Their frame/guide -observations remain available; coverage states the limitation. Beyond the hints -above, this tool does not judge aesthetics, scientific correctness or statistical -significance. - -**Read coverage even when no issues are returned.** Per-target statuses distinguish -`complete`, `unsupported`, `unavailable` and `not_applicable` (for example hidden, -empty rendered data or absent legend). Overall `partial` means more pages remain; -`limited` means completed traversal with unsupported/unavailable parts. Estimates -remain estimates even with completed traversal. Counts describe scanned objects, -source points and overlap pairs, never a percentage of pixels. Missing assets/fonts, -invalid sources and excluded geometry are reported, not treated as a clean figure. - -Follow a non-null `continuation` using only these arguments: - -```json -{"expected_project_context":"PROJECT_CONTEXT","expected_revision":7,"cursor":"RETURNED_CURSOR"} -``` - -The one-use cursor binds the original target, output, checks and page configuration -and expires after 300 idle seconds. A new initial query replaces the previous scan. -Finish all pages before claiming coverage; an empty issue page can still be truncated. -Only one diagnostic batch and one unread snapshot are retained per desktop connection. -The native stdio facade keeps one diagnostic transport between pages and closes it -when stdio ends; other tools retain their one-call, never-replayed transport. -Limits are 200 explicit targets, 200 overlap targets / 19,900 pairs, 200 objects and -1,000,000 source points per batch, 4,096 rendered runs and polygons per plot, 1 MiB text, -64 MiB estimated snapshot payload and 16 MiB encoded-asset probes. Pages default to -100 rows (maximum 200), with 96 KiB page values and 256 KiB JSON-RPC responses. -These are payload/work budgets, not a total process-memory bound. -Snapshot/text overflow returns `diagnostic_budget_exceeded`; narrow the target. -Batch/row limits return `truncated: true` and a cursor without sampling. - -Context, revision, busy barriers and connection access are rechecked before delivery. -Edits, project changes, cancellation, connection shutdown and transport closure -invalidate affected work; expired/consumed cursors return `expired_cursor`. -After `stale_revision` or `project_changed`, read state and start again, never combine -old and new pages. Read-only access suffices. Reads change no object, binding, manual -range, geometry, Undo history, automation revision, edit generation or dirty state. -They do not append project audit records. Geometry, issues, cursors and PNGs are -not persisted as diagnostic copies. - -Call `plotium_render_preview` with the canvas, context and `basis_revision` to -obtain the native PNG, then inspect it. Convert a returned -X coordinate to pixels using `x * width_px / output.size_pt[0]`; use height -for Y. Check its `render_revision` against `basis_revision`. Editor zoom does not -change these units. Direct core `figure.diagnose` returns one bounded batch without -a retained cursor; the MCP query provides continuation. No automatic fix is applied. - -## Read the actual canvas image - -Ask the agent: “Preview this canvas and describe its text, curves and local -images.” Use `plotium_document_inspect` to obtain a complete canvas target, then -call `plotium_render_preview` with that target and the current revision: - -```json -{ - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 7, - "target": {"resource":{"id":"CANVAS_UUID","kind":"plotium.canvas"}}, - "max_edge": 1440 -} -``` - -Replace `CANVAS_UUID` with the discovered canvas ID; do not pass a panel, -content item, selection or Series. The response contains a standard MCP PNG -**image content block**, plus `ToolResult.value` metadata: `target`, -`render_revision`, `width_px`, `height_px` and `mime_type`. It does not require -opening a file or rendering SVG text. A curve with more points than the preview -can show is drawn as a min/max envelope of four point pairs per pixel column, at -least 2,048 pairs across the plot (markers: one per pixel), and `downsampled` -lists each such curve as `{target, source_points, drawn_points}`; it is omitted -when nothing was thinned. A zoomed-in curve keeps every visible point. -Exports always draw every point. The MCP client must deliver image content -to its agent; a text-only client cannot consume this preview. - -The image covers the whole page with its native layout, background, panel clips, -text, curves and embedded local raster assets. Rendering runs off the desktop -thread from an immutable snapshot. `render_revision` identifies that snapshot; -human edits after capture do not change it. Read state again before editing. -Read-only connections permit previews. Previews do not append project run records -or change dirty state, edit generation or automation revision. - -`max_edge` defaults to 1440 px and accepts 1–2048; aspect ratio is preserved -with pixel rounding and a minimum of one pixel per axis. Limits are 4,194,304 -output pixels, 16 MiB of referenced encoded assets, 64 MiB of header-probed -RGBA8 asset pages, 8 MiB of intermediate SVG, 4 MiB of PNG, and 6 MiB of JSON-RPC -preview response (including the request ID). Shared asset bytes count once; -decoded pages count once per asset/page. These are payload and image-buffer limits, not a total process -memory limit. All referenced assets are validated, including hidden items. -Limits are also available with -`plotium_capabilities_get {"section":"limits","key":"image_preview"}`. - -Missing or damaged assets and unavailable image pages return -`preview_asset_unavailable`; no placeholder or incomplete success image is -returned. Budget overflow returns `preview_budget_exceeded`, without silent -quality reduction; lower `max_edge` for output-size overflow, or reduce source -assets for asset-budget overflow. Invalid full identities return -`invalid_parameters`, and outdated revisions return `stale_revision`. -Only one preview renders per connection; another returns `busy`. Other existing -tools remain available while rendering. Cancellation or stopping the connection -prevents image delivery; stopping or switching projects discards the old job. - -## Preview a plan before committing it - -After `plotium_plan`, call `plotium_preview_plan` with the **same** plan ID, -context and revision, and one affected whole-canvas target: - -```json -{ - "plan_id": "RETURNED_PLAN_ID", - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 7, - "target": {"resource":{"id":"CANVAS_UUID","kind":"plotium.canvas"}}, - "max_edge": 1440 -} -``` - -The response contains an actual MCP PNG image block. `ToolResult.value` contains -`plan_id`, `basis_project_context`, `basis_revision`, `candidate: true`, `target`, -`width_px`, `height_px`, `mime_type` and `output` (`size_mm`, `size_pt`, `max_edge`). -There is no `render_revision`: this image has not been committed. The read's -`before_revision` and `after_revision` both identify the baseline. Read the image, -then explicitly call `plotium_execute` with the original `plan_id`. Finally read -`plotium_render_preview` and fresh `plotium_figure_diagnose` results. Candidate -preview does not introduce candidate diagnostics or an automatic repair loop. -Keep diagnostic `measurement_basis`, `coverage` and `unsupported` records: -estimated text bounds are not glyph ink, and a potential legend conflict is not -proof of occlusion. - -| Existing plan | Candidate support | -| --- | --- | -| `properties.set` / `properties.reset` / `properties.set_many` | Document and object display properties, including their native multi-target batch; not canvas, app preference or dataset processing properties, chart type or stack changes | -| `figure.edit` local edits | `content_frame`, `image_replace`, `text_set`, `annotation_create`/`annotation_set`/`annotation_delete` (text and reference lines), including native batches | -| `figure.edit` deletion-only batch | `content_delete`, originally empty `panel_delete`, explicit-column `series_delete`; all existing refusal rules remain | -| Other operations, including save/export | `unsupported_operation`; their normal execution contract is unchanged | - -To let the user choose a style, such as a palette, line widths, legend -placement or label layout, plan two or three alternatives, preview each and show -the images side by side. Execute only the plan the user picks. The others are -never committed: they then fail with `stale_revision`, but count toward the 32 -pending plans until submitted or the connection resets. - -Affected canvases must use ordinary line/scatter plots, native text, shapes and -raster content; previews do not launch scientific computations. A cross-canvas -property plan applies its complete batch to the disposable native context; request -each affected canvas separately. It is still one plan and one Undo step. -Automatic axes, guide dependencies and derived page height use the native action -and renderer, not a second layout model. With identical baseline, settings and -fonts, candidate content and geometry match execution. Cross-machine font or -renderer differences are not a pixel-equivalence guarantee. - -Candidate reads require **Read and modify**, checked at capture and background -delivery alongside context, revision, idle state and the still-pending plan. -Revocation and regrant during rendering also prevent delivery. Preview neither -consumes the plan nor extends its lifetime or grants execution permission. -Ordinary edit plans have no wall-clock TTL; they share the 32-plan session cap -and are cleared on context/connection changes. Submitted plans are single-use, -including failed submissions. `expired_plan` means absent/consumed; -`stale_revision`, `project_changed`, `permission_denied`, `busy`, -`request_cancelled` and the image errors above describe other refusals. -After a human edit or project change, rediscover and replan. Never replay an -outcome-unknown execute after a disconnect. - -Preview borrows frozen inputs and image bytes, without rereading a replacement -path, allocating planned identities or executing then undoing the live document. -It does not change authored content, data, bindings, selection, history, automation -revision, persistent assets, edit generation or dirty state. It adds no project -audit record and persists no PNG bytes. No candidate file or cache is created. Candidate and -committed previews share the single rendering slot, cancellation and image budgets -above. Candidate construction additionally rejects a native snapshot estimate over -64 MiB (canvas geometry, source field dimensions at 64 bytes/element, metadata and -frozen assets); this estimate is not a process-memory ceiling. Cancelled project -work retains the slot until the bounded renderer exits. - -## Position a plot's legend precisely - -Guide properties use `ids:[PLOT_OBJECT_ID]`, not Series components. Discover the -object by its full canvas/object identity; plot names need not be unique. Use -`properties.set` with one key/value, review its plan, then execute the returned -one-use plan ID: - -```json -{ - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 7, - "tool_id": "properties.set", - "ids": ["CANVAS_UUID/OBJECT_ID"], - "parameters": {"key":"object.guides.position","value":[0,1]} -} -``` - -`position` accepts exactly two finite numbers in [0,1], or `null`. It places the -legend box's top-left origin within the space in which that complete box can -move inside the axes' plotting rectangle. x increases rightward, y downward: -`origin = plot_origin + [x,y] * max(plot_size - legend_size, 0)`. These are not -screen pixels, page fractions or data coordinates. [0,0] is top-left; [1,1] -aligns bottom-right when the legend fits. The renderer recomputes this mapping -when the output size, legend content or layout changes. - -The native properties and their necessary coupling are: - -- `visibility`: `auto`, `show`, `hide`. Auto shows a categorical legend with at - least two native entries; Show permits one; Hide hides guides, not data. -- `placement`: `auto`, `inside`, `outside_right`, `outside_bottom`, `custom`. - Custom retains an existing origin or starts at [1,0], and sets Inside. - Every other placement clears the custom origin. -- `position`: [x,y] sets Inside/custom. `null`, position reset, placement Auto - and placement reset clear both origin and placement overrides, matching GUI - double-click. A read of `null` means no custom origin; consult placement for - the actual mode, which may be outside. -- `layout`: `auto`, `vertical`, `horizontal`, retaining native layout behavior. -- `title`: text; blank/whitespace clears its override using native normalization. - -Visibility/layout/title reset only their own overrides. Position changes and -resets retain these fields, font size, bindings, curve styles and manual axis -ranges. Guides still use native entry merging; six curves need not produce six -entries when their native legend identities merge. The four existing properties -retain their color-scale behavior. Free two-dimensional positioning applies to -categorical legend content, independent of guide visibility. Retained origins -without content remain readable/resettable, but new coordinates require legend -content; they do not reposition a colorbar independently. - -Guide inspection adds `guide_geometry` to applicable readings. It returns -`coordinate_space:"object_local_pt"`, `scale:1`, `plot_rect`, nullable -`legend_rect`/`color_scale_rect` (x/y/width/height), `entry_count`, nullable -`available_travel_pt`, `effective_position`, `fits_plot` (two size-fit booleans), -and `not_rendered_reason` (`hidden`, `no_entries`, `auto_single_entry`, or null). -`measurement_basis:"renderer_layout_text_width_estimate"` names the same layout -boxes used by rendering, not exact glyph bounds. Object/parent visibility and -clipping are not evaluated here. Effective position is the -resolved origin relative to available travel, without clamping outside placements; -a zero-travel axis reports zero. Guide-hidden or automatically omitted legends return null geometry -and the reason, while the property value retains the configured origin. - -An oversized legend is not silently shrunk. Its unavailable travel axes are zero, -`fits_plot` reports false, and the effective position can differ from the requested -origin. Size fit does not promise absence of clipping or curve overlap; inspect -the native PNG and final exports. This observation is limited to guide layout, -not a whole-figure diagnostic. - -Guide writes validate every explicit target before committing; an existing but -inapplicable target rejects the whole batch with `invalid_parameters`, unlike -the unchanged skip policy of older properties. Duplicate IDs are processed once. -One request changes one property across at most 200 IDs with one Undo/Redo step; -titles are limited to 16,384 UTF-8 bytes, structured responses to 256 KiB -(`response_too_large`), and the existing shared limit is 32 pending plans. -Malformed/out-of-range values fail with `invalid_parameters`. Inspection reports -inapplicable targets. Read-only connections can inspect/preflight but execute -requires reversible-modify permission. Context/revision changes, revocation, -busy and expired-plan failures retain the normal single-use contract. Inspection -does not add project audit records or change dirty state, edit generation, -automation revision or Undo history. Discover these rules with `plotium_capabilities_get {"section":"guide_contract"}`. - -## Change display without rebuilding the plot - -Use an exact target from preflight `creation.series_defaults[].target` or execution -`value.bindings[].target`, or discover -it with `plotium_document_inspect`. The owner resource and stable SeriesId travel -together: same-name curves remain separate targets. `plotium_properties_list` -lists the allowed properties; `plotium_properties_inspect` supplies current values, -defaults, target-specific unit choices and range input schemas. - -Read `plotium_get_state` first. Call `plotium_plan` with its `project_context` -and current revision, replacing the placeholders below with discovered values: - -```json -{ - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 7, - "tool_id": "properties.set", - "targets": [{ - "resource": {"id":"CANVAS_UUID/OBJECT_ID","kind":"plotium.canvas.object", - "parent_id":"CANVAS_UUID","local_id":"OBJECT_ID"}, - "component": {"kind":"series","id":1} - }], - "parameters": {"key": "series.line.color", "value": "#0072B2"} -} -``` - -Review the preflight, then pass only its returned `plan_id` to `plotium_execute`. -This changes only that curve's color, including its error bars, not its width or -source columns. Axis and local font properties instead take `ids:[PLOT_OBJECT_ID]`. - -One request changes one key across its targets, atomically, with one Undo step. -An existing but inapplicable target is reported as skipped; a missing or forged -identity rejects the request. Invalid colors, non-finite values and invalid -ranges are refused at preflight. Execution rechecks revision and permission; -a rejected execute consumes its plan. Re-read state before planning again. - -Range values distinguish these operations: - -- `{"mode":"auto"}` clears only that axis's manual range. -- `{"mode":"manual","min":0,"max":10,"unit":"mA"}` sets finite increasing - bounds in the stated compatible unit. `unit:null` is only for unknown coordinate - units. A known unit cannot be introduced onto an unknown-unit plot. -- Resetting **all** axis settings is a separate native operation, not a side - effect of Auto. Axis reset clears only the named override; guide origin/placement - coupling follows the rules above. - -Display units use compatible codes returned by property inspection, such as `s` → `ms` or `mA` → `A`. -The plot retains R4's coordinate-unit contract: source data, manual range storage, -shifts and error amplitudes keep their meaning. Ticks and automatically derived -unit text change; authored axis titles stay verbatim. Rebinding/reordering curves -and removing the first curve do not redefine coordinates. Numeric range editing -is unavailable on hidden/categorical axes; a retained range can still be cleared. -In inspection, `unit_code.codes` lists the target's compatible choices; `axis_range.input_schema` describes -the range value and its `view`/`unit` describe the current display window. - -Marker size is a diameter in points, independent after explicitly set. Without -an override, native point curves retain their existing width-based radius; the -existing stroke-width API retains this behavior. Reset restores the native -marker/size, and an explicit empty legend label omits that legend entry. Stroke -style applies to line curves; scatter curves are skipped for that property. -Markers apply to line/scatter curves, not sticks, bars, boxes or violins. Bar -width and outline width apply to bar, box and violin curves; the outline color to -bar curves. Marker fill and edge color -apply to closed markers and follow the curve color until set; reset returns -them to it. A hollow marker draws no fill and keeps an outline, 0.5 pt when -no edge width is set. `marker_every` thins markers to every n-th source point, -starting with the first; the line still passes through every point. A chart -that owns semantic colors rejects a single series -color, marker fill or marker edge color override as inapplicable. - -Plot-local tick, axis-title and legend sizes inherit document typography until -set. Reset removes only that override; changing one plot's font does not style -other plots. Font/title measurements use the native renderer. These edits do not -retile pages or change panel/content positions and sizes. GUI edits use the same -catalog controls in Line, Axes, and Legend & scales; plot-local units, ranges and -font sizes appear under Advanced. Document-level font properties -retain their existing project-wide scope. - -After editing, get a fresh revision and request `plotium_render_preview` for the -returned canvas. Inspect its PNG and `render_revision`, then use GUI Undo/Redo to -check the same native objects. MCP `project.save` requires separate desktop -authorization; exporting requires its own desktop authorization. - -## Inspect and edit an exact curve - -An example agent task is: “Find my line plot, inspect its stroke width, preflight -changing it to 1.5 pt, then apply the saved plan.” The tool sequence is: - -1. `plotium_get_state` with `{}` returns `project_context`, `revision`, project overview, selection - and connection permissions. -2. `plotium_resources_search` with `expected_project_context`, `expected_revision` and a `query` such as - `{"kinds":["plotium.canvas.object"],"name_contains":"Plot"}` locates resources. - When every match has the same reason, as in an unfiltered search, `value.reason` - states it once instead of `value.reasons`. - Resolve results to explicit stable IDs; `plotium_resources_inspect` reads - descriptors using `ids` and `expected_revision`. -3. `plotium_properties_list` with `{}` lists supported IDs and value types. Discover - curve addresses with `plotium_properties_inspect`: - - ```json - {"ids":["CANVAS_UUID/OBJECT_ID"],"key":"series.line.stroke_width","expected_project_context":"PROJECT_CONTEXT","expected_revision":7} - ``` - - The response's `value.readings` contains one row per applicable curve. When - every reading shares its schema or default, `value.schema` and - `value.default_value` hold it once instead. Copy - the complete `value.readings[0].target` for the curve you want, for example: - - ```json - { - "resource": { - "id":"CANVAS_UUID/OBJECT_ID", - "kind":"plotium.canvas.object", - "parent_id":"CANVAS_UUID", - "local_id":"OBJECT_ID" - }, - "component":{"kind":"series","id":0} - } - ``` - -4. Pass that target unchanged to `plotium_plan` to edit exactly that curve: - - ```json - { - "tool_id":"properties.set", - "parameters":{"key":"series.line.stroke_width","value":1.5}, - "targets":[{ - "resource":{ - "id":"CANVAS_UUID/OBJECT_ID", - "kind":"plotium.canvas.object", - "parent_id":"CANVAS_UUID", - "local_id":"OBJECT_ID" - }, - "component":{"kind":"series","id":0} - }], - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision":7 - } - ``` - -5. Review `preflight`, then call `plotium_execute` with only - `{"plan_id":"RETURNED_PLAN_ID"}`. Plotium immediately displays the change; - **Undo** restores it and **Redo** reapplies it. Repeating the current value is - reported as skipped. A batch applies as one undo step. - -Property inspection and property-edit planning require exactly one nonempty `ids` or -`targets` array. `ids` expands each resource to all components addressed by the -property; `targets` addresses only the supplied Series components. Series IDs -are local to their plot, so always copy the full target, including its resource. -Duplicate targets are processed once. A missing component or forged resource -identity rejects the entire request; an existing curve to which the property -does not apply is skipped. Inspection returns values, defaults, bounds and -applicability. To inspect just one curve, use `targets` in the inspection request. -To reset it, plan `properties.reset` with `{"key":"series.line.stroke_width"}` -and the same target. Component addressing supports only the listed display -properties; processing parameters use the separate `processing.edit` operation. `resource.rename` requires -`ids`. - -`dataset.delete` takes `{}` and DatasetIds in `ids`. Preflight refuses a dataset -that a plot, projection, derived dataset or analysis report still uses and names -the page and panel, dataset or report using it; delete those first. Delete a -derived dataset in its own request before deleting its sources. One Undo restores -every deleted dataset with its original ID and position. - -Tool responses include structured content and its JSON text representation. -Project reads and preflight require the current `expected_revision`; fetch the -state when dynamic values are needed or after desktop edits or Undo. Known exact -targets may reuse committed synchronous results as described above. Execution rechecks the saved revision and current -permission. Plans are single-use, including failed submissions, and at most 32 -can be pending. Restarting the connection clears them. Requests cancelled before -desktop execution are skipped without changing the project. Cancellation cannot -roll back an edit that has already started its atomic commit; use **Undo**. - -Errors include stable codes: `permission_denied`, `expired_plan`, -`stale_revision`, `busy`, `invalid_parameters`, `unsupported_operation`, `unsupported_property`, -`project_changed`, `unavailable`, `connection_lost`, `plan_limit`, `request_cancelled`, `connection_stopped`, `response_too_large` and `execution_failed`. -Invalid capability sections or keys point back to static discovery, with valid -candidates in `error.details`. Invalid plan parameters point to that operation's -`operation_constraints` instead of asking for project state. Input errors include -`error.details.field` at the decoded request boundary, such as `plan_id`, -`parameters`, or `parameters.writes[0].key`. Stale revisions and changed projects -still require reading state and replanning. This guidance never permits replay. -Nested source and target errors report their full path, such as -`parameters.series[0].source.y`. - -Errors carry `error.recovery`; asynchronous save, export and task receipts carry -`recovery`. `retryable: false` means do not repeat the failed call: follow the -reported next action. A `busy` execute can already have consumed its plan. -For stale revisions, read state and review a fresh plan. An expired plan may -already have run; inspect its outcome before deciding on a new operation. -The AI connections (MCP) settings page shows recent operations and errors without -opening itself in response to background activity. - -## Recovery actions and uncertain outcomes - -`recovery` describes this request, not permission to execute another one: - -| Field | Meaning | -| --- | --- | -| `plan_consumed` | `true` / `false` when observed; `null` when unknown. A consumed plan cannot be reused. | -| `submission` | `submitted`, `not_submitted` or `unknown`; accepted background work is not completed work. | -| `committed` | `true` / `false` when known; `null` when effects or durable completion are uncertain. | -| `completion` | `pending`, `succeeded`, `failed`, `partial` or `unknown`. | -| `receipt` | Status tool and exact ID in `arguments`; `retained` is `true` when found, `false` when missing, or `null` when unknown. A null `receipt` means no known receipt query. | -| `next_action` | One next step: `call_tool` with exact arguments, `desktop_file_confirmation`, `check_desktop_connection`, `inspect_outcome`, or `none`. | -| `replay_allowed` | Always `false`; recovery never authorizes replay or automatic resubmission. | - -For `call_tool`, make only the named read. For desktop confirmation, review the -pending request's exact paths and overwrite scope in Plotium, then query its -receipt. For `check_desktop_connection`, check AI connections (MCP) and access -mode in the desktop, then read state. For `inspect_outcome`, compare the retained -receipt, saved preflight targets/paths and current state; missing evidence needs -human review before any new scientific computation or file request. - -- **Busy:** planning fails before submission. Execution may consume the plan - before the busy check; finish the desktop operation, read state and review a - fresh plan. Never resubmit the consumed ID. -- **Stale revision / project switch / revoked permission:** refresh state and - access in the desktop. After a switch, rediscover targets in the new context. - Existing plan IDs and file permissions do not transfer to the new project. -- **Save refused or cancelled before installation:** the consumed plan's receipt is terminal with - `phase: not_installed`, `committed: false` and `completion: failed`. Closing the - confirmation is refusal. Inspect state and ask whether saving is still wanted; - a newly intended save requires a fresh plan and desktop confirmation. - Cancellation after a worker starts must be resolved from its final phase; - it does not undo installed output. -- **Pending save/task:** accepted, queued, running or saving is `pending`, not - success. Use the receipt query; do not submit a replacement task or save. - `installed_unconfirmed` stays unknown even after a save worker terminates. -- **Export:** the batch succeeds only when completed and every file succeeded. - Mixed terminal results are `partial`; inspect each exact output path and error. - A failed file can have been installed before a durability error, so failure - alone does not prove that its path is unchanged. Never retry the entire batch - automatically, including its successful files. -- **Disconnect / expired plan / unknown or evicted receipt:** preserve unknown - consumption, submission and commit state. Reconnect and query a known receipt - ID in the same desktop process. If it is absent, inspect saved targets/paths; - absence does not prove non-execution and does not authorize recomputation or - overwrite. Receipts are not persisted across desktop restarts. - -These actions retain server permissions, revision/context checks, one-use plans -and fresh per-request desktop file consent. Tool annotations are neither -authorization nor a reason to retry. Reconnect clients and refresh their tool -catalog after updating the desktop and connector together. - -## Style several curves in one plan - -`properties.set` writes one value. To give each curve its own colour and legend -label, plan `properties.set_many` instead: each write names an exact target, one -supported key and a value. Omit top-level `ids` and `targets`; series writes use -the complete Series target from inspection, and object-level writes such as axis -titles or legend settings use the plot object's resource target without a -component. - -```json -{ - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 7, - "tool_id": "properties.set_many", - "parameters": {"writes": [ - {"target": SERIES_0_TARGET, "key": "series.line.color", "value": "#0072B2"}, - {"target": SERIES_0_TARGET, "key": "series.label", "value": "Sample 1"}, - {"target": SERIES_1_TARGET, "key": "series.line.color", "value": "#D55E00"}, - {"target": SERIES_1_TARGET, "key": "series.label", "value": "Sample 2"}, - {"target": {"resource": PLOT_OBJECT_RESOURCE}, "key": "object.axes.x_label", "value": "Temperature (°C)"} - ]} -} -``` - -After `plot.create` executes, use its full stable targets directly. For example, -with the decoded creation `ToolResult` in `created` and the original state in -`state`, prepare this `plotium_plan` argument object: - -```js -const request = { - expected_project_context: state.project_context, - expected_revision: created.after_revision, - tool_id: "properties.set_many", - parameters: { writes: [ - ...created.value.bindings.map((binding, index) => ({ - target: binding.target, - key: "series.label", - value: `Sample ${index + 1}` - })), - { target: created.value.creation.plot, - key: "object.axes.x_label", value: "Temperature (°C)" } - ] } -}; -``` - -Copy each whole `target`, including owner resource `kind`, `id`, `parent_id`, -`local_id` and component identity when present. A bare SeriesId, name or array -index is not a selector. Keep the total within 200 writes. Preflight this object, -review it and execute its new `plan_id` once. `unsupported_operation` means the -operation is unavailable; `unsupported_property` identifies an unsupported key -in `error.details.write_index` (zero based) and `key`. Query -`plotium_properties_list` and correct the whole batch before planning again. - -A batch holds 1–200 writes and accepts the display properties listed above. -Planning refuses the whole -batch, and nothing is committed, when any write's target is missing, its -property does not apply to that target, its value is invalid, or the same key is -written twice to one target. A write whose target already holds the value is -reported as skipped while the others apply. `plotium_execute` commits every -write as one **Undo** step; `value.writes` lists each write that was skipped, -with its index, key, outcome and `skip_reason`. - -Property-write responses are short. The preflight of `properties.set`, -`properties.set_many` and `properties.reset` returns `required_authority`, -`estimated_changes`, `summary` (`compatible`, `skipped`, `failed`) and, in -`targets`, only the targets that will not be written. The execute result adds -`summary` (`succeeded`, `skipped`, `failed`, and `by_reason` counts of -`skip_reason`); `targets` and a batch's `value.writes` list only what did not -succeed. When every write applies, both lists are empty. -`plotium_preview_plan` still renders the complete plan. - -## Values the user set by hand - -When the user changes a figure value in Plotium — in the property panels, by -scrolling over a control or by dragging a legend — Plotium records it as set by -hand. `plotium_get_state` lists these values in `hand_edits`, and -`properties.inspect` marks each one with `"hand_set": true`. - -`properties.set`, `properties.set_many` and `properties.reset` leave hand-set -values alone: the target is reported as skipped with `skip_reason: "hand_set"`, -in preflight and in the result, and the other targets still apply. A legend's -placement and its dragged position count as one value. Pass -`"override_hand_edits": true` in `parameters` only when the user asked for that -change; the new value then counts as the user's. - -Values you write without the override are not recorded, so a later theme or -write may replace them. Themes keep hand-set values; see the next section. - -## Apply a theme or saved style to a canvas - -`figure.apply_theme` restyles whole canvases with one of Plotium's built-in -themes, such as `nature`, or with a canvas style saved in Plotium. Set -`theme_id` to a built-in id from -`builtin_themes` in -`plotium_capabilities_get {"section":"operation_constraints","key":"figure.apply_theme"}`, or to the saved style's name. Saved styles are not -part of the static capabilities: an unknown `theme_id` fails preflight with -`invalid_parameters`, and `error.details.themes` lists every built-in theme and -saved style currently available. Plan it with the canvas ids in top-level `ids`: - -```json -{ - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 7, - "ids": ["CANVAS_ID"], - "tool_id": "figure.apply_theme", - "parameters": {"theme_id": "nature"} -} -``` - -Preflight needs only read access; executing requires Read and modify. -Preflight rejects an unknown `theme_id`, Series `targets`, and ids that include -no canvas; other ids that are not canvases are skipped. A saved style is read -again when the plan executes. Execution changes each canvas's background, text -and shape colours, and every curve's colour, marker paint, marker size and line -width the theme defines, as one **Undo** step. Curve and marker colours set by -hand are kept when a theme is re-applied; resetting a curve's colour returns it -to theme colours. -The document's style defaults are also replaced: plot text sizes, axis strokes -and ticks, so plots on other canvases change with them, and the default text, -panel-label and shape styles for new objects. Values the user set by hand are -kept, including figure typography; `diagnostics` adds a note saying how many. A theme sized for journal columns -(today `nature`) never resizes a canvas; for each canvas whose width matches -none of its column presets, the result's `diagnostics` adds a note listing the -preset widths (89 / 136 / 183 mm). - -## Save the current desktop project - -Saving uses the same native snapshot, background worker, backups and completion -path as **Save project**. It saves the current desktop state, not a separate CLI -project. First read `plotium_get_state`; `save_state` reports the current path, -persisted archive revision, dirty flag, edit generation and up to 16 retained -`receipt_ids`. Query each ID with `plotium_save_status` for the complete receipt -and recovery action. An ID alone does not indicate submission success or completion. - -Plan a first save or Save As with no `ids` or `targets`: - -```json -{ - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 46, - "tool_id": "project.save", - "parameters": {"path": "/absolute/path/figure.plotium"} -} -``` - -Omit `path` to save the current file; an untitled project requires a path. -The parent directory must exist. Targets must be regular, non-symlink `.plotium` -files or absent paths. Preflight resolves the parent directory and freezes the -observed target. `include_view_snapshots` optionally overrides the project's -current native save profile. The plan returns `save_id`, the resolved path and -`overwrite_required`; it grants no file-write permission. - -Submit the one-use plan with `plotium_execute {"plan_id":"PLAN_ID"}`. The result -contains `save.status: "awaiting_authorization"`. In Plotium, review the exact -path and press **Allow save**. If a file already exists, first check **Replace the -existing file at this exact path**. **Deny** leaves the target untouched. -This permission is independent of **Read and modify**, applies to one save only, -and cannot be supplied as a tool argument. A changed target requires a fresh -plan and approval. One external save may be pending at a time. - -Serialization uses an exclusively created private sibling temporary, not a fixed -`.tmp`. For an existing target, its frozen metadata is checked again after -backup preparation, immediately before replacement. A detected change refuses -installation and preserves the later target. Permission admission and this file -check are separate: the check plus replacement is not an inter-process -compare-and-swap. A non-cooperating write after the check, or one that preserves -the checked metadata, may go undetected; avoid concurrent saves to the same path. - -Poll `plotium_save_status {"save_id":"SAVE_ID"}`; this read needs no document -revision or context, works while saving, and does not dirty the project. -`awaiting_authorization`, `queued` and `saving` are incomplete states with null -`phase`. Only `completed` gives a final phase: - -| Phase | File state and next action | -| --- | --- | -| `not_installed` | This save did not install its snapshot at the target. Resolve the reported denial/failure, inspect current state, then obtain fresh authorization if another save is needed. | -| `installed_unconfirmed` | The snapshot replaced/created the target, but backup finalization or durable sync failed. Keep the desktop project open; inspect the target and storage before an explicitly authorized retry. Do not assume the old file remains. | -| `committed` | The captured snapshot completed the native durable commit. Later edits may still be unsaved. | - -On Windows, a partial replacement failure can remove or move the old target even -when the new snapshot is `not_installed`. Plotium keeps the serialized candidate -and reports its exact recovery path. It restores a known original backup only -without overwriting an existing target; otherwise it retains and reports that -backup and any older staged backup. If Windows moved the original without -returning its location, the error says so. Keep the project open and inspect the -reported files before retrying; this failure does not clear dirty state. - -The receipt records original `project_context`, `snapshot.document_revision`, -`snapshot.edit_generation`, `persisted_revision`, exact path, `state_applied`, -`dirty_after_completion`, error and recovery message. The status response also -reports current context/path/revision/dirty and `matches_current_project`. -The snapshot is captured after desktop approval and before background work. -New edits after capture remain dirty; a committed save does not mean every -current edit is on disk. An installed-but-unconfirmed -save keeps dirty and records the installed baseline for native recovery. - -Switching projects or stopping the connection revokes pending write permission. -The worker only holds its original snapshot and path, checks authorization at -installation, and cannot adopt a completion into a different project, even at -an equal document revision. Once the worker has atomically admitted installation, stopping cannot guarantee -cancellation of that original file write; inspect its receipt. Revocation before -admission prevents installation. Saving creates no Undo step and Undo does not delete or restore files. - -The desktop retains the latest 16 receipts across reconnects and project changes -until application exit. After a lost response, query the original `save_id` -before doing anything else; do not replay the submitted call. After application -restart or `unknown_save`, inspect the target and freshly opened project instead -of assuming success or failure. Stable stdio configuration continues to work; -reopening/restarting still requires fresh state, target discovery and plans. -Connection recovery is not evidence of a successful save. - - -## Export a captured canvas as SVG, PDF and PNG - -Use `figure.export` with one exact whole-canvas TargetRef and no top-level -`ids`/`targets`. The native exporters preserve the canvas background, complete -page, curves, absolute Y-error amplitudes, native text and embedded images. -There is no trimming, theme application or project modification. Keep the -editable `.plotium` project as well as these delivery formats. - -```json -{ - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 48, - "tool_id": "figure.export", - "parameters": { - "canvas": {"resource":{"id":"CANVAS_ID","kind":"plotium.canvas"}}, - "size_mm": [180,90], - "dpi": 300, - "outputs": [ - {"format":"svg","path":"/absolute/path/figure.svg"}, - {"format":"pdf","path":"/absolute/path/figure.pdf"}, - {"format":"png","path":"/absolute/path/figure.png"} - ] - } -} -``` - -`size_mm` defaults to the native page size. An explicit size uniformly scales -the whole figure and must retain its aspect ratio (0.001 mm height tolerance); -it does not resize the editable page. `dpi` defaults to 300, accepts 1–2400 and -only controls PNG. Each PNG axis is rounded to the nearest integer from the -native physical points / 72 × DPI × uniform size scale, with a minimum of one -pixel. A 180 × 90 mm page at 300 DPI is **2126 × 1063 pixels**. SVG/PDF retain -physical page dimensions. Text uses the native generic sans-serif family; -a machine without usable system fonts returns a font error. SVG font appearance -on another machine depends on that machine's available sans-serif fonts. - -There are 1–8 outputs per batch. Each absolute path needs its matching lowercase -extension and an existing parent directory; targets must be regular non-symlink -files or absent. Duplicate resolved output paths are refused. Preflight returns -`export_id`, physical/pixel size and an error or resolved target for each file. -A bad directory does not hide the other files' results. `overwrite` defaults to -false: an existing target reports `overwrite_not_requested` and remains untouched. -Set `overwrite:true` only when replacement is intended; this still grants no -write permission. - -Submit the one-use plan through `plotium_execute`. Valid files await Plotium's -**Allow AI to export this figure?** prompt, listing the exact canvas, revision, -size and paths. Review it and press **Allow export**. Existing files additionally -require the unchecked **Replace the listed existing output files** checkbox. -**Deny** installs nothing. **Read and modify** is not export authorization; -Read only may request fresh, separate export consent. All-invalid batches finish -with per-file errors without asking for consent. - -Poll `plotium_export_status {"export_id":"EXPORT_ID"}` without context/revision. -It is non-auditing, works while rendering, and returns `export`, current context, -current revision and `matches_current_project`. Batch status is -`awaiting_authorization`, `rendering` or `completed`. Each `files[]` entry has -format, exact path, overwrite requirement, `status`, `error_code`, `message` -and installed byte count. File status is `pending`, `succeeded`, `failed` or -`unknown` (worker failed; inspect that path before deciding what to do). -Completion does not imply every file succeeded. Missing/corrupt images, fonts, -changed targets, permission denial and rendering/budget errors are reported -without replacing that output. Successful files in the same batch remain. - -Rendering runs off-thread on the canvas/assets captured after desktop consent, -bound to the original `project_context`, `canvas` and `render_revision`. Later -edits do not change that snapshot. Project transition, connection Stop or access -change revokes pending installation permission. Each file's atomic permission -admission precedes its installation: revocation before admission blocks it; -an already admitted file may finish and must be checked in the receipt. Old -completion never changes the new project's document, save path, dirty state or -status. Unique owned sibling staging and atomic no-clobber creation preserve -unapproved files. Existing-file metadata is checked just before replacement; -this is not a cross-process compare-and-swap, so avoid concurrent writers. -Export success means installed output, not the native save's durable-commit -phase; Undo cannot remove or restore exported files. - -Limits: one running batch, 32 shared pending plans, 4096 bytes per path, PNG -16,384 pixels per edge and 16,777,216 pixels total; referenced embedded assets -16 MiB, decoded asset RGBA 64 MiB, SVG 8 MiB and encoded output 64 MiB per file. -No external asset lookup or placeholder substitution occurs. Limits and the -complete schema are discoverable in the `limits` and `operation_constraints` -capability sections. - -The last 16 export receipts survive reconnects and project changes in this -desktop process, not application exit. After response loss query the original -`export_id`; do not resubmit the export. After restart or `unknown_export`, -inspect the exact output files first. Reopen the editable project, fetch fresh -state and targets, then make a new plan only for a newly intended operation. - - -## Scientific operations and tasks - -`plotium_processing_inspect`, `plotium_diffusion_inspect` and -`plotium_analysis_results_inspect` are read-only queries with explicit `ids`, -`expected_project_context` and `expected_revision`. Result inspection accepts -`offset` and `limit` (1–100); use smaller pages for large ILT grids. Discovery's -`scientific_operations` comes from the core descriptors, including parameter -schemas, capabilities, permissions and execution modes. - -Scientific edits use `plotium_plan` / `plotium_execute`: - -| Operation | Parameters and target | -| --- | --- | -| `processing.edit` | One dataset; `edits` uses `replace`, `enable`, `add`, `remove` or `move`; existing steps use stable StepIds | -| `processing.apply_scheme` | `path`, optional `compatible_only`; preflight freezes scheme bytes, fingerprint and compatible target configurations | -| `diffusion.set_input` | One dataset; complete `input`; invalid input errors include a structured validation report | -| `analysis.regions.extract` | One region-series field; `regions` references RegionIds or explicit bounds and metrics; optional explicit `input` | -| `analysis.diffusion.fit` | One native table; stable `response_column` ColumnId, optional native `options`; the x column must use `s/m²` | -| `analysis.dosy.build` | One diffusion source field; `method` is `mono_exp` or `ilt`; optional `input` and ILT `params` | - -An explicit region is -`{"source":"explicit","bounds":[0.8,1.2],"metric":"Height","name":"Signal"}`; -reference an existing region with `{"source":"existing","id":0}`. Other metrics -are `Area`, `Mean`, `Max` and `Min`. Extraction creates an independent native table -with source evidence, region-to-column correspondence and diffusion increment -bindings. It does not create a plot. - -Except for input updates, these edits return `ToolResult.value.task`. Preflight -allocates `task_id`; `queued` means registered. Query with -`plotium_tasks_get({task_id})` or `plotium_tasks_list({offset,limit})`; cancel with -`plotium_tasks_cancel({task_id})` (modify permission required). States are -`queued / running / committing / succeeded / failed / cancelled / stale`. -Receipts include the original plan_id, source project, start/end revisions, -source field versions, phase, completed columns, failure code, resource references -and terminal summary. Unknown work totals are `null`. Receipt queries remain -available while busy and after a project switch. - -Receipts belong to the application process. Disconnecting does not cancel -submitted work; reconnect in the same process to query it. All active tasks and -the most recent 128 terminal receipts are retained; process restart is outside -this retention contract. `task_not_found` means unknown or evicted and must never -trigger automatic recomputation. Repeating a consumed scientific plan returns -its retained receipt. Cancellation is idempotent, prevents writes before commit, -and returns the existing state after termination. - -Frozen inputs run in the existing ComputeService. Before one atomic undoable -commit, the main thread checks project, document revision, field versions, -generation, cancellation and caller permission. Any document edit during -computation makes the task stale. Undo restores configuration, results and linked -tables; Redo reuses computed results. Background completion does not open or close -panels. Synchronous workflows retain `processing.apply_scheme` and wait for -its commit before dependent nodes run; other background scientific operations -require single-step calls and terminal receipts. - -Diffusion inspection distinguishes executable input, missing parameters, evidence -requiring confirmation and invalid input. Issues carry codes, parameter paths, -expected units, actual values, evidence and remedies. b values bind IncrementIds -and use `s/m²`; D uses `m²/s`. Original units and conversion evidence remain -available. Resolution uses explicit input, target result provenance, then stored -default/acquisition information. JEOL validation retains full program identity, -gradient shape, timing and vendor coefficient checks. - -Mono-exponential diagnostics include D, I₀, D standard error, effective points, -R², residuals and rejection reasons. ILT returns its D grid, λ, nonnegative -solution, reconstruction residuals and solver termination rather than -mono-exponential confidence estimates. `empty` means no accepted scientific -result. Unavailable numbers are `null` with a reason. Result inspection pages -column diagnostics; provenance retains algorithm version, actual parameters and -input fingerprint. - -Completed decay-fit tasks return a stable `plotium.analysis` resource in the task's `produced` list. Pass its ID directly to `plotium_analysis_results_inspect` to read that analysis. A task status of `succeeded` means the calculation and result commit completed; check `converged`, `termination` and `notices` separately for scientific convergence. The outer `converged` follows the attempt with the lowest finite cost. Attempts that exhaust the iteration budget without meeting a convergence criterion or terminate with trust-region collapse remain unconverged, and their estimates are retained with a warning for diagnosis. - -## Plot native scientific results - -Use `plotium_plan` and `plotium_execute` with either operation below. Both -require `{source: ResourceRef, name: string}` in `parameters` and omit top-level -`ids` and `targets`. Discover the complete source reference and schema first. - -| Operation | Source and native output | -| --- | --- | -| `plot.field.create` | One native field, including mono-exponential `nmr.dosy_map` or ILT `nmr.ilt_map`; creates a canvas pinned to that field and its native encoding. | -| `analysis.diffusion.plot` | One diffusion-fit analysis with one response dataset; creates a frozen table and canvas with b–intensity scatter, stored fitted curve, residual panel, D standard error, R² and effective point count. | - -Preflight returns `preflight.scientific_plot.summary` with proposed `canvas`, -`source`, `produced` and scientific `evidence`; execute returns the same summary -in `value`. Plotting does not recompute scientific results. Stale or empty DOSY -results and stale, unconverged or multiple-response fits must be corrected first. -Missing D uncertainty is labelled unavailable. Field preparation permits at most -4,000,000 elements and 200 series, including a default 128-row ILT of a -20,480-point spectrum; fit plots permit 20,000 rows. Plot points, -contour vertices and heatmap cells share the 2,000,000 pending-element budget -with explicit curve rows. Contour plots count generated vertices toward this -budget; heatmaps count cells. -One Undo removes created resources; Redo restores the same identities and data. -Changing the owner's display mode does not change a field plot's source. -Frozen fit tables retain source-table lineage; the automation run retains the -selected analysis, row selection, extraction evidence and diffusion input. - -Use `value.canvas` with `plotium_figure_diagnose` and `plotium_render_preview`, -then inspect the returned PNG. An image alone does not validate the science: - -1. Start at the welcome page with `plotium_get_state`; import the acquisition, - inspect processing and wait for processing tasks to succeed. -2. Inspect diffusion units, increment bindings, missing parameters and evidence. - Supply confirmed input only when supported by the experiment. -3. State the region-selection rule, bounds, metric and overlap policy before - extraction. Wait for extraction, then fit the returned response ColumnId. -4. Inspect the exact analysis: validity, D in `m²/s`, standard error, effective - points, R², residuals, rejected rows and provenance. Create its native plot. - Independently compute and inspect mono-exponential or ILT DOSY; check accepted - and rejected columns, algorithm settings, input fingerprint and numerical - agreement with the region fit. ILT supplies solver diagnostics instead of - mono-exponential confidence estimates. -5. Plot the DOSY result field. Check resource identities and state, geometry - diagnostics and both PNGs for correct axes, curves, contours, residuals and - readable labels. Report scientific or visual failures explicitly. diff --git a/docs/src/content/docs/reference/mcp/discovery.md b/docs/src/content/docs/reference/mcp/discovery.md new file mode 100644 index 00000000..7c621026 --- /dev/null +++ b/docs/src/content/docs/reference/mcp/discovery.md @@ -0,0 +1,249 @@ +--- +title: MCP state and discovery +description: Read the current state, discover capabilities and find exact targets. +--- + +## Read state and discover capabilities on demand + +`plotium_get_state {}` reads the latest dynamic state. It returns +`project_context`, `revision`, `availability`, `permissions`, `save_state`, +`capability_fingerprint`, project counts and a bounded selection page. It does not +include the full capability catalog or project blueprint. Discover exact targets +with the revision-bound `plotium_document_inspect` pages or +`plotium_resources_search`, then inspect explicit IDs with +`plotium_resources_inspect`. Copy complete returned targets rather than names or +collection positions. + +Two short forms save copying. A resource reference may omit `parent_id` and +`local_id`; Plotium derives them from a nested ID such as `CANVAS_UUID/OBJECT_ID`. +A Series target may be written `{"plot":"CANVAS_UUID/OBJECT_ID","series":0}` in +plan and property-inspection targets and in curve-binding and `properties.set_many` +writes. Both expand to the full target before planning; plans, results and audit +records keep the full form. + +When idle, `selection` is `{items,total,next_offset}`. The default page contains +at most 16 stable resource references. Pass `selection_offset` (default 0) and +`selection_limit` (1–50) to read further pages, for example: + +```json +{"selection_offset":16,"selection_limit":50} +``` + +`selection.canvas` reports what the user selected on the active page: +`{items,total,part}`. `items` holds at most `selection_limit` summaries +(`target`, `kind`, `name`, `visible`) of the selected panels and items. `part` +is the legend, label or annotation the user clicked inside the lead plot, or `null`. A +legend reads `{target,part:"legend",property:"object.guides.position",value}`, +where a `null` value means automatic placement. A label reads +`{target,part:"label",kind,annotation_id,edit:"figure.edit annotation_set",…}` +with its current placement; an arrow or a reference line itself reads +`{target,part:"annotation",kind,annotation_id,edit,…}` with its position and +`hand_moved`. When the user says "this", edit that target or part. + +Every call reads the current selection; pages are not a frozen snapshot. GUI +selection can change without changing the document revision. Do not combine pages +as an atomic selection or use selection as execution authority. + +`hand_edits` lists the figure values the user set by hand in Plotium, as +`{items,total,next_offset}`. Each item has the `target`, the property `key`, its +`label` and current `value`. Pass `hand_edits_offset` and `hand_edits_limit` +(1–50, default 16) for further pages. Keep these values when you continue +editing; see [Values the user set by hand](/reference/mcp/styling/#values-the-user-set-by-hand). + +While busy, `project`, `selection` and `hand_edits` are `null`; availability, +permissions, the capability fingerprint and save receipt IDs remain readable. + +Call `plotium_capabilities_get {}` to obtain a compact index, +`{capability_fingerprint,connection_capabilities}`. The index lists each tool's +operations and required permission, the editable operations grouped by preflight +and execute permission, the scientific operations, the recovery, revision and +property-batch contracts, the document root and `sections`. Tool descriptions, +input schemas and annotations are in `tools/list`; property definitions are in +`plotium_properties_list`. + +`sections` names each detail section with its size in bytes and whether it takes a +`key`. `operation_constraints` and `operation_details` list each key with a +one-line purpose, so you can match a task to an operation before fetching it. Fetch one detail with `{"section":...,"key":...}`, which returns +`{capability_fingerprint,section,key,contract}`: + +| Section | Key | Contract | +| --- | --- | --- | +| `tools` | optional tool name | result contract and target rules; a keyed request also includes the tool input schema | +| `operation_constraints` | required operation id | schema, permissions and result contract of one editable operation | +| `operation_details` | required operation/suboperation key, or `keys` | focused figure-edit schema, permissions, result contract and example | +| `scientific_operations` | required operation id | descriptor and required permission; editable operations link to their canonical input schema | +| `guide_contract` | none | legend and colorbar placement rules | +| `candidate_preview` | none | uncommitted plan preview contract | +| `limits` | optional limit name | connection budgets | + +For example, read the `figure.edit` schema with: + +```json +{"section":"operation_constraints","key":"figure.edit"} +``` + +Known operations can request their detail directly without first reading the index. +For a page edit, use `{"section":"operation_details","key":"figure.edit/page"}`. +For several edits, pass `keys` instead of `key`, for example +`{"section":"operation_details","keys":["figure.edit/panel_label","figure.edit/annotation_create.arrow"]}`. +The response has `keys` and a `contract` map keyed by the requested names. This +section accepts 1–32 unique keys per call; other sections accept only `key`. +Each detail holds one exact edit schema with only the restrictions and result +fields that apply to that edit. Replace example targets with +full stable references from document inspection. Use `operation_constraints` for +the complete mixed-edit schema. Editable scientific descriptors expose +`input_schema_ref: {section,key}` instead of duplicating that schema. + +An unknown section or key fails with `invalid_parameters`; `error.details.sections` +or `error.details.keys` lists the valid values. + +The fingerprint is SHA-256 of the complete static discovery contract (index, every +section, the MCP tool definitions and the property catalog) with canonical JSON +object ordering. Cache the index and fetched sections under the returned +fingerprint; fetch it again when the state +fingerprint differs. If state changes before discovery completes, use the +fingerprint returned with the discovered contract. Project edits, project changes, +selection changes and permission changes do not change static capabilities. + +Static discovery includes required permissions, not `currently_permitted` flags. +Always read current `permissions` and `availability` from state; execution still +checks server permissions, context, revision and single-use plans. Fingerprints, +cached schemas and annotations grant no permissions and never authorize retry. +Save and export still require fresh desktop confirmation for each exact request. +Update the desktop and connector together and reconnect clients to refresh the +tool catalog after upgrading. + +The advertised inputs for planning, property inspection, document inspection and +figure diagnostics list their fields directly so clients can display complete +signatures. Plotium still validates conditional rules: use exactly one nonempty +`ids` or `targets` selector where required, omit both for operations with embedded +targets, and supply one dataset ID for table operations. Only `properties.set` +and `properties.reset` accept Series targets. Document pagination applies only +to `view: "children"`; diagnostic continuation accepts only `cursor`, context and +revision, whereas an initial diagnostic request requires `canvas` and `output`. + +Committed synchronous `plotium_execute` results include `project_context`, +`before_revision` and `after_revision`. For known exact targets in that context, +use the returned context and `after_revision` for the next query or plan without +an extra state read. This does not refresh selection, hand edits, availability or +permissions. Read state initially, after desktop edits or Undo/Redo, when those +dynamic values are needed, and on stale/context errors or uncertain outcomes. +Execution still rechecks context, revision and permissions. + +Plans for figure edits, curve append/bind/expansion, scientific plots, renames, +themes and dataset deletion return `plan_id`, `project_context`, `basis_revision` +and a `preflight` without the echoed request or frozen target set. +`preflight.summary` counts compatible, skipped and failed targets, and +`preflight.targets` lists only the targets that will be skipped or fail. Their +execution results carry `summary` counts of succeeded, skipped and failed +targets, list only skipped or failed rows in `targets`, and report changed +resources in `produced` and `modified`. + +`plotium_apply` takes the same inputs as `plotium_plan` and plans and commits one +reversible edit in a single call, returning the `plotium_execute` result. It +accepts `properties.set`, `properties.set_many`, `properties.reset`, +`figure.edit` without deletions, `plot.create`, `plot.series.append`, +`plot.series.bind`, `plot.series.materialize_default`, `resource.rename` and +`figure.apply_theme`, and requires Read and modify. Preflight, revision and +permission checks, Undo and run records are those of the two-step form, and no +plan is retained. Saving, export, deletions, imports, table and scientific +operations still use `plotium_plan` and `plotium_execute`, as does previewing a +candidate. A rejected apply commits nothing. After a disconnection, read state: +a revision equal to the request's `expected_revision` means the edit was not +committed; otherwise inspect the targets. Never replay the call. + +A queued or submitted scientific task is not a committed edit; its immediate +`after_revision` must not be reused. Only a terminal `succeeded` receipt in the +known project context with `end_revision` permits reuse. Check scientific +validity/convergence separately: successful task completion alone does not prove +a valid fit. Failed, cancelled, stale, missing or uncertain receipts require the +existing recovery flow and never authorize automatic replay. Save/export receipts +describe file operations and do not provide a new document revision. + +## Discover structure without relying on names + +Resource descriptors describe **core** data and rendering capabilities; a +capability listed on a resource does not make that operation callable through +this connection. The capability index lists the operations you can plan. + +Use the returned revision to list the document's canvases: + +```json +{ + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 7, + "target": {"resource":{"id":"document","kind":"plotium.document"}}, + "view": "children", + "offset": 0, + "limit": 50 +} +``` + +Call `plotium_document_inspect` with this request. Copy a complete +`value.items[].target` into the next request to descend from canvas to panel, +content, and Series. A canvas lists its panels followed by loose content; +parented content appears only under its panel. `view: "self"`, with pagination +arguments omitted, reads one target's details, `ancestors` and `child_count`. +The content kinds are plot, text, shape and raster image; image pixels and data +rows are not returned. Frames use points: a panel is page-relative, while content +inside it is panel-local. Content details include its exact `parent`, `frame_space`, +converted `page_frame`, and `geometry` constraints/editability. Raster details retain +`asset_id` and add `image` attributes and replacement eligibility. Canvas dimensions are in millimetres. + +Series discovery uses the plot's current display binding, like property addressing. +Inactive channel or display-mode alternatives remain stored but are not listed or +addressable until reactivated. Authored hidden Series in the active binding are +still listed with `visible: false`. After switching channels or display modes, +fetch the current revision and discover the active targets again. + +`encoding` names the native encoding family: `line` includes both line and scatter +curves; `plot.create` reports the authored subtype in `series_defaults[].kind`. + +A Series detail includes its complete property-compatible target, encoding, +visibility, explicit label, and `source`: dataset and field resource references, +owner-local `field_id`, optional `item_id`, units and binding status. Use the +returned resource IDs with `plotium_resources_inspect` for field/column +descriptors. A missing field retains its `field_id` but has no resolvable field +reference. A source can report `resolved`, `missing_dataset`, `missing_field`, +`missing_item`, `incompatible_encoding`, `unbound` or `missing_column`. + +For tables, `binding_mode: "table_default"` reports the shared `x_column` and +all `series_columns` Y/error bindings. One logical Series may expand to several +rendered table traces; those traces do not gain separate Series IDs here. +Explicit sources report `binding_mode: "table_explicit"`, TableId, current table revision, +`x_column`, `y_column` and optional `error_column`, without reporting defaults as their source. +`coordinate_units` reports the plot coordinate contract. Names, including identical curve names, are display +text, never identity. Panels use `CANVAS_UUID/panels/PANEL_ID`; content and Series +retain the existing addresses shown below. + +Children queries default to 50 entries, accept 1–200, and return `total`, +`next_offset` and `truncated`. Follow `next_offset` with the **same revision and +target**, including when the 256 KiB structured-response budget shortens a page. +A detail or single entry that exceeds that budget returns `response_too_large`. +There is no recursive whole-project dump. Revision changes reject continuation; +read state and restart the listing. Missing targets and forged identities return +`invalid_parameters`, without using the current selection. + +`plotium_properties_list {}` browses every supported property, one compact row +each: `id`, `label`, value `type`, and where they apply `min`/`max`, `unit`, +`format`, enum `values`, the curve `encoding` and required field capabilities +(`requires`). An ID starting with `document.` has document scope; every other ID +has object scope, and `series.` IDs target a Series. Rows marked `requires_full` +(nested inputs and display-unit codes) need full detail. Fetch complete +definitions for the properties you need in one call: + +```json +{"keys":["series.line.stroke_width","series.line.color"],"detail":"full"} +``` + +Use `scope` with a scope name from the catalog, or `prefix` with the start of a +property ID such as `series.line` or `object.axes`, to filter the list. A prefix +that matches nothing fails with `error.details.prefixes`. `keys` must be +nonempty and unique; unsupported keys, unknown scopes and key/scope conflicts are +errors, rather than silently omitting requested properties. `detail: "full"` +without filters returns the complete catalog. Both forms are static, callable +while busy, and contain no current target values. Full details preserve complex +input constraints, colour format `#rrggbb` and every registered unit code. +Use `plotium_properties_inspect` for target-specific values, defaults, bounds and +applicability; an axis accepts only codes compatible with its coordinate unit. +Static applicability does not grant connection write permission. diff --git a/docs/src/content/docs/reference/mcp/index.md b/docs/src/content/docs/reference/mcp/index.md new file mode 100644 index 00000000..34f2a078 --- /dev/null +++ b/docs/src/content/docs/reference/mcp/index.md @@ -0,0 +1,137 @@ +--- +title: MCP setup and permissions +description: Register Plotium with a local MCP client and the rules every tool call follows. +--- + +These pages are for people writing their own MCP client or checking what a +single tool call does. To connect Codex, Claude Code or Claude Desktop and work +with Plotium in plain language, see [Connect an AI client](/ai/connect/). + +| Page | Covers | +| --- | --- | +| This page | Manual registration, permissions, rules shared by every plan, tool annotations | +| [State and discovery](/reference/mcp/discovery/) | `plotium_get_state`, capability discovery, document structure, property catalog | +| [Data import and tables](/reference/mcp/tables/) | Native and CSV/TSV/XLSX import, table reads, transforms, cell patches, refresh | +| [Plots and curves](/reference/mcp/plots/) | `plot.create`, appending and rebinding curves | +| [Styling](/reference/mcp/styling/) | Display properties, batches, hand-set values, legends, themes | +| [Page layout and deletion](/reference/mcp/layout/) | `figure.edit`: page, panels, text, images, annotations, deletion | +| [Preview, diagnostics and recovery](/reference/mcp/review/) | Canvas and candidate previews, figure diagnostics, recovery, error codes | +| [Save and export](/reference/mcp/save-and-export/) | `project.save`, `figure.export` | +| [Scientific operations](/reference/mcp/scientific/) | Processing, diffusion, DOSY, tasks, plotting results | + +## Manual configuration and diagnostics + +On Windows, Plotium finds standalone client executables on `PATH`. For Codex +installed with npm, it resolves the native executable inside the npm package, +using prefixes on `PATH` and the default `%APPDATA%\npm` prefix. Both x64 and +ARM64 installations are supported. For a custom npm prefix, add it to `PATH` and +restart Plotium, or use **Choose executable…** to select the package's +`codex.exe`. Adding a client requires the Codex CLI to be installed. + +In **Preferences → AI connections (MCP)**, expand **Manual configuration and diagnostics** +and press **Copy stable stdio configuration**. The copied JSON contains the actual +absolute connector path; the path below is a placeholder: + +```json +{"mcpServers":{"plotium":{"command":"/ABSOLUTE/USER/DATA/bin/plotium-mcp","args":[]}}} +``` + +Use the copied path for your platform (`plotium-mcp.exe` on Windows). Plotium +copies the connector to its user data directory when enabled and updates it on +application upgrades. Keep `plotium-mcp` beside the desktop executable in a release +installation. The official CLI registration forms are: + +```sh +codex mcp add plotium -- /ABSOLUTE/USER/DATA/bin/plotium-mcp +claude mcp add --transport stdio --scope user plotium -- /ABSOLUTE/USER/DATA/bin/plotium-mcp +``` + +See [Codex MCP](https://learn.chatgpt.com/docs/extend/mcp?surface=cli), +[Claude Code MCP](https://code.claude.com/docs/en/mcp) and the +[MCP Bundle manifest](https://github.com/modelcontextprotocol/mcpb/blob/main/MANIFEST.md). +Temporary HTTP diagnostics include a secret token and expire on service restart; +they are an advanced diagnostic entry, not the saved client configuration. +Discovery is private to the current user and local machine. Remote and cross-environment +WSL access are outside this interface. + +After upgrading Plotium, restart its MCP connection in your AI client to load +the updated tools. If connector installation fails, open +**AI connections (MCP)** to read the error and press **Retry**. + +## Permissions and supported operations + +Edits use Plotium's normal **Undo** and **Redo**. **Read only** prevents further +edit execution, including pending plans. Table reads and property preflight remain +available; import, native binding and creation and transform/patch/refresh preflight require Read and modify. +The selected permission persists until you change it. + +Project queries and plan creation require both `expected_revision` and +`expected_project_context`, using the `project_context` from `plotium_get_state`. +The examples in these pages use `PROJECT_CONTEXT` as a placeholder for that value. +Every project open, new, close or recovery creates a new context, even when +revision numbers match. Switching clears plans and rejects queued work; +`busy` during a transition means wait until it finishes or is cancelled. +On `project_changed`, reread state and replan with newly discovered targets. +Never reuse old targets or plans. Executions bind the context of their saved plan. + +Project edits, scientific computations and data transformations retain durable run +provenance and mark the project as unsaved. Ordinary queries, including state, +resource/property/table/document browsing, scientific result inspection, previews +and diagnostics, do not append project audit records or change dirty state, edit +generation or automation revision. Query-only workflows also leave the project +unchanged; workflows containing modifying operations retain the complete run, +including query inputs needed to reproduce those operations. Handshakes, tool listing, authenticated status, five-second heartbeats, +the static property catalog and save coordination (planning, submission and +`plotium_save_status`), and export planning/submission/status do not add audit records. + +The connection covers the operations described on the pages listed above. +[`plotium_properties_list`](/reference/mcp/discovery/#discover-structure-without-relying-on-names) +lists the properties it can write, with complete schemas; [Setting IDs](/reference/settings-ids/#figures) maps figure settings in +Plotium's panels to their IDs. The `object.axes.y2_*` properties +apply only while some curve of the plot has `series.y_axis` `right`. +Preferences, new format parsers, automatic scientific-result plotting and +built-in chat are outside this interface. + +## Rules every plan follows + +Tool responses include structured content and its JSON text representation. +Project reads and preflight require the current `expected_revision`; fetch the +state when dynamic values are needed or after desktop edits or Undo. Known exact +targets may reuse committed synchronous results, as described in +[State and discovery](/reference/mcp/discovery/#read-state-and-discover-capabilities-on-demand). Execution rechecks the saved revision and current +permission. Plans are single-use, including failed submissions, and at most 32 +can be pending. Restarting the connection clears them. Requests cancelled before +desktop execution are skipped without changing the project. Cancellation cannot +roll back an edit that has already started its atomic commit; use **Undo**. + +## Tool annotations and client approval + +Every tool advertises MCP `annotations` in `tools/list`, independently of the +current **Access** setting. +`readOnlyHint` describes environment changes; `destructiveHint` distinguishes +potentially destructive writes from additive ones; `idempotentHint` describes +whether repeating identical arguments has additional effects; `openWorldHint` +describes interaction with external entities, including local input/output files. +Destructive and idempotent hints are meaningful only for non-read-only tools. +See the [MCP annotation definitions](https://modelcontextprotocol.io/specification/2025-11-25/schema#toolannotations). + +Queries, previews and receipt inspection are read-only and operate on native +project/application state. Diagnosis is also read-only, but continuation cursors +are single-use. `plotium_plan` is not read-only: each successful call retains a new +executable plan and can read external data, schema, processing-scheme or image +files and prepare computation. It does not commit the candidate or write +save/export outputs. `plotium_execute` covers edits, deletion, scientific tasks +and save/export requests, so the entire tool advertises potentially destructive, +non-idempotent, open-world behavior. Task cancellation is a potentially destructive +write to task state; repeating cancellation for the same retained task has no +additional effect. + +A client's policy may use trusted-server hints when deciding whether to ask for +approval; clients can still ask, and untrusted annotations must not authorize +calls. Client approval, Plotium **Access**, and desktop file consent are separate +decisions. Annotations grant no permission: revision/context checks, revocation +and one-use plans still apply. Every save/export request retains its own desktop +confirmation and exact file/overwrite scope, including in **Read only**. +Never replay a call after disconnection or an unknown outcome, even when marked +idempotent; inspect state or retained receipts instead. After upgrading Plotium +and its connector, reconnect the client to refresh the tool catalog. diff --git a/docs/src/content/docs/reference/mcp/layout.md b/docs/src/content/docs/reference/mcp/layout.md new file mode 100644 index 00000000..da218f6a --- /dev/null +++ b/docs/src/content/docs/reference/mcp/layout.md @@ -0,0 +1,338 @@ +--- +title: MCP page layout and deletion +description: Arrange pages, panels, text and images, and delete exact content through MCP. +--- + +## Author page layout, text and local images atomically + +Plan `figure.edit` with `parameters: {canvas: EXACT_CANVAS_TARGET, edits: [...]}`; +omit top-level `ids`/`targets`. Discover the complete tagged edit schema with +`plotium_capabilities_get {"section":"operation_constraints","key":"figure.edit"}`. +One batch changes one canvas, in supplied edit order, with one Undo/Redo: + +| `op` | Required fields and meaning | +| --- | --- | +| `page` | At least one of `size_mm: [width,height]` or `size_preset`, `margin_mm: [top,right,bottom,left]`, `gutter_mm`; lengths in mm. A journal `size_preset` sets the column width and keeps the height of a page with content; paper and slide presets set both dimensions. Presets also replace the page margins (0 mm journal, 15 mm paper, 10 mm slides) unless `margin_mm` is given; the result reports `size_preset` | +| `panel_frame` | `target: EXACT_PANEL_TARGET`, `frame_pt: [x,y,width,height]` in page pt | +| `content_frame` | `target: EXACT_CONTENT_TARGET`, complete `frame_pt: [x,y,width,height]` in parent-local pt; changes only this item | +| `image_replace` | `target: EXACT_RASTER_TARGET`, `path`; replaces only its asset reference with frozen local PNG/JPEG | +| `content_delete` | `target: EXACT_CONTENT_TARGET`; removes this content, retaining its empty parent | +| `panel_delete` | `target: EXACT_PANEL_TARGET`; requires an originally empty panel | +| `series_delete` | `target: EXACT_SERIES_TARGET`; removes a non-final explicit Series | +| `panel_label` | `target`, `text`, `visible`; writes a native manual panel label, preserving its position/font | +| `panel_stack` | `panel: EXACT_PANEL_TARGET`, `shared_x: true\|false`; optional `gap_pt` (0–144) and `merge: [EXACT_PANEL_TARGET,...]`, both only with `shared_x: true`. Stacks the panel's plots on one shared x axis or returns it to free layout | +| `align` | `panels: [EXACT_PANEL_TARGET,...]`, `edge: left\|center\|right\|top\|middle\|bottom`; at least two panels | +| `distribute` | `panels`, `axis: horizontal\|vertical`; at least three panels | +| `grid` | `panels`, `rows`, `cols`; native Frame-basis cells in supplied target order | +| `text_create` | `parent: EXACT_CANVAS_OR_PANEL_TARGET`, `name`, `frame_pt`, `text`, `font_pt` | +| `text_set` | `target: EXACT_TEXT_TARGET`, `text`; optional `font_pt` | +| `image_create` | `parent`, `name`, `frame_pt`, `path: "/absolute/local/image.png"` (PNG or JPEG) | +| `annotation_create` | `target: EXACT_PLOT_TARGET`, `text`, `at: [x,y]` in the plot's data coordinates, `font_pt`; optional `kind: "text"`, `color: "#rrggbb"` | +| `annotation_create` (reference line) | `target: EXACT_PLOT_TARGET`, `kind: "reference_line"`, `orientation: vertical\|horizontal`, `value`; optional `label`, `font_pt`, `line: {color, width_pt, style}` | +| `annotation_create` (arrow) | `target: EXACT_PLOT_TARGET`, `kind: "arrow"`, tail `at: [x,y]`, head `to: [x,y]`; optional `head: none\|open\|filled\|double`, `line_width_pt`, `color: "#rrggbb"` | +| `annotation_set` | `target: EXACT_PLOT_TARGET`, `annotation_id`; at least one of `text`, `at`, `font_pt`, `color`, `offset_pt`, `placement` (text), `orientation`, `value`, `label`, `font_pt`, `line`, `placement` (reference line) or `at`, `to`, `head`, `line_width_pt`, `color` (arrow); optional `override_hand_edits` | +| `annotation_delete` | `target: EXACT_PLOT_TARGET`, `annotation_id` | + +For example, after creating two plots, set their page and selected-panel grid: + +```json +{ + "tool_id": "figure.edit", + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 3, + "parameters": { + "canvas": {"resource":{"id":"CANVAS_UUID","kind":"plotium.canvas"}}, + "edits": [ + {"op":"page","size_mm":[180,90],"margin_mm":[4,4,15,4],"gutter_mm":5}, + {"op":"grid","panels":[{"resource":{"id":"CANVAS_UUID/panels/PANEL_A_UUID","kind":"plotium.canvas.panel","parent_id":"CANVAS_UUID","local_id":"PANEL_A_UUID"}},{"resource":{"id":"CANVAS_UUID/panels/PANEL_B_UUID","kind":"plotium.canvas.panel","parent_id":"CANVAS_UUID","local_id":"PANEL_B_UUID"}}],"rows":1,"cols":2} + ] + } +} +``` + +Replace all identity placeholders with discovered complete targets, not names. The resulting frames are (4,4,83.5,71) and (92.5,4,83.5,71) mm. +A frame uses a top-left origin, X rightwards and Y downwards; 1 pt = 1/72 inch. +Panel frames use the existing **Object Geometry/drag authoring** semantics: +moving preserves child-local coordinates; resizing scales all child-local frames +proportionally, without changing curve IDs, bindings, styles, axis ranges or fonts. +This differs from the free Panel inspector's container-only dimensions. +New text/image frames are parent-local pt, or page pt for a canvas parent. + +`panel_stack` with `shared_x: true` needs at least two plots. `plot.create` +places each new plot in its own Panel, so list the other plots' Panels in +`merge`: they are merged into `panel` and their plots are stacked top to bottom +in their page order, like **Stack with Shared X** on the desktop. Without +`merge` the plots keep the Panel's content order. The stack fills the Panel's +inner width; +their heights keep the proportions of their current frames, so change one with +`content_frame` to give it a larger share. The gap defaults to 0 pt when the +stack is turned on. Only the bottom plot draws x tick labels and the x title, +only the top plot draws a figure title, inner boundaries touch with inward x +ticks, and the plot areas share left and right edges. Entering the stack writes +one x range covering every member's data (in its own coordinate unit) and the +top member's x major step (in the unit it displays) to each member, so members +must already share an x scale; every member draws the bottom +member's x direction without storing it. The plots share one x viewport, and +later x range, x scale, x display unit, x thousands-separator and x major step +edits on any +member apply to all of them in one Undo step; the write is rejected when any +member cannot take the value, and `applied` lists the member edits. A batch that +requests conflicting shared x settings is rejected without changes; equivalent +ranges expressed in compatible coordinate units are accepted. +`shared_x: false` returns the Panel to free layout and keeps +the frames. The result lists each operation in `panel_edits` with `layout`, +`gap_pt`, `members_top_to_bottom` and `merged_panels`. `plotium_document_inspect` reports every +Panel's `layout` (`free`, `vertical_stack`, `horizontal_stack`, `grid` or +`shared_x_stack`); a stack adds `shared_x_stack: {members_top_to_bottom, +gap_pt}`. `plotium_figure_diagnose` and plan previews use the stacked geometry. + +Plot annotations are anchored in data coordinates, not page pt: the label is +centred above its `at` point and follows the plot's axis ranges, zoom and pan, +in the canvas and in every export. When that spot covers data, the legend, a +value label or another label, the text moves to the nearest clear spot within +about three text heights; an arrow pointing at it does not count. +`offset_pt: [dx, dy]` (pt, x right, y up) pins the text there instead, with +`[0, 0]` exactly at `at`, and `placement: "auto"` returns it to automatic +placement. `color` (`#rrggbb`) sets the text colour, black by default. A label +the user dragged on the canvas keeps its place through edits of `text` and +`font_pt`; a new `at`, `offset_pt` or `placement` on it is rejected unless +`override_hand_edits: true` says the user asked. Each text in +`annotations` reports `placement` (`auto`, `fixed` or `hand`) and the drawn +`offset_pt`, and `plotium_get_state` lists dragged labels under `hand_edits` +with key `annotation.label_position`. An anchor outside the visible range is +clipped with the plot. `annotation_id` is local to the plot and never reused +after deletion; read it from `annotation_edits` in the result or from the plot's +`annotations` list in `plotium_document_inspect`. `at` uses the plot's source +units reported in `coordinate_units`, not a display unit chosen for the tick +labels. `\n` in `text` starts a new line. +Annotation text permits 1024 UTF-8 bytes (nonblank), and a plot holds at +most 256 annotations. The plot and its parent panel must be unlocked; Auto height +may stay on. + +A reference line is a plot annotation of `kind: "reference_line"`: a vertical +line at x = `value` or a horizontal line at y = `value`, in the same source +units as `at`, that spans the whole plot area. It follows the axis ranges, zoom +and pan, and disappears when `value` lies outside the visible range. `line` +sets `color` (`#rrggbb`), `width_pt` (0.1–20) and `style` (`solid`, `dashed`, +`dotted` or `dash_dot`); a new line defaults to `#000000`, 0.75 pt (or the +theme's supporting-line width, 0.3 pt under Nature), dashed, and +omitted `line` fields keep their value on `annotation_set`. The optional +`label` is drawn in the line colour near the top of a vertical line or the right +end of a horizontal one, or further along the line or on its other side when +that spot covers data, the legend or another label; inspection reports +`label_placement` and the drawn `label_position: {along, side}`, and +`placement: "auto"` returns a dragged label to automatic placement under the +same `override_hand_edits` rule. It uses the tick label size until `font_pt` sets an +explicit size, which then stays until changed. An empty `label` removes it. Reference lines and text +annotations share one id sequence and the 256-per-plot budget, and +`plotium_document_inspect` lists both under `annotations`, each with its `kind`. +Fields of the other kind are rejected rather than ignored; a reference line +takes its colour in `line.color`, not `color`. + +An arrow or reference line the user moved on the canvas reports +`hand_moved: true` and is listed under `hand_edits` with key +`annotation.position`. Restyling it is allowed, but a new `at` or `to` on such +an arrow, or a new `value` or `orientation` on such a line, is rejected unless +`override_hand_edits: true` says the user asked; the moved position then +becomes the agent's again. + +```json +{"op":"annotation_create","target":EXACT_PLOT_TARGET,"kind":"reference_line", + "orientation":"horizontal","value":0,"label":"baseline", + "line":{"color":"#7f7f7f","width_pt":0.5,"style":"dotted"}} +``` + +An arrow annotation (`kind: "arrow"`) draws a straight line from its tail `at` to +its head `to`, both in the same data coordinates, so it follows the axes and is +clipped to the plot area like a label. `head` defaults to `filled` (`double` +fills both ends, `none` draws a plain line); `line_width_pt` (0.1–20 pt) defaults to 1 pt, or the +theme's supporting-line width (0.3 pt under Nature); `color` defaults to black. The two ends must differ. An arrow carries no +text: label it with a separate text annotation, for example at its tail. Arrows +share the `annotation_id` sequence and 256-per-plot budget with the other kinds, +are listed under `annotations` with `kind: "arrow"`, and reject fields of the +other kinds. + +Align uses the selected bounding edges/centres. Distribution equalizes centres +between fixed endpoints, not edge gaps. Grid composes the existing native cell +algorithm with the authoring resize setter for an explicit subset; it does not +claim an existing GUI subset-grid button. Grid uses the current page margins and +gutter, but does not change saved grid preferences or simplify axes. Page size +and margin edits alone never rearrange content. Non-target panels and loose +content remain in place, including any resulting overlap or clipping. + +Panel layout-operation targets must be distinct, on this canvas, unlocked and +use free or shared-x stack layout; new text and images need a free-layout parent; +locked children reject a panel edit. Hidden explicit targets remain addressable. Turn off native Auto height before +exact page/layout authoring. +Dimensions must be finite/positive; page size is 10–1000 mm, margins/gutter are +nonnegative and must leave positive space. Grid is 1–16 rows/columns with enough +cells for every target; each cell must reach the native 1 pt minimum. Text permits 16384 UTF-8 bytes and 1–72 pt fonts; names +and manual labels permit 1024 bytes (nonblank). A batch permits 1–200 edits and +at most 200 panels per layout operation. + +Image preflight reads only explicitly named absolute regular files: at most 8 +image inputs (creation and replacement combined; duplicates still count), 1 MiB encoded per file, 4 MiB encoded per batch, and 4 MiB decoded RGBA8 +per image. PNG/JPEG probing and decoding reuse native image I/O; bytes are frozen +in the plan and embedded in the native asset store at commit. Identical encoded +assets are shared, not linked to the external path. Missing/damaged assets or +unsupported formats reject the entire batch with `invalid_parameters` and a +specific asset error. There is no directory scan, network fetch or source write. + +`preflight.figure_plan` reports proposed `created`/`modified` targets and `result` +with page dimensions, margins/gutter and exact `panel_frames`. Execute returns +that result in `ToolResult.value`. Preflight commits nothing; invalid targets, +geometry, assets or a stale revision leave no partial objects. Both planning and +execution require Read and modify. Plans are single-use, including failed +execution; the 32-plan and 256 KiB response limits apply. One Undo restores the +whole batch; Redo restores the same native content and asset IDs. After a lost +execute response, inspect the proposed targets before making another create call. + +Use the ordinary GUI Object Geometry, text and image inspectors to continue +editing. Preview the actual canvas PNG after layout changes; native text frames +can clip long text, and layout never silently shrinks fonts or resolves collisions. + +## Move existing content or replace an image in place + +To widen an existing caption or replace one of two images sharing an asset, first +inspect the exact content with `plotium_document_inspect`, `view: "self"`. Copy +its complete target, not its name, selection or collection position. Use the +current context/revision and plan `figure.edit` with edits such as: + +```json +[ + {"op":"content_frame","target":{"resource":{"id":"CANVAS_UUID/CONTENT_ID","kind":"plotium.canvas.object","parent_id":"CANVAS_UUID","local_id":"CONTENT_ID"}},"frame_pt":[12,18,140,30]}, + {"op":"image_replace","target":{"resource":{"id":"CANVAS_UUID/IMAGE_ID","kind":"plotium.canvas.object","parent_id":"CANVAS_UUID","local_id":"IMAGE_ID"}},"path":"/absolute/local/replacement.png"} +] +``` + +Place this array in `parameters.edits` alongside the discovered whole-canvas +`parameters.canvas`. Omit top-level `ids`/`targets`. The two targets above may be +different items; to move and replace the same image, repeat that image's target. +Existing text/font edits still use `text_set`. + +`content_frame` supports native plot, text, raster and existing rect/ellipse/line/ +arrow content, without creating or reparenting anything. It sets a **complete** +frame, not a relative delta. Coordinates use the parent's local pt, or page pt +for loose content: top-left origin, X rightwards, Y downwards. `parent` identifies +the actual canvas/panel; `page_frame` uses the native parent-origin translation. +Positions may extend beyond the panel or page and are not clamped or snapped. +All components and converted bounds must be finite, and width/height must be at +least 1 pt. This numeric minimum does not change the GUI drag minimum. + +Only the target item changes (in a shared-x stack its siblings reflow to the +new share): its parent and siblings otherwise keep their frames/order; +plot bindings, Series identities, sources, units, manual axis ranges and styles, +and text contents/fonts remain intact. The target and its parent must be unlocked; +a parent must use Free or Shared X Stack layout and Auto height must be off. In a +shared-x stack only the height counts: it sets the item's share of the stack, and +the stack reflows. A locked sibling does +not block this edit. `geometry.frame_editable` and `frame_edit_error` report these +native eligibility conditions, independent of connection modify permission. + +For a raster with `preserve_aspect: true`, dimensions preserve the **existing +frame ratio**, not the replacement's pixel ratio. The native aspect rule chooses +the width/height scale with the larger absolute departure from 1 (width wins a +tie), bounded by the 1 pt minimum. Requested X/Y remain the top-left anchor. +Preflight reports `requested_frame_pt` and `effective_frame_pt`; they may differ. +`geometry` exposes `min_size_pt`, `preserve_aspect` and `aspect_ratio`. +`fit` independently controls contain/cover/stretch rendering within the frame. + +`image_replace` sets only the target's AssetId. It retains ContentId, parent, +frame, z-order, name, visibility and all native image attributes: +`page_index`, crop, fit, quarter-turn rotation, opacity, interpolation and +preserve_aspect. Other references to the old asset remain unchanged. A retained +crop/fit can make the new image look different; settings are never reset to hide +that effect. PNG/JPEG replacement requires the existing `page_index` to be 0; +other pages reject the batch instead of silently changing page index. Replacement +requires the target/parent unlocked, but not Free layout or Auto height off. +`image.replaceable` and `replace_error` disclose that eligibility. + +Creation and replacement share the image budgets above, byte freezing, encoded +asset deduplication, embedding and Undo lifecycle. Changing or deleting the source +after preflight cannot alter the candidate or Redo. There is no source write or +asset garbage collection. Bad files, unsupported formats, wrong/stale targets, +locked targets and invalid geometry reject the whole batch, not just that edit. + +`preflight.figure_plan.result.content_edits` reports each new edit in input order: +`edit_index`, `op`, `target`, `parent`, `frame_space`, `before_frame_pt`, +`effective_frame_pt`, `page_frame` and `geometry`; frame edits add +`requested_frame_pt`, replacement adds `asset_change` with `before`/`after` +AssetIds, `format` and `pixel_size`. These are the state at that edit's step. +`result.content_frames` gives the final geometry for each distinct targeted +content after all edits, including any later explicit parent-panel resize. +Execute returns the same result in `ToolResult.value`. Both operations reuse the +same permission/context/revision checks and one-use plans as other figure edits; +one Undo restores the batch's frames and asset references, Redo restores the +same identities and frozen image. Inspect/render the committed state afterwards. + +## Delete exact content or selected Series + +Ask the agent: “Delete this duplicate note and this redundant curve, keeping the +other curve with the same name.” Discover the complete canvas/content targets +and plot-owned Series targets first. Do not identify them by name, row index, +visible trace number or the current GUI selection. + +Use a deletion-only `figure.edit` batch on one canvas: + +```json +{"tool_id":"figure.edit","expected_project_context":"PROJECT_CONTEXT","expected_revision":12,"parameters":{ + "canvas":{"resource":{"id":"CANVAS_UUID","kind":"plotium.canvas"}}, + "edits":[ + {"op":"content_delete","target":{"resource":{"id":"CANVAS_UUID/CONTENT_ID","kind":"plotium.canvas.object","parent_id":"CANVAS_UUID","local_id":"CONTENT_ID"}}}, + {"op":"series_delete","target":{"resource":{"id":"CANVAS_UUID/PLOT_ID","kind":"plotium.canvas.object","parent_id":"CANVAS_UUID","local_id":"PLOT_ID"},"component":{"kind":"series","id":2}}} + ] +}} +``` + +`content_delete` removes one whole native plot, text, raster or existing +rect/ellipse/line/arrow shape. Deleting a plot does not delete its source Dataset. +`panel_delete` takes a complete Panel target and requires it to be empty in the +original state. Deleting all its children in the same batch does not make a +nonempty panel eligible. Content deletion retains the empty parent panel and +does not reflow siblings. + +`series_delete` removes only the exact SeriesId inside its owning plot. It +supports line/scatter plots with explicit column bindings and an established +coordinate contract, including bindings to derived tables. The last Series +cannot be removed: use an explicit `content_delete` to remove the whole plot. +Table-default bindings and dynamic multi-channel displays are rejected; this +operation never materializes, rebinds or edits a Dataset. Remaining Series keep +their identities, sources, order, encodings, coordinate units and manual ranges, +including when the first Series is deleted. + +Duplicate targets, a whole plot plus any of its Series, cross-canvas targets, +locked targets/parents, and mixing deletion with non-deletion edits reject the +whole batch. Hidden exact targets remain eligible. A locked sibling is not a +reason to reject an unrelated deletion. Native automatic page height remains +enabled if it was enabled; its derived height is reported, not silently disabled. + +Read `preflight.figure_plan.deleted` and `result.deleted_targets` before executing. +`result.deletions` includes parent/order information and all owned Series removed +with a plot. `parent_changes`, `group_changes`, `viewport_link_changes` and +`selection_change` list necessary relationship updates; group/link changes retain +surviving members or remove a relationship that has fewer than two members. +`remaining_series` reports the surviving order and active Series identity, `retained_asset_ids` lists the +assets referenced by removed raster content, and `auto_height` reports derived +before/after heights when enabled. These are metadata, not a candidate image. +Execute returns the same deletion manifest in `ToolResult.value`. + +Planning commits nothing. One successful execute is one atomic Undo/Redo; +invalid batches leave no partial deletion. Undo restores exact identities, +parents, object/panel order, groups, links and necessary selection. Identity +allocator high-water marks never move backwards. No original file, Dataset or +asset is deleted. Runtime Undo retains embedded assets; saving uses the existing +reachable-asset policy, and reopening a project does not restore Undo history. + +The existing modify permission, project-context/revision checks and one-use +plan rules apply. A selection change that alters the reported deletion effect +also requires a new preflight, even though GUI selection does not advance the +revision. Up to 200 explicit deletion targets, 2,000,000 remaining curve-row +visits per Series candidate batch, 32 shared pending plans and the complete +256 KiB response budget apply. Oversized manifests fail rather than truncate. +Target/contract failures return `invalid_parameters` with the reason; +`stale_revision`, `project_changed`, `permission_denied`, `expired_plan`, +`plan_limit` and `response_too_large` retain their existing meanings. + +After an unknown execute outcome, rediscover the current context, revision and +exact targets before planning again; do not replay deletion automatically. View +the committed PNG, then use native Undo/Redo and save/reopen to check the result. diff --git a/docs/src/content/docs/reference/mcp/plots.md b/docs/src/content/docs/reference/mcp/plots.md new file mode 100644 index 00000000..2ba518f4 --- /dev/null +++ b/docs/src/content/docs/reference/mcp/plots.md @@ -0,0 +1,279 @@ +--- +title: MCP plots and curves +description: Create native plots and add or rebind curves through MCP. +--- + +## Create a native single plot from an imported table + +Ask the agent: “Import this CSV, use time in s and current/error in mA, and create +one editable line plot with symmetric Y error bars. Preview it, then change only +that curve's line width to 1.5 pt and preview again.” Supply an absolute input path +and explicit units. The agent can discover the complete import and creation +schemas through the `operation_constraints` section of `plotium_capabilities_get`. + +After data-only import, read the actual DatasetId, FieldId, TableId, table revision +and ColumnIds from import results / table metadata. Plan `plot.create` without +top-level `ids` or `targets`: + +```json +{ + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 1, + "tool_id": "plot.create", + "parameters": { + "parent": {"resource": {"id": "document", "kind": "plotium.document"}}, + "name": "Current", + "series": [{ + "kind": "line", + "source": { + "dataset_id": "RETURNED_DATASET_UUID", + "field_id": 0, + "table_id": "RETURNED_TABLE_UUID", + "table_revision": "RETURNED_TABLE_REVISION_UUID", + "x_column_id": "RETURNED_TIME_COLUMN_UUID", + "y_column_id": "RETURNED_CURRENT_COLUMN_UUID", + "y_error_column_id": "RETURNED_ERROR_COLUMN_UUID" + } + }] + } +} +``` + +Replace every identity, including the example FieldId, with the actual returned +identity. `kind` is `line`, `scatter`, `bar`, `box` or `violin`; `y_error_column_id` is a +ColumnId, `null` or omitted for no error bars. A source can instead name columns: +`{"dataset_id":"DATASET_UUID","x":"time","y":"signal","y_error":"sd"}`. `x`, `y` +and optional `y_error` are exact, case-sensitive column names or ColumnIds; +Plotium fills in the default field, table and current table revision. A missing +or repeated name fails with `invalid_parameters`, the path in +`error.details.field` and the table's columns in `error.details.candidates`. +The plan response lists each source resolved this way in `resolved_sources`. +The same source forms apply to `plot.series.append` and `plot.series.bind`. A `bar` curve draws filled bars from zero with optional +error whiskers, filled in the curve color with a thin outline. Whiskers use the +outline's color and width, and their caps span 45% of the bar. A bar too small +for its outline on paper (narrower than 4 or shorter than 2 outline widths, such +as a near-zero value) is drawn as a plain fill, keeping its whiskers. On a numeric +x, a slot is the typical spacing between positions, narrowed only where +neighbours sit closer. Its x column may be numeric or a +Utf8 text column; text values become categories in table row order, and equal +texts share one slot. Bar curves that share a slot sit side by side within it; a +bar alone in its slot keeps the full width, so one bar curve per category gives +centred bars in their own colors. A `box` or `violin` curve summarises the raw y +samples that share each x (Tukey box: median, IQR and 1.5 × IQR whiskers with +outliers; violin: Gaussian kernel density with a quartile bar), takes no y error +column, and shares slots with bars. `line` and `scatter` curves may use a text x +too and overlay the slots: the k-th line or scatter curve sits on the k-th bar, +box or violin curve's position, so raw points line up with their bar. +`series.points.spread` spreads replicate points that share an x across that +mark (0–1 of its width, in row order), and `series.value_labels` writes each +bar's or point's value past its end (or whisker) in tick-label size. +`object.chart.orientation` `horizontal` turns an explicit plot on its side: +categories run down the vertical axis, first at the top, and values along the +horizontal one; error bars, labels and axis titles turn with it, and the view +resets. All series in one plot share a text or a numeric x. Plots with bars, +boxes or violins have no logarithmic axes. Optional `y_axis` +is `left` (default) or `right` for a line or scatter curve; `right` on a bar, +box or violin is rejected. Any right curve gives the plot a right y axis with its own automatic +range, scale and title, which starts as the first right curve's column name and +unit; that curve also fixes the right axis's unit. Reference lines, annotations +and arrows stay in left-axis coordinates. Multiple entries create independent native Series in this +one plot, not separate plots. Source extraction and all numeric, missing-value, +error and unit rules are the same as explicit curve binding below. Table-wide +X/Y defaults and other plots are untouched; no source table is copied. + +Optional `intent: {purpose, claim}` records what the plot is meant to show. +`purpose` is `compare`, `trend`, `distribution`, `relationship`, `composition`, +`change` (ratio or fold difference) or `detail` (zoom or inset); `claim` is one +sentence of at most 500 characters. Ask the user for both before creating a +plot instead of guessing; if they leave it open, propose your reading and let +them confirm or edit it. The intent never changes the drawing. It is saved with +the project, edited later through `object.intent.purpose` (`unspecified` clears +it) and `object.intent.claim`, and shown under **Chart › Advanced** in the Object inspector. + +The exact `parent` determines which objects are new: + +- Document root: create canvas, single panel and plot. Optional + `canvas: {name, size_mm: [width, height]}` sets the new canvas (10–1000 mm per + dimension), or `canvas: {name, size_preset}` uses a built-in page size such as + `nature-1col` (89 mm), `nature-1p5col` (136 mm) or `nature-2col` (183 mm) with + its default height and margins (0 mm for journal columns, 15 mm for paper, + 10 mm for slides); the result reports the applied `size_preset`. Omission freezes the native default size and + plot name. +- Existing canvas without a panel or plot: create panel and plot using native + GUI empty-page placement and the canvas's existing layout settings/margins. + Do not supply `canvas` options. +- Existing canvas with content: supply `panel_frame_pt: [x,y,width,height]` to + create another panel and plot at that exact page-relative pt frame. Existing + panels, curves and loose content stay in place; overlap is allowed. +- Its sole empty, visible, unlocked free-layout panel: create only the plot, + preserving the panel's page position and size. Omit `canvas`, `panel_name` and `panel_frame_pt`. + +`panel_name` optionally names a newly created panel; otherwise it uses the plot +name. Names must be nonblank and at most 1024 UTF-8 bytes. `panel_frame_pt` +sets only a newly created panel: X/Y are finite page pt, width/height are finite +and positive. Omission retains the original empty-page native placement contract; +an already plotted canvas requires the explicit frame. Existing content is never +retiled or rebuilt into a replacement plot. + +The MCP plan returns `plan_id`, `project_context` and `basis_revision`. +`preflight` includes `required_authority`, `created_target_count`, exceptional +`targets` and `outputs`. `preflight.binding_plan.creation` contains the exact +`parent`, proposed complete `canvas`, `panel`, `plot` and `created` targets +(including all Series), plus `size_mm`, any `size_preset`, `panel_frame_pt` +(page coordinates), `frame_pt` (panel-local coordinates), `coordinate_units` +and `series_defaults` (kind and line width in pt). Keep these frozen identities +when checking an uncertain execution outcome. + +`preflight.binding_plan.binding_count` counts curves, and `row_counts` sums +`total_rows` and `plotted_rows` across them. `binding_plan.bindings` includes only +curves with missing/non-finite data or missing errors, with each complete target +and full diagnostics including sample `affected_rows`. An empty list means no +such issues, not zero bindings. The response omits echoed requests, frozen-target +duplicates, source mappings and successful-target explanations; the stored plan +still retains the complete validated sources and candidate. + +Planning creates nothing. Executing the single-use plan returns +`value.creation` with the same canvas/panel/plot and layout, and `value.bindings` +with **every** Series target and its `total_rows`, `plotted_rows`, `missing_xy`, +`non_finite_xy` and `missing_error` counts. Defaults are disclosed only in +preflight. `produced` lists newly created resources; `summary` counts target +outcomes, while `targets` retains only exceptional rows. Diagnostics and +verification remain available. `project_context` and `after_revision` identify +the committed result. + +The creation is atomic: a bad source, incompatible units, invalid error or +changed parent/revision leaves no new canvas, panel or partial plot. Read-only +connections reject creation preflight and execution. There are 1–200 curves per +plot, at most 2,000,000 curve-row visits, a shared 2,000,000-row pending-plan +budget with binding edits, 32 pending plans and a 256 KiB structured-response +limit. Failed submissions consume their plan too. After a lost execute response, +query current state and the proposed targets before deciding what to do; do not +blindly make a new creation request. + +Use returned targets with document inspection and properties; preview the +returned whole-canvas target at the current revision. The result is selectable +and editable in the GUI. One Undo removes the created subtree but keeps existing +parents and imported data; Redo restores the same IDs. Existing native resize +and layout controls retain plot/Series identities and source bindings. Known exact +targets may reuse committed synchronous results; refresh state after desktop edits +or Undo/Redo. + +## Add a derived curve to an existing plot + +Use `plot.series.append` when a newly calculated table should appear beside the +existing curves, without replacing a plot. + +For MCP, omit top-level `ids`/`targets` and provide the exact whole plot target: + +```json +{ + "expected_project_context": "", + "expected_revision": 23, + "tool_id": "plot.series.append", + "parameters": { + "plot": {"resource": {"id": "/", "kind": "plotium.canvas.object", "parent_id": "", "local_id": ""}}, + "series": [{"kind": "line", "source": { + "dataset_id": "", "field_id": 0, + "table_id": "", "table_revision": "", + "x_column_id": "", "y_column_id": "", + "y_error_column_id": null + }}] + } +} +``` + +Copy targets, FieldId and all table/column IDs from discovery; labels are not +identity. The target must already have explicit coordinates. A batch adds +1–200 selected line/scatter/bar/box/violin curves, with at most 200 total curves in that plot. +Existing bars regroup to share their slots with appended bars. +The shared binding validator checks every source revision, complete curve data, +errors and units before one atomic commit. Compatible source units convert to +the plot's existing coordinate units; incompatible batches fail without adding +any curve. The binding service's 2,000,000 curve-row and pending-plan limits and +256 KiB response limit also apply, including existing curves in the affected plot. + +`preflight.binding_plan.appended` contains the proposed new Series targets; +`bindings` includes the unchanged existing and newly appended bindings. Execute +adopts those frozen IDs. One Undo removes the additions; Redo restores them. +Retired IDs are not reused by a different append after Undo. Existing Series +styles, coordinate meaning, authored axis ranges, plot/Panel identity and frames +remain unchanged. Preparation and execution require Read and modify; context, +revisions and permission use the same one-use-plan lifecycle as binding edits. +After response loss, inspect the proposed targets before making another plan. + +## Rebind an existing curve without changing another plot + +Two plots can use the same native table with different numeric X, Y and optional +symmetric Y-error columns. The table's shared default bindings are unchanged. + +For MCP, discover the exact Series target with `plotium_document_inspect` and +copy the DatasetId, TableId, FieldId, table revision and ColumnIds from +`plotium_table_columns`. Use project ColumnIds, not `source_column_id`, names, +trace positions or a guessed field resource address. Call `plotium_plan`: + +```json +{ + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 8, + "tool_id": "plot.series.bind", + "parameters": { + "edits": [{ + "target": { + "resource": {"id":"CANVAS_UUID/OBJECT_ID","kind":"plotium.canvas.object", + "parent_id":"CANVAS_UUID","local_id":"OBJECT_ID"}, + "component": {"kind":"series","id":0} + }, + "source": { + "dataset_id":"DATASET_UUID", "field_id":0, + "table_id":"TABLE_UUID", "table_revision":"TABLE_REVISION_UUID", + "x_column_id":"X_COLUMN_UUID", "y_column_id":"Y_COLUMN_UUID", + "y_error_column_id":null + } + }] + } +} +``` + +Replace every placeholder, including the numeric IDs, with discovered values. +Do not add top-level `ids` or `targets`: each edit carries its complete target. +`y_error_column_id` is a ColumnId, or null or omitted to remove the error binding. +Review `preflight.binding_plan.bindings`, including source mappings and row +diagnostics, then submit its one-use `plan_id` with `plotium_execute`. + +A default table Series can represent several displayed curves. First use +`plot.series.materialize_default` with +`parameters: {"edits":[{"target":EXACT_SERIES_TARGET, +"retain_y_column_id":"EXISTING_Y_COLUMN_UUID", +"table_revision":"TABLE_REVISION_UUID"}]}`. The SeriesId of the retained Y +column is kept; the other existing curves receive new owner-local SeriesIds, returned in the plan and +execution result. This expands existing content; it does not create a plot. +Fit overlays and normalized/offset multi-curve defaults cannot be expanded +losslessly and are rejected. Default drawing remains available without expansion. + +Only Int64 and Float64 columns are accepted. Integers that cannot be represented +exactly in f64 curve coordinates are rejected. X/Y nulls and non-finite values +create gaps, never zero values or connecting lines across a gap. A null error +keeps the valid point without its error bar; zero error is valid. Negative or +non-finite errors reject the entire batch, including on rows with missing X/Y. +Errors are non-negative absolute amplitudes; their names do not assign standard +deviation, standard error or confidence-interval meaning. Diagnostics count all +rows and include up to 20 affected RowIds per curve. No row sampling is used for +binding validation or native curve extraction. + +Compatible units are converted into the plot's persisted coordinate units. +Error amplitudes use scale only, not affine offsets. Known and unknown units +cannot be combined. Manual ranges and shifts retain their coordinate meaning +through rebinding, deletion of the first curve and reordering. An incompatible +binding is rejected rather than reinterpreting those numbers. Authored labels, +colors, line/point encoding, visibility, panel placement and axis settings stay +with their existing targets. Explicit plots retain line/point encodings rather +than switching to unrelated table chart types. + +A batch accepts 1–200 edits and at most 2,000,000 curve-row visits across the +affected plots. Pending MCP curve plans share that same row budget; complete +responses are limited to 256 KiB. All targets, columns, units, rows and revisions +are checked before one atomic commit and one Undo. There is no partial success +or skipped invalid target. Read-only connections reject binding preflight and +execution. Failed or stale execution consumes the plan; discover current state +and plan again. GUI save/reopen preserves the native bindings and units; MCP +`project.save` requires separate desktop approval; SVG/PDF/PNG exports require their own desktop approval. Use `plot.create` above to create a new plot. diff --git a/docs/src/content/docs/reference/mcp/review.md b/docs/src/content/docs/reference/mcp/review.md new file mode 100644 index 00000000..b3b587b6 --- /dev/null +++ b/docs/src/content/docs/reference/mcp/review.md @@ -0,0 +1,373 @@ +--- +title: MCP preview, diagnostics and recovery +description: Render previews, diagnose figure geometry and recover from errors. +--- + +## Read the actual canvas image + +Ask the agent: “Preview this canvas and describe its text, curves and local +images.” Use `plotium_document_inspect` to obtain a complete canvas target, then +call `plotium_render_preview` with that target and the current revision: + +```json +{ + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 7, + "target": {"resource":{"id":"CANVAS_UUID","kind":"plotium.canvas"}}, + "max_edge": 1440 +} +``` + +Replace `CANVAS_UUID` with the discovered canvas ID; do not pass a panel, +content item, selection or Series. The response contains a standard MCP PNG +**image content block**, plus `ToolResult.value` metadata: `target`, +`render_revision`, `width_px`, `height_px` and `mime_type`. It does not require +opening a file or rendering SVG text. A curve with more points than the preview +can show is drawn as a min/max envelope of four point pairs per pixel column, at +least 2,048 pairs across the plot (markers: one per pixel), and `downsampled` +lists each such curve as `{target, source_points, drawn_points}`; it is omitted +when nothing was thinned. A zoomed-in curve keeps every visible point. +Exports always draw every point. The MCP client must deliver image content +to its agent; a text-only client cannot consume this preview. + +The image covers the whole page with its native layout, background, panel clips, +text, curves and embedded local raster assets. Rendering runs off the desktop +thread from an immutable snapshot. `render_revision` identifies that snapshot; +human edits after capture do not change it. Read state again before editing. +Read-only connections permit previews. Previews do not append project run records +or change dirty state, edit generation or automation revision. + +`max_edge` defaults to 1440 px and accepts 1–2048; aspect ratio is preserved +with pixel rounding and a minimum of one pixel per axis. Limits are 4,194,304 +output pixels, 16 MiB of referenced encoded assets, 64 MiB of header-probed +RGBA8 asset pages, 8 MiB of intermediate SVG, 4 MiB of PNG, and 6 MiB of JSON-RPC +preview response (including the request ID). Shared asset bytes count once; +decoded pages count once per asset/page. These are payload and image-buffer limits, not a total process +memory limit. All referenced assets are validated, including hidden items. +Limits are also available with +`plotium_capabilities_get {"section":"limits","key":"image_preview"}`. + +Missing or damaged assets and unavailable image pages return +`preview_asset_unavailable`; no placeholder or incomplete success image is +returned. Budget overflow returns `preview_budget_exceeded`, without silent +quality reduction; lower `max_edge` for output-size overflow, or reduce source +assets for asset-budget overflow. Invalid full identities return +`invalid_parameters`, and outdated revisions return `stale_revision`. +Only one preview renders per connection; another returns `busy`. Other existing +tools remain available while rendering. Cancellation or stopping the connection +prevents image delivery; stopping or switching projects discards the old job. + +## Preview a plan before committing it + +After `plotium_plan`, call `plotium_preview_plan` with the **same** plan ID, +context and revision, and one affected whole-canvas target: + +```json +{ + "plan_id": "RETURNED_PLAN_ID", + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 7, + "target": {"resource":{"id":"CANVAS_UUID","kind":"plotium.canvas"}}, + "max_edge": 1440 +} +``` + +The response contains an actual MCP PNG image block. `ToolResult.value` contains +`plan_id`, `basis_project_context`, `basis_revision`, `candidate: true`, `target`, +`width_px`, `height_px`, `mime_type` and `output` (`size_mm`, `size_pt`, `max_edge`). +There is no `render_revision`: this image has not been committed. The read's +`before_revision` and `after_revision` both identify the baseline. Read the image, +then explicitly call `plotium_execute` with the original `plan_id`. Finally read +`plotium_render_preview` and fresh `plotium_figure_diagnose` results. Candidate +preview does not introduce candidate diagnostics or an automatic repair loop. +Keep diagnostic `measurement_basis`, `coverage` and `unsupported` records: +estimated text bounds are not glyph ink, and a potential legend conflict is not +proof of occlusion. + +| Existing plan | Candidate support | +| --- | --- | +| `properties.set` / `properties.reset` / `properties.set_many` | Document and object display properties, including their native multi-target batch; not canvas, app preference or dataset processing properties, chart type or stack changes | +| `figure.edit` local edits | `content_frame`, `image_replace`, `text_set`, `annotation_create`/`annotation_set`/`annotation_delete` (text and reference lines), including native batches | +| `figure.edit` deletion-only batch | `content_delete`, originally empty `panel_delete`, explicit-column `series_delete`; all existing refusal rules remain | +| Other operations, including save/export | `unsupported_operation`; their normal execution contract is unchanged | + +To let the user choose a style, such as a palette, line widths, legend +placement or label layout, plan two or three alternatives, preview each and show +the images side by side. Execute only the plan the user picks. The others are +never committed: they then fail with `stale_revision`, but count toward the 32 +pending plans until submitted or the connection resets. + +Affected canvases must use ordinary line/scatter plots, native text, shapes and +raster content; previews do not launch scientific computations. A cross-canvas +property plan applies its complete batch to the disposable native context; request +each affected canvas separately. It is still one plan and one Undo step. +Automatic axes, guide dependencies and derived page height use the native action +and renderer, not a second layout model. With identical baseline, settings and +fonts, candidate content and geometry match execution. Cross-machine font or +renderer differences are not a pixel-equivalence guarantee. + +Candidate reads require **Read and modify**, checked at capture and background +delivery alongside context, revision, idle state and the still-pending plan. +Revocation and regrant during rendering also prevent delivery. Preview neither +consumes the plan nor extends its lifetime or grants execution permission. +Ordinary edit plans have no wall-clock TTL; they share the 32-plan session cap +and are cleared on context/connection changes. Submitted plans are single-use, +including failed submissions. `expired_plan` means absent/consumed; +`stale_revision`, `project_changed`, `permission_denied`, `busy`, +`request_cancelled` and the image errors above describe other refusals. +After a human edit or project change, rediscover and replan. Never replay an +outcome-unknown execute after a disconnect. + +Preview borrows frozen inputs and image bytes, without rereading a replacement +path, allocating planned identities or executing then undoing the live document. +It does not change authored content, data, bindings, selection, history, automation +revision, persistent assets, edit generation or dirty state. It adds no project +audit record and persists no PNG bytes. No candidate file or cache is created. Candidate and +committed previews share the single rendering slot, cancellation and image budgets +above. Candidate construction additionally rejects a native snapshot estimate over +64 MiB (canvas geometry, source field dimensions at 64 bytes/element, metadata and +frozen assets); this estimate is not a process-memory ceiling. Cancelled project +work retains the slot until the bounded renderer exits. + +## Diagnose figure geometry at an output size + +Ask: “At 180 × 90 mm, report out-of-page content, clipped geometry, text overflow, +intentional overlap between these two captions, and possible line/scatter occlusion +by legends. Do not edit anything. Inspect the returned targets and native PNG.” + +After discovering the canvas, call `plotium_figure_diagnose` directly (no edit plan): + +```json +{ + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 7, + "canvas": {"resource":{"id":"CANVAS_UUID","kind":"plotium.canvas"}}, + "output": {"size_mm":[180,90]}, + "checks": ["bounds","clipping","text_overflow","content_overlap","legend_occlusion","data_shape","layout_aesthetics","intent"], + "detail": "full", + "limit": 100 +} +``` + +Copy complete content or Series targets into optional `targets` to narrow the scan. +A Series target also includes its owning plot frame and guides as context. +Omission scans the canvas; it never uses GUI selection. `content_overlap` additionally +requires explicit whole-content `overlap_targets` (at least two). It compares visible, +page-clipped frames, not opaque pixels. `view` accepts `issues` (default) for +findings, `layout` for measured geometry rows instead, or `both`. `detail` is +`compact` (default) or `full`. Compact issue rows keep `target`, `component`, +`code`, `severity`, `message`, `measurement_basis` and any `suggestions`; their +`evidence` keeps only `other_target`, `other_component`, `point_range` and +`interpretation`, and coverage rows of checks that completed are left out. +`full` returns all evidence geometry and every coverage row. Coverage rows that +report a limit are always returned. + +`output.size_mm` must be positive and preserve the canvas aspect ratio (0.001 mm +height tolerance). Like native export, it uniformly scales the existing page without +reflow. Every initial query recalculates geometry. Results use `output_page_pt`: +72 points per inch, top-left origin, X right, Y down. `output` includes native size +and scale; text, stroke widths and bounds scale together. Panel-local frames are +converted through the native page-frame service. Plot data uses the actual plot +clip; a panel border is **not** a general content clip. Native raster frame and +`clip_children` clipping are reported separately. + +`ToolResult.value` contains `project_context`, `basis_revision`, `canvas`, `summary`, +`output`, `items`, `coverage`, `truncated` and `continuation`. In the default +compact detail, `output` has `size_mm` and `size_pt`, and `coverage` reports its +status, scan counts and unavailable or unsupported items. `detail: "full"` adds the +page coordinate description to `output`, the requested, supported and unsupported +check lists to `coverage`, and `budget`, `preview_request` and `read_policy`. `summary` +counts the issues on this page (`issues`, `by_code`, `by_severity`); add the +counts of every page of a continued scan. Each issue has a full native `target`, +an owner-relative `component`, `code`, `severity` and explanation; with +`detail: "full"` its evidence also carries bounds, clip and intersection geometry. Pass `target` to `plotium_document_inspect` +with `view: "self"`; names do not identify objects. `guide.legend` belongs to its +plot, not a new resource. A curve conflict points to the existing Series and its +owning plot's legend through `evidence.other_target` / `other_component`. + +- `out_of_canvas`, `partially_clipped`, `fully_clipped` and + `curve_primitives_clipped` / `shape_clipped` are informational facts, including intentional manual + range clipping. Curve evidence applies to the reported native run's point range. +- `text_container_overflow` is a warning based on native width/line-spacing + **estimates**, not exact glyph ink. Text does not automatically wrap or shrink. +- `content_frame_overlap` is informational; deliberate overlap is allowed. +- `axis_ticks_sparse` is a warning: at the output size an axis with shown tick + labels draws fewer than two ticks, so its scale cannot be read. Enlarge the + panel or lower `object.figure.typography.tick_pt`. +- `right_axis_untitled` is a warning: curves use the right y axis but it shows + no title. Set `object.axes.y2_label` (or turn `object.axes.y2_show_label` + back on). +- `legend_occlusion_potential` is a warning, not a claim that data is invisible. + The scan visits projected line segments and marker shapes after effective + clipping, retaining dash phase across batches. It does not use a whole-curve + bounding box or sample points. Stroke envelopes and the legend layout rectangle + are conservative; rounded corners, translucency and exact antialiasing can differ. + +The `data_shape`, `layout_aesthetics` and `intent` checks report issues with severity +`hint`: the figure could show its data more clearly, nothing is wrong. They are +included when `checks` is omitted. Hints never edit the document. Each carries +`suggestions`, a list of `{action, property, target, reason}`; `property` names a +property to set on `target`, or both are null. Lengths are measured at the +requested `output.size_mm`; the thresholds are provisional. A query narrowed to +Series reports Series hints for those Series only. + +| Code | Fires when | +| --- | --- | +| `small_values_invisible` | A bar's value is under 1 % of the value-axis span, or it prints under 0.5 mm, beside bars at least 5 mm long | +| `bars_too_narrow` | A bar prints narrower than 0.6 mm | +| `few_samples_hidden` | Every group of a box or violin Series, or of a bar Series with repeated rows per x, has fewer than 10 values, or a bar Series of one row per x has `series.replicates` of 1–9; and the plot has no scatter Series | +| `too_many_categories` | The category axis draws its labels but drops some, or neighbouring labels collide | +| `log_scale_candidate` | A plot without bars, boxes or violins has only positive line or scatter values on a linear value axis, spanning three or more decades | +| `bar_baseline_not_zero` | The value-axis range leaves out the bars' baseline | +| `labels_overlap` | Two text boxes on the canvas overlap by more than 0.2 mm in both directions; evidence names both and a direction to move the second. Entries of one legend and tick labels of one axis are not compared with each other | +| `text_over_data` | An annotation or value label overlaps a bar, box, violin, line or marker | +| `intent_mismatch` | The chart form does not suit the plot's `object.intent.purpose` (see below) | +| `panels_misaligned` | Two frames in one column (left edges within 1 mm) or row (bottom edges within 1 mm) have plot areas whose left or bottom edges differ by more than 0.5 mm, or the gaps between three or more frames in a row or column differ by more than 0.5 mm | + +Hints beyond 50 of one kind, and checks that hit a budget, add an `unavailable` +coverage row. + +The `intent` check weighs each plot built from explicit columns against the +purpose its author stated; `detail` is never reported. A plot without a purpose +gets a `not_applicable` coverage row, `no_purpose_stated`: ask the user what it +should show. Table chart types get `chart_type_not_covered`. `intent_mismatch` +evidence keeps the reason in `interpretation` and, with `detail: "full"`, adds +the purpose, the claim and the chart features it read. Its suggestions name +chart forms Plotium can draw; relay them and let the user choose. + +| Purpose | Reported when | +| --- | --- | +| `compare` | Lines join categories | +| `trend` | The category axis holds categories, or the plot draws bars | +| `distribution` | On a category axis, bars or lines without a box, violin or scatter Series | +| `relationship` | The category axis holds categories, or the plot draws bars, boxes or violins | +| `composition` | The plot draws lines or points but no bars | +| `change` | Two or more bar Series sit side by side, or positive bar values span tenfold or more; or, without bars, boxes or violins, positive left-axis line or scatter values span tenfold or more on a linear axis | + +Native guide layout includes estimated text widths. Font availability is checked +using native export font discovery; glyph coverage and cross-backend ink bounds +remain unverified. Raster viewport geometry uses header dimensions, integer crop, +rotation and fit; successful decoding and alpha-pixel coverage require the preview. +Non-line/scatter internal geometry, error-bar clipping/occlusion, derived scientific +annotations and opaque-pixel occlusion are not covered. Native rectangle, ellipse, line and arrow extrema use the actual page clip. Their frame/guide +observations remain available; coverage states the limitation. Beyond the hints +above, this tool does not judge aesthetics, scientific correctness or statistical +significance. + +**Read coverage even when no issues are returned.** Per-target statuses distinguish +`complete`, `unsupported`, `unavailable` and `not_applicable` (for example hidden, +empty rendered data or absent legend). Overall `partial` means more pages remain; +`limited` means completed traversal with unsupported/unavailable parts. Estimates +remain estimates even with completed traversal. Counts describe scanned objects, +source points and overlap pairs, never a percentage of pixels. Missing assets/fonts, +invalid sources and excluded geometry are reported, not treated as a clean figure. + +Follow a non-null `continuation` using only these arguments: + +```json +{"expected_project_context":"PROJECT_CONTEXT","expected_revision":7,"cursor":"RETURNED_CURSOR"} +``` + +The one-use cursor binds the original target, output, checks and page configuration +and expires after 300 idle seconds. A new initial query replaces the previous scan. +Finish all pages before claiming coverage; an empty issue page can still be truncated. +Only one diagnostic batch and one unread snapshot are retained per desktop connection. +The native stdio facade keeps one diagnostic transport between pages and closes it +when stdio ends; other tools retain their one-call, never-replayed transport. +Limits are 200 explicit targets, 200 overlap targets / 19,900 pairs, 200 objects and +1,000,000 source points per batch, 4,096 rendered runs and polygons per plot, 1 MiB text, +64 MiB estimated snapshot payload and 16 MiB encoded-asset probes. Pages default to +100 rows (maximum 200), with 96 KiB page values and 256 KiB JSON-RPC responses. +These are payload/work budgets, not a total process-memory bound. +Snapshot/text overflow returns `diagnostic_budget_exceeded`; narrow the target. +Batch/row limits return `truncated: true` and a cursor without sampling. + +Context, revision, busy barriers and connection access are rechecked before delivery. +Edits, project changes, cancellation, connection shutdown and transport closure +invalidate affected work; expired/consumed cursors return `expired_cursor`. +After `stale_revision` or `project_changed`, read state and start again, never combine +old and new pages. Read-only access suffices. Reads change no object, binding, manual +range, geometry, Undo history, automation revision, edit generation or dirty state. +They do not append project audit records. Geometry, issues, cursors and PNGs are +not persisted as diagnostic copies. + +Call `plotium_render_preview` with the canvas, context and `basis_revision` to +obtain the native PNG, then inspect it. Convert a returned +X coordinate to pixels using `x * width_px / output.size_pt[0]`; use height +for Y. Check its `render_revision` against `basis_revision`. Editor zoom does not +change these units. Direct core `figure.diagnose` returns one bounded batch without +a retained cursor; the MCP query provides continuation. No automatic fix is applied. + +## Recovery actions and uncertain outcomes + +`recovery` describes this request, not permission to execute another one: + +| Field | Meaning | +| --- | --- | +| `plan_consumed` | `true` / `false` when observed; `null` when unknown. A consumed plan cannot be reused. | +| `submission` | `submitted`, `not_submitted` or `unknown`; accepted background work is not completed work. | +| `committed` | `true` / `false` when known; `null` when effects or durable completion are uncertain. | +| `completion` | `pending`, `succeeded`, `failed`, `partial` or `unknown`. | +| `receipt` | Status tool and exact ID in `arguments`; `retained` is `true` when found, `false` when missing, or `null` when unknown. A null `receipt` means no known receipt query. | +| `next_action` | One next step: `call_tool` with exact arguments, `desktop_file_confirmation`, `check_desktop_connection`, `inspect_outcome`, or `none`. | +| `replay_allowed` | Always `false`; recovery never authorizes replay or automatic resubmission. | + +For `call_tool`, make only the named read. For desktop confirmation, review the +pending request's exact paths and overwrite scope in Plotium, then query its +receipt. For `check_desktop_connection`, check AI connections (MCP) and access +mode in the desktop, then read state. For `inspect_outcome`, compare the retained +receipt, saved preflight targets/paths and current state; missing evidence needs +human review before any new scientific computation or file request. + +- **Busy:** planning fails before submission. Execution may consume the plan + before the busy check; finish the desktop operation, read state and review a + fresh plan. Never resubmit the consumed ID. +- **Stale revision / project switch / revoked permission:** refresh state and + access in the desktop. After a switch, rediscover targets in the new context. + Existing plan IDs and file permissions do not transfer to the new project. +- **Save refused or cancelled before installation:** the consumed plan's receipt is terminal with + `phase: not_installed`, `committed: false` and `completion: failed`. Closing the + confirmation is refusal. Inspect state and ask whether saving is still wanted; + a newly intended save requires a fresh plan and desktop confirmation. + Cancellation after a worker starts must be resolved from its final phase; + it does not undo installed output. +- **Pending save/task:** accepted, queued, running or saving is `pending`, not + success. Use the receipt query; do not submit a replacement task or save. + `installed_unconfirmed` stays unknown even after a save worker terminates. +- **Export:** the batch succeeds only when completed and every file succeeded. + Mixed terminal results are `partial`; inspect each exact output path and error. + A failed file can have been installed before a durability error, so failure + alone does not prove that its path is unchanged. Never retry the entire batch + automatically, including its successful files. +- **Disconnect / expired plan / unknown or evicted receipt:** preserve unknown + consumption, submission and commit state. Reconnect and query a known receipt + ID in the same desktop process. If it is absent, inspect saved targets/paths; + absence does not prove non-execution and does not authorize recomputation or + overwrite. Receipts are not persisted across desktop restarts. + +These actions retain server permissions, revision/context checks, one-use plans +and fresh per-request desktop file consent. Tool annotations are neither +authorization nor a reason to retry. Reconnect clients and refresh their tool +catalog after updating the desktop and connector together. + +## Error codes + +Errors include stable codes: `permission_denied`, `expired_plan`, +`stale_revision`, `busy`, `invalid_parameters`, `unsupported_operation`, `unsupported_property`, +`project_changed`, `unavailable`, `connection_lost`, `plan_limit`, `request_cancelled`, `connection_stopped`, `response_too_large` and `execution_failed`. +Invalid capability sections or keys point back to static discovery, with valid +candidates in `error.details`. Invalid plan parameters point to that operation's +`operation_constraints` instead of asking for project state. Input errors include +`error.details.field` at the decoded request boundary, such as `plan_id`, +`parameters`, or `parameters.writes[0].key`. Stale revisions and changed projects +still require reading state and replanning. This guidance never permits replay. +Nested source and target errors report their full path, such as +`parameters.series[0].source.y`. + +Errors carry `error.recovery`; asynchronous save, export and task receipts carry +`recovery`. `retryable: false` means do not repeat the failed call: follow the +reported next action. A `busy` execute can already have consumed its plan. +For stale revisions, read state and review a fresh plan. An expired plan may +already have run; inspect its outcome before deciding on a new operation. +The AI connections (MCP) settings page shows recent operations and errors without +opening itself in response to background activity. diff --git a/docs/src/content/docs/reference/mcp/save-and-export.md b/docs/src/content/docs/reference/mcp/save-and-export.md new file mode 100644 index 00000000..858bc9e2 --- /dev/null +++ b/docs/src/content/docs/reference/mcp/save-and-export.md @@ -0,0 +1,180 @@ +--- +title: MCP save and export +description: Save the desktop project and export figures with desktop approval. +--- + +## Save the current desktop project + +Saving uses the same native snapshot, background worker, backups and completion +path as **Save project**. It saves the current desktop state, not a separate CLI +project. First read `plotium_get_state`; `save_state` reports the current path, +persisted archive revision, dirty flag, edit generation and up to 16 retained +`receipt_ids`. Query each ID with `plotium_save_status` for the complete receipt +and recovery action. An ID alone does not indicate submission success or completion. + +Plan a first save or Save As with no `ids` or `targets`: + +```json +{ + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 46, + "tool_id": "project.save", + "parameters": {"path": "/absolute/path/figure.plotium"} +} +``` + +Omit `path` to save the current file; an untitled project requires a path. +The parent directory must exist. Targets must be regular, non-symlink `.plotium` +files or absent paths. Preflight resolves the parent directory and freezes the +observed target. `include_view_snapshots` optionally overrides the project's +current native save profile. The plan returns `save_id`, the resolved path and +`overwrite_required`; it grants no file-write permission. + +Submit the one-use plan with `plotium_execute {"plan_id":"PLAN_ID"}`. The result +contains `save.status: "awaiting_authorization"`. In Plotium, review the exact +path and press **Allow save**. If a file already exists, first check **Replace the +existing file at this exact path**. **Deny** leaves the target untouched. +This permission is independent of **Read and modify**, applies to one save only, +and cannot be supplied as a tool argument. A changed target requires a fresh +plan and approval. One external save may be pending at a time. + +Serialization uses an exclusively created private sibling temporary, not a fixed +`.tmp`. For an existing target, its frozen metadata is checked again after +backup preparation, immediately before replacement. A detected change refuses +installation and preserves the later target. Permission admission and this file +check are separate: the check plus replacement is not an inter-process +compare-and-swap. A non-cooperating write after the check, or one that preserves +the checked metadata, may go undetected; avoid concurrent saves to the same path. + +Poll `plotium_save_status {"save_id":"SAVE_ID"}`; this read needs no document +revision or context, works while saving, and does not dirty the project. +`awaiting_authorization`, `queued` and `saving` are incomplete states with null +`phase`. Only `completed` gives a final phase: + +| Phase | File state and next action | +| --- | --- | +| `not_installed` | This save did not install its snapshot at the target. Resolve the reported denial/failure, inspect current state, then obtain fresh authorization if another save is needed. | +| `installed_unconfirmed` | The snapshot replaced/created the target, but backup finalization or durable sync failed. Keep the desktop project open; inspect the target and storage before an explicitly authorized retry. Do not assume the old file remains. | +| `committed` | The captured snapshot completed the native durable commit. Later edits may still be unsaved. | + +On Windows, a partial replacement failure can remove or move the old target even +when the new snapshot is `not_installed`. Plotium keeps the serialized candidate +and reports its exact recovery path. It restores a known original backup only +without overwriting an existing target; otherwise it retains and reports that +backup and any older staged backup. If Windows moved the original without +returning its location, the error says so. Keep the project open and inspect the +reported files before retrying; this failure does not clear dirty state. + +The receipt records original `project_context`, `snapshot.document_revision`, +`snapshot.edit_generation`, `persisted_revision`, exact path, `state_applied`, +`dirty_after_completion`, error and recovery message. The status response also +reports current context/path/revision/dirty and `matches_current_project`. +The snapshot is captured after desktop approval and before background work. +New edits after capture remain dirty; a committed save does not mean every +current edit is on disk. An installed-but-unconfirmed +save keeps dirty and records the installed baseline for native recovery. + +Switching projects or stopping the connection revokes pending write permission. +The worker only holds its original snapshot and path, checks authorization at +installation, and cannot adopt a completion into a different project, even at +an equal document revision. Once the worker has atomically admitted installation, stopping cannot guarantee +cancellation of that original file write; inspect its receipt. Revocation before +admission prevents installation. Saving creates no Undo step and Undo does not delete or restore files. + +The desktop retains the latest 16 receipts across reconnects and project changes +until application exit. After a lost response, query the original `save_id` +before doing anything else; do not replay the submitted call. After application +restart or `unknown_save`, inspect the target and freshly opened project instead +of assuming success or failure. Stable stdio configuration continues to work; +reopening/restarting still requires fresh state, target discovery and plans. +Connection recovery is not evidence of a successful save. + +## Export a captured canvas as SVG, PDF and PNG + +Use `figure.export` with one exact whole-canvas TargetRef and no top-level +`ids`/`targets`. The native exporters preserve the canvas background, complete +page, curves, absolute Y-error amplitudes, native text and embedded images. +There is no trimming, theme application or project modification. Keep the +editable `.plotium` project as well as these delivery formats. + +```json +{ + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 48, + "tool_id": "figure.export", + "parameters": { + "canvas": {"resource":{"id":"CANVAS_ID","kind":"plotium.canvas"}}, + "size_mm": [180,90], + "dpi": 300, + "outputs": [ + {"format":"svg","path":"/absolute/path/figure.svg"}, + {"format":"pdf","path":"/absolute/path/figure.pdf"}, + {"format":"png","path":"/absolute/path/figure.png"} + ] + } +} +``` + +`size_mm` defaults to the native page size. An explicit size uniformly scales +the whole figure and must retain its aspect ratio (0.001 mm height tolerance); +it does not resize the editable page. `dpi` defaults to 300, accepts 1–2400 and +only controls PNG. Each PNG axis is rounded to the nearest integer from the +native physical points / 72 × DPI × uniform size scale, with a minimum of one +pixel. A 180 × 90 mm page at 300 DPI is **2126 × 1063 pixels**. SVG/PDF retain +physical page dimensions. Text uses the native generic sans-serif family; +a machine without usable system fonts returns a font error. SVG font appearance +on another machine depends on that machine's available sans-serif fonts. + +There are 1–8 outputs per batch. Each absolute path needs its matching lowercase +extension and an existing parent directory; targets must be regular non-symlink +files or absent. Duplicate resolved output paths are refused. Preflight returns +`export_id`, physical/pixel size and an error or resolved target for each file. +A bad directory does not hide the other files' results. `overwrite` defaults to +false: an existing target reports `overwrite_not_requested` and remains untouched. +Set `overwrite:true` only when replacement is intended; this still grants no +write permission. + +Submit the one-use plan through `plotium_execute`. Valid files await Plotium's +**Allow AI to export this figure?** prompt, listing the exact canvas, revision, +size and paths. Review it and press **Allow export**. Existing files additionally +require the unchecked **Replace the listed existing output files** checkbox. +**Deny** installs nothing. **Read and modify** is not export authorization; +Read only may request fresh, separate export consent. All-invalid batches finish +with per-file errors without asking for consent. + +Poll `plotium_export_status {"export_id":"EXPORT_ID"}` without context/revision. +It is non-auditing, works while rendering, and returns `export`, current context, +current revision and `matches_current_project`. Batch status is +`awaiting_authorization`, `rendering` or `completed`. Each `files[]` entry has +format, exact path, overwrite requirement, `status`, `error_code`, `message` +and installed byte count. File status is `pending`, `succeeded`, `failed` or +`unknown` (worker failed; inspect that path before deciding what to do). +Completion does not imply every file succeeded. Missing/corrupt images, fonts, +changed targets, permission denial and rendering/budget errors are reported +without replacing that output. Successful files in the same batch remain. + +Rendering runs off-thread on the canvas/assets captured after desktop consent, +bound to the original `project_context`, `canvas` and `render_revision`. Later +edits do not change that snapshot. Project transition, connection Stop or access +change revokes pending installation permission. Each file's atomic permission +admission precedes its installation: revocation before admission blocks it; +an already admitted file may finish and must be checked in the receipt. Old +completion never changes the new project's document, save path, dirty state or +status. Unique owned sibling staging and atomic no-clobber creation preserve +unapproved files. Existing-file metadata is checked just before replacement; +this is not a cross-process compare-and-swap, so avoid concurrent writers. +Export success means installed output, not the native save's durable-commit +phase; Undo cannot remove or restore exported files. + +Limits: one running batch, 32 shared pending plans, 4096 bytes per path, PNG +16,384 pixels per edge and 16,777,216 pixels total; referenced embedded assets +16 MiB, decoded asset RGBA 64 MiB, SVG 8 MiB and encoded output 64 MiB per file. +No external asset lookup or placeholder substitution occurs. Limits and the +complete schema are discoverable in the `limits` and `operation_constraints` +capability sections. + +The last 16 export receipts survive reconnects and project changes in this +desktop process, not application exit. After response loss query the original +`export_id`; do not resubmit the export. After restart or `unknown_export`, +inspect the exact output files first. Reopen the editable project, fetch fresh +state and targets, then make a new plan only for a newly intended operation. diff --git a/docs/src/content/docs/reference/mcp/scientific.md b/docs/src/content/docs/reference/mcp/scientific.md new file mode 100644 index 00000000..1721d997 --- /dev/null +++ b/docs/src/content/docs/reference/mcp/scientific.md @@ -0,0 +1,125 @@ +--- +title: MCP scientific operations +description: Run processing, diffusion fitting and DOSY through MCP, and plot the results. +--- + +These operations are the ones the desktop runs for +[processing](/guides/processing/) and [DOSY](/guides/dosy/). The command line +runs them too, with [`plotium-cli tool run`](/reference/cli/#single-step-scientific-operations). + +## Scientific operations and tasks + +`plotium_processing_inspect`, `plotium_diffusion_inspect` and +`plotium_analysis_results_inspect` are read-only queries with explicit `ids`, +`expected_project_context` and `expected_revision`. Result inspection accepts +`offset` and `limit` (1–100); use smaller pages for large ILT grids. Discovery's +`scientific_operations` comes from the core descriptors, including parameter +schemas, capabilities, permissions and execution modes. + +Scientific edits use `plotium_plan` / `plotium_execute`: + +| Operation | Parameters and target | +| --- | --- | +| `processing.edit` | One dataset; `edits` uses `replace`, `enable`, `add`, `remove` or `move`; existing steps use stable StepIds | +| `processing.apply_scheme` | `path`, optional `compatible_only`; preflight freezes scheme bytes, fingerprint and compatible target configurations | +| `diffusion.set_input` | One dataset; complete `input`; invalid input errors include a structured validation report | +| `analysis.regions.extract` | One region-series field; `regions` references RegionIds or explicit bounds and metrics; optional explicit `input` | +| `analysis.diffusion.fit` | One native table; stable `response_column` ColumnId, optional native `options`; the x column must use `s/m²` | +| `analysis.dosy.build` | One diffusion source field; `method` is `mono_exp` or `ilt`; optional `input` and ILT `params` | + +An explicit region is +`{"source":"explicit","bounds":[0.8,1.2],"metric":"Height","name":"Signal"}`; +reference an existing region with `{"source":"existing","id":0}`. Other metrics +are `Area`, `Mean`, `Max` and `Min`. Extraction creates an independent native table +with source evidence, region-to-column correspondence and diffusion increment +bindings. It does not create a plot. + +Except for input updates, these edits return `ToolResult.value.task`. Preflight +allocates `task_id`; `queued` means registered. Query with +`plotium_tasks_get({task_id})` or `plotium_tasks_list({offset,limit})`; cancel with +`plotium_tasks_cancel({task_id})` (modify permission required). States are +`queued / running / committing / succeeded / failed / cancelled / stale`. +Receipts include the original plan_id, source project, start/end revisions, +source field versions, phase, completed columns, failure code, resource references +and terminal summary. Unknown work totals are `null`. Receipt queries remain +available while busy and after a project switch. + +Receipts belong to the application process. Disconnecting does not cancel +submitted work; reconnect in the same process to query it. All active tasks and +the most recent 128 terminal receipts are retained; process restart is outside +this retention contract. `task_not_found` means unknown or evicted and must never +trigger automatic recomputation. Repeating a consumed scientific plan returns +its retained receipt. Cancellation is idempotent, prevents writes before commit, +and returns the existing state after termination. + +Frozen inputs run in the existing ComputeService. Before one atomic undoable +commit, the main thread checks project, document revision, field versions, +generation, cancellation and caller permission. Any document edit during +computation makes the task stale. Undo restores configuration, results and linked +tables; Redo reuses computed results. Background completion does not open or close +panels. Synchronous workflows retain `processing.apply_scheme` and wait for +its commit before dependent nodes run; other background scientific operations +require single-step calls and terminal receipts. + +Diffusion inspection distinguishes executable input, missing parameters, evidence +requiring confirmation and invalid input. Issues carry codes, parameter paths, +expected units, actual values, evidence and remedies. b values bind IncrementIds +and use `s/m²`; D uses `m²/s`. Original units and conversion evidence remain +available. Resolution uses explicit input, target result provenance, then stored +default/acquisition information. JEOL validation retains full program identity, +gradient shape, timing and vendor coefficient checks. + +Mono-exponential diagnostics include D, I₀, D standard error, effective points, +R², residuals and rejection reasons. ILT returns its D grid, λ, nonnegative +solution, reconstruction residuals and solver termination rather than +mono-exponential confidence estimates. `empty` means no accepted scientific +result. Unavailable numbers are `null` with a reason. Result inspection pages +column diagnostics; provenance retains algorithm version, actual parameters and +input fingerprint. + +Completed decay-fit tasks return a stable `plotium.analysis` resource in the task's `produced` list. Pass its ID directly to `plotium_analysis_results_inspect` to read that analysis. A task status of `succeeded` means the calculation and result commit completed; check `converged`, `termination` and `notices` separately for scientific convergence. The outer `converged` follows the attempt with the lowest finite cost. Attempts that exhaust the iteration budget without meeting a convergence criterion or terminate with trust-region collapse remain unconverged, and their estimates are retained with a warning for diagnosis. + +## Plot native scientific results + +Use `plotium_plan` and `plotium_execute` with either operation below. Both +require `{source: ResourceRef, name: string}` in `parameters` and omit top-level +`ids` and `targets`. Discover the complete source reference and schema first. + +| Operation | Source and native output | +| --- | --- | +| `plot.field.create` | One native field, including mono-exponential `nmr.dosy_map` or ILT `nmr.ilt_map`; creates a canvas pinned to that field and its native encoding. | +| `analysis.diffusion.plot` | One diffusion-fit analysis with one response dataset; creates a frozen table and canvas with b–intensity scatter, stored fitted curve, residual panel, D standard error, R² and effective point count. | + +Preflight returns `preflight.scientific_plot.summary` with proposed `canvas`, +`source`, `produced` and scientific `evidence`; execute returns the same summary +in `value`. Plotting does not recompute scientific results. Stale or empty DOSY +results and stale, unconverged or multiple-response fits must be corrected first. +Missing D uncertainty is labelled unavailable. Field preparation permits at most +4,000,000 elements and 200 series, including a default 128-row ILT of a +20,480-point spectrum; fit plots permit 20,000 rows. Plot points, +contour vertices and heatmap cells share the 2,000,000 pending-element budget +with explicit curve rows. Contour plots count generated vertices toward this +budget; heatmaps count cells. +One Undo removes created resources; Redo restores the same identities and data. +Changing the owner's display mode does not change a field plot's source. +Frozen fit tables retain source-table lineage; the automation run retains the +selected analysis, row selection, extraction evidence and diffusion input. + +Use `value.canvas` with `plotium_figure_diagnose` and `plotium_render_preview`, +then inspect the returned PNG. An image alone does not validate the science: + +1. Start at the welcome page with `plotium_get_state`; import the acquisition, + inspect processing and wait for processing tasks to succeed. +2. Inspect diffusion units, increment bindings, missing parameters and evidence. + Supply confirmed input only when supported by the experiment. +3. State the region-selection rule, bounds, metric and overlap policy before + extraction. Wait for extraction, then fit the returned response ColumnId. +4. Inspect the exact analysis: validity, D in `m²/s`, standard error, effective + points, R², residuals, rejected rows and provenance. Create its native plot. + Independently compute and inspect mono-exponential or ILT DOSY; check accepted + and rejected columns, algorithm settings, input fingerprint and numerical + agreement with the region fit. ILT supplies solver diagnostics instead of + mono-exponential confidence estimates. +5. Plot the DOSY result field. Check resource identities and state, geometry + diagnostics and both PNGs for correct axes, curves, contours, residuals and + readable labels. Report scientific or visual failures explicitly. diff --git a/docs/src/content/docs/reference/mcp/styling.md b/docs/src/content/docs/reference/mcp/styling.md new file mode 100644 index 00000000..846d993a --- /dev/null +++ b/docs/src/content/docs/reference/mcp/styling.md @@ -0,0 +1,367 @@ +--- +title: MCP styling +description: Change display properties, legends and themes through MCP. +--- + +## Change display without rebuilding the plot + +Use an exact target from preflight `creation.series_defaults[].target` or execution +`value.bindings[].target`, or discover +it with `plotium_document_inspect`. The owner resource and stable SeriesId travel +together: same-name curves remain separate targets. `plotium_properties_list` +lists the allowed properties; `plotium_properties_inspect` supplies current values, +defaults, target-specific unit choices and range input schemas. + +Read `plotium_get_state` first. Call `plotium_plan` with its `project_context` +and current revision, replacing the placeholders below with discovered values: + +```json +{ + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 7, + "tool_id": "properties.set", + "targets": [{ + "resource": {"id":"CANVAS_UUID/OBJECT_ID","kind":"plotium.canvas.object", + "parent_id":"CANVAS_UUID","local_id":"OBJECT_ID"}, + "component": {"kind":"series","id":1} + }], + "parameters": {"key": "series.line.color", "value": "#0072B2"} +} +``` + +Review the preflight, then pass only its returned `plan_id` to `plotium_execute`. +This changes only that curve's color, including its error bars, not its width or +source columns. Axis and local font properties instead take `ids:[PLOT_OBJECT_ID]`. + +One request changes one key across its targets, atomically, with one Undo step. +An existing but inapplicable target is reported as skipped; a missing or forged +identity rejects the request. Invalid colors, non-finite values and invalid +ranges are refused at preflight. Execution rechecks revision and permission; +a rejected execute consumes its plan. Re-read state before planning again. + +Range values distinguish these operations: + +- `{"mode":"auto"}` clears only that axis's manual range. +- `{"mode":"manual","min":0,"max":10,"unit":"mA"}` sets finite increasing + bounds in the stated compatible unit. `unit:null` is only for unknown coordinate + units. A known unit cannot be introduced onto an unknown-unit plot. +- Resetting **all** axis settings is a separate native operation, not a side + effect of Auto. Axis reset clears only the named override; guide origin/placement + coupling follows the rules in + [Position a plot's legend precisely](#position-a-plots-legend-precisely). + +Display units use compatible codes returned by property inspection, such as `s` → `ms` or `mA` → `A`. +The plot retains R4's coordinate-unit contract: source data, manual range storage, +shifts and error amplitudes keep their meaning. Ticks and automatically derived +unit text change; authored axis titles stay verbatim. Rebinding/reordering curves +and removing the first curve do not redefine coordinates. Numeric range editing +is unavailable on hidden/categorical axes; a retained range can still be cleared. +In inspection, `unit_code.codes` lists the target's compatible choices; `axis_range.input_schema` describes +the range value and its `view`/`unit` describe the current display window. + +Marker size is a diameter in points, independent after explicitly set. Without +an override, native point curves retain their existing width-based radius; the +existing stroke-width API retains this behavior. Reset restores the native +marker/size, and an explicit empty legend label omits that legend entry. Stroke +style applies to line curves; scatter curves are skipped for that property. +Markers apply to line/scatter curves, not sticks, bars, boxes or violins. Bar +width and outline width apply to bar, box and violin curves; the outline color to +bar curves. Marker fill and edge color +apply to closed markers and follow the curve color until set; reset returns +them to it. A hollow marker draws no fill and keeps an outline, 0.5 pt when +no edge width is set. `marker_every` thins markers to every n-th source point, +starting with the first; the line still passes through every point. A chart +that owns semantic colors rejects a single series +color, marker fill or marker edge color override as inapplicable. + +Plot-local tick, axis-title and legend sizes inherit document typography until +set. Reset removes only that override; changing one plot's font does not style +other plots. Font/title measurements use the native renderer. These edits do not +retile pages or change panel/content positions and sizes. GUI edits use the same +catalog controls in Line, Axes, and Legend & scales; plot-local units, ranges and +font sizes appear under Advanced. Document-level font properties +retain their existing project-wide scope. + +After editing, get a fresh revision and request `plotium_render_preview` for the +returned canvas. Inspect its PNG and `render_revision`, then use GUI Undo/Redo to +check the same native objects. MCP `project.save` requires separate desktop +authorization; exporting requires its own desktop authorization. + +## Inspect and edit an exact curve + +An example agent task is: “Find my line plot, inspect its stroke width, preflight +changing it to 1.5 pt, then apply the saved plan.” The tool sequence is: + +1. `plotium_get_state` with `{}` returns `project_context`, `revision`, project overview, selection + and connection permissions. +2. `plotium_resources_search` with `expected_project_context`, `expected_revision` and a `query` such as + `{"kinds":["plotium.canvas.object"],"name_contains":"Plot"}` locates resources. + When every match has the same reason, as in an unfiltered search, `value.reason` + states it once instead of `value.reasons`. + Resolve results to explicit stable IDs; `plotium_resources_inspect` reads + descriptors using `ids` and `expected_revision`. +3. `plotium_properties_list` with `{}` lists supported IDs and value types. Discover + curve addresses with `plotium_properties_inspect`: + + ```json + {"ids":["CANVAS_UUID/OBJECT_ID"],"key":"series.line.stroke_width","expected_project_context":"PROJECT_CONTEXT","expected_revision":7} + ``` + + The response's `value.readings` contains one row per applicable curve. When + every reading shares its schema or default, `value.schema` and + `value.default_value` hold it once instead. Copy + the complete `value.readings[0].target` for the curve you want, for example: + + ```json + { + "resource": { + "id":"CANVAS_UUID/OBJECT_ID", + "kind":"plotium.canvas.object", + "parent_id":"CANVAS_UUID", + "local_id":"OBJECT_ID" + }, + "component":{"kind":"series","id":0} + } + ``` + +4. Pass that target unchanged to `plotium_plan` to edit exactly that curve: + + ```json + { + "tool_id":"properties.set", + "parameters":{"key":"series.line.stroke_width","value":1.5}, + "targets":[{ + "resource":{ + "id":"CANVAS_UUID/OBJECT_ID", + "kind":"plotium.canvas.object", + "parent_id":"CANVAS_UUID", + "local_id":"OBJECT_ID" + }, + "component":{"kind":"series","id":0} + }], + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision":7 + } + ``` + +5. Review `preflight`, then call `plotium_execute` with only + `{"plan_id":"RETURNED_PLAN_ID"}`. Plotium immediately displays the change; + **Undo** restores it and **Redo** reapplies it. Repeating the current value is + reported as skipped. A batch applies as one undo step. + +Property inspection and property-edit planning require exactly one nonempty `ids` or +`targets` array. `ids` expands each resource to all components addressed by the +property; `targets` addresses only the supplied Series components. Series IDs +are local to their plot, so always copy the full target, including its resource. +Duplicate targets are processed once. A missing component or forged resource +identity rejects the entire request; an existing curve to which the property +does not apply is skipped. Inspection returns values, defaults, bounds and +applicability. To inspect just one curve, use `targets` in the inspection request. +To reset it, plan `properties.reset` with `{"key":"series.line.stroke_width"}` +and the same target. Component addressing supports only the listed display +properties; processing parameters use the separate `processing.edit` operation. `resource.rename` requires +`ids`. + +## Style several curves in one plan + +`properties.set` writes one value. To give each curve its own colour and legend +label, plan `properties.set_many` instead: each write names an exact target, one +supported key and a value. Omit top-level `ids` and `targets`; series writes use +the complete Series target from inspection, and object-level writes such as axis +titles or legend settings use the plot object's resource target without a +component. + +```json +{ + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 7, + "tool_id": "properties.set_many", + "parameters": {"writes": [ + {"target": SERIES_0_TARGET, "key": "series.line.color", "value": "#0072B2"}, + {"target": SERIES_0_TARGET, "key": "series.label", "value": "Sample 1"}, + {"target": SERIES_1_TARGET, "key": "series.line.color", "value": "#D55E00"}, + {"target": SERIES_1_TARGET, "key": "series.label", "value": "Sample 2"}, + {"target": {"resource": PLOT_OBJECT_RESOURCE}, "key": "object.axes.x_label", "value": "Temperature (°C)"} + ]} +} +``` + +After `plot.create` executes, use its full stable targets directly. For example, +with the decoded creation `ToolResult` in `created` and the original state in +`state`, prepare this `plotium_plan` argument object: + +```js +const request = { + expected_project_context: state.project_context, + expected_revision: created.after_revision, + tool_id: "properties.set_many", + parameters: { writes: [ + ...created.value.bindings.map((binding, index) => ({ + target: binding.target, + key: "series.label", + value: `Sample ${index + 1}` + })), + { target: created.value.creation.plot, + key: "object.axes.x_label", value: "Temperature (°C)" } + ] } +}; +``` + +Copy each whole `target`, including owner resource `kind`, `id`, `parent_id`, +`local_id` and component identity when present. A bare SeriesId, name or array +index is not a selector. Keep the total within 200 writes. Preflight this object, +review it and execute its new `plan_id` once. `unsupported_operation` means the +operation is unavailable; `unsupported_property` identifies an unsupported key +in `error.details.write_index` (zero based) and `key`. Query +`plotium_properties_list` and correct the whole batch before planning again. + +A batch holds 1–200 writes and accepts the properties `plotium_properties_list` returns. +Planning refuses the whole +batch, and nothing is committed, when any write's target is missing, its +property does not apply to that target, its value is invalid, or the same key is +written twice to one target. A write whose target already holds the value is +reported as skipped while the others apply. `plotium_execute` commits every +write as one **Undo** step; `value.writes` lists each write that was skipped, +with its index, key, outcome and `skip_reason`. + +Property-write responses are short. The preflight of `properties.set`, +`properties.set_many` and `properties.reset` returns `required_authority`, +`estimated_changes`, `summary` (`compatible`, `skipped`, `failed`) and, in +`targets`, only the targets that will not be written. The execute result adds +`summary` (`succeeded`, `skipped`, `failed`, and `by_reason` counts of +`skip_reason`); `targets` and a batch's `value.writes` list only what did not +succeed. When every write applies, both lists are empty. +`plotium_preview_plan` still renders the complete plan. + +## Values the user set by hand + +When the user changes a figure value in Plotium — in the property panels, by +scrolling over a control or by dragging a legend — Plotium records it as set by +hand. `plotium_get_state` lists these values in `hand_edits`, and +`properties.inspect` marks each one with `"hand_set": true`. + +`properties.set`, `properties.set_many` and `properties.reset` leave hand-set +values alone: the target is reported as skipped with `skip_reason: "hand_set"`, +in preflight and in the result, and the other targets still apply. A legend's +placement and its dragged position count as one value. Pass +`"override_hand_edits": true` in `parameters` only when the user asked for that +change; the new value then counts as the user's. + +Values you write without the override are not recorded, so a later theme or +write may replace them. Themes keep hand-set values; see the next section. + +## Position a plot's legend precisely + +Guide properties use `ids:[PLOT_OBJECT_ID]`, not Series components. Discover the +object by its full canvas/object identity; plot names need not be unique. Use +`properties.set` with one key/value, review its plan, then execute the returned +one-use plan ID: + +```json +{ + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 7, + "tool_id": "properties.set", + "ids": ["CANVAS_UUID/OBJECT_ID"], + "parameters": {"key":"object.guides.position","value":[0,1]} +} +``` + +`position` accepts exactly two finite numbers in [0,1], or `null`. It places the +legend box's top-left origin within the space in which that complete box can +move inside the axes' plotting rectangle. x increases rightward, y downward: +`origin = plot_origin + [x,y] * max(plot_size - legend_size, 0)`. These are not +screen pixels, page fractions or data coordinates. [0,0] is top-left; [1,1] +aligns bottom-right when the legend fits. The renderer recomputes this mapping +when the output size, legend content or layout changes. + +The native properties and their necessary coupling are: + +- `visibility`: `auto`, `show`, `hide`. Auto shows a categorical legend with at + least two native entries; Show permits one; Hide hides guides, not data. +- `placement`: `auto`, `inside`, `outside_right`, `outside_bottom`, `custom`. + Custom retains an existing origin or starts at [1,0], and sets Inside. + Every other placement clears the custom origin. +- `position`: [x,y] sets Inside/custom. `null`, position reset, placement Auto + and placement reset clear both origin and placement overrides, matching GUI + double-click. A read of `null` means no custom origin; consult placement for + the actual mode, which may be outside. +- `layout`: `auto`, `vertical`, `horizontal`, retaining native layout behavior. +- `title`: text; blank/whitespace clears its override using native normalization. + +Visibility/layout/title reset only their own overrides. Position changes and +resets retain these fields, font size, bindings, curve styles and manual axis +ranges. Guides still use native entry merging; six curves need not produce six +entries when their native legend identities merge. The four existing properties +retain their color-scale behavior. Free two-dimensional positioning applies to +categorical legend content, independent of guide visibility. Retained origins +without content remain readable/resettable, but new coordinates require legend +content; they do not reposition a colorbar independently. + +Guide inspection adds `guide_geometry` to applicable readings. It returns +`coordinate_space:"object_local_pt"`, `scale:1`, `plot_rect`, nullable +`legend_rect`/`color_scale_rect` (x/y/width/height), `entry_count`, nullable +`available_travel_pt`, `effective_position`, `fits_plot` (two size-fit booleans), +and `not_rendered_reason` (`hidden`, `no_entries`, `auto_single_entry`, or null). +`measurement_basis:"renderer_layout_text_width_estimate"` names the same layout +boxes used by rendering, not exact glyph bounds. Object/parent visibility and +clipping are not evaluated here. Effective position is the +resolved origin relative to available travel, without clamping outside placements; +a zero-travel axis reports zero. Guide-hidden or automatically omitted legends return null geometry +and the reason, while the property value retains the configured origin. + +An oversized legend is not silently shrunk. Its unavailable travel axes are zero, +`fits_plot` reports false, and the effective position can differ from the requested +origin. Size fit does not promise absence of clipping or curve overlap; inspect +the native PNG and final exports. This observation is limited to guide layout, +not a whole-figure diagnostic. + +Guide writes validate every explicit target before committing; an existing but +inapplicable target rejects the whole batch with `invalid_parameters`, unlike +the unchanged skip policy of older properties. Duplicate IDs are processed once. +One request changes one property across at most 200 IDs with one Undo/Redo step; +titles are limited to 16,384 UTF-8 bytes, structured responses to 256 KiB +(`response_too_large`), and the existing shared limit is 32 pending plans. +Malformed/out-of-range values fail with `invalid_parameters`. Inspection reports +inapplicable targets. Read-only connections can inspect/preflight but execute +requires reversible-modify permission. Context/revision changes, revocation, +busy and expired-plan failures retain the normal single-use contract. Inspection +does not add project audit records or change dirty state, edit generation, +automation revision or Undo history. Discover these rules with `plotium_capabilities_get {"section":"guide_contract"}`. + +## Apply a theme or saved style to a canvas + +`figure.apply_theme` restyles whole canvases with one of Plotium's built-in +themes, such as `nature`, or with a canvas style saved in Plotium. Set +`theme_id` to a built-in id from +`builtin_themes` in +`plotium_capabilities_get {"section":"operation_constraints","key":"figure.apply_theme"}`, or to the saved style's name. Saved styles are not +part of the static capabilities: an unknown `theme_id` fails preflight with +`invalid_parameters`, and `error.details.themes` lists every built-in theme and +saved style currently available. Plan it with the canvas ids in top-level `ids`: + +```json +{ + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 7, + "ids": ["CANVAS_ID"], + "tool_id": "figure.apply_theme", + "parameters": {"theme_id": "nature"} +} +``` + +Preflight needs only read access; executing requires Read and modify. +Preflight rejects an unknown `theme_id`, Series `targets`, and ids that include +no canvas; other ids that are not canvases are skipped. A saved style is read +again when the plan executes. Execution changes each canvas's background, text +and shape colours, and every curve's colour, marker paint, marker size and line +width the theme defines, as one **Undo** step. Curve and marker colours set by +hand are kept when a theme is re-applied; resetting a curve's colour returns it +to theme colours. +The document's style defaults are also replaced: plot text sizes, axis strokes +and ticks, so plots on other canvases change with them, and the default text, +panel-label and shape styles for new objects. Values the user set by hand are +kept, including figure typography; `diagnostics` adds a note saying how many. A theme sized for journal columns +(today `nature`) never resizes a canvas; for each canvas whose width matches +none of its column presets, the result's `diagnostics` adds a note listing the +preset widths (89 / 136 / 183 mm). diff --git a/docs/src/content/docs/reference/mcp/tables.md b/docs/src/content/docs/reference/mcp/tables.md new file mode 100644 index 00000000..71260b42 --- /dev/null +++ b/docs/src/content/docs/reference/mcp/tables.md @@ -0,0 +1,404 @@ +--- +title: MCP data import and tables +description: Import data, read tables, derive and patch tables through MCP. +--- + +## Import native data from the welcome page + +`plotium_get_state {}` works immediately after opening Plotium, including while +background work, recovery or saving blocks project access. It adds +`availability` entries for `project_read`, `project_modify` +and `native_import`; each has `available` and a nullable `{code,message}` reason. +You can import native data or tables directly from the welcome page. When idle, +`project` contains dataset and canvas counts, even before importing data. While busy, +`project` and `selection` are both `null`. Check `availability` before planning +an operation. Queries add no project audit entry or unsaved changes. +Connection capabilities remain discoverable through `plotium_capabilities_get {}` in every state. + +Enable **Read and modify**, copy `project_context` and `revision` from state, +then call `plotium_plan`: + +```json +{ + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 0, + "tool_id": "data.import", + "parameters": {"paths": ["C:/Data/experiment.jdf"]} +} +``` + +Use actual absolute paths. Native import accepts explicit data files and atomic +acquisition directories supported by the desktop loader, such as Bruker acquisition +or processed-data directories. It reads required companions without recursive batch +discovery or scanning adjacent experiments. ZIP archives, project files and new +formats are outside this operation. Optional `sampling_declaration` uses the core +import contract. Discover the shared schema with +`plotium_capabilities_get {"section":"operation_constraints","key":"data.import"}`. + +Preflight runs in the background and returns per-input format, dimensions, +warnings, failures and proposed dataset/canvas IDs in `import.items[].metadata`. +It creates no resources or document edits. Call `plotium_execute {"plan_id":"PLAN_ID"}` +to commit frozen data; changing or deleting the source after preflight does not +affect execution. Success adds native datasets and default canvases to the current +project, preserving its context and selection. + +Results report `succeeded`, `partial` or `failed`. All successful inputs commit +atomically in one Undo step. Undo leaves an empty project when the batch was its +first content; Redo restores the same resource IDs. If every input fails or the +import is cancelled, no resources, Undo entry or unsaved changes are added. +Successful imports retain scientific provenance. Permissions, context and revision +are checked again at submission. Plans are single-use even when execution is refused. After +`project_changed`, read state and preflight again. + +Native import allows 16 inputs per batch, one preflight in flight and four retained +prepared imports, shared with table import. Conservative native frozen-payload +reservations total at most 512 MiB across retained plans and the active preflight; +oversized batches fail with `import_budget_exceeded`. A call with more than 16 +paths fails with a message that gives the number received; import the rest in +further calls. Preflight responses are limited to 256 KiB. Scientific processing and DOSY use the separate shared scientific operations. +CSV, TSV and XLSX files are tables: import them with `mode: "table_data_only"`. +Native import rejects them with that hint. + +## Import CSV/TSV/XLSX data without creating a plot + +Ask the agent to import an explicitly named UTF-8 CSV or TSV, or an XLSX workbook, inspect its columns, +and read the whole table in pages. Start with `plotium_get_state {}`, then call +`plotium_plan`: + +```json +{ + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 7, + "tool_id": "data.import", + "parameters": { + "mode": "table_data_only", + "paths": ["/absolute/path/measurement.csv"], + "header": "present" + } +} +``` + +Do not supply `ids` or `targets` for import. `header` accepts `auto` (default), +`present` or `absent`; ambiguous auto detection fails. The `.csv` or `.tsv` +extension selects comma or tab; `format: "csv" | "tsv"` overrides it explicitly. +An `.xlsx` file (or `format: "xlsx"`) imports each visible worksheet that has +cells as its own table, named after the worksheet, or after the file when the +workbook holds a single table, the same way the desktop imports it. +`sheets: ["Figure 3", …]` imports only the named worksheets; an unknown name +fails that file and lists the visible worksheets. Each worksheet is prepared on +its own: one that holds no table or exceeds a limit fails as its own item and +the others still import. One file reads at most 8,000,000 worksheet cells, +counted over each worksheet's used range. `header`, `schema` and `schema_path` +apply to CSV/TSV only. If the summary of a batch with XLSX files would exceed +128 KiB, the preflight fails and lists each workbook's worksheets, so you can +import one workbook at a time and name fewer worksheets. +Only named regular files are read. There is no directory discovery, adjacent +sidecar lookup, source writeback, implicit plotting or X/Y binding. + +Preflight runs in the background and returns only when preparation finishes. +`import.items` reports each file, or each XLSX worksheet with its `sheet`, as +`prepared` or `failed`, with proposed native IDs, metadata and diagnostics. No +dataset exists yet. After reviewing the result, call +`plotium_execute {"plan_id":"RETURNED_PLAN_ID"}`. Execution uses those frozen +bytes and typed snapshots, even if a source file changed after preflight. It +rechecks revision and permission before one atomic commit of all prepared items. +`value.status` is `succeeded`, `partial` or `failed`; inspect every item and its +created IDs. Failed files leave no partial dataset. One Undo removes the batch's +successful items; Redo restores the same DatasetId, FieldId, ColumnId and RowId. +Existing GUI/CLI import entry points retain their original behavior. + +Metadata includes DatasetId, TableId, table RevisionId, field identities, stable +ColumnIds, logical types, nullable flags, units, total rows and diagnostics. +Fields and columns are distinct native identities. Missing cells remain null; +mixed numeric/text columns preserve text. Integer-looking tokens outside signed +64-bit range remain text rather than being rounded. Units are never inferred +from numbers or header spelling. Column `type_source` is `file`, `user`, +`inferred` or `unknown`; `unit_source` is `file`, `user` or `unknown`. + +Optional `schema` is an ordered native TableSchema with typed ColumnSchema IDs, +logical types, nullable flags and optional UnitSpec declarations. Alternatively, +`schema_path` names a v1 PlotiumDelimitedSchema JSON file explicitly. Its header +and order must match exactly; declarations are strict, with no inference fallback +for invalid values. Supported declared types are null, boolean, int64, float64, +utf8, date and timestamp. Uniqueness/business-key constraints and uncertainty +relations are not accepted by this import. Plain `_sigma` column names do not +assign scientific uncertainty meanings. New native IDs are allocated per import; +file/user schema IDs describe the source, not an existing project target. + +Limits are 16 files, 16 MiB per file, 64 MiB selected input bytes per batch, +256 columns and 1,000,000 rows per file. Explicit metadata files are limited to +256 KiB. The prepared item summary is limited to 128 KiB and the complete +preflight response to 256 KiB; reduce the batch/schema if either is exceeded. +At most four prepared imports and 32 total plans are retained per +connection; one import preflight runs at a time. Limits bound inputs, not total +process memory. Cancellation, a project transition, permission revocation or an +intervening edit prevents a pending preflight from becoming an executable plan. +Queued or running work is not completion. Failed/stale submissions consume their +plan; fetch state and preflight again instead of replaying a create request. + +## Read a complete table in bounded pages + +Copy DatasetId and table RevisionId from import metadata or the dataset resource +descriptor. Call `plotium_table_columns` with those IDs and `expected_revision` to +inspect metadata, then `plotium_table_read_rows`: + +```json +{ + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 8, + "dataset_id": "DATASET_UUID", + "table_revision": "TABLE_REVISION_UUID", + "offset": 0, + "limit": 200 +} +``` + +Replace the placeholders with returned IDs. Optional `column_ids` projects +columns by stable ColumnId, in the supplied order; omitted or empty selects all +columns in schema order. Rows follow immutable native snapshot order. The result +includes `column_ids`, `rows: [{row_id, values}]`, `total_rows`, `requested_rows`, +`returned_rows`, `next_offset` and `end`. Values are tagged by `kind`; null has no +value. Int64, time, timestamp and duration values use decimal strings to avoid +JSON number rounding. Date values are days since the Unix epoch; time, timestamp +and duration values use nanoseconds. Non-finite floats are explicit `NaN`, +`+Inf` or `-Inf` strings, not null. + +Follow `next_offset` with the same dataset, document revision, table revision +and projection until `end: true` and `next_offset: null`. The default page is +200 rows, maximum 1000 rows and 20000 projected cells; the complete structured +ToolResult is limited to 256 KiB. The byte limit can shorten a page, never a cell; +use the actual returned count and continuation. A single oversized row returns +`response_too_large`. An offset equal to total_rows returns an empty end page; +an offset beyond it fails. Invalid limits, duplicate/absent columns and oversized +requests fail rather than being silently clamped. + +Both revisions must still match on every read. Human edits, including Undo/Redo, +invalidate old document revisions: read state and restart rather than mixing +pages. Invalid IDs never use the current selection. Read-only connections can +query existing tables but cannot import them. Limits appear in the `limits` +capability section and the import permission condition in the index. + +## Derive a table without changing its source + +Ask the agent: “Calculate `signal_x2 = y_left * 2`, exclude rows whose +`x_left` equals zero, sort X descending, then bind the result to this existing +curve.” Table processing creates one native table, not a plot. Rebinding uses +[the existing curve-binding operation](/reference/mcp/plots/#rebind-an-existing-curve-without-changing-another-plot). + +1. Read `plotium_get_state`, then `plotium_table_columns` with the DatasetId + and table revision. Copy the actual ColumnIds, `table_id`, `table_revision` + and `snapshot_fingerprint`; names and `source_column_id` are not identities. +2. Discover the native plan schema with + `plotium_capabilities_get {"section":"operation_constraints","key":"data.transform"}`. + Supply one DatasetId in `ids` and `mode: "table_data_only"`. The leaf must + pin exactly that dataset's current snapshot. Supply fresh UUIDs for + `operation_id` and each computed column's `id`. +3. Call `plotium_plan`, inspect `transform.status: "prepared"` and its + `output`, then submit the returned `plan_id` with `plotium_execute`. + Preparation does not insert data. A successful execution returns + `value.status: "succeeded"`, `value.output` and one `produced` dataset. + The prepared output identity is retained when committed. +4. Read the complete output with `plotium_table_read_rows`. Bind its actual + DatasetId, FieldId, TableId, revision and X/Y ColumnIds to an existing curve; + use `plotium_render_preview` to inspect the native result. To create a new plot, + pass the same output identities to [`plot.create`](/reference/mcp/plots/#create-a-native-single-plot-from-an-imported-table) + instead, then preview the returned canvas. Processing and plot creation remain + separate, individually undoable operations. + +This complete native plan appends a Float64 column. Replace every placeholder +with a discovered identity or a fresh UUID. This example declares unknown units +with `unit: null`; when `y_left` has an explicit unit, copy its **whole UnitSpec** +to the output column for this dimensionless multiplication. + +```json +{ + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 7, + "tool_id": "data.transform", + "ids": ["DATASET_UUID"], + "parameters": { + "mode": "table_data_only", + "name": "Scaled signal", + "memory_limit_bytes": 16777216, + "plan": { + "version": 1, + "operation_id": "NEW_OPERATION_UUID", + "root": { + "op": "computed_column", + "input": { + "op": "snapshot_read", + "table": "TABLE_UUID", + "revision": "TABLE_REVISION_UUID", + "fingerprint": "SNAPSHOT_FINGERPRINT" + }, + "column": { + "id": "NEW_COLUMN_UUID", "name": "signal_x2", + "logical_type": {"kind": "float64"}, "nullable": true, "unit": null + }, + "expression": { + "expr": "call", "function": "multiply.v1", + "args": [ + {"expr": "cast", "input": {"expr": "column", "column": "Y_COLUMN_UUID"}, + "target": {"kind": "float64"}, "failure": "error"}, + {"expr": "literal", "value": {"type": "float64", + "value": {"kind": "finite", "value": 2.0}}} + ] + } + } + } + } +} +``` + +Supported relation nodes are `snapshot_read`, `project` (ordered ColumnIds), +`filter` (Boolean predicate), `stable_sort` (ordered keys with `column`, +`direction: ascending|descending`, `nulls: first|last`) and `computed_column` +(explicit column schema and expression). Wrap an earlier node in `input` to +compose them. For the task above, wrap the computed node in a filter using +`not.v1(eq.v1(column(X_COLUMN_UUID), literal(int64, 0)))`, then sort X descending, +then project X, Y and the new ColumnId. The schema defines the exact JSON forms. + +Expressions use `column`, `literal`, `cast` or versioned `call`. Available +functions are `is_null.v1`, `is_finite.v1`, `eq.v1`, `not.v1`, `and.v1`, `or.v1`, +`add.v1`, `subtract.v1`, `multiply.v1` and `divide.v1`; no arbitrary function, +SQL or script is accepted. Arithmetic requires Float64 operands. Casts are +explicit and may fail; `failure: error` rejects the transform, while `null` +produces a missing value. Native Int64-to-Float64 casts can lose precision. +Computed outputs support Boolean, Int64, Float64 and Utf8. Units are explicitly +declared, not inferred or converted by arithmetic. + +Filter keeps only true predicates; false and null are excluded. Sorting preserves +RowIds, resolves equal keys by RowId and places nulls independently of direction. +Non-null float order is `-Inf < finite < +Inf < NaN`. Projected columns retain +their IDs, types and units; computed columns retain the new IDs in the recipe. +Source values, table defaults, canvases and existing styles are unchanged. + +Output metadata includes the frozen native recipe, backend, input revisions and +fingerprints, column lineage and row-mapping contract. To inspect it later, call +`plotium_table_columns` with `include_provenance: true`. The same flag on +`plotium_table_read_rows` returns per-row `sources`: source DatasetId (when +recorded), TableId, revision, fingerprint, original RowId and zero-based +`input_position`. This decodes the stored native mapping for the returned page; +it does not follow the latest source revision. Imported rows have no derived +sources. Other relational lineage shapes are explicitly rejected for row-source +paging; ordinary reads without the flag retain their existing behavior. + +Preparation runs off the desktop thread. Planning and execution require **Read +and modify**. Permission, document revision and source snapshot are rechecked +when preparation finishes and immediately before commit. Each execution consumes +the plan, including a failed submission. Cancellation, stopping the connection, +project transitions and stale inputs discard uncommitted results. An already +started atomic commit is undone with normal Undo. One successful transform is +one Undo step; Redo restores the same table and column identities. + +There is one transform preflight in flight per connection. Parameters are limited +to 64 KiB, 64 relation/expression nodes and depth 16 (JSON nesting at most 48). +The memory budget defaults to and is capped at 512 MiB; it is the reference +executor's **materialized-result estimate**, checked after evaluation, not a +peak-process-memory limit. At most four prepared transforms share a 512 MiB +reservation budget, charged at each request's declared budget. Complete +responses are limited to 256 KiB; the prepared output summary is limited to +128 KiB, leaving room for the request and plan envelope. Limits are discoverable with +`plotium_capabilities_get {"section":"limits","key":"table_transform"}`. Budget failure returns +`transform_budget_exceeded`; cancellation returns `request_cancelled`. Neither +leaves a derived table or a successful execution result. Plan again after fixing +the input or budget. Use the separate cell-patch and explicit refresh operations below for subsequent updates. + +## Patch cells, then explicitly refresh derived tables + +Use `table.patch` with exactly one DatasetId in top-level `ids`, no `targets`, +and the current table revision. Copy RowIds and ColumnIds from table reads; +page offsets, row numbers and names are not cell identities. For example: + +```json +{ + "tool_id": "table.patch", + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 12, + "ids": ["DATASET_UUID"], + "parameters": { + "table_revision": "TABLE_REVISION_UUID", + "edits": [{ + "row_id": "RETURNED_ROW_UUID", + "column_id": "RETURNED_COLUMN_UUID", + "value": {"kind": "float64", "value": 2.5} + }] + } +} +``` + +Values use the tagged `kind`/`value` representation returned by table reads. +Use decimal strings for Int64 and nanosecond temporal values, a JSON number or +`"NaN"`/`"+Inf"`/`"-Inf"` for Float64, and `{"kind":"null"}` for a missing cell. +Types and nullability must match exactly; a Float64 patch cannot silently widen +an Int64 column. Categorical values address existing level indices. Extension +values and live calculated region tables are not editable through this operation. + +A batch accepts 1–1000 distinct cells and at most 64 KiB of parameters. An absent +row/column, duplicate cell, invalid type or stale revision rejects the entire +patch. It cannot insert/delete rows, change schema, reimport files or write to the +original CSV/TSV. Preparation produces `update: {status:"prepared", output, +before_table_revision, changed}`; nothing is applied until execution. A no-op +returns `changed:false` without advancing the document revision or adding Undo. +Before a patch or refresh is committed, its values must remain valid for existing +curve bindings. For example, a column used as Y error cannot contain negative +amplitudes. A rejected update preserves the table, plots and Undo history. + +Table metadata, row pages and Series sources include +`freshness: {status, refreshable, reason, sources, mcp_refreshable, mcp_refresh_reason}`. +`refreshable` reports native refresh capability; `mcp_refreshable` additionally checks +the connection's supported recipe subset, not the current permission mode. Dataset +resource metadata exposes these as `table_refreshable`, `table_mcp_refreshable` and +`table_mcp_refresh_reason`, alongside `table_freshness` and its reason. `source` means no saved derived recipe; `current` means recorded input +revisions still match; `stale` means a direct or upstream input changed; +`unavailable` means sources or a supported recipe are missing. The Data browser +marks affected relational tables **Out of date**, and their sheets explain why. +Stored results remain readable and drawable, with this explicit freshness state. +Editing a table invalidates its stored curve-fit analyses; Undo restores them. +A stale derived table's analyses describe its old result, not current source data. + +Refresh only when requested. Plan `table.refresh` with `ids:["DERIVED_DATASET_UUID"]` +and `parameters:{"table_revision":"CURRENT_DERIVED_REVISION"}`. It reruns the +persisted single-source `snapshot_read`/`project`/`filter`/`stable_sort`/`computed_column` +recipe, with the same expression and complexity limits as data-only transforms, +using current source snapshots and the existing reference executor/lineage path. +Other native recipes, including Pivot, are rejected by MCP refresh with a reason; +the native GUI/core refresh capabilities are unchanged. Before adoption, the output +must retain TableId and the column schema, including ColumnIds, types and units; +every output RowId must belong to the current input. A mismatch rejects the whole +refresh without changing tables, plot bindings or Undo. Refresh stale upstream tables first; +missing sources or recipes report a reason instead of recomputing unrelated data. +Existing manual cell edits on a derived table are rebased by stable RowId; missing +or ambiguous identities block the whole refresh, never fall back to row position. +Repeated refreshes retain those edits. `include_provenance:true` returns both the +current `operation` and the effective `refresh_recipe` through edit/rebase history. + +Optional `memory_limit_bytes` resolves the explicit value, then the saved recipe +budget, then 512 MiB; valid range is 1–536870912. This remains the executor's +materialized-result estimate, not a peak-memory limit. Patches, transforms and +refreshes share one background preflight, four prepared candidates and a 512 MiB +reservation limit; each patch reserves 64 KiB. Prepared summaries are at most +128 KiB and complete responses at most 256 KiB. Discover schemas and limits in the +`operation_constraints` and `limits` (`table_update`) capability sections. + +Both operations require **Read and modify** for preparation and execution. +Permission, document/table revisions and current inputs are rechecked before a +candidate can be adopted. Cancellation, project changes, connection stop or stale +inputs discard uncommitted work. Execute consumes the plan even when rejected. +After a lost response, inspect actual state; do not replay the submitted operation. + +Each patch or refresh is one independent Undo/Redo step. DatasetId, TableId, +ColumnId, existing RowId and native plot/Series identities remain intact; filters +can change which existing rows are present. Revisions and source mappings change, +while authored colors, axis ranges and panel frames stay untouched. Freshness is +computed from saved provenance and current revisions, so Undo/Redo restores the +corresponding freshness as well as values. Native sheet editing and refresh use +the same typed revision-adoption service. + +## Delete datasets + +`dataset.delete` takes `{}` and DatasetIds in `ids`. Preflight refuses a dataset +that a plot, projection, derived dataset or analysis report still uses and names +the page and panel, dataset or report using it; delete those first. Delete a +derived dataset in its own request before deleting its sources. One Undo restores +every deleted dataset with its original ID and position. diff --git a/docs/src/content/docs/reference/preferences.md b/docs/src/content/docs/reference/preferences.md index 4e1f5503..7a43ae19 100644 --- a/docs/src/content/docs/reference/preferences.md +++ b/docs/src/content/docs/reference/preferences.md @@ -92,12 +92,7 @@ Click the robot in the Ribbon to open this page directly. | **Add to Claude Desktop…** | Opens the extension installer on macOS and Windows; confirm installation in Claude Desktop | | **Manual configuration and diagnostics** | Provides configuration for other clients and connection details for troubleshooting | -Permissions apply to every connected client and project and are remembered when -you restart Plotium. Closing Preferences or switching projects keeps access -available. Turning MCP off stops access immediately and discards pending edits; -client configuration is retained. Exiting Plotium also stops access. - -**Configured** confirms client setup. Recent client activity shows whether a -client has actually contacted Plotium. This page also shows recent operations and -errors. See [AI client connections](/guides/automation/#local-agent-connections-mcp) -for setup, example requests, robot status and troubleshooting. +The settings are remembered across restarts. See +[Connect an AI client](/ai/connect/) for setup, and +[Access, review and undo](/ai/control-and-review/) for what each access level +allows, the robot icon and troubleshooting. diff --git a/docs/src/content/docs/reference/settings-ids.md b/docs/src/content/docs/reference/settings-ids.md new file mode 100644 index 00000000..c975e2e2 --- /dev/null +++ b/docs/src/content/docs/reference/settings-ids.md @@ -0,0 +1,221 @@ +--- +title: Setting IDs +description: Stable identifiers for settings used by the Automation window, workflows, the command line and AI clients. +--- + +Every setting in the Object inspector, the processing steps and Preferences has +a stable ID such as `series.contour.count`. You need these IDs only when you +name a setting outside the panels: in the Automation window's property tools, in +a workflow file, on [the command line](/reference/cli/) or from your own +[MCP client](/reference/mcp/). An AI client finds them by itself. + +The complete list, with value types and ranges, comes from +`plotium-cli tool properties` or the MCP tool `plotium_properties_list`. The +tables below cover the settings people use most. The command palette also +matches a setting by its ID. + +## Reading and writing settings + +The Automation window and workflows reach settings through three tools: + +| Tool | What it does | +| --- | --- | +| **Inspect a property** | Reads the current value, the default, and the range the setting accepts | +| **Set a property** | Writes a value | +| **Reset a property** | Re-derives the value from the current data, as the panel's reset button does | + +Name the setting by its ID in the tool's parameters: +`{"key": "series.contour.count", "value": 12}` for **Set a property**, and +`{"key": "series.contour.count"}` for the other two. Which resource to target +follows from the setting: a contour or line setting lives on a plot object, an +apodization setting on a dataset, figure typography on the document (listed as +**Plotium document**), a page size on a canvas, and a preference on the +application (listed as **Plotium application**). + +## Figures + +These IDs address the plot and figure settings described in the +[Figures](/guides/plots-and-charts/) guides. Plot settings (`object.*`) apply to +one plot, series settings (`series.*`) to one curve, and typography settings +(`document.figure.typography.*`) to every plot in the document. + +### Axes + +| Setting | ID | +| --- | --- | +| X / Y title | `object.axes.x_label`, `object.axes.y_label` | +| X / Y range | `object.axes.x_range`, `object.axes.y_range` | +| X / Y display unit | `object.axes.x_display_unit`, `object.axes.y_display_unit` | +| X / Y tick labels shown | `object.axes.x_show_tick_labels`, `object.axes.y_show_tick_labels` | +| X / Y title shown | `object.axes.x_show_label`, `object.axes.y_show_label` | +| X / Y scale | `object.axes.x_scale`, `object.axes.y_scale` | +| Equal x/y scale (1:1) | `object.axes.equal_scale` | +| Frame | `object.axes.frame` | +| X / Y major tick step | `object.axes.x_major_step`, `object.axes.y_major_step` | +| X / Y thousands separator | `object.axes.x_thousands_separator`, `object.axes.y_thousands_separator` | +| X / Y break | `object.axes.x_break`, `object.axes.y_break` | +| X / Y lower share | `object.axes.x_break_lower_fraction`, `object.axes.y_break_lower_fraction` | +| Right Y title, range, display unit | `object.axes.y2_label`, `object.axes.y2_range`, `object.axes.y2_display_unit` | +| Right Y tick labels / title shown | `object.axes.y2_show_tick_labels`, `object.axes.y2_show_label` | +| Right Y scale, major tick step | `object.axes.y2_scale`, `object.axes.y2_major_step` | +| Curve on the right y axis | `series.y_axis` | + +An axis break is written as `{"mode":"manual","min":…,"max":…,"unit":…}`, or +`{"mode":"auto"}` for no break. Figure diagnosis reports data points that a +break hides. + +### Legends, lines and markers + +| Setting | ID | +| --- | --- | +| Legend visibility, position, layout, title | `object.guides.visibility`, `object.guides.position`, `object.guides.layout`, `object.guides.title` | +| Legend placement | `object.guides.placement` | +| Legend text | `series.label` | +| Curve visible | `series.visible` | +| Line colour, stroke width, line style | `series.line.color`, `series.line.stroke_width`, `series.line.style` | +| Marker and marker size | `series.line.marker`, `series.line.marker_size` | +| Marker fill, edge colour, edge width | `series.line.marker_fill`, `series.line.marker_edge_color`, `series.line.marker_edge_width` | +| Hollow marker, marker every N points | `series.line.marker_hollow`, `series.line.marker_every` | +| Bar width, edge colour, edge width | `series.bar.width`, `series.bar.edge_color`, `series.bar.edge_width` | +| Error bars show, replicates | `series.error_bars` (`unspecified`, `sd`, `sem`, `ci95`), `series.replicates` | + +### Typography + +| Setting | ID | +| --- | --- | +| Font, font weight | `document.figure.typography.typeface`, `document.figure.typography.font_weight` | +| Tick-label, axis-title, figure-title and legend sizes | `document.figure.typography.tick_pt`, `document.figure.typography.label_pt`, `document.figure.typography.title_pt`, `document.figure.typography.legend_pt` | +| Legend text colour | `document.figure.typography.legend_color` | +| Axis line width, tick length, tick direction | `document.figure.typography.axis_line_pt`, `document.figure.typography.tick_length_pt`, `document.figure.typography.tick_direction` | +| Minor ticks | `document.figure.typography.minor_ticks` | +| Text sizes for one plot | `object.figure.typography.tick_pt`, `object.figure.typography.label_pt`, `object.figure.typography.legend_pt` | + +### Charts and colour maps + +| Setting | ID | +| --- | --- | +| Chart type | `object.chart.type_id` | +| Auto bins, bins | `object.chart.bins.auto`, `object.chart.bins.count` | +| Stacked bars | `object.chart.stacked` | +| Colormap | `object.chart.colormap` | +| Purpose, claim | `object.intent.purpose`, `object.intent.claim` | +| Heatmap colour range, range centre | `series.heatmap.range_span`, `series.heatmap.range_center` | + +### Contour levels + +| Setting in the Object inspector | id | Accepts | +| --- | --- | --- | +| **Lowest level** | `series.contour.base.magnitude` | a number above 0; what it measures depends on the anchor | +| **Anchor** | `series.contour.base.policy` | `absolute`, `noise_floor`, `background_scale`, `fraction_of_range` | +| **Levels** | `series.contour.count` | 1 to 256 | +| **Level ratio** | `series.contour.ratio` | above 1, at most 10 | +| **Negative contours** | `series.contour.negative.enabled` | `true` or `false` | +| **Positive colour** | `series.contour.positive_color` | `"#rrggbb"` | +| **Negative colour** | `series.contour.negative_color` | `"#rrggbb"` | +| **Line width** | `series.contour.line_width` | 0.05 to 10 pt; default 0.5 | + +[Contour levels](/guides/contour-levels/) explains what each contour setting +does and which data each anchor needs. + +## Processing settings + +| Setting on an apodization step | id | Accepts | +| --- | --- | --- | +| **Window** | `dataset.processing.apodization.kind` | `none`, `cosine_bell`, `exponential`, `gaussian` | +| **LB** | `dataset.processing.apodization.lb_hz` | −10000 to 10000 | +| **GB** | `dataset.processing.apodization.gb_hz` | greater than 0, at most 10000 | + +[Processing pipeline](/guides/processing/) explains each row. + +## Application preferences + +Preferences take the same three tools on **Plotium application**. For +`settings.appearance.accent.color`, **Set a property** accepts `"#rrggbb"` and +pins the canvas accent to that colour; **Reset a property** clears it, and the +accent follows the theme again. + +## Batch results + +### What a checked target expands to + +The resource you check is rarely the thing that is written — the setting decides +what inside it is. A plot object expands to its series, a dataset to its +processing steps, and the document to itself. Preflight and the result list show +one row per component, so a plot holding three series produces three rows, +naming the object and the series inside it. + +A component the setting does not reach is listed as **Skipped** with the reason, +and the rest still apply: a heatmap drawn under a contour, a zero-fill step when +the setting belongs to apodization, or a **GB** asked of a step whose window is +*Exponential*. A resource with nothing to address at all — a text box, a dataset +with no pipeline — is skipped the same way. + +Result rows and the run record name the component beside the resource: + +```json +{ + "resource": { "id": "…", "kind": "plotium.dataset" }, + "component": { "kind": "processing_step", "id": 3 } +} +``` + +Series components read `{"kind": "series", "id": 2}`. Both ids are local to the +resource they travel with, so a step id means nothing next to a different +dataset. + +### Why a target was skipped + +Every skipped row carries a sentence written to be read. Rows the write itself +passed over also carry `skip_reason`, a stable token a workflow can branch on +without matching on wording: + +| `skip_reason` | Means | +| --- | --- | +| `already_at_value` | The target already held that value, so nothing was written | +| `not_applicable` | The setting does not apply to this target | +| `target_missing` | The address no longer names anything in the document | + +Rows already ruled out at preflight carry the sentence alone. They are never +same-value no-ops, so the absence of the token is itself the distinction. + +A **Set a property** whose every target already stores the requested value and +override state writes nothing: each target is reported as skipped, the document revision does not move, +and nothing is added to the undo stack. Setting an inherited value as an explicit +override still records that author choice. + +A value outside the range is refused at **Preflight**, before you confirm, and +names both the value you gave and the limit that rejected it. Past that point +either every listed component takes the value or none does, and what is written +collapses into one **Undo automation** step. + +**Inspect a property** returns its readings to whoever ran it: run it as a +workflow step and the values land in the run record, which is also what +[the command line](/reference/cli/) writes to its manifest file. In the +Automation window the numbers appear under **Result value (JSON)**, below the +per-component rows. + +## Readings and schemas + +Each reading names its `target` and carries the current `value`, a +`default_value` where the setting has one, `modified` — whether the value +differs from that default — an `availability`, and the `schema` that bounds it. + +A setting the current state does not allow you to write is still read back: +`availability` is `"disabled"` and `disabled_reason` names what has to change +first, such as switching the phase mode to *Manual* before φ0 can be set. + +Schemas are tagged by `type`: `bool`, `text`, `int`, `stepped_int`, `float`, +`enum`, `color`, `unit_code`, or `axis_range`. + +- `int` and `stepped_int` carry `min` and `max`, plus a `unit` where the setting + has one. `stepped_int` also carries the `step` its values must land on — a + Savitzky-Golay window, for instance, runs from 3 to 201 in steps of 2. +- `float` carries `min`, `max` and `exclusive_min`, and where a setting refuses + particular values, `excluded` (one value) or `excluded_magnitude` (everything + at or below that magnitude). Its `display` — `linear`, `degrees` or `log10` — + is how the panel shows the number; the `unit` and `log` fields beside it + restate the same thing. +- `enum` lists its variants, each with a stable id and a label. + +Bounds and values are always in the setting's own units, whatever `display` +says: a phase whose `display` is `degrees` is radians on the wire. diff --git a/docs/src/content/docs/reference/troubleshooting.md b/docs/src/content/docs/reference/troubleshooting.md index be2d7800..63b2ffaf 100644 --- a/docs/src/content/docs/reference/troubleshooting.md +++ b/docs/src/content/docs/reference/troubleshooting.md @@ -5,28 +5,25 @@ description: What to check when an import, analysis, export, or update doesn't b ## Importing -**An image will not import.** Confirm that its actual content is PNG, JPEG, -TIFF, WebP, or BMP. Plotium checks the signature, not just the extension. SVG is -not supported. For an animated PNG or WebP, use **Add Animated Image First -Frame…**. Open **Operation and Diagnostic History** to see the file name, -detected format, point of failure, and reason. A failed import does not change -the project. - -**My ABF file won't open.** Plotium reads ABF 2.x with int16 or float32 -samples. ABF1 files and compressed ABF2 data are not currently supported — -re-export the recording as uncompressed ABF2 from your acquisition software. - -**A numeric column imported as text.** Plotium only types values automatically -when they are unmistakable: `true`/`false`, base-10 integers, `YYYY-MM-DD` -dates, and UTC timestamps. Locale-specific formats (comma decimals, regional -dates) and columns that mix numbers with text stay as text rather than being -guessed at. Check the **Review table import** dialog's diagnostics, fix the -source file, or convert the column after import. +**An image will not import.** Plotium checks the file's actual content, not +just its extension; see [Images in figures](/guides/images/) for the accepted formats and +the commands for animated and multi-page images. Open **Operation and +Diagnostic History** to see the file name, detected format, point of failure, +and reason. A failed import does not change the project. + +**My ABF file won't open.** ABF1 files and compressed ABF2 data are not +supported — re-export the recording as uncompressed ABF2 from your acquisition +software. See [Electrophysiology (ABF2)](/guides/supported-formats/#electrophysiology-abf2). + +**A numeric column imported as text.** Plotium types values automatically only +when they are unmistakable, so locale-specific formats (comma decimals, regional +dates) and columns that mix numbers with text stay as text. Check the **Review +table import** dialog's diagnostics, fix the source file, or convert the column +after import. See [How column types are decided](/guides/importing-data/#how-column-types-are-decided). **Cells from my Excel sheet came in empty.** Plotium reads the value Excel -cached for each formula but never recalculates formulas. A formula cell with -no cached value imports as empty and is listed in the import diagnostics — -open the workbook in Excel once and save it to refresh the cached values. +cached for each formula but never recalculates formulas. Open the workbook in +Excel once and save it to refresh the cached values. ## Processing and analysis @@ -46,13 +43,6 @@ window or confirm the exclusion it proposes. ## Exporting -**A project opens with a missing-image placeholder.** The embedded resource is -missing, damaged, or fails its integrity check. Check **Operation -and Diagnostic History**, select the placeholder, and use **Replace Image…**. -Plotium keeps the page editable but blocks normal save and export so the damaged -state is not silently published. The Export dialog can explicitly create a -labelled-placeholder review copy. - **The export precheck flags my figure.** Font sizes or line widths violate the selected journal preset. Fix them on the board — **Figure Typography…** sets all axis text sizes at once — or pick a preset that matches your @@ -69,9 +59,21 @@ silent by design. Use **Check now** in **Preferences → General** to get an explicit result, and check your update channel — switching to a more stable channel never downgrades, it waits for the next release. +**A project opens with a missing-image placeholder.** The embedded resource is +missing, damaged, or fails its integrity check. Check **Operation +and Diagnostic History**, select the placeholder, and use **Replace Image…**. +Plotium keeps the page editable but blocks normal save and export so the damaged +state is not silently published. The Export dialog can explicitly create a +labelled-placeholder review copy. See +[Missing or damaged images](/guides/images/#missing-or-damaged-images). + ## Reporting a problem If none of this helps, report the issue on the [GitHub issue tracker](https://github.com/nmrtist/plotium/issues) with your Plotium version (shown in **Preferences → General**), your platform, and, when -possible, a file that reproduces the problem. +possible, a file that reproduces the problem. After a crash, attach the newest +crash report from the `crashes` folder; for other problems, attach the newest +session log from the `logs` folder beside it. On macOS both are in +`~/Library/Application Support/plotium`; see +[Reporting problems](/reference/reporting-problems/) for other platforms. diff --git a/docs/src/content/docs/reference/ui-overview.md b/docs/src/content/docs/reference/ui-overview.md index 0acc24c7..684648f0 100644 --- a/docs/src/content/docs/reference/ui-overview.md +++ b/docs/src/content/docs/reference/ui-overview.md @@ -51,7 +51,7 @@ introduces the same regions in walkthrough form. **Stats**, **CRAFT** — and shows one page at a time. Its Processing page lists one pipeline for a 1D or pseudo-2D dataset and two, **F2 (direct)** then **F1 (indirect)**, for a - true 2D spectrum. See [Processing](/guides/processing/). + true 2D spectrum. See [Processing pipeline](/guides/processing/). - **Ribbon** — the command strip organized into task tabs (**Data**, **Process**, **Analyze**, **Figure**, **Arrange**, **View**). On macOS its task row also holds the native window controls and project name. It is a @@ -66,6 +66,10 @@ introduces the same regions in walkthrough form. operation reports. **Clear history** clears results, messages, and diagnostics; running tasks continue. Hover the button for the current status and result count. Errors and warnings also appear in the feedback banner. +- **Follow button** — beside the AI connection button; shows whether the + workspace follows an AI client's results (active, paused or off), with a badge + counting results you have not viewed. See + [Follow AI results](/ai/control-and-review/#follow-ai-results). Scientific tasks in **Results** distinguish completion, failure, cancellation, and results that were **not applied**. Editing the project while a computation @@ -76,40 +80,6 @@ Recomputing is always an explicit action. A completed calculation can still carry scientific warnings, such as an unconverged fit or an empty result; review those warnings before using the result. -AI results are followed by default: the workspace focuses on the canvas affected by -the latest completed operation. Results from one operation that affects multiple -canvases are shown together. The follow button beside the AI connection button shows whether -following is active, paused, or off. In **Results**, use **Pause**, **Resume**, -**Stop following**, or **View latest**. Updates to a canvas already in view preserve its zoom. -Opening or selecting other content, panning, zooming, or editing pauses following; -hovering and inspecting operation details do not. Resume following when you want -new results to appear again, or stop following to keep browsing independently. -While paused, a badge on the follow button counts new or updated results you have -not viewed. Repeated changes to the same object count once. Open **Results** to -review them without resuming following. Updates to the object currently in view -also show a brief, dismissible notification. -Viewing a result marks that result as seen; **View latest** leaves older unseen -results in the count. Resuming following clears the count. -While following is paused, a notification also offers **Resume following**, -**Dismiss**, and **Don't remind again**. Dismissing hides the current reminder -without marking results as seen. Repeated changes to the same object do not -reopen it; a new result object can trigger another reminder. The reminder closes -automatically after about eight seconds. **Don't remind again** disables these -reminders across restarts; restore them in **Preferences → General → Remind me -about results while following is paused**. Result counts and error notifications -remain available. -Pausing immediately freezes the current view, including an unfinished automatic -zoom. Resuming or viewing the latest result focuses the latest operation's results, -without collecting earlier canvases. Viewing the latest result once does not turn following back on. Read-only requests -and empty canvases do not move the workspace, and following does not cancel tasks. -Changing projects or losing the AI connection stops following; resume it explicitly -after the new project or connection is ready. - -A spinner on the AI connection button indicates a running scientific task. -Hover for its operation, progress when available, and any risk of editing while -it runs. This indicates known application work, not completion of the AI's -overall task. - Both Side Bars can be shown or hidden at any time: click the pair of layout buttons at the right end of the Ribbon's task row, press Ctrl+B (left) or Ctrl+Shift+B @@ -179,14 +149,14 @@ the region is visible. Closing a task card remains a separate **×** button. to edit its parameters; move it with **Move earlier** / **Move later** in its ⋯ menu or with Alt+↑/↓. Every step in the list is a step that runs, FFT included; an imported spectrum has no FFT row - because its recipe has no FFT. See [Processing](/guides/processing/). + because its recipe has no FFT. See [Processing pipeline](/guides/processing/). ## Data terms - **Dataset** — anything importable or derived that holds data: a spectrum, a recording, or a table. - **Derived data** — results that came from another dataset (slices, - projections, region tables, fit tables); the data browser lists them under + projections, region tables, fit tables); the Data browser lists them under their source. - **Pseudo-2D** — a stack of 1D spectra acquired while one parameter varies (gradient strength for DOSY, delay for T1/T2), as opposed to a **true 2D** diff --git a/docs/src/content/docs/zh-cn/ai/connect.md b/docs/src/content/docs/zh-cn/ai/connect.md new file mode 100644 index 00000000..37da2205 --- /dev/null +++ b/docs/src/content/docs/zh-cn/ai/connect.md @@ -0,0 +1,59 @@ +--- +title: 连接 AI 客户端 +description: 把 Codex、Claude Code 或 Claude Desktop 连接到 Plotium,让它处理你打开的项目。 +--- + +连接到 Plotium 的 AI 客户端可以查看你打开的项目、制作和调整图形、运行支持的 +分析,同时你仍可在桌面端继续操作。你在客户端(Codex、Claude Code 或 Claude +Desktop)里与它对话;Plotium 没有内置聊天窗口。连接只在你自己的电脑上运行, +使用 Model Context Protocol(MCP)。 + +## 开始之前 + +- 安装你要使用的 AI 客户端。 +- 保持 Plotium 安装完整。macOS 应用已包含连接器;ZIP 安装请把 `plotium-mcp` + (Windows 下为 `plotium-mcp.exe`)保留在主程序旁。 + +## 连接 + +1. 打开 Plotium。 +2. 打开 **Preferences → AI connections (MCP)**。也可以点击 Ribbon 中操作历史旁的 + 机器人图标,或使用菜单 **File → AI connections (MCP)…**。 +3. 开启 **Enable MCP**。 +4. 在 **Access** 中,选择 **Read only**(只读)让 AI 只查看不修改,或选择 + **Read and modify**(读取和修改)允许支持的编辑。默认是 **Read and modify**; + 两者的区别见[权限、审阅与撤销](/zh-cn/ai/control-and-review/)。 +5. 按下表添加客户端: + +| 客户端 | 在 Plotium 中 | 在客户端中 | +| --- | --- | --- | +| Codex | 在 Codex 卡片点击 **Add** | 如有需要,重载 MCP 配置或重启客户端 | +| Claude Code | 在 Claude Code 卡片点击 **Add** | 如有需要,重载 MCP 配置或重启客户端 | +| Claude Desktop(macOS 和 Windows) | 点击 **Add to Claude Desktop…** | 确认安装扩展;如有需要,重载或重启 | + +每个客户端只需添加一次。Plotium 会在重启后记住 **Enable MCP** 和权限设置。 + +## 检查连接 + +请自行启动 AI 客户端,Plotium 不会代为启动。卡片上的 **Configured** 只表示已添加 +连接配置。要确认客户端确实能访问 Plotium,请发送: + +> 请使用 Plotium 列出当前项目中的数据集和图形,不要修改任何内容。 + +客户端应能描述你的项目;客户端活跃时,Plotium 中的机器人图标会变为绿色。仅打开 +Claude Desktop 扩展安装包,并不代表连接已经成功。没有反应时,见 +[连接不成功时](/zh-cn/ai/control-and-review/#连接不成功时)。 + +接下来可以看[与 AI 协作](/zh-cn/ai/working-with-ai/),了解可以提什么要求。 + +## 其他 MCP 客户端 + +使用同一台电脑上的其他 MCP 客户端时,展开 **Manual configuration and +diagnostics**,点击 **Copy stable stdio configuration**,把复制的配置粘贴到客户端中。 +此连接只适用于同一台电脑、同一用户账户下的客户端,不支持远程连接或 Windows 与 WSL +之间的访问。手动注册命令和技术参考见 [MCP 配置与权限](/zh-cn/reference/mcp/)。 + +## 更新 Plotium 之后 + +在 AI 客户端中重启 Plotium 连接(或重启客户端),以加载更新后的工具。不需要重新 +添加客户端。 diff --git a/docs/src/content/docs/zh-cn/ai/control-and-review.md b/docs/src/content/docs/zh-cn/ai/control-and-review.md new file mode 100644 index 00000000..0df88c3c --- /dev/null +++ b/docs/src/content/docs/zh-cn/ai/control-and-review.md @@ -0,0 +1,109 @@ +--- +title: 权限、审阅与撤销 +description: 控制 AI 客户端能做什么,跟随和撤销它的修改,以及排查连接问题。 +--- + +AI 客户端在 Plotium 中做什么由你掌控:你决定它能否修改内容,每项修改都能撤销, +没有你在 Plotium 中确认,它不会向磁盘写任何文件。 + +## 决定 AI 能做什么 + +在 **Preferences → AI connections (MCP)** 中设置,或点击 Ribbon 中的机器人图标。 + +| 设置 | 作用 | +| --- | --- | +| **Access → Read only** | AI 可以查看数据、表格和图形(包括当前图形的图片),但不能准备、预览或应用修改。切换为只读还会阻止它已准备但尚未应用的修改 | +| **Access → Read and modify** | AI 还可以做支持的修改。这是默认设置 | +| 关闭 **Enable MCP** | 立即停止所有访问,丢弃 AI 已准备但尚未应用的修改,保留客户端配置 | + +权限设置对所有已连接的客户端和你打开的每个项目生效,Plotium 会在重启后记住它。关闭 +偏好设置或切换项目不会断开连接;退出 Plotium 则停止访问。重启后可以继续使用原来的 +AI 对话,无需再次添加客户端。切换项目后,请先让 AI 查看当前项目,再继续编辑。 + +你的 AI 客户端可能也会请你批准它的工具调用。那是客户端自己的审批,与 Plotium 的 +权限设置相互独立:在客户端里批准调用,不会绕过 **Read only**,也不会免去保存和 +导出确认。 + +## 审阅和撤销修改 + +- 每项修改都会立即出现在 Plotium 中,无论涉及多少内容,都是 **Undo** 和 **Redo** + 中的一步。保存和导出不是对项目的修改,不能撤销。 +- 你手动设置的值,例如在对象检查器中选的颜色或拖动过的图例,在 AI 重新设置样式或 + 套用主题时会保留,除非你要求修改。 +- 查看、预览和检查不会改变项目,也不会使项目变为未保存。 +- **操作历史**(Ribbon 中的时钟箭头按钮)在 **Results** 中列出最近 AI 操作的结果, + 并提供查看链接。 + +## 保存和导出确认 + +AI 请求保存或导出时,Plotium 会显示 **Allow AI to save this project?** 或 +**Allow AI to export this figure?**,并列出具体文件路径。 + +- 点击 **Allow save** 或 **Allow export** 继续,或点击 **Deny**,不写入任何文件。 +- 替换已有文件需要在同一提示中另外勾选。 +- 每次确认只对这一次请求有效;路径变了需要重新确认。 +- 即使是 **Read and modify** 权限也需要这项确认;**Read only** 下 AI 也可以请求它。 + +保存记录的是你允许那一刻的项目,之后的编辑仍未保存。导出不会改变项目,也不会使 +项目变为已保存。 + +## 跟随 AI 结果 + +默认情况下,工作区会跟随 AI:显示最近一次完成的操作所影响的画布。一次操作影响多个 +画布时一起显示;已在视图中的画布保持缩放。只查看项目的请求和空画布不会移动工作区。 + +AI 连接按钮旁的跟随按钮显示跟随状态:活跃、暂停或关闭。你自己操作时跟随会暂停: +打开或选择其他内容、平移、缩放或编辑。悬停和查看操作详情不会暂停。在操作历史的 +**Results** 中可使用 **Pause**、**Resume**、**Stop following** 或 **View latest**。 + +跟随暂停时: + +- 跟随按钮上的角标计数尚未查看的新结果或更新结果。同一对象的多次修改只计一次。 + 查看某个结果会把它标为已看;**View latest** 显示最新结果,但较早的结果仍留在 + 计数中,也不会重新开启跟随。恢复跟随会清零计数。打开 **Results** 可以查看这些 + 结果而不恢复跟随。 +- 当前正在查看的对象发生更新时,也会显示可关闭的短暂提示。 +- 会出现一个提醒,提供 **Resume following**、**Dismiss** 和 **Don't remind + again**。它约八秒后自动关闭。**Dismiss** 只收起提醒,不会把结果标为已看;同一 + 对象再次修改不会重新弹出提醒,出现新的结果对象时则会。**Don't remind again** + 会在重启后仍关闭这类提醒;可在 **Preferences → General → Remind me about results + while following is paused** 中重新开启。结果计数和错误提示仍然保留。 + +暂停会立即冻结当前视图,包括尚未结束的自动缩放。恢复跟随或查看最新结果时,只显示 +最近一次操作的结果。切换项目或连接断开会停止跟随;准备好后请自行恢复。跟随不会 +取消正在运行的任务。 + +机器人图标上的旋转标记表示有科学计算任务正在运行。悬停可查看操作、已知的进度,以及 +此时编辑是否可能导致结果无法应用。它表示 Plotium 自己正在运行的工作,不表示 AI +已经完成了你的请求。 + +## 机器人图标 + +将鼠标停在机器人图标上,可查看项目、权限和最近活动;点击可打开连接设置。Ribbon +折叠后仍可使用此图标。 + +| 外观 | 状态 | 含义 | +| --- | --- | --- | +| 灰色、短斜线 | Off(已关闭) | 需要连接时开启 **Enable MCP** | +| 蓝色、空心点 | Starting / Ready(启动中/就绪) | 等待启动,或从客户端发送请求 | +| 绿色、实心点 | Active(活跃) | 最近 30 秒有客户端活动;不代表它的任务已完成 | +| 橙色、感叹号 | Needs attention(需要处理) | 打开连接设置,查看错误并按提示处理 | + +## 连接不成功时 + +| 遇到的情况 | 建议操作 | +| --- | --- | +| Plotium 找不到 Codex 或 Claude Code | 通过 **Installation help** 安装,或用 **Choose executable…** 选择客户端程序,再点击 **Add** | +| 错误提示缺少 Node.js | 检查客户端的 Node.js 安装,或选择独立的客户端可执行文件后重试 | +| 已有另一个名为 `plotium` 的服务器 | 先检查现有配置;确定要替换时点击 **Back up and replace this entry**。Plotium 会备份原条目,不改动其他服务器 | +| 显示 **Configured**,但没有客户端活动 | 重载客户端的 MCP 配置或重启客户端,再发送[首次请求](/zh-cn/ai/connect/#检查连接);检查客户端是否禁用或阻止了该服务器 | +| AI 说项目已变化或它掌握的信息已过时 | 让它重新查看当前项目后再继续 | +| 提示连接由另一个 Plotium 实例提供 | 使用提供连接的实例,或退出该实例,让当前实例接入。切换窗口焦点不会切换 AI 访问的项目 | +| Windows 更新时提示连接器被占用 | 退出正在使用 Plotium 的 AI 客户端,再在连接设置中点击 **Retry** | +| 缺少连接器或 Claude Desktop 扩展 | 重新解压完整的 Plotium 发行包,将其中的文件保留在一起 | + +启动失败后会自动重试。连接设置会显示最近操作和错误;解决原因后,如页面提供 +**Retry**,可点击重试。 + +如果 AI 修改内容时连接中断,请先检查项目再让它重试:修改可能已经完成,再次执行 +可能产生重复内容。保存和导出也一样:让 AI 查询那次请求的结果,而不是重新发送。 diff --git a/docs/src/content/docs/zh-cn/ai/working-with-ai.md b/docs/src/content/docs/zh-cn/ai/working-with-ai.md new file mode 100644 index 00000000..0ea09da4 --- /dev/null +++ b/docs/src/content/docs/zh-cn/ai/working-with-ai.md @@ -0,0 +1,79 @@ +--- +title: 与 AI 协作 +description: AI 客户端能在 Plotium 中做什么、怎样提要求,以及如何预览、应用和检查它的工作。 +--- + +[连接](/zh-cn/ai/connect/)之后,AI 客户端处理的是 Plotium 中当前打开的项目。它做的 +每项修改都会立即出现在桌面端,成为普通的 Plotium 内容,你可以继续手动编辑。 + +## 能做什么 + +| 方面 | 例子 | +| --- | --- | +| 查看 | 列出数据集和图形、读取表格数值、以图片形式查看图形,检查图形中被裁切或重叠的文字、遮挡数据的图例、难以读数的坐标轴或没有对齐的面板 | +| 数据 | 导入 Plotium 能打开的数据文件和 CSV、TSV 或 XLSX 表格,添加计算列,筛选和排序生成新表,修正单元格并刷新由它派生的表格 | +| 建图 | 用表格列创建折线图、散点图、柱状图、箱线图和小提琴图,添加或更换曲线 | +| 样式 | 颜色、线宽和线型、数据点符号、坐标轴、图例、字号、内置主题和你保存的画布样式 | +| 布局 | 页面尺寸、面板位置和网格、面板字母、共享 x 轴的堆叠图、文字、图片、标注、箭头和参考线,删除指定内容 | +| 分析 | NMR 处理步骤和处理配方、扩散分析输入、区域拟合和 DOSY 图 | +| 文件 | 在你于 Plotium 中确认后,保存项目和导出图形 | + +一般曲线拟合、统计检验和偏好设置不对 AI 客户端开放,请在 Plotium 界面 +中完成。本手册中 AI 能帮忙的任务页,末尾都有一节“使用 AI 客户端”,例如 +[图例与线条](/zh-cn/guides/legends-and-lines/)或[表格](/zh-cn/guides/tables/)。 + +## 怎样提要求 + +用日常语言即可。下面几个习惯能让结果更可预期: + +- **说清改哪里。**“左边那个面板”“名为 Current 的曲线”“第 2 页的图”比“这个”更 + 明确。如果你在 Plotium 中选中了内容,AI 能看到当前选择,并把它当作“这个”。 +- **说清要保留什么。**“保留我的轴范围和颜色”能保护 AI 猜不到的选择。你在 Plotium + 中手动设置的值(包括你拖动过的图例)本来就会保留,除非你要求修改;见 + [手动摆放图例](/zh-cn/guides/legends-and-lines/#手动摆放图例)。 +- **文件写绝对路径,并说明单位。**“导入 `/Users/me/data/run3.csv`,时间单位 s, + 电流单位 mA。”Plotium 从不猜单位。 +- **先让它看。**“不要修改任何内容”让请求只读;把权限切换为 **Read only** 则能 + 确保这一点。 + +建图之前,AI 会问你这张图要表达什么、要支撑哪一句结论;有误差棒时还会问误差棒表示 +什么。参见[图与图表](/zh-cn/guides/plots-and-charts/)。 + +## 预览、应用、检查 + +对你在意的修改,请让 AI 分三步做: + +1. **预览。**AI 准备好修改,在项目发生任何变化之前给你看结果图片。遇到样式选择, + 可以让它给两三个方案;它逐个预览,只应用你选中的那个。 + AI 客户端需要支持接收图片才能显示预览。 +2. **应用。**修改出现在 Plotium 中,是一步 Undo。 +3. **检查。**让它再看一次实际的图,并按发表尺寸做一次图面检查,例如“按 180 × 90 mm + 检查有没有被裁切的文字、有没有图例遮住数据”。它会报告问题,但不会自行修改;也 + 不应为了消除提示而缩小文字或隐藏数据。 + +把三步合在一起的请求可以这样写: + +> 看看这张图,针对重叠的标签提出最小的修改。每项修改应用前先给我看预览,应用后再 +> 检查一次实际的图。保留我的数据、单位和轴范围。 + +如果你在 AI 准备修改时编辑了图形,它需要重新准备。预览准备好的修改需要 **Read and modify** +权限,但不会改变项目;查看当前图形在 **Read only** 下也可以。 + +## 保存和导出 + +AI 可以保存项目和导出图形,但 Plotium 会先问你: + +> 把这个项目保存到 `/Users/me/figures/fig2.plotium`。然后把这张画布按 180 × 90 mm +> 导出为 `/Users/me/figures/fig2.svg`、同名 PDF 和 300 DPI PNG。不要覆盖已有文件。 + +Plotium 会显示 **Allow AI to save this project?** 或 **Allow AI to export this +figure?**,并列出具体路径。替换已有文件需要另外勾选。请让 AI 确认每个文件都已完成, +并打开结果检查;仍在进行中的请求不算完成。保存和导出不能撤销。参见 +[权限、审阅与撤销](/zh-cn/ai/control-and-review/#保存和导出确认)。 + +交出图形之前,不妨先保存,在 Plotium 中重新打开 `.plotium` 文件,确认曲线、文字和 +图片仍可编辑。 + +## 编写自己的客户端 + +要在自己的程序中调用 Plotium 的工具,见 [MCP 参考](/zh-cn/reference/mcp/)。 diff --git a/docs/src/content/docs/zh-cn/getting-started/first-figure.md b/docs/src/content/docs/zh-cn/getting-started/first-figure.md index d59d628d..1328d87a 100644 --- a/docs/src/content/docs/zh-cn/getting-started/first-figure.md +++ b/docs/src/content/docs/zh-cn/getting-started/first-figure.md @@ -1,13 +1,17 @@ --- title: 第一张图 -description: 从原始数据到导出一张出版级图形的完整流程。 +description: 从一张谱或一张表格,到导出一张出版级图形的完整流程。 --- -本页用一个 1D NMR 数据集走完从导入到导出的全过程。每一步都可以推广: -同样的流程适用于 Bruker 文件夹、JCAMP-DX 文件、膜片钳记录或普通 CSV -表格。 +本页带你从数据一直走到导出的图。数据来自 NMR 谱仪等仪器时,从谱开始;数据是 +CSV 或 Excel 文件时,从表格开始。两条路线最后都使用相同的排版、导出和保存步骤。 -## 1. 导入 +也可以让连接到 Plotium 的 AI 客户端先替你做出初稿,再在画板上自己细调;见 +[连接 AI 客户端](/zh-cn/ai/connect/)。 + +## 从谱开始 + +### 1. 导入 把数据文件——例如 JEOL `.jdf`——拖到 Plotium 窗口上,或从 **File** 菜单 选择 **Open File…**。Bruker TopSpin 实验则使用 **Open Folder…** 并选中 @@ -15,7 +19,7 @@ description: 从原始数据到导出一张出版级图形的完整流程。 数据集出现在主侧栏中,并自动放置到画板上,已在自己的页面里绘制完成。 -## 2. 处理 +### 2. 处理 打开 Ribbon 的 **Process** 页签。新的 1D 数据集已带有标准管线——切趾、 零填充、FFT、相位校正、基线校正——并默认启用自动相位,多数情况下屏幕 @@ -29,7 +33,7 @@ description: 从原始数据到导出一张出版级图形的完整流程。 完整步骤列表见[数据处理](/zh-cn/guides/processing/)。 -## 3. 分析 +### 3. 分析 按 `P` 选择**峰**工具,拖动图上的阈值线:松开时高于阈值的峰会被检测出 来。自动检测不足的位置可手动添加、移动或删除峰标记。 @@ -38,7 +42,34 @@ description: 从原始数据到导出一张出版级图形的完整流程。 本走查到峰拾取为止;[分析工具一览](/zh-cn/guides/choosing-a-tool/)介绍 其余工具及其适用场景。 -## 4. 排版页面 +接下来见[排版页面](#排版页面)。 + +## 从表格开始 + +### 1. 导入表格 + +在 **Data** 页签选择 **Import Table…**,选取 CSV、TSV 或 XLSX 文件;也可以用 +`Ctrl` + `Shift` + `V` 粘贴复制的表格。**Review table import** 对话框会显示每列识别出的 +类型和单位;核对后选择 **Import table**。列类型如何确定,见 +[导入表格](/zh-cn/guides/importing-data/#导入表格)。 + +表格以数据表的形式出现在画板上,旁边是一个带空白图的新页面。 + +### 2. 选择列 + +单击图将其选中。在对象检查器中展开 **Data → Curve columns**,选择 **X** 和 **Y** +列,需要时再选 **Y error** 列,然后选择 **Apply curve binding**。曲线随即出现在图上。 + +要在同一坐标轴上再画一列,展开 **Add curve**,选择表格及其 **X**、**Y** 列,选 +**Line** 或 **Scatter**,再选择 **Append curve**。 + +### 3. 选择图表类型 + +图一开始是折线图。要改成柱状图、直方图、箱线图或其他图表,在 **Figure** 页签选择 +**Chart**,再从 **Chart type** 画廊中挑选。哪种图表回答哪种问题,见 +[绘图与图表类型](/zh-cn/guides/plots-and-charts/)。 + +## 排版页面 点击页面左上角上方的尺寸标签(或 **Figure** Ribbon 页签的 **Canvas Size & Settings…**),选择目标期刊的单栏预设。页面宽度会对齐到期刊的 @@ -47,7 +78,7 @@ Size & Settings…**),选择目标期刊的单栏预设。页面宽度会对 需要面板序号或标注时,按 `T` 选择文本工具并点击画布。见 [标注](/zh-cn/guides/annotations/)。 -## 5. 导出 +## 导出 使用 **Figure** 页签的 **Output** 分组(或 **File → Export**),选择矢量格式——SVG 便于继续编辑,PDF 适合投 稿——或栅格预设,例如 *Single column · 89 mm · 600 dpi · TIFF*。导出 @@ -56,8 +87,8 @@ Size & Settings…**),选择目标期刊的单栏预设。页面宽度会对 要快速粘贴到文档里,`Ctrl` + `C` 会把所选图框同时以位图和矢量复制到 剪贴板。 -## 6. 保存项目 +## 保存项目 `Ctrl` + `S` 把一切——数据、处理、分析和排版——保存为一个 `.plotium` 文件,之后可以重新打开或发给同事。见 -[文件格式](/zh-cn/reference/file-formats/)。 +[Plotium 文件](/zh-cn/reference/file-formats/)。 diff --git a/docs/src/content/docs/zh-cn/getting-started/installation.md b/docs/src/content/docs/zh-cn/getting-started/installation.md index 868bb129..9ee21fd9 100644 --- a/docs/src/content/docs/zh-cn/getting-started/installation.md +++ b/docs/src/content/docs/zh-cn/getting-started/installation.md @@ -37,7 +37,7 @@ macOS 应用包已包含 MCP 连接器和 Claude Desktop 扩展,请保持应 (Windows 下为 `plotium-mcp.exe`)保留在主程序旁。macOS 和 Windows ZIP 也包含 Claude Desktop 扩展 `plotium.mcpb`。 -准备好后,按[连接 AI 客户端](/zh-cn/guides/automation/#连接-ai-客户端)中的步骤操作。 +准备好后,按[连接 AI 客户端](/zh-cn/ai/connect/)中的步骤操作。 每个客户端只需添加一次。 ## 首次启动 diff --git a/docs/src/content/docs/zh-cn/getting-started/quick-tour.md b/docs/src/content/docs/zh-cn/getting-started/quick-tour.md index f624f258..35fe380b 100644 --- a/docs/src/content/docs/zh-cn/getting-started/quick-tour.md +++ b/docs/src/content/docs/zh-cn/getting-started/quick-tour.md @@ -73,7 +73,8 @@ Ribbon 是高频命令入口,不是完整菜单的重复。选择 **Data**、* 4. **排版**:在画板上排布图形并**导出**。 [第一张图](/zh-cn/getting-started/first-figure/)用一个真实数据集走完这 -四步。 +四步。其中任何一步也可以交给连接到 Plotium 的 AI 客户端完成;见 +[连接 AI 客户端](/zh-cn/ai/connect/)。 ## 导航 diff --git a/docs/src/content/docs/zh-cn/guides/annotations.md b/docs/src/content/docs/zh-cn/guides/annotations.md index ba6737ea..13c17997 100644 --- a/docs/src/content/docs/zh-cn/guides/annotations.md +++ b/docs/src/content/docs/zh-cn/guides/annotations.md @@ -26,7 +26,7 @@ description: 画板上的文本、面板序号、形状、箭头、图内标签 ## 图内标签 -属于某张图的文字标注和参考线标签(例如 agent 通过[自动化](/zh-cn/guides/automation/) +属于某张图的文字标注和参考线标签(例如 AI 客户端 添加的)会自动避开数据: - 参考线标签默认在竖线顶端或横线右端。那里压到曲线、散点、柱子、误差棒、箭头、 @@ -37,7 +37,7 @@ description: 画板上的文本、面板序号、形状、箭头、图内标签 拖动标签即可自己摆放;拖动中按 `Esc` 恢复原位,一次拖动是一步撤销。拖过的文字保持 与锚点的相对距离,拖过的参考线标签保持在线上的位置,因此都会跟随轴范围、缩放和 -平移移动。agent 修改文字或字号时保留你摆的位置,只有你要求时才会挪动你摆过的标签。 +平移移动。AI 客户端修改文字或字号时保留你摆的位置,只有你要求时才会挪动你摆过的标签。 右键标签并选择 **Automatic position** 即可恢复自动摆放。 ### 编辑标签、箭头和参考线 @@ -49,9 +49,9 @@ description: 画板上的文本、面板序号、形状、箭头、图内标签 文字标注中 `Enter` 换行,`Ctrl`/`Cmd` + `Enter` 保存;参考线标签只有一行, `Enter` 保存。`Esc` 取消。 - **移动**:拖动箭头可整体移动,拖动箭头的一端只移动这一端;沿垂直于参考线的方向 - 拖动可改变它的位置。方向键微调所选标注。你移动过的箭头和参考线,agent 只有在你 + 拖动可改变它的位置。方向键微调所选标注。你移动过的箭头和参考线,AI 客户端只有在你 要求时才会挪动。 -- **样式**:点击标注即可选中,Object inspector 中显示文字的字号和颜色,参考线的 +- **样式**:点击标注即可选中,对象检查器中显示文字的字号和颜色,参考线的 颜色、线宽和线型,或箭头的颜色、线宽和箭头样式。 - **删除**:按 `Delete` 或 `Backspace`,或在右键菜单中选择 **Delete annotation**。 @@ -60,7 +60,7 @@ description: 画板上的文本、面板序号、形状、箭头、图内标签 调好一个对象的样式后,可以把它设为同类新对象的默认样式("set as default for new …"),这样一批标签无需逐个调整就能保持一致。这些默认值 在当前会话内有效;坐标轴与标题文字尺寸是文档级设置——见 -[Figure Typography](/zh-cn/guides/layout-and-export/#作图样式与排印)。 +[图形排印](/zh-cn/guides/themes-and-styles/#图形排印)。 ## 选择、分组与锁定 @@ -71,4 +71,13 @@ default for new …"),这样一批标签无需逐个调整就能保持一致 - `Delete` 或 `Backspace` 删除所选标注对象。 标注的对齐、分布与层叠顺序与图框完全一致——见 -[画板](/zh-cn/guides/layout-and-export/)。 +[画板](/zh-cn/guides/multi-panel-figures/#画板)。 + +## 使用 AI 客户端 + +也可以让连接到 Plotium 的 AI 客户端替你完成,例如: + +> 在名为 Kinetics 的图上,在 30 s 处加一条虚线竖线,标签写 Injection,再加一个箭头指向 45 s 附近的峰。先给我看预览。 + +新加的标签会自动避开数据,你手动摆过的标签保持原位,整个修改是一步 Undo。 +同意之前请先看预览。参见[权限、审阅与撤销](/zh-cn/ai/control-and-review/)。 diff --git a/docs/src/content/docs/zh-cn/guides/automation.md b/docs/src/content/docs/zh-cn/guides/automation.md index 2347d0d9..dce38714 100644 --- a/docs/src/content/docs/zh-cn/guides/automation.md +++ b/docs/src/content/docs/zh-cn/guides/automation.md @@ -1,144 +1,91 @@ --- title: 自动化 -description: 把同一个操作一次应用到多个数据集或图,或运行已保存的工作流。 +description: 把同一个操作一次应用到多个数据集或图,运行只读的科学脚本,或运行已保存的工作流。 --- 当同一个操作需要作用于一整个系列的实验时,自动化用一次可预检的批处理 取代逐个数据集的点击。 选择**文件 → Automation…**(命令面板中也可调用)。窗口分两个标签页: +**Current Project** 作用于已打开的内容,**External Inputs** 运行从磁盘文件开始的 +已保存工作流。 + +如果想用日常语言让 AI 客户端完成这类工作,参见[与 AI 协作](/zh-cn/ai/working-with-ai/)。 ## Current Project -作用于已打开的内容。搜索并勾选需要的数据集或图——或点击 **Current -selection** 载入当前选择——再选择一个工具,点击 **Preflight** 预览会影响 -哪些目标、哪些会被跳过。**Confirm and execute** 执行,整批操作合并为 -一次 **Undo automation** 撤销。 +搜索并勾选需要的数据集或图,或点击 **Current selection** 勾选工作区里当前选中的 +内容。然后在列表下方选择两种模式之一:**Scientific Script** 或 **Registered Tool**。 + +### 对勾选的内容应用工具 -### 参数设置 +在 **Registered Tool** 中从列表选择一个工具。窗口会显示工具的作用和它接受的参数; +在 **Parameters (JSON)** 中填写参数。点击 **Preflight** 预览会影响哪些目标、哪些会 +被跳过,再点 **Confirm and execute**。整批操作合并为一次 **Undo automation** 撤销。 -有三个工具能改到对象检查器(**Object inspector**)和处理步骤里的设置,于是 -一个层级、一种颜色、一个线宽、一个字号或一种窗函数,都可以经一次可预检的批 -处理应用到整个项目: +其中三个工具能改到对象检查器(**Object inspector**)、处理步骤和偏好设置里的设置, +于是一个等高线层级、一种颜色、一个线宽、一个字号或一种窗函数,都可以经一次批处理 +应用到整个项目: | 工具 | 作用 | | --- | --- | -| **Inspect a property** | 读取当前值、默认值,以及该参数允许的范围 | +| **Inspect a property** | 读取当前值、默认值,以及该设置允许的范围 | | **Set a property** | 写入一个值 | | **Reset a property** | 按当前数据重新推导该值,与面板上的重置按钮一致 | -在 **Parameters (JSON)** 中用 id 指定参数:**Set a property** 用 -`{"key": "series.contour.count", "value": 12}`,另外两个用 -`{"key": "series.contour.count"}`。 - -这三个工具够得到各面板能编辑的一切设置:对象与序列的样式、处理步骤的参数、 -文档与画布的设置,以及应用偏好。该指定哪个资源由参数本身决定——等高线和线条 -参数在图对象上,切趾参数在数据集上,图形排印在文档上(列为 -**Plotium document**),页面尺寸在画布上,偏好设置在应用上(列为 -**Plotium application**)。 - -| 对象检查器中的设置 | id | 取值 | -| --- | --- | --- | -| **Lowest level** | `series.contour.base.magnitude` | 大于 0 的数;究竟以什么计量取决于 **Anchor** | -| **Anchor** | `series.contour.base.policy` | `absolute`、`noise_floor`、`background_scale`、`fraction_of_range` | -| **Levels** | `series.contour.count` | 1 到 256 | -| **Level ratio** | `series.contour.ratio` | 大于 1,最大 10 | -| **Negative contours** | `series.contour.negative.enabled` | `true` 或 `false` | -| **Positive colour** | `series.contour.positive_color` | `"#rrggbb"` | -| **Negative colour** | `series.contour.negative_color` | `"#rrggbb"` | -| **Line width** | `series.contour.line_width` | 0.05 到 10 pt;默认 0.5 | -| **Stroke width**(**Line** 区域) | `series.line.stroke_width` | 0.05 到 10 pt;默认 0.5 | -| **Tick-label size**(**Figure typography** 区域) | `document.figure.typography.tick_pt` | 1 到 72 | - -应用偏好设置同样用这三个工具。对于 -`settings.appearance.accent.color`,**Set a property** 接受 `"#rrggbb"`,把画布 -强调色固定为该颜色;**Reset a property** 清除它,强调色重新跟随主题。 +用 ID 指定设置。[设置 ID](/zh-cn/reference/settings-ids/#读取和写入设置) 列出各个 ID、 +参数格式、每个设置位于哪类对象上,以及结果如何报告被跳过的目标。 -| 切趾步骤上的设置 | id | 取值 | -| --- | --- | --- | -| **Window** | `dataset.processing.apodization.kind` | `none`、`cosine_bell`、`exponential`、`gaussian` | -| **LB** | `dataset.processing.apodization.lb_hz` | −10000 到 10000 | -| **GB** | `dataset.processing.apodization.gb_hz` | 大于 0,最大 10000 | +超出范围的值在 **Preflight** 阶段、也就是确认之前就会被拒绝。过了这一步,列出的 +目标要么全部生效,要么全部不变。已经是这个值的目标报告为跳过;如果所有目标都已是 +这个值,就不写入任何内容,也不增加撤销步骤。 -各等高线参数的含义、以及每种锚定方式需要什么样的数据,见 -[等高线层级](/zh-cn/guides/contour-levels/);切趾各行的说明见 -[数据处理](/zh-cn/guides/processing/)。 +### 运行科学脚本 -#### 勾选的目标会展开成什么 +科学脚本读取 LC–MS 数据,返回自己的分析摘要,例如在每条色谱中找到的峰。它不能 +修改项目,不能打开其他文件,也不能访问网络。 -被勾选的资源往往并不是真正被写入的对象——展开成什么由参数决定:图对象展开 -为它的各条序列,数据集展开为它的各个处理步骤,文档就是它自己。预检和结果列 -表按展开后的部件逐行列出,因此一个含三条序列的图会给出三行,并指明是哪个图 -对象里的哪条序列。 +1. 勾选要分析的 LC–MS 数据集。勾选画布等于勾选它显示的数据集。 +2. 选择 **Scientific Script**,点击 **Open script…** 并选择 `.plotiumscript` 文件。 + 窗口会显示脚本将处理几个已勾选的 LC–MS 数据集。 +3. 点击 **Run Scientific Script**。数据集逐个处理,并显示进度条。 +4. 每个数据集得到一张结果卡片。脚本返回了 `summary` 时,其中各字段显示为表格; + **Technical details** 显示完整结果。脚本处理失败的数据集显示错误信息,其余 + 数据集照常运行。 +5. 点击 **Save results…** 把全部结果写入一个 JSON 文件。 -参数够不到的部件会标为 **Skipped** 并给出原因,其余部件照常应用:等高线下方 -的热图、参数属于切趾时列表里的零填充步骤,或对一个窗函数为 *Exponential* 的 -步骤索取 **GB**,都是这种情况。完全没有可寻址内容的资源(文本框、没有管线的 -数据集)同样被跳过。 +命令面板中的 **Run Scientific Script** 会打开这个模式,并对已勾选的数据集运行所选 +脚本。只有 LC–MS 数据集(例如 mzML 和 Waters MassLynx 导入的数据)会交给脚本; +没有加载这类数据时该命令不可用。 -结果行和运行记录会在资源旁写出部件: +脚本使用 [Rhai](https://rhai.rs/) 语言编写。`load_input()` 以 map 形式返回数据集: +`source` 和 `instrument`、文件中存储的 `chromatograms`、总离子流和基峰的 +`stream_chromatograms`、`scans` 下每次扫描的摘要,Waters 数据还在 `lc_method` 中 +给出液相方法。保留时间以分钟为单位。脚本最后一个表达式就是它的结果。可用的辅助 +函数: -```json -{ - "resource": { "id": "…", "kind": "plotium.dataset" }, - "component": { "kind": "processing_step", "id": 3 } +| 函数 | 返回 | +| --- | --- | +| `moving_average(values, width)` | 用 `width` 个点的居中窗口平滑后的数值 | +| `rolling_percentile(values, width, q)` | 居中窗口内的 `q` 分位数(0–1),可用作基线 | +| `estimate_noise(values)` | 该曲线的噪声估计 | +| `detect_peaks(x, y, options)` | 峰列表,每个峰含 `index`、`x`、`y` 和 `prominence`;`options` 可设 `min_height`、`min_prominence`、`min_spacing` 和 `max_count` | +| `format_number(value, decimals)` | 最多 12 位小数的数字文本 | + +例如,下面的脚本报告第一条总离子流或基峰色谱中最显著的五个峰: + +```rust +let input = load_input(); +let trace = input.stream_chromatograms[0]; +let peaks = detect_peaks(trace.time_min, trace.values, #{ min_prominence: 1000.0, max_count: 5 }); +#{ + summary: #{ "Peaks found": peaks.len() }, + peaks: peaks } ``` -序列部件写作 `{"kind": "series", "id": 2}`。两种 id 都只在它所属的资源内有 -意义,换一个数据集,同一个步骤 id 就什么也不代表。 - -#### 为什么某个目标被跳过 - -每一条被跳过的行都带有一句供人阅读的说明。由写入本身跳过的行还带有 -`skip_reason`——一个稳定的标记,工作流据此分支即可,不必去匹配文字: - -| `skip_reason` | 含义 | -| --- | --- | -| `already_at_value` | 目标本来就是这个值,没有写入任何内容 | -| `not_applicable` | 该参数不适用于这个目标 | -| `target_missing` | 这个地址在文档里已经指不到任何东西 | - -在预检阶段就被排除的行只有那句说明。它们绝不会是「值本来就一样」这种情况, -因此没有这个标记本身就是区分。 - -如果 **Set a property** 的所有目标已存储所请求的值和覆盖状态,则不再写入: -每个目标报告跳过,文档版本号不变,也不增加撤销步骤。把继承值固定为显式覆盖, -仍会记录这项人工选择。 - -超出范围的值在 **Preflight** 阶段、也就是确认之前就会被拒绝,并同时给出你 -填的值和拒绝它的边界。过了这一步,列出的部件要么全部生效,要么全部不变, -写入的改动合并为一次 **Undo automation** 撤销。 - -**Inspect a property** 把读数返回给调用方:作为工作流的一步运行时,读数会 -进入运行记录,[命令行](/zh-cn/reference/cli/)写出的清单文件里也是同一份 -内容。在窗口里,数值显示在逐部件结果下方的 **Result value (JSON)** 区域: -每个部件一份读数,包含当前值、默认值和它接受的范围。 - -#### 一条读数包含什么 - -每条读数写出自己的 `target`,并带上当前值 `value`、参数有默认值时的 -`default_value`、表示当前值是否偏离默认值的 `modified`、可用状态 -`availability`,以及约束取值的 `schema`。 - -当前状态下不允许写入的参数照样会被读出:`availability` 为 `"disabled"`, -`disabled_reason` 说明要先改什么——例如设置 φ0 之前,先把相位模式切到 -*Manual*。 - -schema 以 `type` 标记,取值为 `bool`、`text`、`int`、`stepped_int`、`float`、 -`enum`、`color`、`unit_code` 或 `axis_range`。 - -- `int` 与 `stepped_int` 带 `min` 与 `max`,参数有单位时还带 `unit`。 - `stepped_int` 另有取值必须落在的格点 `step`——例如 Savitzky-Golay 窗口为 - 3 到 201,步长为 2。 -- `float` 带 `min`、`max` 与 `exclusive_min`;若参数拒绝某些取值,还带 - `excluded`(单个取值)或 `excluded_magnitude`(绝对值不超过该阈值的全部 - 取值)。其 `display`(`linear`、`degrees` 或 `log10`)说明面板如何显示这个 - 数;旁边的 `unit` 与 `log` 只是同一件事的另一种写法。 -- `enum` 列出各变体,每个都带稳定 id 和标签。 - -无论 `display` 是什么,边界和取值始终使用参数自身的单位:`display` 为 -`degrees` 的相位值,在线格式中仍是弧度。 +脚本运行过久、生成过大的数组或文本,或返回超过 10 MB 的结果时,会报错停止。 +结果保留在窗口中,直到再次运行脚本;以后还需要的话请先保存。 ## External Inputs @@ -147,204 +94,20 @@ schema 以 `type` 标记,取值为 `bool`、`text`、`int`、`stepped_int`、` **Validate** 校验,再点 **Confirm and run workflow**。进度会逐步显示, 较长的运行可以取消。 +窗口只运行工作流文件,不创建它们。工作流是普通 JSON 文件,格式见 +[工作流文件结构](/zh-cn/reference/cli/#工作流文件结构)。 + ## 什么会被记录下来 一次工作流运行会留下一份记录:工作流本身及其哈希、Plotium 版本,以及每一步 作用的目标、参数和结果。在这里运行,记录保存在项目中;用 [命令行](/zh-cn/reference/cli/)运行,同样的记录写成文件。**Current Project** 里的批处理不会留下这种记录——它就是一次普通编辑,在文档里,也在 -撤销栈上。 +撤销栈上。科学脚本不修改任何内容,也不留下记录。 原生工作流中向项目之外写文件的操作(例如导出图形)还会列在 **Help → Operation and Diagnostic History** 中,附带每个文件的路径、大小和 SHA-256 校验和。中途 失败的导出也会列出此前已经写出的文件,落到磁盘上的内容不会无从追查。 -工作流文件是纯 JSON,也可以脱离桌面应用运行——见 -[命令行](/zh-cn/reference/cli/),它以无界面方式执行同样的工作流。工作流 +工作流文件也可以脱离桌面应用运行,见[命令行](/zh-cn/reference/cli/)。工作流 与运行记录文件本身的说明见[文件格式](/zh-cn/reference/file-formats/)。 - -## 本机 agent 连接(MCP) - -连接 AI 客户端后,你可以让它查看当前项目、检查图形,或在 Plotium 中完成支持的 -编辑操作。MCP 让客户端能够调用 Plotium 的工具;你仍在 Codex、Claude Code 或 -Claude Desktop 中与 AI 对话。 - -### 按需发现能力 - -让 Agent 用 `plotium_get_state` 读取当前权限和项目上下文,仅在需要静态契约 -或能力指纹变化时调用 `plotium_capabilities_get`。它返回精简索引,Agent 再逐个分区读取详细 -schema 和限制。状态包含项目数量摘要、有上限的选择分页 -和保留的保存回执 ID;完整目标及回执通过各自查询读取。缓存能力不授予修改或重试权限, -每次保存/导出仍须桌面确认。 -详见[状态与能力发现](/zh-cn/reference/mcp/#读取状态与按需发现能力)。 - -### 连接 AI 客户端 - -请保留完整的 Plotium 发行目录,包括 `plotium-mcp`(Windows 下为 -`plotium-mcp.exe`)。接入前,先安装你要使用的 AI 客户端。 - -1. 打开 Plotium。 -2. 打开 **Preferences → AI connections (MCP)**。也可以点击 Ribbon 中操作历史 - 旁的机器人图标,或使用菜单 **File → AI connections (MCP)…**。 -3. 开启 **Enable MCP**。在 **Access** 中,选择 **Read only**(只读)可先查看项目, - 选择 **Read and modify**(读取和修改)则允许支持的编辑。默认允许读取和修改。 -4. 按下表添加客户端。 - -| 客户端 | 在 Plotium 中操作 | 在客户端中操作 | -| --- | --- | --- | -| Codex | 在 Codex 卡片点击 **Add** | 如有需要,重载 MCP 配置或重启客户端 | -| Claude Code | 在 Claude Code 卡片点击 **Add** | 如有需要,重载 MCP 配置或重启客户端 | -| Claude Desktop(macOS 和 Windows) | 点击 **Add to Claude Desktop…** | 确认安装扩展;如有需要,重载或重启 | - -请自行启动 AI 客户端,Plotium 不会代为启动。Codex 和 Claude Code 卡片上的 -**Configured** 表示已添加连接配置。要确认客户端确实能访问 Plotium,请发送: - -> 请使用 Plotium 列出当前项目中的数据集和图形,不要修改任何内容。 - -客户端应能描述你的项目,Plotium 中也应显示最近的客户端活动。连接活跃时,机器人 -图标会变为绿色。仅打开 Claude Desktop 扩展安装包,并不代表连接已经成功。 - -新 AI 结果默认显示在工作区。手动浏览或编辑会暂停跟随,避免后续结果打断操作; -准备好后可主动恢复。随时可在操作历史中查看结果;控制方式见 -[跟随结果](/zh-cn/reference/ui-overview/#窗口区域)。 - -### 试着完成一个任务 - -在 AI 客户端中直接用自然语言描述任务,例如: - -- **检查图形:**“请使用 Plotium 预览我的画布,描述曲线和标签,不要修改内容。” - 客户端需要支持接收图像。 -- **只诊断不修改:**“按 180 × 90 mm 定位文字溢出和图例潜在遮挡,说明覆盖限制并实际查看原生 PNG;保留有意重叠与手动轴范围。”见[图面诊断](/zh-cn/reference/mcp/#按输出尺寸诊断图面几何)。 -- **调整线宽:**“找到名为 Current 的曲线,查看当前线宽,再仅将这条曲线改为 - 1.5 pt。”需要 **Read and modify** 权限。 -- **编排图形:**“将页面设为 180 × 90 mm,这两个面板横排,边距 4 mm、间距 - 5 mm,标 a/b,加入说明文字和本地 PNG/JPEG,再显示预览;其他面板不动。” - 明确目标面板与图片绝对路径。图、文字和图片仍可在 Plotium 分别编辑,Undo - 可恢复整批版式修改。 -- **更新数据:**“只改源表这个单元格,显示哪些派生表已失效,再刷新这张表的已存配方;保留我的颜色、轴范围和布局。”补丁与刷新可分别 Undo。 -- **创建图形:**“导入 `/absolute/path/experiment.csv`,用时间列作 X、电流列作 Y, - 单位分别为 s 和 mA,创建可编辑折线图并显示预览。”请换成实际文件的绝对路径, - 并说明要使用的列和单位。 - -连接支持导入 CSV/TSV 表格、读取表格数据、查看项目结构、预览画布、创建折线图或 -散点图及多面板、设置页面/面板几何、对齐/分布/网格排列明确面板、添加可编辑文字和本地 PNG/JPEG、更换曲线的数据列、使用受支持的原生计划派生表格、修改已有单元格、显式刷新已存配方、为画布套用内置主题或已保存的画布风格,以及重命名数据集、画布或对象。显示设置可精确修改曲线颜色、线宽/线型、符号、可见性和图例文字;轴标题、显示单位及自动/手动范围;单图刻度、轴标题和图例字号,以及已有等高线和文档字号控制。 -处理参数、受支持表格处理之外的拟合等计算、其他格式导入尚未开放给此连接,请在 Plotium 界面 -中完成。Plotium 不提供内置聊天窗口。 - -保存时可说:“把当前桌面项目保存到 `/absolute/path/figure.plotium`。” -在 Plotium 的 **Allow AI to save this project?** 提示中核对路径;已有文件还须 -明确确认替换。保存使用独立的一次性授权,不能 Undo;Agent 收到完成回执才算 -保存结束,之后的编辑和读取仍可能未保存。 - -### 只删除明确指定的内容 - -可以要求:“删除这段重复说明和这条明确的冗余 Series,保留另一条同名曲线、单位和我的手动 -范围。先列出删除清单,再执行并显示实际 PNG。”Agent 必须发现稳定 ID,不按名称或当前选择 -定位。一次 Undo 恢复整批;空父容器和来源数据保留,删除末条 Series 会被拒绝。 -空 panel 可显式删除,非空 panel 不能经 MCP 级联删除。 -详见[精确删除及拒绝规则](/zh-cn/reference/mcp/#精确删除内容或指定-series)。 - -### 看过候选后再应用局部修正 - -可以要求:“自行发现明确对象,读取诊断和实际 PNG,提出最小局部修正。**每个**计划都 -先显示并实际读取候选 PNG,再明确 execute 同一计划;执行后读取真实 PNG 和 fresh 诊断。 -保留数据、单位、手动范围、其他同名对象及有意裁切/重叠,不要缩字或隐藏数据消除告警。” - -候选支持显示属性的修改(如颜色、线宽、坐标轴、图例和字体字号),以及内容几何、原位换图、 -文字更新和精确删除。它需要 **Read and -modify**,但不改 authored state、Undo/Redo、dirty 或 edit generation,也不追加项目审计记录。如果你在 -Agent 审阅候选时编辑项目,旧计划必须重做。一次 execute 仍是一个原生 Undo 步骤。 -详见[支持矩阵与候选元数据](/zh-cn/reference/mcp/#提交前读取计划候选)。 - -遇到配色、线宽、图例位置这类审美选择,可以让 AI 给出两三个方案。它逐个预览,不改动项目, -只应用你选中的那个。 - -### 交付可编辑项目和成品 - -先让 Agent 导入 CSV/TSV、检查明确单位,再创建折线加误差/散点双面板,添加 -文字和 PNG/JPEG。请它实际看预览后只修正指定局部;需要派生曲线时,先计算再 -追加到已有图。你可在 GUI 改颜色、轴范围和面板位置,再让 Agent 精确补丁数据、 -检查派生失效并显式刷新;用 Undo/Redo 核对补丁和刷新各自保留人工设计。 - -保存后在 GUI 重开 `.plotium`,确认曲线、文字、图片仍可编辑。再说:“将这张 -180 × 90 mm 画布导出为 `/absolute/path/figure.svg`、同名 PDF 和 300 DPI PNG, -不要覆盖已有文件。”在 **Allow AI to export this figure?** 核对路径并批准; -替换已有文件另需勾选确认。Agent 应逐文件查完成回执、实际打开成品检查,而不把 -排队当成功。PNG 应为 2126 × 1063 像素。导出不替代项目,也不使项目变为已保存。 -MCP 导出结果保存在当前进程的导出回执中;重连先查回执,不重放未知调用。 - -### 只修改图例,保留数据 - -可以说:“只把左面板的图例移到可用左下角,保持纵向,标题为 Samples。保留全部 -曲线、单位和手动范围,显示修改前后预览;放不下时如实报告。”Agent 应按完整对象 -ID 区分同名 plot,并实际查看原生 PNG。之后仍可在 GUI 拖动图例,双击恢复自动位置; -保存前检查 Undo/Redo。[坐标与重置规则](/zh-cn/reference/mcp/#精确放置单图图例)见接口参考。 - -### 控制权限与检查修改 - -**Access** 对使用此 Plotium 连接的所有客户端生效,也适用于之后打开的项目。 -Plotium 会在重启后记住权限和 **Enable MCP** 的选择。改为 **Read only** 会阻止 -后续编辑,包括已准备但尚未应用的修改;仍可查看数据和预览图形。 - -支持的修改会立即显示在桌面中,可使用 Plotium 的 **Undo**(撤销)和 **Redo** -(重做)。普通查询、预览和诊断不改变项目审计记录、dirty、edit generation 或 automation revision。 - -关闭 **Enable MCP** 会立即停止访问,并保留客户端配置。关闭设置或切换项目不会 -断开连接;退出 Plotium 则停止访问。重启 Plotium 或重新开启 MCP 后,可继续使用 -原来的 AI 会话,无需再次添加客户端。切换项目后,请先让 AI 重新查看当前项目, -再继续编辑。 - -MCP 工具注解描述工具副作用,也可供客户端审批策略参考;它们不授予 Plotium 权限, -也不取消桌面文件确认。混合的规划/执行入口采用保守提示。客户端审批应限定于需要的 -工具,并遵循[注解与授权指引](/zh-cn/reference/mcp/#工具-annotations-与客户端审批)。 - -AI 建图前,Plotium 会要求它先和你确认这张图要表达什么(比较各组大小、趋势、分布、 -两个量的关系、组成占比、变化或比值、局部细节),以及这张图要支撑的那句结论。可以用 -自己的话回答,也可以让 AI 先给出它的理解再由你修改。意图随图保存,不会改变图的画法; -之后可在对象检查器 **Chart** 区的 **Advanced** 中修改。让 AI 检查图时,它会对照这个目的, -建议更合适的图型,但不会自行更换。对带误差棒的曲线,它还会问每个数据点由几次重复得到, -误差棒表示 SD、SEM 还是 95 % CI。参见[建图](/zh-cn/reference/mcp/#从已导入表格创建原生单图)。 - -要为不同曲线设置颜色或标签,可要求一个原子 `properties.set_many` 计划,包含 -1–200 项准确的目标/属性/值写入,作为一个 Undo 步骤提交。直接复用 `plot.create` -返回的完整目标,参见[批量样式指引](/zh-cn/reference/mcp/#一次计划设置多条曲线的样式)。 -错误后遵循[恢复动作](/zh-cn/reference/mcp/#恢复动作与未知结果)。排队的任务或保存仍未 -完成;先检查回执再宣告完成。拒绝、取消或断连不授权自动重算、文件写入或重放已消费 -计划。每个新的文件请求仍需桌面确认其准确路径和覆盖范围。 - -### 看懂机器人图标 - -将鼠标停在机器人图标上,可查看项目、权限和最近活动;点击可打开连接设置。 -Ribbon 折叠后仍可使用此图标。 - -| 外观 | 状态 | 你可以做什么 | -| --- | --- | --- | -| 灰色、短斜线 | Off(已关闭) | 需要连接时开启 **Enable MCP** | -| 蓝色、空心点 | Starting / Ready(启动中/就绪) | 等待启动,或从客户端发送请求 | -| 绿色、实心点 | Active(活跃) | 最近 30 秒有客户端活动;不代表任务已完成 | -| 橙色、感叹号 | Needs attention(需要处理) | 打开连接设置,查看错误并按提示处理 | - -### 连接不成功时 - -| 遇到的情况 | 建议操作 | -| --- | --- | -| Plotium 找不到 Codex 或 Claude Code | 通过 **Installation help** 安装,或用 **Choose executable…** 选择客户端程序,再点击 **Add** | -| 错误提示缺少 Node.js | 检查客户端的 Node.js 安装,或选择独立的客户端可执行文件后重试 | -| 已有另一个名为 `plotium` 的服务器 | 先检查现有配置;确定要替换时点击 **Back up and replace this entry**。Plotium 会备份原条目,不改动其他服务器 | -| 显示 **Configured**,但没有客户端活动 | 重载客户端的 MCP 配置或重启客户端,再发送上面的首次请求;检查客户端是否禁用或阻止了该服务器 | -| 客户端报告项目状态过时 | 让客户端重新调用 `plotium_get_state` 后再继续 | -| 提示连接由另一个 Plotium 实例提供 | 使用提供连接的实例,或退出该实例,让当前实例接入。切换窗口焦点不会切换 AI 访问的项目 | -| Windows 更新时提示连接器被占用 | 退出正在使用 Plotium 的 AI 客户端,再在连接设置中点击 **Retry** | -| 缺少连接器或 Claude Desktop 扩展 | 重新解压完整 Plotium 发行包,将其中的文件保留在一起 | - -启动失败后会自动重试。连接设置会显示最近操作和错误;解决原因后,如页面提供 -**Retry**,可点击重试。编辑过程中断线时,先检查项目再让 AI 重试:修改可能已经 -完成,再次执行可能产生重复内容。 - -### 其他客户端与技术说明 - -使用其他本机 MCP 客户端时,展开 **Manual configuration and diagnostics**,点击 -**Copy stable stdio configuration**,将复制的配置用于客户端。此连接适用于同一台 -电脑、同一用户账户下的客户端,不支持远程连接或 Windows 与 WSL 之间的跨环境访问。 - -手动注册命令、工具参数、调用示例和限制见 [MCP 接口参考](/zh-cn/reference/mcp/)。 diff --git a/docs/src/content/docs/zh-cn/guides/axes.md b/docs/src/content/docs/zh-cn/guides/axes.md new file mode 100644 index 00000000..f8ef0142 --- /dev/null +++ b/docs/src/content/docs/zh-cn/guides/axes.md @@ -0,0 +1,111 @@ +--- +title: 坐标轴与刻度 +description: 设置坐标轴标题和范围、对数轴与断轴、第二 y 轴以及刻度线。 +--- + +Plotium 无需设置就按印刷习惯绘制坐标轴:只保留左轴和底轴、向外的短刻度、随显示 +范围调整的刻度精度,以及图框变窄或变矮时抽稀的刻度密度(矮图框只要放得下仍保留 +两个 y 刻度)。选中单个图形后,在对象检查器的 **Axes** 区域修改需要的设置。不显示 +坐标轴的图表没有轴设置。 + +## 标题与范围 + +在 **Axes** 区域可以覆盖 X/Y 轴标题或数值范围。标题留空或范围保持 **Auto**,即可 +继续使用由数据自动推导的值。手动范围会成为该轴的完整范围:缩放和平移仍限制在其中, +双击图内即回到这个手动范围。分类轴不提供范围控制。 + +轴标题支持真正的上下标,见[上标与下标](/zh-cn/guides/legends-and-lines/#上标与下标)。 + +要隐藏某条轴上的文字,使用 **X text** 与 **Y text** 两行:它们分别切换 +**Tick labels** 和 **Title**,**Automatic** 则让该轴恢复为两者都显示。要在一格格 +分图中一次隐藏内侧轴文字,见[精简内侧轴](/zh-cn/guides/multi-panel-figures/#精简内侧轴)。 + +## 等比例坐标 + +**Equal x/y scale (1:1)** 让两个坐标轴使用相同的单位/屏幕距离,适用于 Nyquist 图、 +AFM 图像和 2D NMR 谱等。绘图区在框内缩成相应形状,坐标范围保持不变。它要求两条轴 +都是线性、非分类轴且没有右 y 轴;共用 x 轴堆叠中的图不能开启。AFM 图像默认开启; +对于真正的 2D NMR 谱,Plotium 在导入时设定初始值,此后可单独修改,且不会改变导入 +偏好设置。 + +## 边框 + +同一 **Axes** 区域的 **Frame**(边框)可选 *Left and bottom*(左、下两条轴)或 +*All four sides*(四边框)。四边框会补上顶部和右侧轴线,线宽和颜色与其他坐标轴 +相同;刻度和刻度标签仍只在左轴和下轴。多数图默认只有左、下两条轴,等高线图、 +热图等 2D 图默认是四边框。 + +## 对数轴 + +**Axes** 区域更多选项中的 **X scale**、**Y scale** 可把折线图、散点图和棒状图的 +坐标轴在 *Linear*(线性)与 *Logarithmic*(对数)之间切换。对数轴以 10 的幂 +(10¹、10²……)作刻度,轴较短时自动稀疏,可见的 10 的幂少于两个时改用普通刻度; +开启次刻度后,次刻度位于每个数量级的 2–9 倍处。对数轴的自动范围只依据正值数据。 +零和负值在对数轴上没有位置:折线会在该处断开,延伸到轴以下的误差棒和棒状线止于 +图框边缘。对数轴的手动范围下限必须大于零。缩放和平移按数量级进行。分类轴、2D 图、 +柱状图与分布图以及 NMR 谱图不提供对数轴;NMR 的积分、相位和光标工具按线性 ppm 计量。 + +## 第二 y 轴 + +**Line** 区域高级选项中的 **Y axis** 可把折线或散点曲线放到图右侧的第二条 y 轴上, +用于单位或数量级不同的量。只要有一条曲线使用右轴,右轴就会出现;所有曲线都回到 +左轴后,右轴随之消失。右轴按自己的曲线自动确定范围,并绘制自己的刻度、刻度标签 +和标题;标题与左轴标题同样从下往上读,初始为第一条右轴曲线的列名和单位。 + +对象检查器中的 **Right Y axis** 区域只在图有右轴时出现,可设置右轴的标题、范围、 +对数刻度、刻度标签、显示单位和主刻度间隔。滚轮、拖动和框选缩放会让两条 y 轴按 +各自范围的相同比例一起移动,双击会让两条轴都回到完整范围,**Inspect** 光标同时 +读出指针处的 x 和左右两个 y 值。所有曲线共用一个图例。柱状曲线始终在左轴上, +参考线、标注和箭头按左轴坐标放置。表格曲线图中,每条 y 轴保持其第一条曲线的单位; +单位无法换算到该单位的曲线不能放到这条轴上。 + +## 断轴 + +**Axes** 区域更多选项中的 **X break**、**Y break** 可以断开线性数值轴:两个端点 +之间的数值不显示,轴线在断口处留空并画一对斜线。取消勾选 **None** 后,断口从当前 +范围的中间三分之一开始,再修改两个端点即可;端点必须都在轴范围之内。默认两段使用 +相同的比例尺;**X lower share** 或 **Y lower share** 可改为指定数值较小那一段占 +轴长的比例。 + +每段各自生成刻度,紧挨断口的刻度不显示,以免标签相互重叠。穿过断口的折线从断口 +一侧出去、在另一侧继续;跨过 y 断口的柱子会被截断显示。对数轴、分类轴、等比例轴、 +2D 图和 NMR 谱不能断开;有右 y 轴的图不能断开 y 轴。在共用 x 轴的堆叠中,x 断口 +会作用于所有图。 + +## 刻度位置与数字格式 + +若要指定主刻度的位置,在 **Axes** 区域的 **Advanced** 中设置 **X major tick step** +或 **Y major tick step**,右 y 轴则在 **Right Y axis** 区域设置 +**Right Y major tick step**。主刻度随后落在该轴显示单位下间隔的整数倍上——间隔 20 +给出 80、100、120——次刻度在其间均分。设为 0 恢复自动刻度。对数轴、分类轴和断轴 +不适用此设置;间隔会画出少于 2 个或超过 100 个刻度时退回自动刻度。更换显示单位会 +清除间隔。 + +若要把较大的刻度值写成 `1,000` 而不是 `1000`,在同一区域的 **Advanced** 中打开 +**X thousands separator** 或 **Y thousands separator**。当该轴范围达到 ±10,000 时, +其刻度标签会完整写出(如 `15,000`),不再使用统一的 ×10ⁿ 倍数;若该轴达到 10¹⁵ +及以上,或其最大值小于 0.001,则仍保留倍数。 + +## 刻度线与坐标轴线 + +刻度线和坐标轴线对文档中所有图统一设置,位于 **Figure typography** 分区的高级设置中 +(见[字体、主题与样式](/zh-cn/guides/themes-and-styles/#图形排印)): + +- **Axis line width**——坐标轴线与刻度线的线宽,0.05 到 10 pt,默认 1 pt。 +- **Tick length**——刻度长度,0 到 20 pt,默认 3 pt。 +- **Tick direction**——刻度方向,默认 *Outward* 朝外,可选 *Inward* 朝内。刻度 + 朝内时伸进绘图区,刻度标签随之贴近坐标轴线。 +- **Minor ticks**——在两条坐标轴相邻主刻度之间画出相应数量的无标签子刻度(0 到 9, + 默认 0,即不显示)。子刻度长度为主刻度的一半,线宽和方向与主刻度相同。分类轴以及 + 主刻度少于两个的轴不画子刻度。 + +## 使用 AI 客户端 + +也可以让连接到 Plotium 的 AI 客户端替你完成,例如: + +> 在名为 Kinetics 的图上把 y 轴改成对数轴,x 范围设为 0–120 s。应用之前先给我看预览。 + +> 把 Temperature 这条曲线放到右侧的第二条 y 轴上,轴标题写 Temperature (K)。 + +你手动设置过的值会保留,除非你明确让 AI 改;整个修改是一步 Undo。同意之前请先看 +预览。参见[权限、审阅与撤销](/zh-cn/ai/control-and-review/)。 diff --git a/docs/src/content/docs/zh-cn/guides/choosing-a-tool.md b/docs/src/content/docs/zh-cn/guides/choosing-a-tool.md index 68729012..3777d295 100644 --- a/docs/src/content/docs/zh-cn/guides/choosing-a-tool.md +++ b/docs/src/content/docs/zh-cn/guides/choosing-a-tool.md @@ -17,6 +17,8 @@ Plotium 有几个名字相近的分析工具。从你想测量什么出发: | 用数学模型拟合 x-y 数据 | **曲线拟合** | 数据表(含系列表) | 带不确定度与诊断的参数 | | 构建化学位移 × 扩散系数图 | **DOSY…** | 具有有效扩散输入的频域谱堆叠 | 逐列或 ILT DOSY 图 | | 组间比较、相关性或正态性检验 | **统计** | 数据表 | 已保存的统计结果 | +| 直接把复数 FID 拟合为共振组分 | **CRAFT…**(Process 菜单) | 带原始 FID 的 1D NMR 采集 | 各组分的频率、幅度、线宽与相位 | +| 从 LC–MS 数据中提取质谱或离子色谱图 | **Extract Mass Spectrum** | LC–MS 数据(Waters、WIFF、mzML) | 提取质谱与 XIC | 两个工具都像能用时的判断准则: @@ -36,5 +38,6 @@ Plotium 有几个名字相近的分析工具。从你想测量什么出发: [同核 2D 对称审核](/zh-cn/guides/symmetry-review/)、 [曲线拟合](/zh-cn/guides/curve-fitting/)、 [统计](/zh-cn/guides/statistics/),以及按数据类型的 -[伪 2D](/zh-cn/guides/pseudo-2d/)、[DOSY](/zh-cn/guides/dosy/) 与 -[电生理](/zh-cn/guides/electrophysiology/)指南。 +[伪 2D](/zh-cn/guides/pseudo-2d/)、[DOSY](/zh-cn/guides/dosy/)、 +[CRAFT](/zh-cn/guides/craft/)、[质谱](/zh-cn/guides/mass-spectrometry/)、 +[XPS](/zh-cn/guides/xps/) 与[电生理](/zh-cn/guides/electrophysiology/)指南。 diff --git a/docs/src/content/docs/zh-cn/guides/dosy.md b/docs/src/content/docs/zh-cn/guides/dosy.md index 701a7889..b6b657ba 100644 --- a/docs/src/content/docs/zh-cn/guides/dosy.md +++ b/docs/src/content/docs/zh-cn/guides/dosy.md @@ -60,8 +60,9 @@ CSV 或 TSV 文件。用空格、逗号、分号或换行分隔数值,不要 ## 拟合选定峰区 1. 显示 **Stack**,选择 **Analyze → Draw Regions**,在感兴趣的峰上绘制区域。 -2. 在 Regions 任务卡片中选择 **View extracted curves**。每个区域生成一个点系列, - 横轴为 b;有梯度数据时会保留辅助梯度列。 +2. 在 Regions 任务卡片中选择 **Extract curves**(提取曲线)准备表格;来源计算期间 + 该按钮不可用。准备好后选择 **View extracted curves**(查看提取曲线)。每个区域 + 生成一个点系列,横轴为 b;有梯度数据时会保留辅助梯度列。后台完成不会自动切换面板。 3. 在 **Curve Fit** 中确认选择了 **Diffusion (b values)**,再点击 **Run Fit**。 模型为 `I = I₀ exp(−Db)`,D 的单位为 `m²/s`。 4. 检查拟合曲线、参数不确定度及诊断。通过 **View data** 查看同步表格,或用 @@ -132,15 +133,15 @@ ILT 在每个谱列估计 D 的非负分布,可用于考察某个化学位移 这样可保留结果实际使用的输入,避免后来的默认值被静默替换进来。 -## 自动化接口 +## 使用 AI 客户端 -桌面、CLI 和 MCP 复用原生处理与科学计算语义。操作及参数 schema 见 -[MCP 科学操作与任务](/zh-cn/reference/mcp/#科学操作与任务);命令行可用 -[`tool run`](/zh-cn/reference/cli/#单步科学操作)。处理管线与方案、区域提取、 -扩散拟合及 DOSY/ILT 使用应用级任务回执,查询终态后再消费结果。后台提交是 -一个 Undo 步骤,Redo 复用结果;计算期间修改文档会使任务过期。扩散检查报告 -SI 单位和来源证据,结果检查提供分页诊断;`empty` 不代表有效科学结论。 +也可以让连接到 Plotium 的 AI 客户端完成这项分析,例如: -在桌面区域工具中,先选择 **Extract curves**(提取曲线)准备表格。来源计算期间 -提取按钮不可用;完成后选择 **View extracted curves**(查看提取曲线)打开表格。 -后台完成不会自动切换面板。 +> 检查这个 DOSY 实验的扩散分析输入,告诉我缺什么。然后拟合我画好的区域并构建 +> DOSY 图。建图之前先报告 D、它的标准误差和 R²。 + +Plotium 不会替 AI 补全缺失的扩散参数:它报告缺少什么,等你确认数值。计算完成不等于 +结果有效,请检查它报告的拟合诊断。每次计算是一步 Undo。参见 +[权限、审阅与撤销](/zh-cn/ai/control-and-review/);脚本可以通过 +[MCP 科学运算](/zh-cn/reference/mcp/scientific/)和 +[`plotium-cli tool run`](/zh-cn/reference/cli/#单步科学操作)使用同样的操作。 diff --git a/docs/src/content/docs/zh-cn/guides/exporting.md b/docs/src/content/docs/zh-cn/guides/exporting.md index 56888d21..b11eb56b 100644 --- a/docs/src/content/docs/zh-cn/guides/exporting.md +++ b/docs/src/content/docs/zh-cn/guides/exporting.md @@ -50,7 +50,8 @@ TIFF*——并且导出前的合规检查会按所选预设标出字号与线宽 选中数据集后,可从 File 菜单、Data Ribbon 选项卡或命令面板选择 **导出数据…**。对话框只显示当前数据集实际存在的内容,并提供 -**保存 CSV…**、**保存 TSV…**、**保存 XLSX…**和**复制 TSV**。 +**保存 CSV…**、**保存 TSV…**、**保存 XLSX…**和**复制 TSV**。空单元格保持为空; +`NaN`、`+Inf` 和 `-Inf` 会写成这些字面标记,因为它们是真实取值而非空白。 处理后的 NMR 数据可选择 Real、Imaginary 或 Magnitude 强度。真实 2D 与 伪 2D 均支持 **Matrix** 和 **Long**:Matrix 首行是 F2/ppm,首列是 @@ -68,3 +69,12 @@ Bootstrap 分位数。CasaXPS 结果始终标为 `Imported (CasaXPS)`,不会 则把同样的信息保存在隐藏工作表中。可见的列在 Excel、Origin 或 Prism 中正常打开, 而配套信息让 Plotium 日后能连同列类型、单位和误差棒一起重新打开该表。导出的 XLSX 文件只包含确定值,没有需要重新计算的公式。 + +## 使用 AI 客户端 + +也可以让连接到 Plotium 的 AI 客户端替你完成,例如: + +> 把这张 180 × 90 mm 的画布导出到 /Users/me/figures/figure.svg,同时导出对应的 PDF 和 300 DPI 的 PNG。不要覆盖已有文件。 + +写文件前 Plotium 会请你确认具体路径;覆盖已有文件还要单独勾选。导出不会保存项目。 +参见[权限、审阅与撤销](/zh-cn/ai/control-and-review/)。 diff --git a/docs/src/content/docs/zh-cn/guides/images.md b/docs/src/content/docs/zh-cn/guides/images.md new file mode 100644 index 00000000..e38d1973 --- /dev/null +++ b/docs/src/content/docs/zh-cn/guides/images.md @@ -0,0 +1,59 @@ +--- +title: 图中的图片 +description: 把显微图、照片等图片添加到图形页面和 Panel 中。 +--- + +## 添加图片 + +若要让每张图片各占一个适配大小的页面,请从 File 菜单、Ribbon 或命令面板选择 +**Add Images…**。一次可以选择多张 PNG、JPEG、TIFF、WebP 或 BMP 图片。Plotium 按文件内容而不是扩展名 +判断格式。不支持 GIF 和 SVG 图片。也可以 +直接把文件拖到画板上;即使落点位于已有页面内,每张图片仍会新建一个页面。 + +图片超过 1 亿像素或预计解码后超过 512 MiB 时,Plotium 会要求确认;超过 5 亿像素或 +2 GiB 的图片会被拒绝。 + +若要把图片放进已有 Panel,请先选中或进入未锁定的 Panel,再把文件拖入绿色轮廓。 +若要粘贴图片或复制的一组图片文件,请使用 **Paste Image**,或按 `Ctrl`/`Cmd` + +`V`。在 Windows 上,可以从文件资源管理器复制文件,也可以从 Paint 等应用复制 +图片像素。光标位于文本框中时,该快捷键仍会正常粘贴文本。 + +Plotium 创建图片页面时,会优先采用图片的 DPI 信息确定实际尺寸;没有 DPI 信息时按 +96 DPI 计算。页面宽度不超过 89 mm,高度保持图片的原始宽高比,图片会无变形地 +铺满页面。一次导入多张图片只产生一个撤销步骤;导入失败或取消不会改动项目。 + +以下格式需要使用专门的命令: + +- **Add Animated Image First Frame…** 导入动画 PNG 或 WebP 的第一帧。用 + **Add Images…** 添加动画图片时,Plotium 会提示它是动画。 +- **Add Images Without Metadata…** 先把图片转换为 PNG,以去除元数据,再添加到项目。 +- **Add All TIFF Pages…** 添加多页 TIFF 中所有可读取的页面;常规的 **Add Images…** + 只添加第一页。 + +## 调整图片 + +选中图片后,可在对象检查器的 **Image** +区域裁剪或旋转图片、调整透明度,或选择插值方式。这些调整不会改变嵌入的源图片。图片保存在 `.plotium` 项目中;复制图片不会复制其 +存储的源图,每个副本各自保留裁剪、旋转、透明度、适配和插值设置。 + +画板使用有内存上限的代理图以保持编辑流畅;SVG、PDF、EMF、PNG、JPEG、TIFF +以及 **Copy Figure** 则从项目中嵌入的原图采样。裁剪、90 度旋转、透明度、适配、 +插值、Panel 裁切和图层顺序都会与画板一致,也不依赖源文件原先所在的路径。 + +## 图片缺失或损坏 + +打开项目时,Plotium 会校验每张嵌入图片。若图片缺失、损坏或与记录不符,项目仍会打开,并在原位置保留带说明的占位项。请在对象 +检查器中使用 **Replace Image…** 修复。替换前,常规保存和出版导出会停止;若仍需 +生成审阅稿,可在导出对话框中明确允许输出带标签的占位图。 + +导出对话框对图片所做的检查见[导出](/zh-cn/guides/exporting/#导出图形)。 + +## 使用 AI 客户端 + +也可以让连接到 Plotium 的 AI 客户端替你完成,例如: + +> 把 /Users/me/images/sem.png 这张显微图放进 Panel b,按 Panel 大小适配,先给我看预览。 + +AI 可以添加本地的 PNG 和 JPEG 文件,每个文件不超过 1 MiB(解码后不超过 4 MiB), +请告诉它文件的完整路径。更大的图片请自己用 **Add Images…** 添加。修改会立即出现在 +Plotium 里,是一步 Undo。同意之前请先看预览。参见[权限、审阅与撤销](/zh-cn/ai/control-and-review/)。 diff --git a/docs/src/content/docs/zh-cn/guides/importing-data.md b/docs/src/content/docs/zh-cn/guides/importing-data.md index efcea3ae..014fc03e 100644 --- a/docs/src/content/docs/zh-cn/guides/importing-data.md +++ b/docs/src/content/docs/zh-cn/guides/importing-data.md @@ -1,30 +1,10 @@ --- title: 导入数据 -description: 支持的文件格式及打开方式。 +description: 打开仪器文件、文件夹和表格,查看导入进度,以及表格列类型如何确定。 --- -Plotium 直接读取厂商 LC–MS、NMR、XPS、AFM 与电生理格式,无需任何转换步骤。 - -## 支持的格式 - -| 格式 | 扩展名 | 说明 | -| --- | --- | --- | -| JEOL Delta | `.jdf` | 原始与已处理的 1D、2D 及参数系列;实验性支持 | -| Bruker TopSpin | `fid` / `ser` / `pdata` | 原始及已处理的 1D、2D;NUS 为实验性支持 | -| Varian/Agilent VnmrJ | `.fid` 目录 | 原始 1D、`phase=[1,2]` 的 2D,或单参数变化系列 | -| Waters MassLynx RAW | `.raw` 目录 | 已验证的低分辨率数据,包括 SQD2 数据 | -| SCIEX legacy WIFF | `.wiff` + `.wiff.scan` | 支持单样本与多样本 legacy 数据;两个文件必须放在一起 | -| Rigaku 粉末 XRD | `.rasx`、FI `.raw`、RAS_RAW `.txt` | 衍射图样、采集元数据,以及文件提供的衰减系数 | -| mzML | `.mzML` | 使用 32 位或 64 位数组的质心/轮廓谱图及 TIC、BPC、SIM 或 SRM 色谱图 | -| Bruker NanoScope AFM | `.spm` / `.pfc` | 图像、力曲线、Force Volume 与 PeakForce Capture 数据立方体 | -| JCAMP-DX | `.dx` / `.jdx` / `.jcamp` | 1D 频域 NMR 谱 | -| Axon Binary Format 2 | `.abf` | int16/float32、多通道、多 sweep,以及文件内 DAC/epoch 刺激 | -| VAMAS XPS | `.vms` | ISO 14976 `NORM` / `REGULAR` XPS 区块,支持多个测量位置与谱区 | -| CasaXPS 文本 | `.txt` | 含原始谱、背景、包络、组件和拟合参数的结构化八行头导出 | -| 表格数据 | `.csv`、`.tsv`、`.txt`、`.xlsx` | 保留列类型与空单元格;每个 XLSX 工作表导入为独立数据表 | -| Origin 项目(实验性) | `.opj`、`.opju` | 经验证的 Origin 7.0552 与 Origin 9.51 OPJ 配置中的工作表;不导入图形,`.opju` 仅作识别。见[兼容性详情](/zh-cn/reference/file-formats/)。 | -| Zip 压缩包 | `.zip` | 打包的数据文件夹 | -| Plotium 项目 | `.plotium` | 完整项目:数据、处理与排版 | +Plotium 直接读取仪器文件和表格,无需任何转换步骤。完整的格式列表以及各导入器 +读取的内容,见[支持的格式](/zh-cn/guides/supported-formats/)。 ## 打开文件 @@ -32,13 +12,14 @@ Plotium 直接读取厂商 LC–MS、NMR、XPS、AFM 与电生理格式,无需 *Open Folder…*(用于 Bruker TopSpin、Varian/Agilent VnmrJ 与 Waters MassLynx RAW 等采集目录)、 *Open Project…* 或 *Import Table…*。每个导入的数据集会出现在主侧栏中, 并自动放置到画板上。 -文件选择器可以一次选择多个 ABF。打开文件夹时会递归导入其中所有 `.abf`、 + +文件选择器可以一次选择多个文件。打开文件夹时会递归导入其中所有 `.abf`、 `.spm`、`.pfc`、`.vms`、`.wiff`、结构化 CasaXPS `.txt` 和已识别的 `.raw` -数据包;配套的 `.wiff.scan` 不会作为独立数据集导入。每个 `.raw` 目录会作为一次完整采集 -导入一次,其中的内部文件不会被当作独立数据集。对 ABF 文件,每个文件的直接 -父目录名会成为可编辑的初始 cell ID。 -CasaXPS `.txt` 按结构头内容识别,而不是只看扩展名;其他 `.txt` 仍进入表格导入。 -能量轴与拟合细节见 [XPS 工作流](/zh-cn/guides/xps/)。 +数据包。配套文件(例如 `.wiff.scan`,或 `.raw` 目录中的内部文件)不会作为 +独立数据集导入。 + +扩展名有歧义时,Plotium 按文件内容识别格式:`.txt` 只有在文件头表明是 CasaXPS 或 +Rigaku XRD 时才按这些格式打开,否则进入[表格导入](#导入表格)。 ## 查看导入进度 @@ -50,154 +31,23 @@ CasaXPS `.txt` 按结构头内容识别,而不是只看扩展名;其他 `.tx NMR 导入包含默认处理,NUS 重建可能比读取文件耗时长得多。项目文件、表格预览、 ZIP 文件和手动补录采样表的导入使用各自的导入流程。 -## 补录缺失的 NMR 采样表 +## 导入表格 -此选项适用于受支持的二维 Bruker NUS 或只采集了部分间接网格点的 JEOL 数据。 -请准备原始采样表,以及含有足够网格与校准信息、可用于核对采样表的采集文件。 - -1. 选择 **File → Import NMR with Sampling Table…**(命令面板中也可搜索), - 再选择 Bruker `ser` 或 JEOL `.jdf` 文件。 -2. 填写采样表来源或说明,以及原始间接轴的完整网格点数(包括未采样点)。 -3. 填写 **Lanes per observation**:每个所列间接点采集的分量记录数。 - 请按采集设置填写,不是填写采样表的点数。 -4. 根据原表选择 **Zero-based**(从 0 开始)或 **One-based**(从 1 开始)。 - 按采集顺序每行填写一个间接索引;每行代表该次观测的全部分量,并保留重复观测。 -5. 点击 **Validate and import**。校验失败时,根据提示与采集记录核对。 - 与已有采样表冲突、观测或分量数量不符、缺少网格或校准信息,都会阻止导入。 - -导入不会修改厂商文件。保存项目后,采样表及其来源会一并保留,重开无需原文件。 -重复坐标可以导入,但目前不能进行 [NUS 重建](/zh-cn/guides/processing/#重建非均匀采样谱)。 -脚本用法见 [CLI 声明格式](/zh-cn/reference/cli/#采样声明)。 - -## Varian/Agilent VnmrJ - -要导入原始 1D 或常规 2D 采集,请选择 **Open Folder…** 并选中 -`.fid` 目录。也可以选择 **Open File…**,再选中目录内的 `fid` -文件。请将 `fid` 和 `procpar` 保持在同一目录中。 - -也支持仅改变一个非分组参数的系列。二维数据要求 `phase=[1,2]`。分组或多个参数数组、 -其他 phase 顺序、Varian NUS、已处理谱和超过二维的数据不受支持。 -校准要求与格式限制见[文件格式](/zh-cn/reference/file-formats/#nmr-数据与项目)。 - -## mzML - -打开或拖入 `.mzML` 文件。Plotium 会将谱图导入与 Waters 数据相同的 LC–MS -数据集和图表工作流。谱图按 MS 级别和极性分组;每张 scan 仍会保留文件中可用的 -采集功能元数据,例如 mzML instrument configuration、preset scan configuration 和 -filter string。以秒或分钟记录的 -扫描时间都会换算为分钟显示。对于每张谱图,Plotium 优先使用文件提供的 TIC 和 -base-peak 摘要,而不是对 profile 采样点简单求和;同时保留摘要来自源文件还是由数组派生。 -Plotium 也会导入文件自带的 TIC、BPC、SIM 与 SRM 色谱图,包括只有色谱图而没有 -scan 谱图的采集。文件提供时,会保留 transition 的 -precursor/product m/z、极性、碰撞能量和活化方法。 -对于 MS2 及更高级谱图,Plotium 会分别保留 precursor 谱图引用、selected-ion m/z、 -selected-ion 强度与电荷、隔离窗目标与上下偏移、碰撞能量和活化方法。因此,即使 -DIA 没有 selected ion,其隔离窗目标也不会被误写成 selected-ion m/z。当前数据模型 -为每张谱图保存一个 precursor 和一个 selected ion;若文件包含更多值,导入警告会 -指出对应谱图,并说明只保留了第一个值。Scientific Script 的 scan 快照会暴露摘要 -provenance、instrument configuration、源 event 或 preset,以及 filter string。 - -TIC 与 BPC 的 provenance 分开保存。文件直接提供的 TIC 或 BPC channel 会标记为 -source chromatogram,并在其绑定的 acquisition stream 中优先使用。缺少绑定 channel -时,Plotium 会先使用每张谱图的 source summary;只有没有 source summary 时,才确定性地 -从强度数组派生 TIC,或从最大的非负峰派生 BPC。因此同一次采集中可能同时存在 source -summary 与数组派生点。多 stream 运行中未绑定的 source chromatogram 会作为独立 channel -保留,不会被猜测成某个 stream 的 TIC 或 BPC,也不会让 TIC channel 代替 BPC。field -metadata、Scientific Summary 和 Scientific Script 都会暴露最终选用的 provenance。 - -对于包含大量色谱 channel 的数据,请通过 **Extract Mass Spectrum** 或命令面板打开 -**Dataset tools → Mass spectrometry**。**Chromatogram channels** 浏览器会显示稳定的 -数量和顺序,其中 TIC、BPC 排在 SIM/SRM transition 之前。自由文本可匹配 channel -名称和 native ID;对于结构化 transition,还可按 precursor m/z、product m/z、极性、 -碰撞能量和活化方法筛选。数值输入支持精确值、`>=400` 之类的比较式,以及 -`400..500` 之类的区间。 - -选择一行会通过 Plotium 原有的 field 与 binding 流程,把当前 LC–MS 色谱图中的 series -替换为该单一 channel;质谱图绝不会被重新绑定。该操作可使用标准命令撤销,并随页面 -保存到 `.plotium` 项目。只有色谱图的采集也使用同一浏览器。没有可绘制 channel、没有 -结构化 transition metadata 或当前筛选无结果时,面板都会给出明确提示。列表采用 -虚拟化渲染,大型 scheduled-MRM 数据只创建当前可见行。 - -导入器支持小端 32 位和 64 位浮点 m/z、时间与强度数组,可不压缩或使用 zlib -压缩。Numpress、大端数组以及缺少必需数组的谱图或色谱图会使导入停止并显示错误。 - -## SCIEX legacy WIFF - -请打开或拖入 `.wiff` 文件,并将文件名末尾追加 `.scan` 的配套文件放在同一 -目录,例如 `sample.wiff` 与 `sample.wiff.scan`。Plotium 会导入原始 scan ID、 -保留时间、m/z 与强度数组、可用的 precursor 信息、极性、仪器与采集开始时间 -元数据,以及每个已验证 experiment 的独立 TIC。谱图按样本与 experiment 分成独立 -的 acquisition stream,并保留 cycle 顺序,包括零 TIC 和空 DDA 槽位。重复样本名 -不会合并,会稳定显示为 `yjs_10ppm #1`、`yjs_10ppm #2` 等后缀。 - -缺少配套文件、容器无样本或 WIFF 布局未识别时,Plotium 会明确拒绝,不会创建不完整的数据集。 -暂不支持 SCIEX `.wiff2` 与 `.timeseries.data`;请先将这些采集转换为 mzML, -再在 Plotium 中打开。 - -## Rigaku 粉末 XRD - -有 `.rasx` 时请优先打开该文件。Plotium 会同时读取实测 2theta、强度、衰减系数, -以及仪器名称、X 射线靶材、Kalpha1 波长、管电压/电流、扫描步长和扫描速度。 -初始页面显示 XRD pattern。**Processing** 中可选择 SNIP 背景扣除、 -Savitzky-Golay 平滑,以及按最大强度或积分面积归一化;这些设置与原始观测值 -都会保存在 Plotium 项目中。 - -采用 `FI` 布局的 Rigaku `.raw`,以及文件头标明 `RAS_RAW` 的 profile `.txt`, -也会作为 XRD 打开。二进制读取器会保留扫描坐标、强度、X 射线靶材、Kalpha1 -波长、管电压/电流和扫描速度。由于不同厂商会使用互不兼容的 `.raw` 格式, -Plotium 会明确拒绝其他文件签名。普通 `.txt` 仍进入表格导入预览,不会被静默改判。 - -## Waters MassLynx RAW - -请打开或拖入 `.raw` 目录本身。Plotium 会导入其中受支持的 MS 功能和光学检测器 -通道。温度、压力及其他可读取的辅助通道会保留在数据集中,但默认不绘图。 - -存在光学检测器数据时,初始页面会把 UV 通道放在活动功能的总离子流图(TIC) -上方,并共享保留时间轴。多个 UV 通道会叠加显示,图例使用文件中存储的波长, -例如 `214 nm`。若要隐藏、移动或调整该图例的排版,请选中 UV 图并使用对象检查器的 -**Legend & scales**。没有光学数据时,初始页面只显示 TIC。 - -选中 LC–MS 数据集,然后在 **Analyze(分析)** 标签中选择 **Extract Mass -Spectrum**。Plotium 会在右侧栏打开 **Dataset tools → Mass spectrometry**,并启用 -保留时间范围选择。 - -单击 TIC 或 UV 色谱图,会在 **Scan preview** 中显示保留时间最近的 MS 扫描。 -预览会标明保留时间和原始扫描编号,但不会加入页面,也不会保存为结果。选择 -**Extract current scan** 可把该扫描作为棒状谱加入页面。 - -若要从时间窗提取,请选择 **Method**,启用 **Select range**,然后在 TIC 或 UV -色谱图上拖出范围。选择 **Extract spectrum**,即可把峰顶扫描、最近扫描、平均谱 -或求和谱加入页面。每张提取谱都会记录功能、时间范围和提取方式;移动预览游标 -不会改变它,并且它会列在数据浏览器的 **Analysis** 下。 - -要创建提取离子色谱图(XIC,也称 EIC),请打开 **Dataset tools → Mass -spectrometry** 并选择 **Select m/z range**。在当前质谱图上拖出 m/z 区间, -确认显示的 m/z 区间和采集流,然后选择 **Extract ion chromatogram**。 - -生成的折线图会在每次扫描的保留时间(分钟)处显示一个点。每个点的值是 -所选 m/z 区间内的强度之和,并包含两个端点。该结果会被保存;移动扫描预览或 -选择其他采集流都不会改变它。XIC 提取不进行色谱峰积分,也不计算峰面积。 - -数据中含多个受支持的 MS 功能时,请使用 **Dataset tools → Mass spectrometry** -中的 **Acquisition stream**。初始采集流是第一个非参考 MS 功能。切换采集流、 -提取质谱和提取 XIC 都可通过标准的 Edit 命令撤销和重做。 - -Plotium 支持已使用 SQD2 数据验证的低分辨率 MassLynx 编码。如果必需的 MS 功能 -使用其他编码,导入会停止并指出相应功能和仪器。如果其余数据可读,不受支持的 -可选功能或参考功能会产生导入警告。 - -Plotium 不提供 LC–MS 处理流程。导入的数据、当前采集流、检测器通道、提取质谱、 -提取离子色谱图和页面排版都会保存在 `.plotium` 项目中。扫描预览是临时状态, -重新打开项目后会被清除。 - -表格也可以直接从剪贴板粘贴:`Ctrl` + `Shift` + `V` 会把逗号、制表符或 -分号分隔的文本变成新数据表。 +对 CSV、TSV、带分隔符的 `.txt` 或 XLSX 文件,选择 **Import Table…**。表格也可以 +直接从剪贴板粘贴:`Ctrl` + `Shift` + `V` 会把逗号、制表符或分号分隔的文本变成 +新数据表。 无论从文件还是剪贴板导入表格,都会先打开 **Review table import** 对话框。它会 列出每列推断出的类型和单位、该列是否允许空单元格、前几行的预览,以及任何导入 诊断。选择 **Import table** 导入,或选择 **Cancel** 保持项目与最近文件列表不变。 含多个工作表的 XLSX 会额外提供 **Table** 选择器,可逐一预览工作簿中的各工作表; -一次 **Import table** 会把它们作为独立数据表全部导入。 +一次 **Import table** 会把它们作为独立数据表全部导入。预览尚未处理完时,再选择 +第二个表格文件会被拒绝;请先完成或取消当前预览。 + +导入的表格会以数据表的形式出现在画板上,旁边是一个放它的图的新页面。如何选择 +图中显示哪些列,见[绘图与图表类型](/zh-cn/guides/plots-and-charts/)。 + +### 列类型如何确定 Plotium 会区分布尔、整数、小数、文本和空单元格。混合了不同类型、或取值含糊的列会 保留为文本而不会被丢弃。除非文件自带 Plotium 的类型信息(见下),只有毫不含糊的 @@ -209,59 +59,62 @@ Plotium 会区分布尔、整数、小数、文本和空单元格。混合了不 几行。如果各列交替组成长度不同的 x/y 列对(例如每条曲线有自己 x 列的 Source Data),诊断会列出这些列对。 +### 误差棒列 + +要为自己的数据添加误差棒,请在 CSV 或 TSV 中紧跟某个 y 列之后放一列 +`_sigma`,存放每个点的不确定度(零或正数);导入时 Plotium 会把它作为对称标准差 +关联到该 y 列。 + +### Origin 导出的 CSV + 从 Origin 导出的 CSV 开头有标签行(`Short Name`、`Long Name`、`Units`、 `Comments`)和一列行号。Plotium 用 Long Name 给列命名(没有时依次用 Comments、 Short Name),把单位加在括号里,把 Origin 的上标、下标和希腊字母写法转成正常字符 (`cm\+(-1)` 变成 cm⁻¹),把 Comments 保存在列上,并去掉行号列。如果 Origin 只导出了 一列、没有 x 值,就保留行号作为 x 列,并在诊断中给出警告。 +Origin 项目文件(`.opj`)也在同一预览中打开;见 +[Origin 项目](/zh-cn/guides/supported-formats/#origin-项目实验性)。 + +### Plotium 导出的表格 + Plotium 导出 CSV 或 TSV 时,会在旁边写入一个配套的 `.plotium-schema.json` 文件; 复制 TSV 时(Windows 上)也会把同样的信息与纯文本一起放到剪贴板。重新打开其中 任一种,都能恢复原始的列类型、单位和误差棒关系。没有该配套信息时,Plotium 会在 导入时推断类型,并在检查对话框中标出含糊之处。 +### Excel 工作簿 + 在 `.xlsx` 工作簿中,每个可见工作表都导入为独立数据表,Plotium 会把类型信息保存在 一个隐藏工作表中。Plotium 读取 Excel 为每个公式缓存的结果,但不会自行重新计算公式; 没有缓存值的公式单元格会以空导入,并列入诊断。导出的 XLSX 文件只包含确定值, 因此不依赖 Excel 重新计算。 -## Origin 项目导入(实验性) - -Origin 的 `.opj` 与 `.opju` 文件会出现在 *Open File…* 和 *Import Table…* -两个入口的文件选择器中。这两个入口均根据文件内容与签名识别格式, -而不是只看扩展名。 - -受支持的 `.opj` 成功生成工作表后,Plotium 会打开现有的 **Review table -import** 预览,可先检查每个候选数据表。确认一次会导入全部候选数据表; -取消则保持当前项目和最近文件列表不变。预览尚未处理完时,若再选择第二个 -表格路径,Plotium 会给出明确提示并拒绝该操作;请先完成或取消当前预览。 - -无需安装或启动 Origin,Plotium 也不会自动化或调用 Origin。严格且以证据为限的 -兼容范围见[文件格式](/zh-cn/reference/file-formats/)。 +## 补录缺失的 NMR 采样表 -## 伪 2D 实验 +此选项适用于受支持的二维 Bruker NUS 或只采集了部分间接网格点的 JEOL 数据。 +请准备原始采样表,以及含有足够网格与校准信息、可用于核对采样表的采集文件。 -DOSY、T1、T2 实验会根据采集参数自动识别,并获得专属的分析工具——参见 -[伪 2D 分析](/zh-cn/guides/pseudo-2d/)和 [DOSY 扩散分析](/zh-cn/guides/dosy/)。 -缺失的扩散参数可在导入后通过 **DOSY** 任务卡片补充。 +1. 选择 **File → Import NMR with Sampling Table…**(命令面板中也可搜索), + 再选择 Bruker `ser` 或 JEOL `.jdf` 文件。 +2. 填写采样表来源或说明,以及原始间接轴的完整网格点数(包括未采样点)。 +3. 填写 **Lanes per observation**:每个所列间接点采集的分量记录数。 + 请按采集设置填写,不是填写采样表的点数。 +4. 根据原表选择 **Zero-based**(从 0 开始)或 **One-based**(从 1 开始)。 + 按采集顺序每行填写一个间接索引;每行代表该次观测的全部分量,并保留重复观测。 +5. 点击 **Validate and import**。校验失败时,根据提示与采集记录核对。 + 与已有采样表冲突、观测或分量数量不符、缺少网格或校准信息,都会阻止导入。 -膜片钳 sweep、滤波、时间窗统计、刺激与 IV 分析见 -[电生理](/zh-cn/guides/electrophysiology/)。 +导入不会修改厂商文件。保存项目后,采样表及其来源会一并保留,重开无需原文件。 +重复坐标可以导入,但目前不能进行 [NUS 重建](/zh-cn/guides/processing/#重建非均匀采样谱)。 +脚本用法见 [CLI 声明格式](/zh-cn/reference/cli/#采样声明)。 -## Bruker NanoScope AFM +## 使用 AI 客户端 -Plotium 可导入 NanoScope `.spm` 图像、力曲线与 Force Volume 网格,以及 -PeakForce Capture `.pfc` 数据立方体。图像通道按文件记录的扫描尺寸和物理单位 -绘制成地图,并锁定纵横比。力曲线按 approach 与 retract 两段分别绘制;文件中 -记录了偏转灵敏度时,纵轴为以纳米计的偏转量,否则曲线保持文件中存储的单位。 -Plotium 按采集原样显示数据——不会推断接触点、压痕或模量,也不会拟合接触力学 -模型。 +也可以让连接到 Plotium 的 AI 客户端替你导入数据,例如: -PeakForce Capture 文件旁通常保存着一个 AllImages `.spm` 导出文件。Plotium 会 -找到这个配套文件,核对其图像网格与力网格一致后,把两者作为一个数据集导入; -打开文件夹时这样的文件对也只导入一次,不会成为两个数据集。默认画布会把通道 -地图和网格中心像素的力曲线并排放置。找不到配套文件、或其网格不一致时, -`.pfc` 文件仍会导入,只是仅含力曲线。 +> 导入 `/absolute/path/experiment.csv`。时间单位是 s,电流单位是 mA。画图之前先告诉我有哪些列。 -PeakForce Capture 曲线是逐像素采集的原始信号。模量等派生 QNM 地图作为独立的 -图像通道导入;Plotium 不会从曲线重新计算这些地图。 +AI 客户端可以导入你用完整路径指明的仪器文件和 CSV、TSV 或 XLSX 表格。单位只按你说明的来, +Plotium 不会猜。整次导入是一步 Undo;导入失败的文件不会在项目里留下任何内容。 +画图之前请先核对它报告的列和单位。参见[权限、审阅与撤销](/zh-cn/ai/control-and-review/)。 diff --git a/docs/src/content/docs/zh-cn/guides/layout-and-export.md b/docs/src/content/docs/zh-cn/guides/layout-and-export.md deleted file mode 100644 index 932d6396..00000000 --- a/docs/src/content/docs/zh-cn/guides/layout-and-export.md +++ /dev/null @@ -1,408 +0,0 @@ ---- -title: 画板与页面排版 -description: 在无限画板上排布图形,并按期刊规范设定页面尺寸。 ---- - -## 画板 - -图形放置在按页面组织的无限画板上。拖动图框时会自动吸附到页面网格、 -页边距以及相邻图框的边缘;吸附可在 **Arrange** 页签中关闭。**Arrange** 页签还提供 -对齐(选中两个及以上图框)、水平 / 垂直分布(三个及以上)、层叠顺序, -以及 *Tidy up frames*(一键整理)命令。 - -在画板空白处拖动可框选页面和工作表图框。按住 `Shift` 可追加框内图框,按住 -`Ctrl`(macOS 上为 `Cmd`)可切换框内图框。拖动任一所选图框的标题栏会移动 -整个选择,并可作为一步撤销。在 Canvas 列表中,`Shift` + 单击选择连续区间, -`Ctrl` + 单击添加或移除单个画布。`Ctrl` + `A` 会根据最近使用的区域全选图框 -或画布。 - -## 科学摘要与备注 - -Plotium 会在画板中每个页面的下方自动概述当前绘制的数据。对于多 Panel 页面, -共同信息只显示一次,其余内容跟在相应的 Panel 标签后。 - -打开 **Canvas settings** 可以添加页面备注;也可以选中 Panel 后编辑其 -**Note**。备注显示在摘要之后,不会包含在导出结果中。使用 -**Show summary below page** 可以显示或隐藏整个画板专用信息区块。 - -## 添加外部图片 - -若要让每张图片各占一个适配大小的页面,请从 File 菜单、Ribbon 或命令面板选择 -**Add Images…**。一次可以选择多张 PNG、JPEG、TIFF、WebP 或 BMP 图片。也可以 -直接把文件拖到画板上;即使落点位于已有页面内,每张图片仍会新建一个页面。 - -若要把图片放进已有 Panel,请先选中或进入未锁定的 Panel,再把文件拖入绿色轮廓。 -若要粘贴图片或复制的一组图片文件,请使用 **Paste Image**,或按 `Ctrl`/`Cmd` + -`V`。在 Windows 上,可以从文件资源管理器复制文件,也可以从 Paint 等应用复制 -图片像素。光标位于文本框中时,该快捷键仍会正常粘贴文本。 - -Plotium 创建图片页面时,会优先采用图片的 DPI 信息确定实际尺寸;没有 DPI 信息时按 -96 DPI 计算。页面宽度不超过 89 mm,高度保持图片的原始宽高比,图片会无变形地 -铺满页面。一次导入多张图片只产生一个撤销步骤;导入失败或取消不会改动项目。 - -以下格式需要使用专门的命令: - -- **Add Animated Image First Frame…** 导入动画 PNG 或 WebP 的第一帧。 -- **Add Images Without Metadata…** 先把图片转换为 PNG,以去除元数据,再添加到项目。 -- **Add All TIFF Pages…** 添加多页 TIFF 中所有可读取的页面;常规的 **Add Images…** - 只添加第一页。 - -导入尺寸很大的图片前,Plotium 会要求确认。选中图片后,可在对象检查器的 **Image** -区域裁剪或旋转图片、调整透明度,或选择插值方式。这些调整不会改变嵌入的源图片。 - -画板使用有内存上限的代理图以保持编辑流畅;SVG、PDF、EMF、PNG、JPEG、TIFF -以及 **Copy Figure** 则从项目中嵌入的原图采样。裁剪、90 度旋转、透明度、适配、 -插值、Panel 裁切和图层顺序都会与画板一致,也不依赖源文件原先所在的路径。 - -若嵌入图片缺失或损坏,项目仍会打开,并在原位置保留带说明的占位项。请在对象 -检查器中使用 **Replace Image…** 修复。替换前,常规保存和出版导出会停止;若仍需 -生成审阅稿,可在导出对话框中明确允许输出带标签的占位图。 - -## 使用图版面板 - -使用 Arrange 菜单或命令面板中的 Panel 命令,可以制作多 Panel 图版。你可以创建 -空 Panel、把所选对象组成 Panel,也可以复制、合并、拆分、解散或删除 Panel。 -在 Layers 中展开 Panel,即可查看其中的对象。 - -单击 Panel 内任意位置可将其选中,随后可以拖动整个 Panel,或用四角控制点连同 -其中内容一起缩放。按住 `Shift` 单击可选择多个 Panel。若要编辑 Panel 内的对象, -请双击 Panel 或按 `Enter` 进入。点击页面上方的面包屑或按 `Esc` 可返回页面。也可 -按住 `Ctrl`/`Cmd` 单击对象,无需先进入 Panel 即可直接选择它。 -缩小时,若其中某张图的数据区会被坐标轴、刻度和色标挤占,缩放就会停在那里。 -移动或缩放 Panel 或图时,它的绘图区也会吸附到其他图的绘图区边缘;即使刻度标签宽度 -不同,坐标轴也能对齐。 - -关闭 **Clip contents to panel** 时,内容可以超出 Panel 和页面边界;拖动可见内容即可 -将它移回。开启裁剪时,拖动或缩放会确保内容在 Panel 内仍可选中。对象重叠时, -拖动会作用于最上层的可见对象。 - -若要交换同一 canvas 中的两个 Panel,将其中一个拖到另一个上面,待两个位置高亮后 -松开。两个 Panel 会交换位置和尺寸,内部内容随目标框缩放;整个交换可一步撤销。 -隐藏或锁定的 Panel 不能作为交换目标,多 Panel 拖动仍保持整体移动。 - -在 Panel 内,对象会吸附到 Panel 边缘和其他对象。若要把对象移入另一个未锁定的 -Panel,请将它拖到目标 Panel 上,待目标高亮后松开。也可以在 Layers 中把对象行 -拖到 Panel 行。若目标采用 Stack 或 Grid 布局,内容会在移入后重新排列。隐藏对象 -仍可在 Layers 中选择;锁定对象可以选择,但不能编辑。 - -对象检查器中的 Panel 设置可控制可见性、锁定、裁剪、标签和布局。**Vertical -Stack**、**Horizontal Stack** 与 **Grid** 会按选定的间距、内边距和对齐方式排列 -内容;**Shared X Stack** 把多张图上下堆叠在同一条 x 轴上,见 -[共享 x 轴堆叠](#共享-x-轴堆叠)。页面有多个可见 Panel 时,自动字母标签才会出现,并按阅读顺序排列:从上到下 -逐行排列,同一行内从左到右。移动或添加 Panel 后,字母会立即更新。选择 -**Locked auto** 可保留 Panel 当前的字母,取消 **Participates in sequence** 可让它 -不参与编号、不显示字母。标签位于图片上时会自动切换黑白颜色以保持清晰;图的 y 轴标题 -会在需要时自动下移,避免与字母重叠;若图太矮无法下移,整幅图会移到字母右侧。手工标签和锁定 -标签在单 Panel 页面中仍会显示。 -若要一次隐藏页面上的所有字母,请在 **Canvas settings** 中取消 -**Show panel letters**;字母会保留原有编号,重新开启后恢复原样,隐藏期间 -轴标题也不再为其预留空间。 - -将单个 Panel 完全拖离所有 canvas,并在外部持续停留 0.5 秒,即可准备新建 canvas。 -预览会先显示进度条,随后变为绿色边框,并显示 **Release to create canvas**。 -此时松手,整个 Panel 会移入当前位置新建的 canvas,页面尺寸与 Panel 一致。 -内容、标签、备注和内部布局均保留,源 canvas 保持原位;移动和新建可一起撤销。 -Panel 任一部分重新进入 canvas 都会重置计时。调整尺寸或拖动多个 Panel 时不会 -新建 canvas,按 `Esc` 可取消拖动。 - -## 画布尺寸 - -活动页面左上角上方会显示一个尺寸标签,内容为当前尺寸和匹配到的预设 -(例如 *89 × 60 mm · Nature · Single column*)。点击它、在 Figure Ribbon -选项卡中使用 **Canvas Size & Settings…**,或在命令面板中运行任意 -"Canvas Size" 条目,都可以更换尺寸。 - -预设列表支持搜索并按组显示:期刊图幅宽度(Nature、Science、Cell Press、 -ACS、Elsevier、PNAS 和 IEEE,数值取自各出版社的作图规范)、纸张尺寸 -(支持纵向/横向切换)、演示文稿幻灯片、最近使用过的条目,以及你自己保存 -的自定义尺寸。期刊预设只锁定页面*宽度*——高度由内容决定,上限为该期刊 -的最大图幅深度;页面超过该深度时会显示警告。 - -默认情况下,更改尺寸不会移动或缩放内容;如果对象超出页面,尺寸标签一栏 -会出现溢出警告,单击即可把内容等比缩小到页面内(可撤销,字号保持物理磅 -值不变)。勾选 **Scale content when applying sizes** 后,应用预设时对象 -会随页面一起缩放。 - -另有两项自动辅助: - -- **Auto height**(自动高度)保持宽度不变,页面高度跟随内容深度变化, - 并以期刊最大深度为上限。 -- 当布局网格设置为两列及以上、而页面仍是单栏宽度时,会出现一条可关闭的 - 提示,单击即可切换到同一期刊的全宽——它绝不会自行改变页面尺寸。 - -导出对话框会预先选中匹配的期刊预设,因此按栏宽制作的页面默认按该宽度 -导出。 - -## 分图之间的间距 - -多分图的版面,只有各分图的数据区间隔均匀才好看;但每个图为刻度标签和 -轴标题预留的空间各不相同,图框等距往往看起来并不等距。 -**Canvas Size & Settings…** 里既设定想要的间距,也设定它按什么来量。 - -**Minimum spacing**(最小间距)就是这个间距本身,单位与画布一致; -**Tight**(2 mm)、**Normal**(5 mm)、**Spacious**(10 mm)三个预设可 -直接填入常用值。 - -**Spacing basis**(间距依据)决定这个间距量的是哪两处之间: - -- **Visual**(默认)量的是相邻两图数据区之间的距离,并把夹在中间的刻度 - 标签和轴标题计算在内,因此 y 轴标题较长的分图能自动获得所需空间。该值 - 是下限:实际间距只会更宽,不会更窄,图框也不会重叠。相邻两图的轴文字 - 之间始终至少相隔 8 pt。 -- **Frame** 量的是图框之间的距离,不计轴文字。图框会严格按设定值排开, - 但各对分图数据区之间的可见空隙会随标签长短而变化。 - -图框止于最外侧的文字、刻度或轴线,自身不再留空白边。因此贴着页面边缘的 -分图会直达导出图的边缘,适合页面即成品图的期刊尺寸。 - -凡是由 Plotium 自动摆放图形的场合都遵循该依据——**Apply grid**,以及把图形 -拖到已有图形的页面上时的自动平铺。 - -把图拖到另一页面,即把它移到该页并重新平铺目标页。拖动过程中图形跟随 -指针移动,按下时抓住的那一点始终停在光标下,目标页面上同时画出松手后 -各图所在的位置。若目标页面上已有两个及以上的图,整页会重排成均匀网格, -拖入的图落在指针所指的那一格里。 - -如果这次移动把源页面清空,Plotium 会随本次拖放一并删除该页面,移动与删除 -同属一步撤销/重做。释放鼠标时按住 `Alt` 则保留这个空页面;操作历史窗口会提示 -当前这次拖放按住 `Alt` 会变成哪种结果。若希望默认保留空的源页面,可在 -偏好设置 → General 中打开 **Keep source canvas when tiling its last -object**——此后按住 `Alt` 就只为这一次拖放删除空页面。 - -使用 Select 工具时,每条非零页边距都会画成一条贯穿页面的虚线,标示出正在 -排版的内容区;设为 0 的一边不画线。打开布局网格会另外显示单元格轮廓, -拖动时出现的吸附参考线使用对比色。 - -## 精简内侧轴 - -一格格分图共用同一套坐标轴时,每个分图都重复刻度数字和轴标题只会浪费 -版面。**Simplify Inner Axes**(精简内侧轴)只在每列最下方的图上保留 x 轴 -文字,只在每行最左侧的图上保留 y 轴文字;轴线和短刻度在所有分图上都保留。 - -两种用法: - -- 在画布设置中勾选 **Apply grid** 旁的 **Simplify inner axes**,排布与精简 - 合并为一次可撤销的操作。图框会按精简后的坐标轴重新丈量,因此各分图能 - 占用原先被隐藏文字占据的空间。 -- 对已经排好的图形,可从 Arrange Ribbon 选项卡、画布右键的 Arrange 菜单 - 或命令面板运行 **Simplify Inner Axes**。它要求至少有两个图形已对齐成 - 网格;否则操作历史窗口会提示需要先做什么。 - -若要让某个分图重新显示文字,选中它后在对象检查器的 **Axes** 区域操作: -**X text** 与 **Y text** 两行可分别切换 **Tick labels** 和 **Title**, -**Automatic** 则让该轴恢复为两者都显示。 - -若要把较大的刻度值写成 `1,000` 而不是 `1000`,请在同一 **Axes** 区域展开 -**Advanced**,打开 **X thousands separator** 或 **Y thousands separator**。 -当该轴范围达到 ±10,000 时,其刻度标签会完整写出(如 `15,000`),不再 -使用统一的 ×10ⁿ 倍数;若该轴达到 10¹⁵ 及以上,或其最大值小于 0.001, -则仍保留倍数。智能体可通过 -`object.axes.x_thousands_separator` 与 `object.axes.y_thousands_separator` -属性设置同一选项。 - -若要指定主刻度的位置,在同一区域的 **Advanced** 中设置 **X major tick step** 或 -**Y major tick step**,右 y 轴则在 **Right Y axis** 区域设置 -**Right Y major tick step**。主刻度随后落在该轴显示单位下间隔的整数倍上—— -间隔 20 给出 80、100、120——次刻度在其间均分。设为 0 恢复自动刻度。对数轴、 -分类轴和断轴不适用此设置;间隔会画出少于 2 个或超过 100 个刻度时退回自动刻度。更换显示单位会清除间隔。智能体使用 -`object.axes.x_major_step`、`object.axes.y_major_step` 与 -`object.axes.y2_major_step`。 - -## 共享 x 轴堆叠 - -Shared X Stack(共享 x 轴堆叠)把一个 Panel 里的两张及以上的图上下排列、共用 -一条 x 轴,例如 XRD 主图加下方的标准卡竖线图,或把几条光谱分开摆放。每张图保留 -自己的 y 轴、图例和图型。 - -有两种进入方式: - -- 选中装有两张及以上图的 Panel,在 Panel 检查器的 **Layout** 列表、 - **Edit ▸ Panel** 菜单或命令面板中选择 **Shared X Stack**。 -- 选中多个各装一张图的 Panel,运行 **Stack with Shared X**:这些 Panel 会合并到 - 第一个 Panel 中,并按页面上的上下位置堆叠,整个操作一步撤销。 - -堆叠后: - -- 各图填满 Panel 宽度,内部边界上下紧贴。间距初始为 0 pt;在 Panel 检查器中调大 - **Gap** 可以分开摆放,同时保持对齐。 -- 所有图的绘图区共用同一条左边缘和右边缘,无论 y 刻度数字多宽,y 轴标题都在一条 - 竖线上。每张图各自决定是否有右 y 轴,有右轴的图的右轴标题也同样对齐。 -- 只有最下面的图绘制 x 刻度数字和 x 轴标题,只有最上面的图绘制图标题。两张图 - 相接处的 x 刻度朝内;最下面的 x 轴保持你设定的刻度方向。下方图 y 轴的 ×10ⁿ - 倍数移到其绘图区左上角内侧,落在共用边界上的 y 刻度数字不再绘制。 -- 各图共用一个 x 视窗。进入堆叠时,会给每张图设置一个覆盖全部数据的 x 范围, - 并统一使用最上面那张图的 x 主刻度间隔,因此各图须先使用相同的 x 刻度类型(线性或对数)。所有图都跟随最下面那张图的 - x 方向:ppm 轴从右到左的 NMR 谱堆叠在升序图上方时,会改为从左到右绘制。 -- 在任一张图上缩放或平移 x,其他图会一起移动。在任一张图上修改 x 范围、对数刻度、 - x 显示单位、千位分隔符或主刻度间隔,会同时改到堆叠中的所有图,并合为一次撤销;若其中某张图 - 不接受该修改(例如 NMR 谱不能使用对数轴),整个修改会被拒绝。 -- 从上到下的顺序就是 Panel 内容顺序。每张图的高度决定它在堆叠中所占的比例:在 - 画布上拖动某张图的下边框,即可让它比其他图更高或更矮。 -- 整个堆叠是一个 Panel,只有一个面板字母。 - -画布、操作历史中的检查以及所有导出都使用同一套堆叠几何。要退出堆叠,把布局改回 -**Free** 或 **Vertical Stack** 即可,各图会重新绘制自己的 x 轴和 x 方向。共用的 -x 范围会保留,直到你把 **X range** 改回 **Auto**。 - -## 堆叠与多数据集图 - -一个图框可以同时显示多个 1D 数据集——可叠加显示,也可以按可调的垂直 -间距与 3D 错切堆叠。2D 数据集则以颜色叠加方式组合。 - -若要沿 x 轴对齐线条序列,请选中图形,然后在 **Analyze** 页签的 **Align** 组中 -选择 **Align Traces…**。当图中至少有两条可见线条序列使用相同的 x 轴单位时, -此命令才可用。也可以从对象检查器的 **Data** 中选择 **Align traces…**,打开 -同一个对话框。 - -选择参考序列后,可用 **Trace start**(第一个有限绘制样本)对齐,也可在指定的 -x 区间内按峰对齐。按峰对齐时,**Positive** 查找向上的峰,**Negative** 查找 -向下的峰,**Magnitude** 比较两者的突出度。选择 **Apply** 前,请检查 -**Anchor**、**Delta** 和 **Result** 列。隐藏、不兼容或没有可用对齐位置的序列会 -列为 **Skipped**,并保持不变。 - -对齐会保留图形当前的缩放范围。若要手动调整一条线,可在 **Data** 中编辑其 -**X shift**。自动和手动位移都是可撤销的图形设置,不会改变来源数据或数据导出。 - -## 作图样式与排印 - -Plotium 自动按印刷习惯设定图形样式:只保留左轴和底轴、向外的短刻度、随 -显示范围调整的刻度精度、图框变窄或变矮时抽稀的刻度密度(矮图框只要放得下 -仍保留两个 y 刻度),以及以上标显示的 -NMR 核素质量数。新数据集默认使用 89 × 60 mm 单栏画布:单个图占满画布 -时,屏幕上看到的字号就是期刊印出的字号;多分图的组合图之后再拼合到更宽 -的页面上,各分图保持原始尺寸。 - -你可以直接控制的部分: - -- 选中单个图形后,可在对象检查器的 **Axes** 区域覆盖 X/Y 轴标题或数值 - 范围,也可隐藏某条轴的刻度标签和标题。**Equal x/y scale (1:1)** - 让两个坐标轴使用相同的单位/屏幕距离,适用于 Nyquist 图、AFM 图像和 - 2D NMR 谱等。绘图区在框内缩成相应形状,坐标范围保持不变。它要求两条轴 - 都是线性、非分类轴且没有右 y 轴;共用 x 轴堆叠中的图不能开启。AFM 图像 - 默认开启;对于真正的 2D NMR 谱,Plotium 在导入时设定初始值,此后可单独 - 修改,且不会改变导入偏好设置。 - 标题留空或范围保持 **Auto**,即可继续使用由数据自动推导的值。 - 手动范围会成为该轴的完整范围:缩放和平移仍限制在其中,双击图内即回到 - 这个手动范围。不显示坐标轴的图表没有轴设置;分类轴不提供范围控制。 -- 同一 **Axes** 区域的 **Frame**(边框)可选 *Left and bottom*(左、下两条轴) - 或 *All four sides*(四边框)。四边框会补上顶部和右侧轴线,线宽和颜色与其他 - 坐标轴相同;刻度和刻度标签仍只在左轴和下轴。多数图默认只有左、下两条轴, - 等高线图、热图等 2D 图默认是四边框。 -- **Axes** 区域更多选项中的 **X scale**、**Y scale** 可把折线图、散点图和 - 棒状图的坐标轴在 *Linear*(线性)与 *Logarithmic*(对数)之间切换。对数轴 - 以 10 的幂(10¹、10²……)作刻度,轴较短时自动稀疏,可见的 10 的幂少于 - 两个时改用普通刻度;开启次刻度后,次刻度位于每个数量级的 2–9 倍处。对数轴的自动 - 范围只依据正值数据。零和负值在对数轴上没有位置:折线会在该处断开,延伸到轴 - 以下的误差棒和棒状线止于图框边缘。对数轴的手动范围下限必须大于零。缩放和 - 平移按数量级进行。分类轴、2D 图、柱状图与分布图以及 NMR 谱图不提供对数轴; - NMR 的积分、相位和光标工具按线性 ppm 计量。 -- **Line** 区域高级选项中的 **Y axis** 可把折线或散点曲线放到图右侧的第二条 - y 轴上,用于单位或数量级不同的量。只要有一条曲线使用右轴,右轴就会出现; - 所有曲线都回到左轴后,右轴随之消失。右轴按自己的曲线自动确定范围,并绘制 - 自己的刻度、刻度标签和标题;标题与左轴标题同样从下往上读,初始为第一条右轴 - 曲线的列名和单位。对象检查器中的 **Right Y axis** 区域只在图有右轴时出现, - 可设置右轴的标题、范围、对数刻度、刻度标签、显示单位和主刻度间隔。滚轮、拖动和框选缩放 - 会让两条 y 轴按各自范围的相同比例一起移动,双击会让两条轴都回到完整范围, - **Inspect** 光标同时读出指针处的 x 和左右两个 y 值。所有曲线共用一个图例。 - 柱状曲线始终在左轴上,参考线、标注和箭头按左轴坐标放置。表格曲线图中,每条 - y 轴保持其第一条曲线的单位;单位无法换算到该单位的曲线不能放到这条轴上。 -- **Axes** 区域更多选项中的 **X break**、**Y break** 可以断开线性数值轴:两个端点 - 之间的数值不显示,轴线在断口处留空并画一对斜线。取消勾选 **None** 后,断口从 - 当前范围的中间三分之一开始,再修改两个端点即可;端点必须都在轴范围之内。默认 - 两段使用相同的比例尺;**X lower share** 或 **Y lower share** 可改为 - 指定数值较小那一段占轴长的比例。每段各自生成刻度,紧挨断口的刻度不显示,以免标签相互重叠。穿过断口的 - 折线从断口一侧出去、在另一侧继续;跨过 y 断口的柱子会被截断显示。对数轴、 - 分类轴、等比例轴、2D 图和 NMR 谱不能断开;有右 y 轴的图不能断开 y 轴。在共用 x 轴的堆叠中,x 断口会作用于所有图。 - agent 通过 `object.axes.x_break`、`object.axes.y_break` - (`{"mode":"manual","min":…,"max":…,"unit":…}`,或 `{"mode":"auto"}` 表示不断开)以及 `object.axes.x_break_lower_fraction`、 - `object.axes.y_break_lower_fraction` 设置;图形诊断会报告被断口隐藏的数据点。 -- 任意图形都可通过对象检查器的 **Legend & scales** 管理图例与色标。 - **Visibility** 设为 **Auto** 时,图中存在两个及以上命名项便显示分类图例, - 热图则显示连续色标;**Show** 也允许显示单项图例,**Hide** 会隐藏当前图的 - 图例或色标。**Position** 设为 **Auto** 时,图例放在图内四角和四边中点里 - 压住数据点和曲线最少的位置,同样空时优先周围留白更多的位置,再优先右上角。 - 如果这些位置都会压住数据,Plotium 会把图例一侧处于 **Auto** 的坐标轴范围 - 恰好延伸到能腾出一个空位为止,最多延伸原跨度的一半;手动范围、缩放后的 - 视图和锁定纵横比的图不会被改动。 - **Inside** 固定放在图内右上角;**Outside right** 或 **Outside bottom** 在图的 - 右侧或下方预留空间。**Layout** 可把分类图例排成纵向列表或横向一行; - **Title** 位于该分区的高级设置中。 -- 图例不画边框,也没有底色;屏幕显示和所有导出格式都一样,图例只画条目 - 和标题。 -- 启用 **Select** 后,单击图例或色标可直接打开对应的 **Legend & scales** - 设置。拖动分类图例可自由放置;自定义位置在调整图框尺寸后仍会保留,并用于 - 所有导出格式。单击的图例或图内标签会显示选中框,此时用方向键每次移动 - 0.5 pt(按住 `Shift` 为 5 pt)。双击图例或色标可恢复自动位置。 -- 轴标题、图例和文字支持真正的上下标:输入 `cm^{-2}` 或 `H_{2}O`。 - `⁻²`、`₂` 这类字符也按同样方式绘制。EMF 导出仍使用这些 Unicode 字符。 -- 图中文字默认在画布和所有导出格式中都使用 Arial。没有 Arial 时改用 Helvetica - 或 Liberation Sans 等字宽相同的无衬线字体。SVG 文件写明字体,用矢量软件 - 打开也保持 Nature 系列期刊要求的字体。 -- **Figure typography** 分区中的 **Font** 切换所有图内文字的字体——刻度标签、 - 轴标题、图标题、图例、色标和图内标注——可选 *Arial*(默认)、*Helvetica* - 或 *Times New Roman*。Helvetica 在 macOS 上用 Helvetica 绘制;Windows 和 - Linux 上改用字宽相同的 Arial 或 Liberation Sans,SVG 文件仍把 Helvetica - 写在首位。没有 Times New Roman 时改用 Liberation Serif 等字宽相同 - 的衬线字体。高级设置中的 **Font weight** 把这些文字设为 *Regular*(常规)或 - *Bold*(粗体)。画布上的文本框和分图字母仍保持各自的 Arial 样式。这两项设置 - 随主题和已保存的样式一起保存和套用;内置主题使用 Arial Regular。 -- Figure Ribbon 选项卡 **Style** 分组中的 **Figure typography** 会打开文档级 - 排版分区;命令面板中的 **Figure Typography…** 以独立窗口显示同一分区,并 - 多出 **Reset to defaults** 按钮。两者都一次设定文档内所有图的文字尺寸 - (刻度标签、轴标题、图标题与图例),单位为绝对磅值——这是文档级样式, - 缩放分图不会改变字号。各字号取值 1 到 72 pt;图例默认为 7 pt。 -- 同一分区的高级设置可设定所有图的坐标轴线条:**Axis line width**(坐标轴线 - 与刻度线的线宽,0.05 到 10 pt,默认 1 pt)、**Tick length**(刻度长度, - 0 到 20 pt,默认 3 pt)和 **Tick direction**(刻度方向,默认 *Outward* - 朝外,可选 *Inward* 朝内)。刻度朝内时伸进绘图区,刻度标签随之贴近坐标轴线。 -- 同一组高级设置里的 **Minor ticks**(子刻度)在两条坐标轴相邻主刻度之间画出 - 相应数量的无标签刻度(0 到 9,默认 0,即不显示)。子刻度长度为主刻度的一半, - 线宽和方向与主刻度相同。分类轴以及主刻度少于两个的轴不画子刻度。 -- 对象检查器的 **Figure typography** 区域中的 **Tick-label size** 就是同 - 一个刻度标签字号,并提供 **Legend size** 与 **Legend text color**。 - 在两处中任何一处修改,改的都是文档里的同一个值。它属于文档而不属于 - 某个图,因此无论当前选中什么(包括什么都没选中)都会显示。 -- 对象检查器的 **Line** 区域中的 **Stroke width** 设定所选图中线条序列的 - 线宽,单位为 pt;新线条序列默认为 0.5 pt。可以拖动或输入 0.05 到 10 pt - 之间的任意值,也可以从 **Presets**(预设)中取一个——*Fine* 0.50 pt、 - *Medium* 0.75 pt、*Bold* 1.25 pt。只有当所选内容中有以线条绘制的序列时才 - 会出现该区域,标题处会数出即将改动的序列条数。选中多个图即一并编辑;什么 - 都不选时,作用于页面上的活动图。 - - 当所选序列的线宽并不一致时,控件显示破折号和 *mixed*,而不会把其中一 - 个值当成当前设置;此时写入一个值正是让它们重新一致的方式。所选序列中 - 以别的方式绘制的(例如等高线)会在操作历史窗口里报告为跳过,其余序列照常生 - 效。若某个线宽不同于 Plotium 会为这份数据选择的值,该行会标上圆点,旁边 - 的重置按钮按当前数据重新推导默认值。 -- **Line** 区域的 **Advanced** 中可以为每条曲线单独设置符号颜色,与线色无关。**Marker fill** - 设定闭合符号(圆、方、菱形、三角、星形、五边形、六边形)的填充色,**Marker edge color** 设定其边框色; - 未设置时两者都跟随曲线颜色。**Marker edge width** 绘制该边框,范围 0(无边框, - 默认)到 5 pt。**Hollow marker** 使闭合符号不填充、只保留边框,边框宽度为 0 时 - 为 0.5 pt;关闭后恢复原填充色。**Marker every N points** 从第一个点起每 N 个 - 点画一个符号,适合几百圈循环这样的密集数据;折线仍经过每个点。加号和叉号符号 - 仍使用曲线颜色。图例中的符号与之一致。颜色带有 - 语义的图型保持其符号颜色。 -- **画布主题**携带配套字号——例如 Presentation Dark 主题会放大坐标轴 - 文字以适合投影演示。**Nature** 主题遵循 Nature Portfolio 终稿作图规范: - 文字 7 pt,线宽按字号缩放——坐标轴、刻度、柱描边以及新建的参考线和箭头为 - 0.3 pt,折线系列为 0.5 pt——刻度朝外 3 pt,符号 3 pt 且无描边,使用对色盲友好的 - Okabe–Ito 配色。手动加上的符号描边会保留。这些尺寸以 Nature 栏宽为准,套用到宽度 - 不符合任一 Nature 尺寸预设(89、136 或 183 mm)的画布时,状态栏会附带提示列出 - 这些宽度;画布尺寸保持不变。宽度已符合某个 Nature 尺寸、但尚未设定尺寸预设的画布,会 - 随之采用该 Nature 预设,导出检查因此按 Nature 的下限(文字 5 pt、线条 0.25 pt)判断。之后切换到不设定线宽和符号大小的 - 主题时,这些线宽和符号大小会保留。任何主题都会保留你手动设置的值:曲线和符号颜色、 - 线宽、符号大小和描边、文字和形状颜色以及图形排版。状态栏会说明保留了几处;重置某个值后, - 它重新跟随主题。 -- **手动设置的值**(在属性面板中设置、在控件上滚动调整或拖动图例)会替你保留:主题不会 - 改动它们,通过 MCP 连接的 AI agent 也会跳过它们,除非你要求它修改。重置该值(或双击 - 拖动过的图例)即可解除。agent 设置的值不算作你的设置。 -- **Save Canvas Style…**(View ▸ Canvas Theme,或 Figure Ribbon 选项卡 Style - 组中的 **Save Style**)把当前画布的外观保存为命名样式:背景、文字颜色与 - 字号、图形排版(包括字体和字重)、坐标轴和刻度线宽、曲线颜色及其符号填充色、描边和空心设置、线宽和符号 - 大小。 - **Canvas Styles…** 列出已保存的样式,可套用到当前画布或删除。套用样式是一次 - 可撤销的操作。要修改某个样式,先套用它,调整画布后再用同一名称保存。样式以 - `.plotiumstyle` 文件保存在 Plotium 配置目录的 `styles` 文件夹中,可以复制到 - 其他电脑使用。 - -图形完成后,见[导出](/zh-cn/guides/exporting/)。 diff --git a/docs/src/content/docs/zh-cn/guides/legends-and-lines.md b/docs/src/content/docs/zh-cn/guides/legends-and-lines.md new file mode 100644 index 00000000..239ee578 --- /dev/null +++ b/docs/src/content/docs/zh-cn/guides/legends-and-lines.md @@ -0,0 +1,75 @@ +--- +title: 图例、线条与标记 +description: 摆放图例并设置标题,设置线宽和数据点符号,书写上下标。 +--- + +## 图例与色标 + +任意图形都可通过对象检查器的 **Legend & scales** 管理图例与色标。 + +- **Visibility** 设为 **Auto** 时,图中存在两个及以上命名项便显示分类图例,热图则 + 显示连续色标;**Show** 也允许显示单项图例,**Hide** 会隐藏当前图的图例或色标。 +- **Position** 设为 **Auto** 时,图例放在图内四角和四边中点里压住数据点和曲线最少 + 的位置,同样空时优先周围留白更多的位置,再优先右上角。如果这些位置都会压住数据, + Plotium 会把图例一侧处于 **Auto** 的坐标轴范围恰好延伸到能腾出一个空位为止,最多 + 延伸原跨度的一半;手动范围、缩放后的视图和锁定纵横比的图不会被改动。 +- **Inside** 固定放在图内右上角;**Outside right** 或 **Outside bottom** 在图的右侧 + 或下方预留空间。 +- **Layout** 可把分类图例排成纵向列表或横向一行;**Title** 位于该分区的高级设置中。 + +图例不画边框,也没有底色;屏幕显示和所有导出格式都一样,图例只画条目和标题。图例 +文字的字号和颜色是文档级设置,见[图形排印](/zh-cn/guides/themes-and-styles/#图形排印)。 + +### 手动摆放图例 + +启用 **Select** 后,单击图例或色标可直接打开对应的 **Legend & scales** 设置。拖动 +分类图例可自由放置;自定义位置在调整图框尺寸后仍会保留,并用于所有导出格式。单击的 +图例或图内标签会显示选中框,此时用方向键每次移动 0.5 pt(按住 `Shift` 为 5 pt)。 +双击图例或色标可恢复自动位置。 + +## 线宽 + +对象检查器的 **Line** 区域中的 **Stroke width** 设定所选图中线条序列的线宽,单位为 +pt;新线条序列默认为 0.5 pt。可以拖动或输入 0.05 到 10 pt 之间的任意值,也可以从 +**Presets**(预设)中取一个——*Fine* 0.50 pt、*Medium* 0.75 pt、*Bold* 1.25 pt。 +只有当所选内容中有以线条绘制的序列时才会出现该区域,标题处会数出即将改动的序列条数。 +选中多个图即一并编辑;什么都不选时,作用于页面上的活动图。 + +当所选序列的线宽并不一致时,控件显示破折号和 *mixed*,而不会把其中一个值当成当前 +设置;此时写入一个值正是让它们重新一致的方式。所选序列中以别的方式绘制的(例如 +等高线)会在操作历史窗口里报告为跳过,其余序列照常生效。若某个线宽不同于 Plotium +会为这份数据选择的值,该行会标上圆点,旁边的重置按钮按当前数据重新推导默认值。 + +## 数据点符号 + +**Line** 区域的 **Advanced** 中可以为每条曲线单独设置符号颜色,与线色无关。 + +- **Marker fill** 设定闭合符号(圆、方、菱形、三角、星形、五边形、六边形)的填充色, + **Marker edge color** 设定其边框色;未设置时两者都跟随曲线颜色。 +- **Marker edge width** 绘制该边框,范围 0(无边框,默认)到 5 pt。 +- **Hollow marker** 使闭合符号不填充、只保留边框,边框宽度为 0 时为 0.5 pt;关闭后 + 恢复原填充色。 +- **Marker every N points** 从第一个点起每 N 个点画一个符号,适合几百圈循环这样的 + 密集数据;折线仍经过每个点。 + +加号和叉号符号仍使用曲线颜色。图例中的符号与之一致。颜色带有语义的图型保持其符号颜色。 + +## 上标与下标 + +轴标题、图例和文字支持真正的上下标:输入 `cm^{-2}` 或 `H_{2}O`。`⁻²`、`₂` 这类 +字符也按同样方式绘制。EMF 导出仍使用这些 Unicode 字符。NMR 核素质量数会自动以上标 +显示。 + +## 使用 AI 客户端 + +也可以让连接到 Plotium 的 AI 客户端替你完成,例如: + +> 只改左边那张图:把图例移到左下角,保持竖排,标题改成 Samples。应用之前先给我看预览。 + +> 找到名为 Current 的曲线,只把这一条的线宽改成 1.5 pt。 + +> 给这张图的每条曲线各设一种颜色,图例文字分别是 Control、1 mM、5 mM。先给我两三套配色选。 + +Plotium 只修改你指定的图或曲线,保留你手动设置过的值(例如拖动过的图例位置),整个 +修改是一步 Undo。让它给几个方案时,它会逐个预览,只应用你选的那个。参见 +[权限、审阅与撤销](/zh-cn/ai/control-and-review/)。 diff --git a/docs/src/content/docs/zh-cn/guides/mass-spectrometry.md b/docs/src/content/docs/zh-cn/guides/mass-spectrometry.md new file mode 100644 index 00000000..bacff0ab --- /dev/null +++ b/docs/src/content/docs/zh-cn/guides/mass-spectrometry.md @@ -0,0 +1,74 @@ +--- +title: 质谱 +description: 浏览 LC–MS 数据,提取质谱和离子色谱图,选择色谱通道。 +--- + +Waters MassLynx RAW、SCIEX legacy WIFF 和 mzML 都会打开为同一种 LC–MS 数据集。 +打开 Waters 数据时,选择 **Open Folder…** 并选中 `.raw` 目录,或把该目录拖到窗口中。 +本页讲导入之后的操作;各导入器读取哪些内容,见 +[支持的格式](/zh-cn/guides/supported-formats/#质谱)。 + +Plotium 不提供 LC–MS 处理流程。导入的数据、当前采集流、检测器通道、提取质谱、 +提取离子色谱图和页面排版都会保存在 `.plotium` 项目中。 + +## 初始页面 + +初始页面显示当前采集流的总离子流图(TIC)。Waters 数据含光学检测器数据时, +UV 通道会放在 TIC 上方,并共享保留时间轴。多个 UV 通道会叠加显示,图例使用 +文件中存储的波长,例如 `214 nm`。若要隐藏、移动或调整该图例的排版,请选中 +UV 图并使用对象检查器的 **Legend & scales**。 + +## 预览和提取质谱 + +选中 LC–MS 数据集,然后在 **Analyze(分析)** 标签中选择 **Extract Mass +Spectrum**。Plotium 会在右侧栏打开 **Dataset tools → Mass spectrometry**,并启用 +保留时间范围选择。 + +单击 TIC 或 UV 色谱图,会在 **Scan preview** 中显示保留时间最近的 MS 扫描。 +预览会标明保留时间和原始扫描编号,但不会加入页面,也不会保存为结果;重新打开 +项目后会被清除。选择 **Extract current scan** 可把该扫描作为棒状谱加入页面。 + +若要从时间窗提取,请选择 **Method**,启用 **Select range**,然后在 TIC 或 UV +色谱图上拖出范围。选择 **Extract spectrum**,即可把峰顶扫描、最近扫描、平均谱 +或求和谱加入页面。每张提取谱都会记录功能、时间范围和提取方式;移动预览游标 +不会改变它,并且它会列在数据浏览器的 **Analysis** 下。 + +## 提取离子色谱图(XIC) + +要创建提取离子色谱图(XIC,也称 EIC),请打开 **Dataset tools → Mass +spectrometry** 并选择 **Select m/z range**。在当前质谱图上拖出 m/z 区间, +确认显示的 m/z 区间和采集流,然后选择 **Extract ion chromatogram**。 + +生成的折线图会在每次扫描的保留时间(分钟)处显示一个点。每个点的值是 +所选 m/z 区间内的强度之和,并包含两个端点。该结果会被保存;移动扫描预览或 +选择其他采集流都不会改变它。XIC 提取不进行色谱峰积分,也不计算峰面积。 + +## 切换采集流 + +数据中含多个受支持的 MS 功能或 experiment 时,请使用 **Dataset tools → Mass +spectrometry** 中的 **Acquisition stream**。Waters 数据的初始采集流是第一个 +非参考 MS 功能。切换采集流、提取质谱和提取 XIC 都可通过标准的 Edit 命令撤销 +和重做。 + +## 浏览色谱通道 + +对于包含大量色谱通道的数据,请通过 **Extract Mass Spectrum** 或命令面板打开 +**Dataset tools → Mass spectrometry**。**Chromatogram channels** 浏览器会显示稳定的 +数量和顺序,其中 TIC、BPC 排在 SIM/SRM transition 之前。搜索可匹配通道名称和 +native ID;对于结构化 transition,还可按 precursor m/z、product m/z、极性、 +碰撞能量和活化方法筛选。数值输入支持精确值、`>=400` 之类的比较式,以及 +`400..500` 之类的区间。 + +选择一行会把当前 LC–MS 色谱图中的曲线替换为该单一通道;质谱图绝不会被重新绑定。 +该操作可以撤销,并随页面保存到项目中。只有色谱图的采集也使用同一浏览器。没有 +可绘制通道、没有结构化 transition 信息或当前筛选无结果时,面板都会给出明确提示。 +大型 scheduled-MRM 数据中列表也能保持流畅。 + +## TIC 与 BPC 的来源 + +文件直接提供的 TIC 或 BPC 色谱图会标记为源色谱图,并在其所属采集流中优先使用。 +缺少该通道时,Plotium 会先使用每张谱图在文件中提供的 TIC 或 base-peak 摘要; +没有摘要时,才从强度数组派生 TIC,或从最大的非负峰派生 BPC。因此同一次采集中 +可能同时存在文件摘要与数组派生点。多采集流数据中,未归属任何采集流的源色谱图 +会作为独立通道保留,不会被猜测成某个采集流的 TIC 或 BPC。field 元数据和 +Scientific Summary 会显示实际使用的来源。 diff --git a/docs/src/content/docs/zh-cn/guides/multi-panel-figures.md b/docs/src/content/docs/zh-cn/guides/multi-panel-figures.md new file mode 100644 index 00000000..4762119b --- /dev/null +++ b/docs/src/content/docs/zh-cn/guides/multi-panel-figures.md @@ -0,0 +1,207 @@ +--- +title: 多面板图 +description: 在画板上排布图形、组织图版面板,并按期刊规范设定页面尺寸。 +--- + +## 画板 + +图形放置在按页面组织的无限画板上。拖动图框时会自动吸附到页面网格、 +页边距以及相邻图框的边缘;吸附可在 **Arrange** 页签中关闭。**Arrange** 页签还提供 +对齐(选中两个及以上图框)、水平 / 垂直分布(三个及以上)、层叠顺序, +以及 *Tidy up frames*(一键整理)命令。 + +在画板空白处拖动可框选页面和工作表图框。按住 `Shift` 可追加框内图框,按住 +`Ctrl`(macOS 上为 `Cmd`)可切换框内图框。拖动任一所选图框的标题栏会移动 +整个选择,并可作为一步撤销。在 Canvas 列表中,`Shift` + 单击选择连续区间, +`Ctrl` + 单击添加或移除单个画布。`Ctrl` + `A` 会根据最近使用的区域全选图框 +或画布。 + +## 科学摘要与备注 + +Plotium 会在画板中每个页面的下方自动概述当前绘制的数据。对于多 Panel 页面, +共同信息只显示一次,其余内容跟在相应的 Panel 标签后。 + +打开 **Canvas settings** 可以添加页面备注;也可以选中 Panel 后编辑其 +**Note**。备注显示在摘要之后,不会包含在导出结果中。使用 +**Show summary below page** 可以显示或隐藏整个画板专用信息区块。 + +## 使用图版面板 + +使用 Arrange 菜单或命令面板中的 Panel 命令,可以制作多 Panel 图版。你可以创建 +空 Panel、把所选对象组成 Panel,也可以复制、合并、拆分、解散或删除 Panel。 +在 Layers 中展开 Panel,即可查看其中的对象。 + +单击 Panel 内任意位置可将其选中,随后可以拖动整个 Panel,或用四角控制点连同 +其中内容一起缩放。按住 `Shift` 单击可选择多个 Panel。若要编辑 Panel 内的对象, +请双击 Panel 或按 `Enter` 进入。点击页面上方的面包屑或按 `Esc` 可返回页面。也可 +按住 `Ctrl`/`Cmd` 单击对象,无需先进入 Panel 即可直接选择它。 +缩小时,若其中某张图的数据区会被坐标轴、刻度和色标挤占,缩放就会停在那里。 +移动或缩放 Panel 或图时,它的绘图区也会吸附到其他图的绘图区边缘;即使刻度标签宽度 +不同,坐标轴也能对齐。 + +关闭 **Clip contents to panel** 时,内容可以超出 Panel 和页面边界;拖动可见内容即可 +将它移回。开启裁剪时,拖动或缩放会确保内容在 Panel 内仍可选中。对象重叠时, +拖动会作用于最上层的可见对象。 + +若要交换同一 canvas 中的两个 Panel,将其中一个拖到另一个上面,待两个位置高亮后 +松开。两个 Panel 会交换位置和尺寸,内部内容随目标框缩放;整个交换可一步撤销。 +隐藏或锁定的 Panel 不能作为交换目标,多 Panel 拖动仍保持整体移动。 + +在 Panel 内,对象会吸附到 Panel 边缘和其他对象。若要把对象移入另一个未锁定的 +Panel,请将它拖到目标 Panel 上,待目标高亮后松开。也可以在 Layers 中把对象行 +拖到 Panel 行。若目标采用 Stack 或 Grid 布局,内容会在移入后重新排列。隐藏对象 +仍可在 Layers 中选择;锁定对象可以选择,但不能编辑。 + +对象检查器中的 Panel 设置可控制可见性、锁定、裁剪、标签和布局。**Vertical +Stack**、**Horizontal Stack** 与 **Grid** 会按选定的间距、内边距和对齐方式排列 +内容;**Shared X Stack** 把多张图上下堆叠在同一条 x 轴上,见 +[共享 x 轴堆叠](#共享-x-轴堆叠)。页面有多个可见 Panel 时,自动字母标签才会出现,并按阅读顺序排列:从上到下 +逐行排列,同一行内从左到右。移动或添加 Panel 后,字母会立即更新。选择 +**Locked auto** 可保留 Panel 当前的字母,取消 **Participates in sequence** 可让它 +不参与编号、不显示字母。标签位于图片上时会自动切换黑白颜色以保持清晰;图的 y 轴标题 +会在需要时自动下移,避免与字母重叠;若图太矮无法下移,整幅图会移到字母右侧。手工标签和锁定 +标签在单 Panel 页面中仍会显示。 +若要一次隐藏页面上的所有字母,请在 **Canvas settings** 中取消 +**Show panel letters**;字母会保留原有编号,重新开启后恢复原样,隐藏期间 +轴标题也不再为其预留空间。 + +将单个 Panel 完全拖离所有 canvas,并在外部持续停留 0.5 秒,即可准备新建 canvas。 +预览会先显示进度条,随后变为绿色边框,并显示 **Release to create canvas**。 +此时松手,整个 Panel 会移入当前位置新建的 canvas,页面尺寸与 Panel 一致。 +内容、标签、备注和内部布局均保留,源 canvas 保持原位;移动和新建可一起撤销。 +Panel 任一部分重新进入 canvas 都会重置计时。调整尺寸或拖动多个 Panel 时不会 +新建 canvas,按 `Esc` 可取消拖动。 + +## 画布尺寸 + +活动页面左上角上方会显示一个尺寸标签,内容为当前尺寸和匹配到的预设 +(例如 *89 × 60 mm · Nature · Single column*)。点击它、在 Figure Ribbon +选项卡中使用 **Canvas Size & Settings…**,或在命令面板中运行任意 +"Canvas Size" 条目,都可以更换尺寸。 + +预设列表支持搜索并按组显示:期刊图幅宽度(Nature、Science、Cell Press、 +ACS、Elsevier、PNAS 和 IEEE,数值取自各出版社的作图规范)、纸张尺寸 +(支持纵向/横向切换)、演示文稿幻灯片、最近使用过的条目,以及你自己保存 +的自定义尺寸。期刊预设只锁定页面*宽度*——高度由内容决定,上限为该期刊 +的最大图幅深度;页面超过该深度时会显示警告。 + +默认情况下,更改尺寸不会移动或缩放内容;如果对象超出页面,尺寸标签一栏 +会出现溢出警告,单击即可把内容等比缩小到页面内(可撤销,字号保持物理磅 +值不变)。勾选 **Scale content when applying sizes** 后,应用预设时对象 +会随页面一起缩放。 + +另有两项自动辅助: + +- **Auto height**(自动高度)保持宽度不变,页面高度跟随内容深度变化, + 并以期刊最大深度为上限。 +- 当布局网格设置为两列及以上、而页面仍是单栏宽度时,会出现一条可关闭的 + 提示,单击即可切换到同一期刊的全宽——它绝不会自行改变页面尺寸。 + +导出对话框会预先选中匹配的期刊预设,因此按栏宽制作的页面默认按该宽度 +导出。 + +## 分图之间的间距 + +多分图的版面,只有各分图的数据区间隔均匀才好看;但每个图为刻度标签和 +轴标题预留的空间各不相同,图框等距往往看起来并不等距。 +**Canvas Size & Settings…** 里既设定想要的间距,也设定它按什么来量。 + +**Minimum spacing**(最小间距)就是这个间距本身,单位与画布一致; +**Tight**(2 mm)、**Normal**(5 mm)、**Spacious**(10 mm)三个预设可 +直接填入常用值。 + +**Spacing basis**(间距依据)决定这个间距量的是哪两处之间: + +- **Visual**(默认)量的是相邻两图数据区之间的距离,并把夹在中间的刻度 + 标签和轴标题计算在内,因此 y 轴标题较长的分图能自动获得所需空间。该值 + 是下限:实际间距只会更宽,不会更窄,图框也不会重叠。相邻两图的轴文字 + 之间始终至少相隔 8 pt。 +- **Frame** 量的是图框之间的距离,不计轴文字。图框会严格按设定值排开, + 但各对分图数据区之间的可见空隙会随标签长短而变化。 + +图框止于最外侧的文字、刻度或轴线,自身不再留空白边。因此贴着页面边缘的 +分图会直达导出图的边缘,适合页面即成品图的期刊尺寸。 + +凡是由 Plotium 自动摆放图形的场合都遵循该依据——**Apply grid**,以及把图形 +拖到已有图形的页面上时的自动平铺。 + +把图拖到另一页面,即把它移到该页并重新平铺目标页。拖动过程中图形跟随 +指针移动,按下时抓住的那一点始终停在光标下,目标页面上同时画出松手后 +各图所在的位置。若目标页面上已有两个及以上的图,整页会重排成均匀网格, +拖入的图落在指针所指的那一格里。 + +如果这次移动把源页面清空,Plotium 会随本次拖放一并删除该页面,移动与删除 +同属一步撤销/重做。释放鼠标时按住 `Alt` 则保留这个空页面;操作历史窗口会提示 +当前这次拖放按住 `Alt` 会变成哪种结果。若希望默认保留空的源页面,可在 +偏好设置 → General 中打开 **Keep source canvas when tiling its last +object**——此后按住 `Alt` 就只为这一次拖放删除空页面。 + +使用 Select 工具时,每条非零页边距都会画成一条贯穿页面的虚线,标示出正在 +排版的内容区;设为 0 的一边不画线。打开布局网格会另外显示单元格轮廓, +拖动时出现的吸附参考线使用对比色。 + +## 精简内侧轴 + +一格格分图共用同一套坐标轴时,每个分图都重复刻度数字和轴标题只会浪费 +版面。**Simplify Inner Axes**(精简内侧轴)只在每列最下方的图上保留 x 轴 +文字,只在每行最左侧的图上保留 y 轴文字;轴线和短刻度在所有分图上都保留。 + +两种用法: + +- 在画布设置中勾选 **Apply grid** 旁的 **Simplify inner axes**,排布与精简 + 合并为一次可撤销的操作。图框会按精简后的坐标轴重新丈量,因此各分图能 + 占用原先被隐藏文字占据的空间。 +- 对已经排好的图形,可从 Arrange Ribbon 选项卡、画布右键的 Arrange 菜单 + 或命令面板运行 **Simplify Inner Axes**。它要求至少有两个图形已对齐成 + 网格;否则操作历史窗口会提示需要先做什么。 + +若要让某个分图重新显示文字,选中它后在对象检查器的 **Axes** 区域操作: +**X text** 与 **Y text** 两行可分别切换 **Tick labels** 和 **Title**, +**Automatic** 则让该轴恢复为两者都显示。 + +## 共享 x 轴堆叠 + +Shared X Stack(共享 x 轴堆叠)把一个 Panel 里的两张及以上的图上下排列、共用 +一条 x 轴,例如 XRD 主图加下方的标准卡竖线图,或把几条光谱分开摆放。每张图保留 +自己的 y 轴、图例和图型。 + +有两种进入方式: + +- 选中装有两张及以上图的 Panel,在 Panel 检查器的 **Layout** 列表、 + **Edit ▸ Panel** 菜单或命令面板中选择 **Shared X Stack**。 +- 选中多个各装一张图的 Panel,运行 **Stack with Shared X**:这些 Panel 会合并到 + 第一个 Panel 中,并按页面上的上下位置堆叠,整个操作一步撤销。 + +堆叠后: + +- 各图填满 Panel 宽度,内部边界上下紧贴。间距初始为 0 pt;在 Panel 检查器中调大 + **Gap** 可以分开摆放,同时保持对齐。 +- 所有图的绘图区共用同一条左边缘和右边缘,无论 y 刻度数字多宽,y 轴标题都在一条 + 竖线上。每张图各自决定是否有右 y 轴,有右轴的图的右轴标题也同样对齐。 +- 只有最下面的图绘制 x 刻度数字和 x 轴标题,只有最上面的图绘制图标题。两张图 + 相接处的 x 刻度朝内;最下面的 x 轴保持你设定的刻度方向。下方图 y 轴的 ×10ⁿ + 倍数移到其绘图区左上角内侧,落在共用边界上的 y 刻度数字不再绘制。 +- 各图共用一个 x 视窗。进入堆叠时,会给每张图设置一个覆盖全部数据的 x 范围, + 并统一使用最上面那张图的 x 主刻度间隔,因此各图须先使用相同的 x 刻度类型(线性或对数)。所有图都跟随最下面那张图的 + x 方向:ppm 轴从右到左的 NMR 谱堆叠在升序图上方时,会改为从左到右绘制。 +- 在任一张图上缩放或平移 x,其他图会一起移动。在任一张图上修改 x 范围、对数刻度、 + x 显示单位、千位分隔符或主刻度间隔,会同时改到堆叠中的所有图,并合为一次撤销;若其中某张图 + 不接受该修改(例如 NMR 谱不能使用对数轴),整个修改会被拒绝。 +- 从上到下的顺序就是 Panel 内容顺序。每张图的高度决定它在堆叠中所占的比例:在 + 画布上拖动某张图的下边框,即可让它比其他图更高或更矮。 +- 整个堆叠是一个 Panel,只有一个面板字母。 + +画布、操作历史中的检查以及所有导出都使用同一套堆叠几何。要退出堆叠,把布局改回 +**Free** 或 **Vertical Stack** 即可,各图会重新绘制自己的 x 轴和 x 方向。共用的 +x 范围会保留,直到你把 **X range** 改回 **Auto**。 + +## 使用 AI 客户端 + +也可以让连接到 Plotium 的 AI 客户端替你完成,例如: + +> 把这一页改成 180 × 90 mm,把这两个 Panel 左右排开,页边距 4 mm、间距 5 mm,标上 a 和 b,先给我看预览。其他 Panel 不要动。 + +Plotium 只修改你指定的 Panel,整个排版是一步 Undo;之后每张图和每段文字都还能继续编辑。 +同意之前请先看预览。参见[权限、审阅与撤销](/zh-cn/ai/control-and-review/)。 + +图形完成后,见[导出](/zh-cn/guides/exporting/)。 diff --git a/docs/src/content/docs/zh-cn/guides/organizing-data.md b/docs/src/content/docs/zh-cn/guides/organizing-data.md index 1c3a378d..9a253976 100644 --- a/docs/src/content/docs/zh-cn/guides/organizing-data.md +++ b/docs/src/content/docs/zh-cn/guides/organizing-data.md @@ -47,7 +47,7 @@ description: 浏览数据集与派生结果,并把工作保存为项目。 `Ctrl` + `S` 打开项目保存选项。`.plotium` 项目文件保存整个会话——导入的 数据、处理、分析结果和排版——重新打开时恢复原状,也可以作为单个文件 -分享。文件内容与版本处理见[文件格式](/zh-cn/reference/file-formats/)。 +分享。文件内容见 [Plotium 文件](/zh-cn/reference/file-formats/)。 保存会在后台运行。如果保存过程中继续编辑,完成的文件包含保存开始时捕获的 版本,而 Plotium 会让后来发生的编辑继续保持“未保存”状态。 diff --git a/docs/src/content/docs/zh-cn/guides/plots-and-charts.md b/docs/src/content/docs/zh-cn/guides/plots-and-charts.md new file mode 100644 index 00000000..f4777971 --- /dev/null +++ b/docs/src/content/docs/zh-cn/guides/plots-and-charts.md @@ -0,0 +1,125 @@ +--- +title: 绘图与图表类型 +description: 把表格画成图,选择数据列和图表类型,并在一张图中组合多个数据集。 +--- + +每个导入的数据集都会得到一个带图的页面。谱图和其他仪器数据导入完成后图就已经画好。 +普通表格还需要多一步:告诉 Plotium 要画哪几列。 + +## 由表格作图 + +[导入 CSV、TSV 或 XLSX 表格](/zh-cn/guides/importing-data/#导入表格)时,Plotium 会在工作表中打开它,并为它新建一个页面, +页面上是一张空的折线图。要把数据画出来: + +1. 在页面上选中这张图。 +2. 在对象检查器中展开 **Data → Curve columns**。 +3. 选择 **X** 列和 **Y** 列。列表中只列出数值列;Plotium 初始以第一个数值列作 X、 + 第二个数值列作 Y。 +4. 如需误差棒,可再选择 **Y error** 列(见[误差棒](#误差棒))。 +5. 点击 **Apply curve binding**。 + +随后 Plotium 会报告画出了多少行,以及有多少行因数值缺失或不是有限值而未画出。 + +要在同一张图里再画几列,展开 **Data → Add curve**,选择源表格及其 **X**、**Y** 和 +可选的 **Y error** 列,选 **Line** 或 **Scatter**,再点击 **Append curve**。源表格 +可以是项目中的另一张表,因此派生表可以加入它所来源的那张图。单位无法换算到该图 +现有单位的曲线会被拒绝。 + +之后要更换某条曲线的数据列,再次展开 **Curve columns**,选择新的列并点击 +**Apply curve binding**。两张图可以用不同的列绘制同一张表;修改其中一张不会影响另一张。 + +Plotium 自己生成的表格(例如区域积分或拟合结果)已经知道哪一列是 x、哪些是数值列, +会直接画出。如果这样的图画有多条默认曲线,**Curve columns** 会先提供 +**Expand default curves**:选择保留身份的那条曲线,之后就能分别修改每条曲线的数据列。 + +## 图表类型 + +选中由表格生成的图,在对象检查器的**图表类型**画廊中选择。Ribbon 的 **Figure** +页签中的 **Chart** 可直接跳转:它会选中表格对应的图并打开检查器。 + +选图表就是选它回答的问题:沿轴跟踪数值用 **Line**;跨类别比较数量用 +**Bar** 或 **Grouped bars**;看单列数值的分布用 **Histogram**;一眼比较 +多列的分布用 **Box** 或 **Violin**;展示整体中的占比用 **Pie**;一次看 +整个数值矩阵用 **Heatmap** 或 **Surface 3D**。 + +- **Line(散点/折线)**——每列一组散点,按 x 轴排布;已有拟合时叠加拟合曲线。 +- **Bar(柱状图)**——所选单列在数值 x 轴上绘制为填充柱。 +- **Grouped bars(分组柱)**——每行一组、组内各列并排;勾选 **Stacked** + 改为堆叠(正值向上、负值向下堆叠)。 +- **Histogram(直方图)**——所选单列的数值分布。默认按 + Freedman–Diaconis 规则自动分箱;取消勾选 **Auto bins** 后可在 **Bins** 中 + 指定 1 到 512 的固定箱数。取消勾选时沿用自动规则刚算出的箱数,因此直方图 + 不会随之变样。 +- **Box(箱线图)**——每列一箱:中位数、四分位箱体、1.5 × IQR 须线, + 以及逐个绘制的离群点。 +- **Violin(小提琴图)**——每列一个核密度轮廓,内嵌四分位条 + (每列至少需要两个不同数值;退化列回退为原始散点)。 +- **Heatmap(热图)**——整张表作为色图矩阵,行自上而下排列; + 在检查器中选择色图。要设定颜色覆盖的数值范围,见[热图颜色范围](/zh-cn/guides/heatmap-range/)。 +- **Pie(饼图)**——所选单列的每一行为一个扇区,并标注百分比。 + 负值与缺失行不参与。 +- **Surface 3D(3D 曲面)**——把表格视为高度场,以固定正交视角绘制; + 可在检查器中调整方位角/仰角与色图。 + +分组柱、箱线、小提琴、热图与 3D 曲面一次使用全部列;柱状图、直方图和 +饼图读取画廊旁选中的单列。所有图表在屏幕显示与 SVG/PDF/EMF 导出中 +完全一致。 + +**Chart › Advanced** 中的 **Purpose** 和 **Claim** 记录这张图要表达什么(例如趋势或 +组间比较)以及它要支持的那一句结论。它们不会改变图形。AI 客户端检查图形时会拿图表 +与它们对照,提出更合适的图形形式,但不会自行切换。 + +## 误差棒 + +误差棒来自一列——它保存另一列的不确定度。在 **Curve columns** 或 **Add curve** 中 +把它选为 **Y error**。Plotium 会检查数值列与其不确定度的单位是否兼容。折线图、柱状图和 +未堆叠分组柱会把它们绘制为纵向误差棒,并扩展 y 轴范围以保证误差棒完整可见。在对象检查器的 +**Line** 中,**Error bars show** 记录误差棒表示 SD、SEM 还是 95% CI,**Replicates (n)** +记录每个值汇总了多少次测量;AI 客户端会向你询问这两项。 + +Plotium 分析工具生成的表格已经带有不确定度,导入的表格则会带上其文件所描述的关系—— +对称 ±σ、分开的上下误差,或带置信水平的置信区间。要在自己编写的 CSV 或 TSV 中标出不确定度列, +见[误差棒列](/zh-cn/guides/importing-data/#误差棒列)。 + +## 一张图中的多个数据集 + +一个图框可以同时显示多个 1D 数据集——可叠加显示,也可以按可调的垂直间距与 3D 错切 +堆叠。2D 数据集则以颜色叠加方式组合。在对象检查器 **Data** 中使用 **Add series…** +可以把另一个数据集加入所选的图。 + +如果想把相关的几张图上下排列、共用一条 x 轴,请使用 +[共享 x 轴堆叠](/zh-cn/guides/multi-panel-figures/#共享-x-轴堆叠)。 + +## 对齐曲线 + +若要沿 x 轴对齐线条序列,请选中图形,然后在 **Analyze** 页签的 **Overlay** 组中 +选择 **Align Traces…**。当图中至少有两条可见线条序列使用相同的 x 轴单位时, +此命令才可用。也可以从对象检查器的 **Data** 中选择 **Align traces…**,打开 +同一个对话框。 + +选择参考序列后,可用 **Trace start**(第一个有限绘制样本)对齐,也可在指定的 +x 区间内按峰对齐。按峰对齐时,**Positive** 查找向上的峰,**Negative** 查找 +向下的峰,**Magnitude** 比较两者的突出度。选择 **Apply** 前,请检查 +**Anchor**、**Delta** 和 **Result** 列。隐藏、不兼容或没有可用对齐位置的序列会 +列为 **Skipped**,并保持不变。 + +对齐会保留图形当前的缩放范围。若要手动调整一条线,可在 **Data** 中编辑其 +**X shift**。自动和手动位移都是可撤销的图形设置,不会改变来源数据或数据导出。 + +## 使用 AI 客户端 + +也可以让连接到 Plotium 的 AI 客户端替你完成,例如: + +> 导入 /Users/me/data/experiment.csv。用 time 作 X、current 作 Y,单位分别是 s 和 mA。建一张可编辑的折线图,先给我看预览。 + +> 删除这条重复的备注和这条曲线,但保留另一条同名的曲线。删除前先告诉我会删掉什么。 + +建图之前,AI 会先和你确认这张图要表达什么,并把回答记为图的 **Purpose** 和 **Claim**。 +单位只按你说明的来;只删除你指定的内容,源数据保留;每次修改都是一步 Undo。 +同意之前请先看预览。参见[权限、审阅与撤销](/zh-cn/ai/control-and-review/)。 + +## 下一步 + +- [坐标轴与刻度](/zh-cn/guides/axes/):范围、对数轴、断轴和第二 y 轴。 +- [图例、线条与标记](/zh-cn/guides/legends-and-lines/)。 +- [字体、主题与样式](/zh-cn/guides/themes-and-styles/):字体、字号和期刊主题。 diff --git a/docs/src/content/docs/zh-cn/guides/processing.md b/docs/src/content/docs/zh-cn/guides/processing.md index 1fb3df18..bff0f2be 100644 --- a/docs/src/content/docs/zh-cn/guides/processing.md +++ b/docs/src/content/docs/zh-cn/guides/processing.md @@ -10,7 +10,8 @@ Plotium 的处理是应用于原始数据的**有序步骤列表**。步骤可 更新后的谱图稍后自动显示。 XPS 为每个谱区使用独立的有序 recipe,而不是 NMR 管线。recipe 包含能量窗口、平滑和 -归一化;电荷校正由同一测量位置的所有谱区共享。详见 [XPS](/zh-cn/guides/xps/)。 +归一化;电荷校正由同一测量位置的所有谱区共享。详见 [XPS](/zh-cn/guides/xps/)。XRD 图样改用 +**XRD Processing** 卡片,见 [Rigaku 粉末 XRD](/zh-cn/guides/supported-formats/#rigaku-粉末-xrd)。 ## 典型的 1D 谱 @@ -180,7 +181,7 @@ Plotium 根据受支持的 `DSPFVS`/`DECIM` 设置确定延迟;否则延迟保 可以看到默认值,旁边的重置按钮把它改回去。 你自己添加的步骤没有这样的默认值——标准管线里没有与它对应的步骤——因此它既 -没有圆点也没有重置按钮。通过[自动化](/zh-cn/guides/automation/)对这类步骤请求 +没有圆点也没有重置按钮。通过脚本或 AI 客户端(见[设置 ID](/zh-cn/reference/settings-ids/))对这类步骤请求 重置时,该步骤会被报告为跳过,而不会把你选定的窗函数变成 *None*。 ### 暂停自动重算时 @@ -214,7 +215,7 @@ Plotium 根据受支持的 `DSPFVS`/`DECIM` 设置确定延迟;否则延迟保 只有 **Mode** 为 *Manual* 时才能编辑 φ0、φ1 和 pivot;使用自动算法时, 每一行都会写明要先切换哪个开关。 -通过[自动化](/zh-cn/guides/automation/)读写时,这些值保持各自的单位:相位角 +通过脚本或 AI 客户端读写时(见[设置 ID](/zh-cn/reference/settings-ids/)),这些值保持各自的单位:相位角 为弧度,pivot 为分数。 二维数据使用所选自动方法,从最强实部或虚部信号所在的谱线估计相位,再对整个系列 @@ -254,11 +255,20 @@ Source 既可以直接输入,也可以在谱图上拾取:展开该步骤并 [用 CRAFT 处理 1D NMR](/zh-cn/guides/craft/)。 -## 自动化接口 +## 使用 AI 客户端 -桌面、CLI 和 MCP 复用原生处理与科学计算语义。操作及参数 schema 见 -[MCP 科学操作与任务](/zh-cn/reference/mcp/#科学操作与任务);命令行可用 -[`tool run`](/zh-cn/reference/cli/#单步科学操作)。处理管线与方案、区域提取、 -扩散拟合及 DOSY/ILT 使用应用级任务回执,查询终态后再消费结果。后台提交是 -一个 Undo 步骤,Redo 复用结果;计算期间修改文档会使任务过期。扩散检查报告 -SI 单位和来源证据,结果检查提供分页诊断;`empty` 不代表有效科学结论。 +也可以让连接到 Plotium 的 AI 客户端替你修改处理,例如: + +> 只改名为 Sample A 的谱:把 Exponential 窗的 LB 设为 0.3 Hz,其他步骤保持不变。 + +> 把配方 `/absolute/path/routine.plotiumproc` 应用到我选中的、兼容的数据集上,并告诉我跳过了哪些。 + +每次处理修改在计算完成后出现在 Plotium 里,是一步 Undo;计算期间若编辑了项目, +结果会作废而不会被应用。使用结果前请先检查重新计算出的谱。参见 +[权限、审阅与撤销](/zh-cn/ai/control-and-review/)。 + +## 脚本接口 + +脚本和 AI 客户端运行的处理操作与桌面端相同;参见 +[MCP 科学运算](/zh-cn/reference/mcp/scientific/)和 +[`plotium-cli tool run`](/zh-cn/reference/cli/#单步科学操作)。 diff --git a/docs/src/content/docs/zh-cn/guides/supported-formats.md b/docs/src/content/docs/zh-cn/guides/supported-formats.md new file mode 100644 index 00000000..db49bc33 --- /dev/null +++ b/docs/src/content/docs/zh-cn/guides/supported-formats.md @@ -0,0 +1,219 @@ +--- +title: 支持的格式 +description: Plotium 可导入的文件格式,按仪器和数据类型列出各导入器读取的内容与限制。 +--- + +Plotium 直接读取厂商 NMR、LC–MS、XRD、XPS、AFM 与电生理格式,无需任何转换步骤。 +如何打开文件、查看导入进度,见[导入数据](/zh-cn/guides/importing-data/)。 + +## 总览 + +| 格式 | 扩展名 | 说明 | +| --- | --- | --- | +| JEOL Delta | `.jdf` | 原始与已处理的 1D、2D 及参数系列;实验性支持 | +| Bruker TopSpin | `fid` / `ser` / `pdata` | 原始及已处理的 1D、2D;NUS 为实验性支持 | +| Varian/Agilent VnmrJ | `.fid` 目录 | 原始 1D、`phase=[1,2]` 的 2D,或单参数变化系列 | +| JCAMP-DX | `.dx` / `.jdx` / `.jcamp` | 1D 频域 NMR 谱 | +| Waters MassLynx RAW | `.raw` 目录 | 已验证的低分辨率数据,包括 SQD2 数据 | +| SCIEX legacy WIFF | `.wiff` + `.wiff.scan` | 支持单样本与多样本 legacy 数据;两个文件必须放在一起 | +| mzML | `.mzML` | 使用 32 位或 64 位数组的质心/轮廓谱图及 TIC、BPC、SIM 或 SRM 色谱图 | +| Rigaku 粉末 XRD | `.rasx`、FI `.raw`、RAS_RAW `.txt` | 衍射图样、采集元数据,以及文件提供的衰减系数 | +| VAMAS XPS | `.vms` | ISO 14976 `NORM` / `REGULAR` XPS 区块,支持多个测量位置与谱区 | +| CasaXPS 文本 | `.txt` | 含原始谱、背景、包络、组件和拟合参数的结构化八行头导出 | +| Bruker NanoScope AFM | `.spm` / `.pfc` | 图像、力曲线、Force Volume 与 PeakForce Capture 数据立方体 | +| Axon Binary Format 2 | `.abf` | int16/float32、多通道、多 sweep,以及文件内 DAC/epoch 刺激 | +| 表格数据 | `.csv`、`.tsv`、`.txt`、`.xlsx` | 保留列类型与空单元格;每个 XLSX 工作表导入为独立数据表 | +| Origin 项目(实验性) | `.opj`、`.opju` | 两种经验证的 OPJ 配置中的工作表;不导入图形,`.opju` 仅作识别 | +| Zip 压缩包 | `.zip` | 打包的数据文件夹 | +| Plotium 项目 | `.plotium` | 完整项目:数据、处理与排版;见 [Plotium 文件](/zh-cn/reference/file-formats/) | + +## NMR + +Plotium 支持一维和二维 NMR,包括带参数轴的系列。请根据要使用的数据选择输入: + +- **Bruker:**选择实验目录可读取原始数据,选择 `pdata` 内的谱文件可读取已处理谱。 + 若目录中有多个无法区分的候选,请指定具体文件或处理目录。支持 States 二维数据 + (`FnMODE=4`)。已处理谱保留文件中提供的实部和虚部分量。 +- **JEOL:**选择含有受支持的原始或已处理采集数据的 `.jdf` 文件。 +- **JCAMP-DX:**支持 5.00 或 5.01 版普通 XYDATA 频谱,每个坐标对应一个强度值, + 坐标单位可为 Hz 或 ppm。不支持 LINK、NTUPLES 和峰表。 + +缺失的核种、频率参考或数字滤波延迟信息保持未知。Hz 谱可以直接显示,但部分分析 +需要额外校准。滤波延迟未知的原始数据首先显示为 FID;查看未校正频谱的方法见 +[群延迟校正](/zh-cn/guides/processing/#群延迟校正),选择分析功能前请核对 +[校准条件](/zh-cn/guides/processing/#分析前检查校准条件)。坐标未知或数据排列不受支持时, +导入会给出错误或诊断信息。 + +JEOL 与 Bruker NUS 为实验性支持,未覆盖所有仪器和采集设置。使用不熟悉的采集类型时, +请检查导入诊断,并与可信参考结果比较后再使用分析结果。二维 NUS 数据缺少采样表时, +见[补录缺失的 NMR 采样表](/zh-cn/guides/importing-data/#补录缺失的-nmr-采样表)。 + +DOSY、T1、T2 实验会根据采集参数自动识别,并获得专属的分析工具;参见 +[伪 2D 分析](/zh-cn/guides/pseudo-2d/)和 [DOSY 扩散分析](/zh-cn/guides/dosy/)。 +缺失的扩散参数可在导入后通过 **DOSY** 任务卡片补充。 + +保存 `.plotium` 项目会保留导入的 NMR 分量、采样顺序、来源信息、警告和处理设置。 +重开项目时,Plotium 根据保存的设置重新计算频谱,无需原始厂商文件。 + +### Varian/Agilent VnmrJ + +选择 **Open Folder…** 并选中 `.fid` 目录,或选择 **Open File…** 并选中目录内的 +`fid` 文件。请将 `fid` 和 `procpar` 保持在同一目录中。 + +支持原始一维数据、仅改变一个非分组参数的系列,以及 `phase=[1,2]` 的二维数据。 +样本格式可为大端字节序的 16 位整数、32 位整数或 32 位浮点数。不支持分组或多个 +参数数组、其他 phase 顺序、Varian NUS、超过二维的数据和已处理谱。记录的维度或 +分量排列与实际数据不符时,导入会停止。 + +## 质谱 + +三种 LC–MS 格式都导入为同一种数据集,使用相同的图表工作流。导入后如何提取质谱 +和离子色谱图,见[质谱](/zh-cn/guides/mass-spectrometry/)。 + +### Waters MassLynx RAW + +请打开或拖入 `.raw` 目录本身;其中的内部文件不会被当作独立数据集。Plotium 会导入 +其中受支持的 MS 功能和光学检测器通道。温度、压力及其他可读取的辅助通道会保留在 +数据集中,但默认不绘图。 + +Plotium 支持已使用 SQD2 数据验证的低分辨率 MassLynx 编码。如果必需的 MS 功能 +使用其他编码,导入会停止并指出相应功能和仪器。如果其余数据可读,不受支持的 +可选功能或参考功能会产生导入警告。 + +### SCIEX legacy WIFF + +请打开或拖入 `.wiff` 文件,并将文件名末尾追加 `.scan` 的配套文件放在同一 +目录,例如 `sample.wiff` 与 `sample.wiff.scan`;`.wiff.scan` 不会作为独立数据集 +导入。无需安装 SCIEX Analyst、SCIEX OS 或 ProteoWizard。 + +Plotium 会导入原始 scan ID、保留时间、m/z 与强度数组、可用的 precursor 信息、 +极性、仪器与采集开始时间元数据,以及已验证的 11 个 experiment 槽位各自的 TIC。 +谱图按样本与 experiment 分成独立的 acquisition stream,并保留 cycle 顺序,包括 +零 TIC 和空 DDA 槽位;不会跨 experiment 合并时间或插值。重复样本名不会合并, +会稳定显示为 `yjs_10ppm #1`、`yjs_10ppm #2` 等后缀。 + +目前仅支持已验证的 legacy 布局。缺少配套文件、容器无样本或 WIFF 布局未识别时, +Plotium 会明确拒绝,不会创建不完整的数据集。加密或较新的 `.wiff2` 与 +`.timeseries.data` 不受支持;请先将这些采集转换为 mzML,再在 Plotium 中打开。 + +### mzML + +打开或拖入 `.mzML` 文件。谱图按 MS 级别和极性分组;每张 scan 仍会保留文件中 +可用的采集功能元数据,例如 mzML instrument configuration、preset scan +configuration 和 filter string。以秒或分钟记录的扫描时间都会换算为分钟显示。 +Plotium 也会导入文件自带的 TIC、BPC、SIM 与 SRM 色谱图,包括只有色谱图而没有 +scan 谱图的采集。文件提供时,会保留 transition 的 precursor/product m/z、极性、 +碰撞能量和活化方法。 + +对于 MS2 及更高级谱图,Plotium 会分别保留 precursor 谱图引用、selected-ion m/z、 +selected-ion 强度与电荷、隔离窗目标与上下偏移、碰撞能量和活化方法。因此,即使 +DIA 没有 selected ion,其隔离窗目标也不会被误写成 selected-ion m/z。Plotium +为每张谱图保存一个 precursor 和一个 selected ion;若文件包含更多值,导入警告会 +指出对应谱图,并说明只保留了第一个值。 + +导入器支持小端 32 位和 64 位浮点 m/z、时间与强度数组,可不压缩或使用 zlib +压缩。Numpress、大端数组以及缺少必需数组的谱图或色谱图会使导入停止并显示错误。 + +## Rigaku 粉末 XRD + +有 `.rasx` 时请优先打开该文件。Plotium 会同时读取实测 2theta、强度、衰减系数, +以及仪器名称、X 射线靶材、Kalpha1 波长、管电压/电流、扫描步长和扫描速度。 +初始页面显示 XRD pattern。要处理它,先选中该图样,再在 **Process** 选项卡中选择 +**Processing**。打开的 **XRD Processing** 卡片提供可选的 SNIP 背景扣除、 +Savitzky-Golay 平滑,以及按最大强度或积分面积归一化;这些设置与原始观测值 +都会保存在 Plotium 项目中。[数据处理](/zh-cn/guides/processing/)中的 NMR 管线步骤 +不适用于 XRD。 + +采用 `FI` 布局的 Rigaku `.raw`,以及文件头标明 `RAS_RAW` 的 profile `.txt`, +也会作为 XRD 打开。二进制读取器会保留扫描坐标、强度、X 射线靶材、Kalpha1 +波长、管电压/电流和扫描速度。由于不同厂商会使用互不兼容的 `.raw` 格式, +Plotium 会明确拒绝其他文件签名。普通 `.txt` 仍进入表格导入预览,不会被静默改判。 + +## XPS + +VAMAS `.vms` 支持限定为按内容签名识别、具有规则能量标尺的 ISO 14976 +`NORM` / `REGULAR` XPS 区块。一个文件始终是一个实验,并保留稳定的测量位置与 +谱区。Plotium 保存原生能量、Counts、CPS、光子能量、dwell time、sweep、位置、 +采集条件和自由元数据。只有区块边界可信时才会警告并跳过非 XPS 区块;XPS 数据 +结构异常时拒绝整个文件。ordinate 极值属于元数据而不是数据点;ordinate 标签和 +信号模式共同决定脉冲计数是否换算为 CPS。 + +CasaXPS `.txt` 按八行结构头识别,而不是仅按扩展名识别。其源数组与拟合参数 +作为导入结果保存;其他 `.txt` 继续走表格导入。能量换算、处理与拟合见 +[XPS](/zh-cn/guides/xps/)。 + +## Bruker NanoScope AFM + +Plotium 可导入 NanoScope `.spm` 图像、力曲线与 Force Volume 网格,以及 +PeakForce Capture `.pfc` 数据立方体。图像通道按文件记录的扫描尺寸和物理单位 +绘制成地图,并锁定纵横比。力曲线按 approach 与 retract 两段分别绘制;文件中 +记录了偏转灵敏度时,纵轴为以纳米计的偏转量,否则曲线保持文件中存储的单位。 +Plotium 按采集原样显示数据——不会推断接触点、压痕或模量,也不会拟合接触力学 +模型。 + +PeakForce Capture 文件旁通常保存着一个 AllImages `.spm` 导出文件。Plotium 会 +找到这个配套文件,核对其图像网格与力网格一致后,把两者作为一个数据集导入; +打开文件夹时这样的文件对也只导入一次,不会成为两个数据集。默认画布会把通道 +地图和网格中心像素的力曲线并排放置。找不到配套文件、或其网格不一致时, +`.pfc` 文件仍会导入,只是仅含力曲线。 + +PeakForce Capture 曲线是逐像素采集的原始信号。模量等派生 QNM 地图作为独立的 +图像通道导入;Plotium 不会从曲线重新计算这些地图。 + +## 电生理(ABF2) + +Plotium 读取 int16 或 float32 采样的 ABF 2.x 文件,支持多通道、多 sweep 以及 +文件内的 DAC/epoch 刺激。不支持 ABF1 和压缩的 ABF2 数据;请在采集软件中重新 +导出为未压缩的 ABF2。文件选择器可以一次选择多个 ABF,每个文件的直接父目录名 +会成为可编辑的初始 cell ID。sweep、滤波、时间窗统计、刺激与 IV 分析见 +[电生理](/zh-cn/guides/electrophysiology/)。 + +## 表格 + +CSV、TSV、带分隔符的 `.txt`、XLSX 以及从剪贴板粘贴的表格,都会经过表格导入 +预览。列类型推断、Origin CSV 表头和 XLSX 工作表的处理见 +[导入表格](/zh-cn/guides/importing-data/#导入表格)。 + +## Origin 项目(实验性) + +Origin 的 `.opj` 与 `.opju` 文件可以从 **Open File…** 和 **Import Table…** +两个入口选择;两者都根据文件内容识别格式,而不是只看扩展名。受支持的 `.opj` +中的工作表会进入[表格导入预览](/zh-cn/guides/importing-data/#导入表格)。导入过程中 +无需安装、启动或调用 Origin。 + +成功导入仅限两种通过文件内容精确识别的 OPJ 生成配置: + +- Origin 7.0552(`CPYA 4.2673 build 552`)可导入经过验证的 `f64`、`f32`、 + 有符号 `i32`、有符号 `i16`、定宽 ASCII 文本、数值与文本混合的单元格、 + 空值和非零行偏移。项目参数与备注会作为来源元数据保留。 +- Origin 9.51 build 195 W64(`CPYA 4.3268 build 195 W64`)可导入工作表名、 + 列名、`f64` 数值、空值和经过验证的空列。该配置目前不导入文本单元格、 + 项目参数或备注。 + +兼容性仅限上述经过测试的配置。不能因为扩展名相同或 Origin 主版本相同,就推定 +其他文件也受支持。 + +Plotium 会保留经过验证的 Origin 窗口或分组名与列名。每个受支持的窗口以单个 +数据表表示,并使用合成的工作表名 `Sheet1`;不解析原始工作表标签。Origin 7 的 +混合列会保留为文本,长度不等的列会用空值补齐。长名称、单位、注释、列标识、 +日期、分类值和未经验证的代码页不保证能够导入。 + +Plotium 会根据内容签名识别 `.opju` 文件,但本版本不能导入 `.opju`,也不会产生 +任何部分结果。 + +不支持的内容包括图形、公式、脚本、分析重新计算、把已保存的分析结果恢复为 +可执行分析、矩阵、嵌入对象、现代 OPJ 文本单元格、没有已验证代码页的非 ASCII +文本、加密或受保护项目、未经验证的 OPJ 版本或配置,以及未经验证的 OPJU +容器。对于受支持的 Origin 9.51 配置,Plotium 会在经过验证的窗口列表处停止 +解析,并警告剩余项目对象没有被导入。 + +Plotium 绝不猜测导入内容。损坏或截断的文件、超过当前 128 MiB 输入上限的文件、 +扩展名与签名不匹配的文件,以及结构异常或其他不受支持的文件,都会在提交任何 +数据表之前给出明确错误。在其他方面受支持的 OPJ 中,只有在相应内容具有独立框架 +且其外层边界可信时,才可以省略不受支持的工作表列,或跳过不受支持的非表格对象。 +Plotium 会为每次此类省略显示警告,因此导入的工作表可能只含受支持的列。若框架 +含糊,Plotium 会拒绝文件,而不会造成数据错位。 + +## Zip 压缩包 + +`.zip` 文件作为打包的数据文件夹打开。 diff --git a/docs/src/content/docs/zh-cn/guides/tables.md b/docs/src/content/docs/zh-cn/guides/tables.md index 37c2fa56..cf7d0404 100644 --- a/docs/src/content/docs/zh-cn/guides/tables.md +++ b/docs/src/content/docs/zh-cn/guides/tables.md @@ -68,67 +68,36 @@ these names** 把其取值变成新列名。工作表工具栏中的 **Combine** 这些转换也可以作为批处理任务无人值守地运行——参见 [自动化](/zh-cn/guides/automation/)和[命令行](/zh-cn/reference/cli/)。 -## 图表类型 - -选中由表格生成的图,在对象检查器的**图表类型**画廊中选择。Ribbon 的 **Figure** -页签中的 **Chart** 可直接跳转:它会选中表格对应的图并打开检查器。 - -选图表就是选它回答的问题:沿轴跟踪数值用 **Line**;跨类别比较数量用 -**Bar** 或 **Grouped bars**;看单列数值的分布用 **Histogram**;一眼比较 -多列的分布用 **Box** 或 **Violin**;展示整体中的占比用 **Pie**;一次看 -整个数值矩阵用 **Heatmap** 或 **Surface 3D**。 - -- **Line(散点/折线)**——每列一组散点,按 x 轴排布;已有拟合时叠加拟合曲线。 -- **Bar(柱状图)**——所选单列在数值 x 轴上绘制为填充柱。 -- **Grouped bars(分组柱)**——每行一组、组内各列并排;勾选 **Stacked** - 改为堆叠(正值向上、负值向下堆叠)。 -- **Histogram(直方图)**——所选单列的数值分布。默认按 - Freedman–Diaconis 规则自动分箱;取消勾选 **Auto bins** 后可在 **Bins** 中 - 指定 1 到 512 的固定箱数。取消勾选时沿用自动规则刚算出的箱数,因此直方图 - 不会随之变样。 -- **Box(箱线图)**——每列一箱:中位数、四分位箱体、1.5 × IQR 须线, - 以及逐个绘制的离群点。 -- **Violin(小提琴图)**——每列一个核密度轮廓,内嵌四分位条 - (每列至少需要两个不同数值;退化列回退为原始散点)。 -- **Heatmap(热图)**——整张表作为色图矩阵,行自上而下排列; - 在检查器中选择色图。 -- **Pie(饼图)**——所选单列的每一行为一个扇区,并标注百分比。 - 负值与缺失行不参与。 -- **Surface 3D(3D 曲面)**——把表格视为高度场,以固定正交视角绘制; - 可在检查器中调整方位角/仰角与色图。 - -分组柱、箱线、小提琴、热图与 3D 曲面一次使用全部列;柱状图、直方图和 -饼图读取画廊旁选中的单列。所有图表在屏幕显示与 SVG/PDF/EMF 导出中 -完全一致。 - -## 由表格作图 - -误差棒来自一列——它保存另一列的不确定度。Plotium 分析工具生成的表格已经带有这些 -关系,导入的表格则会带上其文件所描述的关系——对称 ±σ、分开的上下误差,或带置信 -水平的置信区间。要给自己的数据添加误差棒,可在 CSV 或 TSV 中,紧跟某个 y 列放一 -个名为 `_sigma` 的列,保存每个点的不确定度(取零或正值);导入时 Plotium 会把它 -作为对称标准差关联到该 y 列。绘图前,Plotium 会检查数值列与其不确定度的单位是否 -兼容。散点图、柱状图和未堆叠分组柱会把这些绘制为纵向误差棒,并扩展 y 轴以保证 -误差棒完整可见。 - -需要用数学模型拟合其中的 x-y 数值时,在**分析**选项卡的**曲线拟合**组中选择**拟合曲线**。画布右上角会打开曲线拟合 -任务卡片:选择模型,再选择拟合全部曲线或一条选定曲线,然后选择**运行拟合**。 -有关内置模型、自定义模型、共享(全局)参数、权重与稳健损失选项以及拟合诊断, -请参阅[曲线拟合](/zh-cn/guides/curve-fitting/)。拟合曲线及其结果会保留在表格中。 -使用**导出数据…**并选择**曲线拟合参数**,可导出参数、诊断、协方差以及 -逐点预测和残差。 -每次完成拟合都会记录它实际使用了哪些行、排除了哪些行以及排除原因,因此后续编辑 -表格不会悄悄改变该结果所依据的观测点。曲线拟合导出会列出这些纳入和排除的行。 - -**导出数据…**也可以把完整表格导出为 CSV、TSV、XLSX 或剪贴板 TSV。空单元格保持为 -空;`NaN`、`+Inf` 和 `-Inf` 会写成这些字面标记,因为它们是真实取值而非空白。以上 -每种格式都会把表格的列类型、单位和误差棒关系与数据一起携带——CSV/TSV 用配套的 -`.plotium-schema.json`,XLSX 用隐藏工作表,复制 TSV 用剪贴板内容——因此只有当你手工 -构造没有这些信息的文件时,才需要 `_sigma` 这样的列名。 - -**谱峰拟合**是另一项独立功能:当绘制出的曲线包含相互重叠、需要分解的 -谱峰时使用它——参见[分析工具一览](/zh-cn/guides/choosing-a-tool/)。 - -要对表格的列比较分组、检验相关性、检查正态性或运行方差分析,请在 -**Analyze(分析)** 标签中选择 **Statistics(统计)**。参见 -[统计分析](/zh-cn/guides/statistics/)。 +## 导出表格 + +**导出数据…**可以把完整表格导出为 CSV、TSV、XLSX 或剪贴板 TSV。空单元格保持为 +空;`NaN`、`+Inf` 和 `-Inf` 会写成这些字面标记,因为它们是真实取值而非空白。CSV、 +TSV 和 XLSX 会把表格的列类型、单位和误差棒关系与数据一起携带(在 Windows 上剪贴板 TSV 也会),因此再次导入时不会 +丢失这些信息;见 [Plotium 文件](/zh-cn/reference/file-formats/#表格-schema-配套文件)。导出选项见 +[导出数值数据](/zh-cn/guides/exporting/#导出数值数据)。 + +## 分析表格 + +- 要把表格的列画成图、选择图表类型,见[绘图与图表类型](/zh-cn/guides/plots-and-charts/), + 其中也介绍了如何添加[误差棒](/zh-cn/guides/plots-and-charts/#误差棒)。 +- 需要用数学模型拟合 x-y 数值时,在**分析**选项卡的**曲线拟合**组中选择 + **拟合曲线**;见[曲线拟合](/zh-cn/guides/curve-fitting/)。拟合曲线及其结果会 + 保留在表格中。每次完成拟合都会记录它使用了哪些行、排除了哪些行以及排除原因, + 因此后续编辑表格不会悄悄改变该结果所依据的观测点。使用**导出数据…**并选择 + **曲线拟合参数**,可导出参数、诊断、协方差以及逐点预测和残差,导出中会列出 + 纳入和排除的行。 +- 要比较分组、检验相关性、检查正态性或运行方差分析,在 **Analyze(分析)** + 标签中选择 **Statistics(统计)**;见[统计分析](/zh-cn/guides/statistics/)。 +- 要分解所绘曲线中相互重叠的谱峰,请改用**谱峰拟合**;见 + [分析工具一览](/zh-cn/guides/choosing-a-tool/)。 + +## 使用 AI 客户端 + +也可以让连接到 Plotium 的 AI 客户端替你修改表格数据,例如: + +> 只改这一个源单元格,告诉我哪些派生表过期了,然后刷新这张表。保留我的颜色、坐标轴范围和排版。 + +> 从这张表生成一张新表:加一列等于 current × 2,只保留 time 不为 0 的行,并按 time 降序排列。 + +修改单元格和刷新派生表是两步独立的 Undo;图的样式不变。派生表是一张新表, +不会改动它的来源。使用前请先检查刷新后的数值。参见[权限、审阅与撤销](/zh-cn/ai/control-and-review/)。 diff --git a/docs/src/content/docs/zh-cn/guides/themes-and-styles.md b/docs/src/content/docs/zh-cn/guides/themes-and-styles.md new file mode 100644 index 00000000..73276b9d --- /dev/null +++ b/docs/src/content/docs/zh-cn/guides/themes-and-styles.md @@ -0,0 +1,86 @@ +--- +title: 字体、主题与样式 +description: 为所有图设定字体和字号,套用 Nature 等画布主题,并保存可复用的样式。 +--- + +Plotium 自动按印刷习惯设定图形样式。新数据集默认使用 89 × 60 mm 单栏画布:单个图 +占满画布时,屏幕上看到的字号就是期刊印出的字号;多分图的组合图之后再拼合到更宽的 +页面上,各分图保持原始尺寸。 + +## 字体 + +图中文字默认在画布和所有导出格式中都使用 Arial。没有 Arial 时改用 Helvetica 或 +Liberation Sans 等字宽相同的无衬线字体。SVG 文件写明字体,用矢量软件打开也保持 +Nature 系列期刊要求的字体。 + +**Figure typography** 分区中的 **Font** 切换所有图内文字的字体——刻度标签、轴标题、 +图标题、图例、色标和图内标注——可选 *Arial*(默认)、*Helvetica* 或 +*Times New Roman*。Helvetica 在 macOS 上用 Helvetica 绘制;Windows 和 Linux 上改用 +字宽相同的 Arial 或 Liberation Sans,SVG 文件仍把 Helvetica 写在首位。没有 +Times New Roman 时改用 Liberation Serif 等字宽相同的衬线字体。高级设置中的 +**Font weight** 把这些文字设为 *Regular*(常规)或 *Bold*(粗体)。画布上的文本框和 +分图字母仍保持各自的 Arial 样式。这两项设置随主题和已保存的样式一起保存和套用; +内置主题使用 Arial Regular。 + +## 图形排印 + +Figure Ribbon 选项卡 **Style** 分组中的 **Figure typography** 会打开文档级排版分区; +命令面板中的 **Figure Typography…** 以独立窗口显示同一分区,并多出 +**Reset to defaults** 按钮。两者都一次设定文档内所有图的文字尺寸(刻度标签、轴标题、 +图标题与图例),单位为绝对磅值——这是文档级样式,缩放分图不会改变字号。各字号取值 +1 到 72 pt;图例默认为 7 pt。 + +同一分区的高级设置还统一设定所有图的坐标轴线条和刻度,见 +[刻度线与坐标轴线](/zh-cn/guides/axes/#刻度线与坐标轴线)。 + +对象检查器的 **Figure typography** 区域中的 **Tick-label size** 就是同一个刻度标签 +字号,并提供 **Legend size** 与 **Legend text color**。在两处中任何一处修改,改的都是 +文档里的同一个值。它属于文档而不属于某个图,因此无论当前选中什么(包括什么都没选中) +都会显示。 + +## 画布主题 + +要给当前画布套用主题,在 **Figure** 选项卡的 **Style** 组中选择 **Paper**、**Nature**、 +**Dark** 或 **Vibrant**,或在 **View ▸ Canvas Theme** 中选择。套用主题是一个可撤销的步骤。 + +画布主题携带配套字号——例如 Presentation Dark 主题会放大坐标轴文字以适合投影演示。 + +**Nature** 主题遵循 Nature Portfolio 终稿作图规范:文字 7 pt,线宽按字号缩放—— +坐标轴、刻度、柱描边以及新建的参考线和箭头为 0.3 pt,折线系列为 0.5 pt——刻度朝外 +3 pt,符号 3 pt 且无描边,使用对色盲友好的 Okabe–Ito 配色。手动加上的符号描边会保留。 +这些尺寸以 Nature 栏宽为准,套用到宽度不符合任一 Nature 尺寸预设(89、136 或 +183 mm)的画布时,状态栏会附带提示列出这些宽度;画布尺寸保持不变。宽度已符合某个 +Nature 尺寸、但尚未设定尺寸预设的画布,会随之采用该 Nature 预设,导出检查因此按 +Nature 的下限(文字 5 pt、线条 0.25 pt)判断。 + +之后切换到不设定线宽和符号大小的主题时,这些线宽和符号大小会保留。 + +## 手动设置的值 + +手动设置的值(在对象检查器中设置、在控件上滚动调整或拖动图例)会替你保留。任何主题 +都不会改动它们:曲线和符号颜色、线宽、符号大小和描边、文字和形状颜色以及图形排版。 +状态栏会说明保留了几处。连接到 Plotium 的 AI 客户端也会跳过它们,除非你要求它修改; +AI 设置的值不算作你的设置。重置该值(或双击拖动过的图例)后,它重新跟随主题。 + +## 已保存的样式 + +**Save Canvas Style…**(View ▸ Canvas Theme,或 Figure Ribbon 选项卡 Style 组中的 +**Save Style**)把当前画布的外观保存为命名样式:背景、文字颜色与字号、图形排版 +(包括字体和字重)、坐标轴和刻度线宽、曲线颜色及其符号填充色、描边和空心设置、线宽 +和符号大小。**Canvas Styles…** 列出已保存的样式,可套用到当前画布或删除。套用样式是 +一次可撤销的操作。要修改某个样式,先套用它,调整画布后再用同一名称保存。 + +样式以 `.plotiumstyle` 文件保存在 Plotium 配置目录的 `styles` 文件夹中,可以复制到 +其他电脑使用:macOS 上位于 `~/Library/Application Support/plotium/styles`;其他平台见 +[Plotium 的设置存放在哪](/zh-cn/getting-started/installation/#plotium-的设置存放在哪)。 + +## 使用 AI 客户端 + +也可以让连接到 Plotium 的 AI 客户端替你完成,例如: + +> 给这张画布套用 Nature 主题,先给我看预览。保留我手动设置的颜色。 + +> 把我保存的样式 Group meeting 套用到这个项目的所有画布上。 + +你手动设置过的值会保留,除非你明确让 AI 改;每次修改都是一步 Undo。同意之前请先看 +预览。参见[权限、审阅与撤销](/zh-cn/ai/control-and-review/)。 diff --git a/docs/src/content/docs/zh-cn/index.mdx b/docs/src/content/docs/zh-cn/index.mdx index 36e004ed..ffa6d1c2 100644 --- a/docs/src/content/docs/zh-cn/index.mdx +++ b/docs/src/content/docs/zh-cn/index.mdx @@ -1,13 +1,17 @@ --- title: Plotium -description: 面向科学数据分析与出版级图形制作的桌面应用。 +description: 面向科学数据分析与出版级图形制作的桌面应用,可以单独使用,也可以配合 AI 客户端。 template: splash hero: - tagline: 导入、处理、分析、出版级导出——一个桌面应用完成全部流程。 + tagline: 导入、处理、分析、出版级导出——一个桌面应用完成全部流程,可以自己动手,也可以和 AI 客户端一起完成。 actions: - text: 快速上手 link: /zh-cn/getting-started/installation/ icon: right-arrow + - text: 连接 AI 客户端 + link: /zh-cn/ai/connect/ + icon: right-arrow + variant: secondary - text: 在 GitHub 查看 link: https://github.com/nmrtist/plotium icon: external @@ -18,8 +22,13 @@ import { Card, CardGrid } from '@astrojs/starlight/components'; - 直接读取 JEOL Delta(`.jdf`)和 Bruker TopSpin 的 NMR 数据、 - 膜片钳记录(ABF2),以及 CSV / Excel 表格数据——无需转换。 + 直接读取 NMR(JEOL、Bruker、Varian/Agilent、JCAMP-DX)、LC–MS(Waters、 + SCIEX WIFF、mzML)、粉末 XRD、XPS、AFM 和膜片钳(ABF2)文件,以及 CSV、TSV、 + Excel 和 Origin 表格——无需转换。见[支持的格式](/zh-cn/guides/supported-formats/)。 + + + 连接 Claude Desktop 或其他 MCP 客户端,让它导入数据、生成并调整图、排布面板。 + 它做的修改都出现在你的画板上,可以先预览,也可以撤销。 以有序步骤列表构建处理管线:切趾、FFT、相位与基线校正——实时预览,完整撤销。 diff --git a/docs/src/content/docs/zh-cn/reference/cli.md b/docs/src/content/docs/zh-cn/reference/cli.md index cdaf7cc8..fed33268 100644 --- a/docs/src/content/docs/zh-cn/reference/cli.md +++ b/docs/src/content/docs/zh-cn/reference/cli.md @@ -33,7 +33,7 @@ NUS 数据报告的形状包含未采样网格点,不等于实际观测数。 报告中的 `domain` 为 `"mixed"`。 处理前请检查报告中的警告。缺失的校准或数字滤波延迟保持未知,详见 -[NMR 格式限制](/zh-cn/reference/file-formats/#nmr-数据与项目)。处理失败会指出 +[NMR 格式限制](/zh-cn/guides/supported-formats/#nmr)。处理失败会指出 具体步骤,并返回非零退出码。 `process` 是"一次导入、一个[处理配方](/zh-cn/guides/templates/)、一次 @@ -110,9 +110,9 @@ plotium-cli inspect experiment/ser --sampling-declaration sampling.json --json plotium-cli batch --workflow --manifest ``` -`batch` 运行一个工作流文件——与应用内自动化窗口使用同一种 JSON,因此 -最简单的做法是先在应用里构建并校验工作流,再把文件交给命令行做无人值守 -运行。 +`batch` 运行一个工作流文件,与应用内自动化窗口运行的是同一种 JSON。手动编写该 +文件(见[工作流文件结构](#工作流文件结构)),需要时可在自动化窗口中用 **Validate** +校验,再交给命令行做无人值守运行。 每次运行都会写出一份运行记录:工作流及其哈希、Plotium 版本、每一步作用的 目标,以及每一步的参数、结果、警告和错误。同一份 JSON 同时写入 @@ -149,9 +149,8 @@ plotium-cli export --output-dir [--format pdf|svg|png|ti ## 工作流文件结构 -工作流(`plotium.workflow.v1`)是无环的 JSON 步骤图。你很少需要从零手写 -——应用会生成它——但格式是纯文本、可编辑的。一个最小的导入 → 处理 → -导出工作流: +工作流(`plotium.workflow.v1`)是无环的 JSON 步骤图。应用不会生成工作流文件, +可以从下面这个最小的导入 → 处理 → 导出示例开始修改: ```json { diff --git a/docs/src/content/docs/zh-cn/reference/command-palette.md b/docs/src/content/docs/zh-cn/reference/command-palette.md index 7db90186..db9175e5 100644 --- a/docs/src/content/docs/zh-cn/reference/command-palette.md +++ b/docs/src/content/docs/zh-cn/reference/command-palette.md @@ -76,7 +76,7 @@ description: 用键盘搜索命令、设置与数据。 `stroke width`、`trace thickness` 与 `line thickness` 都能命中它。 - 对象检查器 **Figure typography** 区域的 **Tick-label size**。`font size`、 `tick size`、`points` 与 `figure typography` 都能命中它。参见 - [版面与导出](/zh-cn/guides/layout-and-export/)。 + [字体、主题与样式](/zh-cn/guides/themes-and-styles/#图形排印)。 - 处理卡片中切趾步骤的 **Window**、**LB** 与 **GB**。`apodization`、 `window function`、`exponential`、`gaussian`、`LB`、`line broadening`、 `GB` 与 `gaussian broadening` 都能命中它们。参见 diff --git a/docs/src/content/docs/zh-cn/reference/file-formats.md b/docs/src/content/docs/zh-cn/reference/file-formats.md index 5af32448..50515341 100644 --- a/docs/src/content/docs/zh-cn/reference/file-formats.md +++ b/docs/src/content/docs/zh-cn/reference/file-formats.md @@ -1,19 +1,22 @@ --- -title: 文件格式 -description: Plotium 自有文件、导入格式及其兼容性边界。 +title: Plotium 文件 +description: Plotium 自己写出的文件:项目、处理配方、样式、拟合模型、工作流、运行记录和表格 schema 配套文件。 --- +本页介绍 Plotium 自己创建的文件。Plotium 能读取的仪器与表格格式见 +[支持的格式](/zh-cn/guides/supported-formats/)。 + ## `.plotium` 项目 `.plotium` 文件把整个会话保存在一个文件里:导入的数据、处理管线、分析结 -果、画板排版、已保存的工作流,以及每次自动化运行的记录。因此它是自包含 -的——复制到另一台机器或发给同事,打开时与你保存时完全一致,不需要记着 +果、画板排版、嵌入的图片、已保存的工作流,以及每次自动化运行的记录。因此它是 +自包含的——复制到另一台机器或发给同事,打开时与你保存时完全一致,不需要记着 带任何附属文件。与使用任何分析软件一样,保留原始仪器数据仍是好习惯。 **Preferences → General → Project backup copies** 会在项目旁以隐藏文件 保留历史保存,误覆盖后可以恢复。 自动崩溃恢复检查点是单独的内部文件;它们只在出现新编辑后更新,并不是可供 -分享的项目副本。 +分享的项目副本。见[保存项目](/zh-cn/guides/organizing-data/#保存项目)。 对于同核 2D 审核,项目会保存交叉峰标记、互为对应峰的配对关系,以及每个 标记的审核状态。固定的光标位置与对称审核结果不会保存。 @@ -23,24 +26,9 @@ description: Plotium 自有文件、导入格式及其兼容性边界。 重新打开项目时,若某张图与项目重建出的数据不再一致,Plotium 就据此发出警告。 等高线绘图本身不保存;项目打开时,Plotium 会根据保存的图重新绘制。 -## 嵌入图片 - -Plotium 支持 PNG、JPEG、TIFF、WebP 与 BMP,并将图片保存在 `.plotium` 项目中。 -复制图片不会重复保存源图片,但每个副本可以分别设置裁剪、旋转、透明度、适配与 -插值方式。导出与剪贴板输出从嵌入像素采样,并保留这些设置、Panel 裁切和 z 顺序; -SVG 会嵌入图片数据,不依赖原始本机路径。 - -Plotium 不支持 SVG。用 **Add Images…** 添加动画 PNG 或 WebP 时,Plotium 会提示该 -图片包含动画;使用 **Add Animated Image First Frame…** 可显示其第一帧。 -**Add Images Without Metadata…** 会先把图片像素转换为 PNG,再保存到项目中。 - -图片超过 5 亿像素或预计解码后超过 2 GiB 时,Plotium 会拒绝导入;超过 1 亿像素或 -512 MiB 时,会先要求确认。对于多页 TIFF,**Add Images…** 导入第一页,**Add All -TIFF Pages…** 导入 Plotium 能够读取的所有页面。导入后的各页可以分别编辑。 - -项目打开时,Plotium 会校验每张嵌入图片。资源缺失、损坏或与记录不符时,Plotium 会 -显示诊断和可替换的占位项,但不会丢弃页面或图片项,也不会静默保存这一降级状态。 -出版导出默认停止;若仅用于审阅,可在导出对话框中明确输出带标签的占位图。 +添加到页面上的图片保存在项目内部。复制图片不会重复保存源图片。项目打开时, +Plotium 会校验每张嵌入图片;缺失或损坏的图片会变成可替换的占位项。见 +[图中的图片](/zh-cn/guides/images/)。 ## `.plotiumproc` 处理配方 @@ -48,50 +36,20 @@ TIFF Pages…** 导入 Plotium 能够读取的所有页面。导入后的各页 任何机器上应用到一整个系列的同类实验。见 [配方与模板](/zh-cn/guides/templates/)。 -## NMR 数据与项目 - -Plotium 支持一维和二维 NMR,包括带参数轴的系列。请根据要使用的数据选择输入: - -- **Bruker:**选择实验目录可读取原始数据,选择 `pdata` 内的谱文件可读取已处理谱。 - 若目录中有多个无法区分的候选,请指定具体文件或处理目录。支持 States 二维数据 - (`FnMODE=4`)。已处理谱保留文件中提供的实部和虚部分量。 -- **JEOL:**选择含有受支持的原始或已处理采集数据的 `.jdf` 文件。 -- **JCAMP-DX:**支持 5.00 或 5.01 版普通 XYDATA 频谱,每个坐标对应一个强度值, - 坐标单位可为 Hz 或 ppm。不支持 LINK、NTUPLES 和峰表。 - -缺失的核种、频率参考或数字滤波延迟信息保持未知。Hz 谱可以直接显示,但部分分析 -需要额外校准。滤波延迟未知的原始数据首先显示为 FID;查看未校正频谱的方法见 -[群延迟校正](/zh-cn/guides/processing/#群延迟校正),选择分析功能前请核对 -[校准条件](/zh-cn/guides/processing/#分析前检查校准条件)。坐标未知或数据排列不受支持时, -导入会给出错误或诊断信息。 - -JEOL 与 Bruker NUS 为实验性支持,未覆盖所有仪器和采集设置。使用不熟悉的采集类型时, -请检查导入诊断,并与可信参考结果比较后再使用分析结果。 - -保存 `.plotium` 项目会保留导入的 NMR 分量、采样顺序、来源信息、警告和处理设置。 -重开项目时,Plotium 根据保存的设置重新计算频谱,无需原始厂商文件。 - -## Varian/Agilent VnmrJ 原始 NMR - -选择同时含有 `fid` 与 `procpar` 的 `.fid` 目录,或其中的 `fid` 文件。支持原始一维 -数据、仅改变一个非分组参数的系列,以及 `phase=[1,2]` 的二维数据。样本格式可为 -大端字节序的 16 位整数、32 位整数或 32 位浮点数。 +命名的处理模板保存在 Plotium [配置目录](/zh-cn/getting-started/installation/#plotium-的设置存放在哪)的 +`templates` 文件夹中。 -不支持分组或多个参数数组、其他 phase 顺序、Varian NUS、超过二维的数据和已处理谱。 -记录的维度或分量排列与实际数据不符时,导入会停止。 +## `.plotiumstyle` 画布样式 -## SCIEX legacy WIFF +**Save Canvas Style…** 会把当前画布的外观写成配置目录 `styles` 文件夹中的一个 +`.plotiumstyle` 文件。把该文件复制到另一台电脑的同一文件夹,即可在那里使用这个 +样式。见[字体、主题与样式](/zh-cn/guides/themes-and-styles/)。 -Plotium 会同时读取 legacy `.wiff` OLE 元数据容器,以及在完整 `.wiff` 文件名 -末尾追加 `.scan` 所得到的 `.wiff.scan` payload。导入器使用纯 Rust,不要求 -安装 SCIEX Analyst、SCIEX OS 或 ProteoWizard SDK。 +## 自定义拟合模型 -目前仅支持已验证的 legacy 布局。原生导入器会读取 sample subtree/index 流,保留 -重复样本为独立样本,并将已验证的 11 个 experiment 槽位分别提供为独立的 -acquisition stream 与 TIC channel。记录按 cycle 顺序保留,包括零 TIC 和空 DDA -槽位;不会跨 experiment 合并时间或插值。未知或结构不同的 WIFF 变体会在创建 -数据集之前被拒绝。加密或较新的 `.wiff2` 与 -`.timeseries.data` 不在此边界内,必须先转换为 mzML。 +自定义拟合模型在 Curve Fit 编辑器中用 `.plotiumfit` 模型语言编写,统一保存在 +模型库中,即配置目录里的 `fit-models.json`。模型只是纯数据,不会运行代码。见 +[自定义拟合模型](/zh-cn/guides/custom-models/)。 ## 工作流与运行记录文件 @@ -103,61 +61,9 @@ acquisition stream 与 TIC channel。记录按 cycle 顺序保留,包括零 TI 工作流不是配方:配方保存一条处理管线,而工作流描述一整次运行,可以把 配方作为其中一个步骤引用。 -## XPS 导入 - -VAMAS `.vms` 支持明确限定为按内容签名识别、具有规则能量标尺的 ISO 14976 -`NORM` / `REGULAR` XPS 区块。一个文件始终是一个实验,并保留稳定的测量位置与 -谱区 ID。Plotium 保存原生能量、Counts、CPS、光子能量、dwell time、sweep、位置、 -采集条件和自由元数据。只有区块边界可信时才会警告并跳过非 XPS 区块;XPS payload -结构异常时拒绝整个文件。ordinate 极值属于元数据而不是数据点;ordinate 标签和 -信号模式共同决定脉冲计数是否换算为 CPS。 - -CasaXPS `.txt` 按八行结构识别,而不是仅按 `.txt` 扩展名识别。源数组与拟合参数 -以 `Imported` 结果保存;非结构化文本继续走表格导入。能量换算、处理、拟合与导出 -约定见 [XPS](/zh-cn/guides/xps/)。 - -## Origin 项目导入(实验性) - -Origin 项目导入仍属实验性。成功导入仅限两种通过文件内容精确识别的 OPJ -生成配置: - -- Origin 7.0552(`CPYA 4.2673 build 552`)可导入经过验证的 `f64`、`f32`、 - 有符号 `i32`、有符号 `i16`、定宽 ASCII 文本、数值与文本混合的单元格、 - 空值和非零行偏移。项目参数与备注会作为来源元数据保留。 -- Origin 9.51 build 195 W64(`CPYA 4.3268 build 195 W64`)可导入工作表名、 - 列名、`f64` 数值、空值和经过验证的空列。该现代配置目前不导入文本单元格、 - 项目参数或备注。 - -兼容性声明仅限仓库中已提交的 Origin 7 回归样本,以及通过两个真实项目、配套 -CSV 导出和独立解析器对照检查的精确 Origin 9.51 配置。不能因为扩展名相同或 -Origin 主版本相同,就推定其他文件也受支持。 - -Plotium 会保留经过验证的 Origin 窗口或分组名与列名。每个受支持的窗口以单个 -数据表表示,并使用合成的工作表名 `Sheet1`;本版本不声称能够解析原始工作表 -标签。Origin 7 的混合列会保留为文本,长度不等的列会用空值补齐。目前不声称 -已验证长名称、单位、注释、列标识、日期、分类值或未经验证的代码页。 - -Plotium 会根据 CPYUA 内容签名识别 `.opju` 文件,但本版本不能导入 `.opju`, -也不会产生任何部分 OPJU 结果。 - -不支持的内容包括图形、公式、脚本、分析重新计算、把已保存的分析结果恢复为 -可执行分析、矩阵、嵌入对象、现代 OPJ 文本单元格、没有已验证代码页的非 ASCII -文本、加密或受保护项目、未经验证的 OPJ 版本或配置,以及未经验证的 OPJU -容器。对于受支持的 Origin 9.51 配置,Plotium 会在经过验证的窗口列表边界停止 -解析,并警告剩余项目对象没有被导入。 - -Plotium 绝不会静默导入,也不会凭推测猜测导入内容。损坏或截断的文件、超过当前 -128 MiB 输入上限的文件、扩展名与签名家族不匹配的文件,以及结构异常或其他 -不受支持的文件,都会在提交任何数据表之前给出明确错误。在其他方面受支持的 -OPJ 中,只有在相应内容具有独立框架且其外层边界可信时,才可以省略不受支持的 -工作表列,或跳过不受支持的非表格对象。Plotium 会为每次此类省略或跳过显示警告; -因此,导入的工作表可能只含受支持的列,而非源文件中的全部列。若框架含糊或 -不可信,Plotium 会拒绝文件,而不会猜测边界或静默造成数据错位。 - -导入过程中无需安装、启动或调用 Origin。 - -## 你导入和导出的数据 +## 表格 schema 配套文件 -受支持的仪器与表格格式见[导入数据](/zh-cn/guides/importing-data/);图形 -与数据导出见[导出](/zh-cn/guides/exporting/)——包括让导出的 CSV/TSV 能 -带着列类型、单位和误差棒完整回到 Plotium 的 `.plotium-schema.json` 配套文件。 +Plotium 把表格导出为 CSV 或 TSV 时,会在旁边写入一个 `.plotium-schema.json` +文件,记录列类型、单位和误差棒关系。导出 XLSX 时同样的信息保存在隐藏工作表中, +复制 TSV 时(Windows 上)则放到剪贴板。再次导入该表格时会恢复这些信息;见 +[Plotium 导出的表格](/zh-cn/guides/importing-data/#plotium-导出的表格)。 diff --git a/docs/src/content/docs/zh-cn/reference/mcp.md b/docs/src/content/docs/zh-cn/reference/mcp.md deleted file mode 100644 index 75435842..00000000 --- a/docs/src/content/docs/zh-cn/reference/mcp.md +++ /dev/null @@ -1,1979 +0,0 @@ ---- -title: MCP 接口参考 -description: Plotium 本机 MCP 客户端的手动配置、工具调用与限制。 ---- - -连接步骤和日常使用请先阅读 [AI 客户端连接](/zh-cn/guides/automation/#本机-agent-连接mcp)。本页用于自定义客户端和工具调用层面的排查。 - -## 手动配置与诊断 - -Windows 上,Plotium 从 `PATH` 查找独立的客户端可执行文件。对于通过 npm 安装的 -Codex,会在 `PATH` 中的 npm 前缀和默认的 `%APPDATA%\npm` 前缀内查找包中的原生 -可执行文件,支持 x64 和 ARM64 安装。使用自定义 npm 前缀时,请将它加入 `PATH` -并重启 Plotium,或通过 **Choose executable…** 选择包内的 `codex.exe`。 -添加 Codex 客户端需要先安装 Codex CLI。 - -在 **Preferences → AI connections (MCP)** 中展开 **Manual configuration and diagnostics**, -点击 **Copy stable stdio configuration**。复制的 JSON 含实际连接器绝对路径; -下例中的路径仅为占位符: - -```json -{"mcpServers":{"plotium":{"command":"/ABSOLUTE/USER/DATA/bin/plotium-mcp","args":[]}}} -``` - -请使用页面复制的真实路径,Windows 文件名为 `plotium-mcp.exe`。启用时连接器会 -复制到用户数据目录,应用升级时更新。发行安装目录中请将 `plotium-mcp` 保留在主 -程序旁。官方 CLI 注册形式为: - -```sh -codex mcp add plotium -- /ABSOLUTE/USER/DATA/bin/plotium-mcp -claude mcp add --transport stdio --scope user plotium -- /ABSOLUTE/USER/DATA/bin/plotium-mcp -``` - -参见 [Codex MCP](https://learn.chatgpt.com/docs/extend/mcp?surface=cli)、 -[Claude Code MCP](https://code.claude.com/docs/en/mcp) 和 -[MCP Bundle manifest](https://github.com/modelcontextprotocol/mcpb/blob/main/MANIFEST.md)。 -临时 HTTP 诊断信息包含密钥,服务重启后失效,仅用于高级诊断,不是保存的客户端 -配置。发现文件只面向当前用户和本机;不支持远程或 WSL 跨环境访问。 - -升级 Plotium 后,请重启 AI 客户端中的 Plotium MCP 连接,以加载更新后的工具。 -如果连接器安装失败,请打开 **AI connections (MCP)** 查看错误并点击 **Retry**。 - -## 权限与支持范围 - -支持的修改使用 Plotium 的 **Undo** 与 **Redo**。只读立即阻止后续修改执行,包括 -待执行计划;表格读取及属性预检仍可用,导入、原生曲线绑定、创建及处理/补丁/刷新预检要求读取和 -修改权限。权限会记住,直到手动更改。 - -项目查询及计划创建须同时提交 `expected_revision` 和 `expected_project_context`, -后者取自 `plotium_get_state` 的 `project_context`;下文示例用 `PROJECT_CONTEXT` -占位。每次打开、新建、关闭或恢复项目都会更换上下文,即使 revision 相同也不可 -混用。切换清空计划并拒绝旧队列工作;切换期间的 `busy` 表示需等待完成或取消。 -收到 `project_changed` 后重新读取状态、发现目标并规划,不沿用旧目标或计划。 -执行计划绑定创建时的上下文。 - -项目编辑、科学计算和数据变换保留持久运行溯源,使项目进入未保存状态。普通查询(状态、 -资源/属性/表格/文档浏览、科学结果查看、预览及诊断)不追加项目审计记录,也不改变 -dirty、edit generation 或 automation revision。纯查询工作流同样不改变项目;包含修改 -操作的工作流仍保留完整运行记录,包括复现操作所需的查询输入。握手、工具发现、 -已认证状态查询、每五秒心跳、静态属性目录以及保存协调(预检、提交与 -`plotium_save_status`),以及导出预检/提交/状态查询均不生成审计记录。 - -连接支持原生采集导入、CSV/TSV/XLSX 仅数据导入、原生表格查询、画布预览、图面几何诊断、文档结构、原生建图及页面/面板/文字/本地图片编辑、显式数值曲线绑定、受支持的表格处理、单元格补丁、已存配方显式刷新和 -资源查询、数据集/画布/画布对象重命名、为画布套用内置主题或已保存的画布风格,以及以下显示属性: - -| 属性 ID | 目标 | 取值 | -| --- | --- | --- | -| `series.line.color` | 图对象+Series | `#RRGGBB` | -| `series.line.stroke_width` | 图对象+Series | 0.05–10 pt | -| `series.line.style` | 图对象+Series | `solid`, `dashed`, `dotted`, `dash_dot` | -| `series.line.marker` | 图对象+Series | `none`, `circle`, `square`, `diamond`, `triangle_up`, `triangle_down`, `star`, `pentagon`, `hexagon`, `plus`, `cross` | -| `series.line.marker_size` | 图对象+Series | 0.1–20 pt,直径 | -| `series.line.marker_fill / series.line.marker_edge_color` | 图对象+Series | `#RRGGBB` | -| `series.line.marker_edge_width` | 图对象+Series | 0–5 pt;0 表示无边框(空心时为 0.5 pt) | -| `series.line.marker_hollow` | 图对象+Series | 布尔值 | -| `series.line.marker_every` | 图对象+Series | 1–1000;从第一个点起每 n 个点画一个符号(默认 1) | -| `series.bar.width` | 图对象+Series | 0.05–1,占所在槽位宽度的比例(仅柱状曲线;默认 0.8) | -| `series.bar.edge_color` | 图对象+Series | `#RRGGBB`,柱描边颜色(仅柱状曲线;未设置时为带填充色色相的近黑色,并随曲线颜色变化) | -| `series.bar.edge_width` | 图对象+Series | 0–5 pt,柱描边宽度;0 表示无描边(仅柱状曲线;默认 0.5 pt,主题规定了辅助线宽时用它) | -| `series.y_axis` | 图对象+Series | `left`、`right`(折线和散点曲线;柱状曲线只能在左轴) | -| `series.points.spread` | 图对象+Series | 0–1,重复数据点在所在柱宽度内的散开程度(散点和折线曲线;默认 0) | -| `series.value_labels` | 图对象+Series | 布尔值;写出每根柱或每个点的数值(柱状、散点和折线曲线) | -| `series.replicates` | 图对象+Series | 0–100000,每个数据点由几次重复得到;0 表示未说明 | -| `series.error_bars` | 图对象+Series | `unspecified`、`sd`、`sem`、`ci95`;y 误差表示什么(有 y 误差列的曲线) | -| `object.chart.orientation` | 图对象 | `vertical`、`horizontal`(按列绑定的图) | -| `object.intent.purpose` | 图对象 | `unspecified`、`compare`、`trend`、`distribution`、`relationship`、`composition`、`change`、`detail`;这张图要表达什么 | -| `object.intent.claim` | 图对象 | 最多 500 个字符的字符串;这张图要支撑的那句结论 | -| `series.visible` | 图对象+Series | 布尔值 | -| `series.label` | 图对象+Series | 文本 | -| `object.axes.x_label / object.axes.y_label` | 图对象 | 文本 | -| `object.axes.x_show_label / object.axes.y_show_label` | 图对象 | 布尔值;显示轴标题 | -| `object.axes.x_show_tick_labels / object.axes.y_show_tick_labels` | 图对象 | 布尔值 | -| `object.axes.x_thousands_separator / object.axes.y_thousands_separator` | 图对象 | 布尔值;刻度数字按千分位分组 | -| `object.axes.x_major_step / object.axes.y_major_step` | 图对象 | ≥ 0,按显示单位计的主刻度间隔;0 表示自动(无断轴的线性轴) | -| `object.axes.frame` | 图对象 | `open`(左、下两条轴)、`box`(四边框) | -| `object.axes.equal_scale` | 图对象 | 布尔值;x、y 每单位长度对应相同的数据量(线性、非分类轴,且没有右 y 轴) | -| `object.axes.x_scale / object.axes.y_scale` | 图对象 | `linear`、`log`(仅折线、散点和棒状图;手动范围须大于零) | -| `object.axes.x_display_unit / object.axes.y_display_unit` | 图对象 | 属性查询返回的兼容单位代码 | -| `object.axes.x_range / object.axes.y_range` | 图对象 | 自动或手动范围对象 | -| `object.axes.y2_label` | 图对象 | 文本;右 y 轴标题 | -| `object.axes.y2_show_tick_labels / object.axes.y2_show_label` | 图对象 | 布尔值 | -| `object.axes.y2_scale` | 图对象 | `linear`、`log` | -| `object.axes.y2_display_unit` | 图对象 | 属性查询返回的兼容单位代码 | -| `object.axes.y2_range` | 图对象 | 自动或手动范围对象 | -| `object.axes.y2_major_step` | 图对象 | 同 `y_major_step`,用于右 y 轴 | -| `object.figure.typography.tick_pt / object.figure.typography.label_pt / object.figure.typography.legend_pt` | 图对象 | 1–72 pt | -| `object.guides.visibility` | 图对象 | `auto`, `show`, `hide` | -| `object.guides.placement` | 图对象 | `auto`, `inside`, `outside_right`, `outside_bottom`, `custom` | -| `object.guides.layout` | 图对象 | `auto`, `vertical`, `horizontal` | -| `object.guides.title` | 图对象 | 文本 | -| `object.guides.position` | 图对象 | [0,1] 内的 `[x,y]` 或 `null` | -| `series.contour.line_width` | 图对象+Series | 0.05–10 pt | -| `series.contour.count` | 图对象+Series | 1–256 | -| `document.figure.typography.tick_pt / document.figure.typography.label_pt` | document | 1–72 pt | -| `document.figure.typography.axis_line_pt` | document | 0.05–10 pt;坐标轴线与刻度线 | -| `document.figure.typography.tick_length_pt` | document | 0–20 pt | -| `document.figure.typography.tick_direction` | document | `out`、`in` | -| `document.figure.typography.minor_ticks` | document | 每个主刻度间隔 0–9 个子刻度;0 为不显示 | -| `document.figure.typography.typeface` | document | `arial`、`helvetica`、`times_new_roman`;作用于所有图内文字 | -| `document.figure.typography.font_weight` | document | `regular`、`bold`;作用于所有图内文字 | - -`object.axes.y2_*` 属性只在图中有曲线的 `series.y_axis` 为 `right` 时适用;其他图上为不适用。 - -科学处理与任务接口见下文。应用偏好、新格式解析、科学结果自动建图及内置聊天暂不在此接口范围内。 - -### 工具 annotations 与客户端审批 - -每个工具都在 `tools/list` 中提供 MCP -`annotations`,不随当前 **Access** 设置变化。`readOnlyHint` 表示是否改变环境; -`destructiveHint` 区分可能破坏性写入与仅追加操作;`idempotentHint` 表示相同参数的 -重复调用是否产生额外影响;`openWorldHint` 表示是否与外部实体交互,包括本地输入/ -输出文件。破坏性和幂等提示仅对非只读工具有意义。参见 -[MCP 注解定义](https://modelcontextprotocol.io/specification/2025-11-25/schema#toolannotations)。 - -查询、预览和回执查看均为只读,仅访问原生项目/应用状态。诊断也是只读,但续查游标 -仅可使用一次。`plotium_plan` 不是只读:每次成功调用都会保留新的可执行计划,部分 -操作会读取外部数据、schema、处理方案或图片文件,并准备计算;它不提交候选结果, -也不写出保存/导出目标文件。`plotium_execute` 覆盖编辑、删除、科学任务提交及保存/ -导出请求,因此整个工具保守声明为可能破坏性、非幂等、开放交互域。任务取消会改变任务 -状态,属于可能破坏性写操作;对同一保留任务重复取消不会产生额外影响。 - -客户端可以依据策略使用可信服务端的提示来决定是否询问审批,但仍可能询问;不可信 -注解不能作为授权依据。客户端审批、Plotium **Access** 与桌面文件确认是独立决定。 -注解不授予权限:revision/context 检查、撤权与一次性计划规则仍然生效。每次保存/导出 -请求仍保留独立桌面确认及准确的文件/覆盖范围,包括 **Read only** 模式。断连或结果 -未知后绝不重放调用,即使标为幂等;应查询状态或保留回执。升级 Plotium 及其连接器后, -重新连接客户端以刷新工具目录。 - -## 读取状态与按需发现能力 - -`plotium_get_state {}` 读取最新动态状态,返回 `project_context`、`revision`、 -`availability`、`permissions`、`save_state`、`capability_fingerprint`、项目数量摘要 -和有上限的选择分页,不附带完整能力清单或项目蓝图。用绑定 revision 的 -`plotium_document_inspect` 分页或 `plotium_resources_search` 发现精确目标, -再用 `plotium_resources_inspect` 按明确 ID 读取详情。复制返回的完整目标,不用名称或集合位置代替。 - -有两种简写可以少抄 ID。资源引用可以省略 `parent_id` 和 `local_id`,Plotium 会从 -`CANVAS_UUID/OBJECT_ID` 这类嵌套 ID 推出。规划和属性查询的 `targets`、曲线绑定和 -`properties.set_many` 的写入目标可以把 Series 写成 -`{"plot":"CANVAS_UUID/OBJECT_ID","series":0}`。两种简写都在规划前展开成完整目标; -计划、结果和审计记录仍保存完整形式。 - -空闲时 `selection` 为 `{items,total,next_offset}`,默认最多返回 16 个稳定资源引用。 -传入 `selection_offset`(默认 0)和 `selection_limit`(1–50)读取后续页,例如: - -```json -{"selection_offset":16,"selection_limit":50} -``` - -`selection.canvas` 报告用户在当前页面上选中的内容:`{items,total,part}`。`items` -最多 `selection_limit` 项,是所选 Panel 和对象的摘要(`target`、`kind`、`name`、 -`visible`)。`part` 是用户在首个所选图中点中的图例、标签或标注,没有时为 `null`。图例为 -`{target,part:"legend",property:"object.guides.position",value}`,`value` 为 `null` -表示自动位置;标签为 `{target,part:"label",kind,annotation_id,edit:"figure.edit annotation_set",…}` -并带当前位置;箭头或参考线本身为 `{target,part:"annotation",kind,annotation_id,edit,…}`, -带位置和 `hand_moved`。用户说“这个”时,改的就是这个目标或部件。 - -每次调用都读取当前选择,分页不是冻结快照;GUI 选择变化不一定改变文档 revision。 -不能将多页视作原子选择或把选择当作执行授权。 - -`hand_edits` 以 `{items,total,next_offset}` 列出用户在 Plotium 中手动设置的图形值, -每项包含 `target`、属性 `key`、`label` 和当前 `value`。传入 `hand_edits_offset` 和 -`hand_edits_limit`(1–50,默认 16)读取后续页。继续编辑时请保留这些值,见 -[用户手动设置的值](#用户手动设置的值)。 - -忙碌时 `project`、`selection` 与 `hand_edits` 为 `null`;仍可读取可用性、权限、能力指纹 -和保存回执 ID。 - -调用 `plotium_capabilities_get {}` 获取精简索引 -`{capability_fingerprint,connection_capabilities}`。索引列出各工具的操作和所需权限、 -按预检与执行权限分组的可编辑操作、科学操作、恢复/revision/属性批量契约、文档根和 -`sections`。工具说明、输入 schema 和 annotations 见 `tools/list`;属性定义见 -`plotium_properties_list`。 - -`sections` 列出每个详情分区的字节大小及是否接受 `key`。`operation_constraints` 和 -`operation_details` 为每个 key 附一句用途,便于先按任务找到操作再读取详情。用 `{"section":...,"key":...}` -读取单项详情,返回 `{capability_fingerprint,section,key,contract}`: - -| 分区 | key | 内容 | -| --- | --- | --- | -| `tools` | 可选,工具名 | 结果约定和目标规则;指定 key 时也返回工具输入 schema | -| `operation_constraints` | 必填,操作 id | 单个可编辑操作的 schema、权限和结果约定 | -| `operation_details` | 必填,操作/子操作 key,或 `keys` | 聚焦的图形编辑 schema、权限、结果约定和示例 | -| `scientific_operations` | 必填,操作 id | 描述符和所需权限;可编辑操作引用其规范输入 schema | -| `guide_contract` | 无 | 图例和色标定位规则 | -| `candidate_preview` | 无 | 未提交计划的预览约定 | -| `limits` | 可选,限制名 | 连接预算 | - -例如读取 `figure.edit` 的 schema: - -```json -{"section":"operation_constraints","key":"figure.edit"} -``` - -已知操作可直接查询详情,无须先读索引。例如页面编辑使用 -`{"section":"operation_details","key":"figure.edit/page"}`。多项编辑用 `keys` 代替 `key`, -例如 `{"section":"operation_details","keys":["figure.edit/panel_label","figure.edit/annotation_create.arrow"]}`。 -响应包含 `keys` 和以请求名称为键的 `contract` 映射。此分区每次接受 1–32 个不重复的 key; -其他分区只接受 `key`。每项详情包含一个精确的编辑 schema,以及只适用于该编辑的限制和 -结果字段;请将示例目标替换为文档检查返回的完整稳定引用。混合编辑的 -完整 schema 仍见 `operation_constraints`。可编辑科学描述符通过 -`input_schema_ref: {section,key}` 引用规范输入 schema,不重复返回该 schema。 - -未知分区或 key 返回 `invalid_parameters`,`error.details.sections` 或 -`error.details.keys` 列出有效值。 - -指纹是完整静态发现契约(索引、全部分区、MCP 工具定义和属性目录)按规范 JSON -对象键顺序计算的 SHA-256。按响应中的指纹缓存索引和已读取的分区;状态中的指纹不同时重新发现。 -若读取状态后、能力查询完成前状态已变化,以能力响应随附的指纹标识该契约。 -项目编辑、项目切换、选择或权限变化均不改变静态能力。 - -静态发现提供所需权限,不返回 `currently_permitted` 标记;当前权限和可用性始终从状态读取。 -执行仍检查服务端权限、上下文、revision 和一次性计划。指纹、缓存的 schema 及 annotations -不授予权限,也不允许自动重试。保存和导出仍须对每个精确请求取得新的桌面确认。 -升级时一起更新桌面与连接器,并重连客户端以刷新工具目录。 - -规划、属性检查、文档检查与图形诊断的工具输入直接列出字段,便于客户端展示完整签名。 -Plotium 仍在服务端检查条件约束:需要选择器时只提供一个非空 `ids` 或 `targets`; -操作在参数内部指定目标时省略二者;表操作只接收一个数据集 ID。只有 -`properties.set` 和 `properties.reset` 接收 Series 目标。文档分页仅适用于 -`view: "children"`;诊断续页只接收 `cursor`、context 和 revision,首次诊断必须提供 -`canvas` 与 `output`。 - -同步提交的 `plotium_execute` 结果包含 `project_context`、`before_revision` 和 -`after_revision`。已知该上下文中的精确目标时,可直接将返回的 context 和 -`after_revision` 用于下一次查询或规划,无须额外读取状态。这不刷新选择、手动值、 -可用性或权限;首次访问、桌面编辑或 Undo/Redo 后、需要这些动态值时,以及 -stale/context 错误或结果不确定时,仍须读取状态。执行继续检查上下文、revision 与权限。 - -图形编辑、曲线追加/绑定/展开、科学结果绘图、重命名、主题和删除数据集的计划返回 -`plan_id`、`project_context`、`basis_revision` 和 `preflight`,不再回显请求和冻结目标集。 -`preflight.summary` 统计可执行、跳过和失败的目标数,`preflight.targets` 只列出将被跳过或 -失败的目标。它们的执行结果用 `summary` 统计成功、跳过和失败数,`targets` 只列跳过或 -失败的行,已修改资源见 `produced` 和 `modified`。 - -`plotium_apply` 的输入与 `plotium_plan` 相同,一次调用完成一项可撤销编辑的规划和提交, -返回 `plotium_execute` 的结果。它接受 `properties.set`、`properties.set_many`、 -`properties.reset`、不含删除的 `figure.edit`、`plot.create`、`plot.series.append`、 -`plot.series.bind`、`plot.series.materialize_default`、`resource.rename` 和 -`figure.apply_theme`,需要“读取和修改”权限。预检、revision 与权限检查、Undo 和运行记录 -都与两步形式相同,且不保留计划。保存、导出、删除、导入、表格和科学操作仍用 -`plotium_plan` 加 `plotium_execute`,预览候选图也是如此。被拒绝的 apply 不提交任何内容。 -断线后先读状态:revision 等于请求的 `expected_revision` 表示编辑没有提交,否则检查目标; -不要重放这次调用。 - -科学任务排队或提交并不代表修改已提交,不可复用即时响应的 `after_revision`。 -只有已知项目上下文中终态为 `succeeded` 且包含 `end_revision` 的回执才允许复用。 -科学有效性与收敛情况须单独检查:任务成功并不证明拟合有效。失败、取消、失效、 -缺失或不确定的回执继续遵循恢复流程,绝不授权自动重放。保存/导出回执描述文件操作, -不提供新的文档 revision。 - -## 从欢迎页导入原生数据 - -只打开 Plotium 即可调用 `plotium_get_state {}`;后台工作、恢复或保存阻塞项目访问时也可查询。 -响应包含 `availability` 中的 `project_read`、`project_modify`、 -`native_import`,各项包含 `available` 和可为空的 `{code,message}` 原因。 -可直接从欢迎页导入原生数据或表格。空闲时 `project` 返回数据集和画布数量,即使尚未导入数据; -忙碌时 `project` 与 `selection` 均为 `null`。规划操作前请检查 `availability`。 -查询不会新增文档审计记录或未保存修改。 -所有状态下均可通过 `plotium_capabilities_get {}` 发现连接能力。 - -启用 **读取并修改**,从状态复制 `project_context` 和 `revision`,再调用 `plotium_plan`: - -```json -{ - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 0, - "tool_id": "data.import", - "parameters": {"paths": ["C:/Data/experiment.jdf"]} -} -``` - -请使用实际绝对路径。原生导入接受桌面加载器支持的明确数据文件及原子采集目录, -例如 Bruker 采集或处理数据目录;可读取采集必需的伴随文件,不递归批量发现或扫描相邻实验。 -此操作不支持 ZIP 归档、项目文件或新格式。可选 `sampling_declaration` 沿用核心导入约定。 -完整共享 schema 可用 -`plotium_capabilities_get {"section":"operation_constraints","key":"data.import"}` 读取。 - -预检在后台完成,`import.items[].metadata` 返回各输入的格式、维度、警告、失败原因和拟创建的 -数据集/画布 ID。预检不创建资源或修改文档。调用 `plotium_execute {"plan_id":"PLAN_ID"}` -提交冻结数据;预检后修改或删除源文件不影响执行。成功后向当前项目添加原生数据集和默认画布, -保留项目上下文和当前选择。 - -结果为 `succeeded`、`partial` 或 `failed`;所有成功项一次原子提交、一次撤销。 -撤销首批内容后移除导入的内容;重做恢复相同资源 ID。全部输入失败或导入取消时, -不新增资源、撤销记录或未保存修改。 -成功导入仍保留科学溯源记录。 -提交时重新检查权限、上下文和版本;即使执行被拒绝,计划也已消耗,不能重复使用。 -遇到 `project_changed` 后重新查询状态并预检。 - -每批最多 16 个输入、1 个预检在途、最多 4 个保留的 prepared import(与表格导入共享)。 -所有保留计划及在途预检的原生冻结负载保守预留合计最多 512 MiB;超限返回 -`import_budget_exceeded`。超过 16 个路径时调用失败,报错写明收到的数量;其余文件请分批 -导入。预检响应最多 256 KiB。科学处理与 DOSY 使用独立的共享科学操作。 -CSV、TSV 和 XLSX 文件是表格,用 `mode: "table_data_only"` 导入;原生导入收到它们会报错并给出这一提示。 - -## 不依赖名称发现结构 - -先用 `{}` 调用 `plotium_get_state` 获取当前上下文、revision 和权限。需要静态契约时, -调用 `plotium_capabilities_get {}`;其索引描述当前连接的工具、支持的操作及其权限, -结果约定、操作 schema 和限制按分区读取。标准 MCP `tools/list` 提供工具输入 schema, -`plotium_properties_list` 提供属性定义。资源描述中的能力属于 **core** 的 -数据和渲染语义;资源列出某项能力,不代表此连接已开放该操作。 -这里可预检 `project.save`、`figure.export`、`resource.rename`、`dataset.delete`、`figure.apply_theme`、`properties.set`、`properties.set_many`、`properties.reset`,以及下述受限的 -`data.import`/`data.transform` 模式、`table.patch`、`table.refresh`、`figure.edit`、`plot.create` 及 `plot.series.append`/`plot.series.bind`/`plot.series.materialize_default`。 -只读权限允许表格查询及既有属性预检,但拒绝导入/绑定/创建/版式编辑/处理/补丁/刷新预检和所有可撤销修改执行;保存和导出使用下文各自独立的逐次桌面授权,只读也可请求。 - -使用返回的 revision 列举文档画布: - -```json -{ - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 7, - "target": {"resource":{"id":"document","kind":"plotium.document"}}, - "view": "children", - "offset": 0, - "limit": 50 -} -``` - -将此请求传给 `plotium_document_inspect`。复制完整的 `value.items[].target` -作为下一次请求目标,依次进入画布、面板、内容和 Series。画布先列面板,再列未归属 -面板的内容;面板内的内容只在所属面板下列出。使用 `view: "self"` 并省略分页参数, -读取目标详情、`ancestors` 归属链和 `child_count`。内容类型包括图、文字、形状和 -栅格图片,不返回图片像素或数据行。frame 使用 pt:面板相对页面,面板内内容相对 -面板;画布尺寸使用 mm。 - -Series 发现与属性寻址一样,使用图对象的当前显示绑定。非当前通道或显示模式的 -替代 Series 仍保存在项目中,但在重新激活前不列出、也不可寻址。当前绑定中由 -用户隐藏的 Series 仍会列出,`visible` 为 false。切换通道或显示模式后,须读取 -当前 revision,再发现当前有效目标。 - -`encoding` 表示原生编码家族:`line` 同时包含折线和散点;`plot.create` 的 -`series_defaults[].kind` 返回创建时的具体类型。 - -Series 详情包含可直接用于属性查询的完整 target、编码、可见性、显式标签,以及 -`source` 中的数据集和字段资源引用、所属数据集内的 `field_id`、可选 `item_id`、 -单位和绑定状态。用返回的资源 ID 调用 `plotium_resources_inspect`,可读取字段和 -列的描述。字段失效时保留 `field_id`,但不提供可解析的字段引用。来源状态包括 -`resolved`、`missing_dataset`、`missing_field`、`missing_item`、 -`incompatible_encoding`、`unbound` 和 `missing_column`。 - -表格的 `binding_mode: "table_default"` 返回共享的 `x_column` 和全部 -`series_columns` Y/误差列绑定。一个逻辑 Series 可能展开为多条表格显示曲线, -这些显示曲线不会因此获得独立 Series ID。 -显式来源返回 `binding_mode: "table_explicit"`、TableId、当前表 revision、 -`x_column`、`y_column` 和可选 `error_column`,不把默认值误报为其来源。 -`coordinate_units` 返回图坐标单位契约。 -名称(包括同名曲线)仅作显示,不能代替身份。面板地址为 -`CANVAS_UUID/panels/PANEL_ID`;内容与 Series 保持下文既有地址。 - -子项查询默认每页 50 项,允许 1–200,返回 `total`、`next_offset` 和 `truncated`。 -保持**相同 revision 和 target**,按 `next_offset` 继续读取;256 KiB 结构化响应 -预算可能使一页提前结束。详情或单个条目超过预算时返回 `response_too_large`。 -不提供递归展开整个项目的接口。revision 变化会拒绝续页,须重读状态并重新列举。 -目标失效或身份伪造返回 `invalid_parameters`,不会改用当前选择。 - -`plotium_properties_list {}` 默认以紧凑形式浏览全部支持属性,每个属性一行:`id`、`label`、 -值类型 `type`,以及适用时的 `min`/`max`、`unit`、`format`、枚举 `values`、曲线 `encoding` -和所需字段能力 `requires`。以 `document.` 开头的 ID 属于文档范围,其他 ID 属于对象范围, -`series.` 开头的 ID 以 Series 为目标。标为 `requires_full` 的行(嵌套输入和显示单位代码) -需要读取完整定义。可一次读取多个属性的完整定义: - -```json -{"keys":["series.line.stroke_width","series.line.color"],"detail":"full"} -``` - -`scope` 使用目录中的范围名称筛选,`prefix` 按属性 ID 开头筛选,例如 `series.line` 或 -`object.axes`;没有匹配的前缀会报错,并在 `error.details.prefixes` 中列出可用前缀。`keys` 必须非空且不重复;不支持的键、未知 scope -和键与 scope 冲突均明确报错,不会静默省略请求项。无筛选的 `detail: "full"` 返回完整目录。 -两种形式均为静态查询,忙碌时也可调用,不包含当前目标值。完整详情保留复杂输入约束、 -颜色格式 `#rrggbb` 和全部已注册单位代码。用 `plotium_properties_inspect` 查询目标值、 -默认值、范围和适用性;坐标轴只接受与其坐标单位兼容的代码。静态适用能力不授予连接修改权限。 - -## 导入 CSV/TSV/XLSX 数据,不创建图 - -让 agent 导入明确指定的 UTF-8 CSV/TSV 或 XLSX 工作簿,检查列信息,再分页读完整张表。先调用 -`plotium_get_state {}`,然后调用 `plotium_plan`: - -```json -{ - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 7, - "tool_id": "data.import", - "parameters": { - "mode": "table_data_only", - "paths": ["/absolute/path/measurement.csv"], - "header": "present" - } -} -``` - -导入不提供 `ids` 或 `targets`。`header` 可为默认的 `auto`、`present` 或 `absent`; -自动判断有歧义则失败。`.csv` 与 `.tsv` 分别选择逗号和制表符;可显式用 -`format: "csv" | "tsv"` 指定。`.xlsx` 文件(或 `format: "xlsx"`)把每个有内容的可见 -工作表各导入成一张表,表名取工作表名,工作簿只有一张表时取文件名,与桌面端导入一致。 -`sheets: ["Figure 3", …]` 只导入列出的工作表;名字不存在时该文件失败,并列出可见工作表。 -每个工作表单独准备:没有表格或超出限制的工作表作为单独一项失败,其余照常导入。一个文件 -最多读取 8,000,000 个工作表单元格,按各工作表的已用范围计算。`header`、`schema` 和 -`schema_path` 只用于 CSV/TSV。含 XLSX 的批次摘要超过 128 KiB 时预检失败,并按文件列出 -工作表,可每次导入一个工作簿并减少 `sheets` 中的工作表。只读所列普通文件,不扫描目录、不自动寻找邻接 -sidecar、不回写源文件、不创建图或 X/Y 绑定。 - -预检在后台完成准备后才返回。`import.items` 逐文件(XLSX 逐工作表,带 `sheet`)报告 `prepared` 或 `failed`, -包含拟建原生 ID、元数据和诊断,此时项目尚未新增数据集。确认结果后调用 -`plotium_execute {"plan_id":"RETURNED_PLAN_ID"}`。执行使用预检冻结的字节和 typed -snapshot,不重新读取可能已变化的文件;提交前重验 revision 和权限,将全部已准备 -成功项作为一次原子修改提交。`value.status` 为 `succeeded`、`partial` 或 `failed`, -须逐项查看结果和已创建 ID;失败文件不留下半成品。一次 Undo 移除本批成功项, -Redo 恢复同一 DatasetId、FieldId、ColumnId 和 RowId。既有 GUI/CLI 导入行为不变。 - -元数据包含 DatasetId、TableId、表 RevisionId、字段身份、稳定 ColumnId、逻辑 -类型、nullable、单位、总行数及诊断。字段和列是不同的原生身份。缺失值保持 null, -混合数值/文本列保留文本;超出有符号 64 位范围的整数字样保留文本,不舍入。 -不根据数值或表头拼写猜单位。`type_source` 区分 `file/user/inferred/unknown`, -`unit_source` 区分 `file/user/unknown`。 - -可选 `schema` 为有序原生 TableSchema,包含 typed ColumnSchema ID、逻辑类型、 -nullable 和可选 UnitSpec;也可用 `schema_path` 明确指定 v1 PlotiumDelimitedSchema -JSON 文件。声明必须与表头及顺序完全对应,非法值明确失败,不回退自动推断。 -支持声明 null、boolean、int64、float64、utf8、date 和 timestamp;本导入不接受 -唯一性/业务键约束及不确定度关系,也不从 `_sigma` 列名赋予科研误差含义。每次 -导入分配新的原生 ID,文件/用户 schema 中的 ID 仅描述来源,不寻址已有项目目标。 - -每批最多 16 个文件、每文件 16 MiB、指定输入合计 64 MiB,每文件最多 256 列、 -1000000 行;明确指定的元数据文件最多 256 KiB。已准备项摘要上限 128 KiB, -完整预检响应上限 256 KiB,超出时缩小批次或 schema。每连接最多保留 4 个已准备导入 -和总计 32 个计划,同时只运行一个导入预检。这些是输入预算,不是进程总内存 -上限。取消、切换项目、撤销权限或期间发生编辑,都会阻止待完成预检成为可执行 -计划。排队或运行不代表完成;失败或过期提交也会消费计划,须重新读状态并预检, -不能盲目重放创建请求。 - -## 有界分页读完整张表 - -从导入元数据或数据集资源描述符复制 DatasetId 和表 RevisionId。将它们与 -`expected_revision` 传给 `plotium_table_columns` 查看元数据,再调用 -`plotium_table_read_rows`: - -```json -{ - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 8, - "dataset_id": "DATASET_UUID", - "table_revision": "TABLE_REVISION_UUID", - "offset": 0, - "limit": 200 -} -``` - -用返回的 ID 替换占位符。可选 `column_ids` 按稳定 ColumnId 投影并保持所给顺序; -省略或空数组表示 schema 顺序的全部列。行按不可变原生 snapshot 顺序读取。 -结果包含 `column_ids`、`rows: [{row_id, values}]`、`total_rows`、`requested_rows`、 -`returned_rows`、`next_offset` 和 `end`。每个值以 `kind` 标明类型,null 无 value。 -Int64、time、timestamp 和 duration 用十进制字符串避免 JSON 舍入;date 为 Unix -纪元以来天数,后三种时间类型为纳秒。非有限浮点值明确返回 `NaN/+Inf/-Inf` -字符串,不转为 null。 - -保持数据集、文档 revision、表 revision 和投影不变,沿 `next_offset` 连续读取, -直到 `end: true` 且 `next_offset: null`。默认每页 200 行,最多 1000 行和 20000 个 -投影单元格;完整结构化 ToolResult 上限 256 KiB。字节预算可缩短整页,但不截断 -单元格;以实际数量和继续位置为准。单行超预算返回 `response_too_large`。 -offset 等于总量时返回空的结束页,大于总量时失败。非法 limit、重复/不存在列及 -超预算请求直接拒绝,不静默裁剪参数。 - -每次读取都检查两个 revision。人工编辑、Undo/Redo 会使旧文档 revision 失效, -须重新读状态并重启分页,不能混读。无效 ID 不回退当前选择。只读连接可查询 -已有表格,但不可导入。预算见 `limits` 能力分区,导入权限条件见索引。 - -## 派生表格而不修改源数据 - -可以让 Agent:“计算 `signal_x2 = y_left * 2`,排除 `x_left` 等于零的行,按 X -降序排列,再把结果绑定到这条已有曲线。”处理操作只创建一张原生表格,不创建图。 -重绑使用[现有曲线绑定操作](#精确重绑已有曲线不影响另一张图)。 - -1. 读取 `plotium_get_state`,再用 DatasetId 和表 revision 调用 - `plotium_table_columns`。复制实际 ColumnId、`table_id`、`table_revision` - 和 `snapshot_fingerprint`;名称和 `source_column_id` 不能作为身份。 -2. 用 `plotium_capabilities_get {"section":"operation_constraints","key":"data.transform"}` - 发现原生计划格式。`ids` 恰好指定一个 DatasetId,模式为 `table_data_only`。 - 叶节点必须固定该数据集的当前快照;为 `operation_id` 和每个计算列的 `id` - 提供新的 UUID。 -3. 调用 `plotium_plan`,检查 `transform.status: "prepared"` 及其 `output`,再将 - 返回的 `plan_id` 交给 `plotium_execute`。准备完成不代表已插入数据。成功执行返回 - `value.status: "succeeded"`、`value.output` 和一个 `produced` 数据集;提交保留 - 准备阶段返回的输出身份。 -4. 用 `plotium_table_read_rows` 读取完整结果,再将实际 DatasetId、FieldId、TableId、 - revision 和 X/Y ColumnId 绑定到已有曲线,用 `plotium_render_preview` 检查原生图像。若要新建图, - 则将相同输出身份交给 [`plot.create`](#从已导入表格创建原生单图),再预览返回的画布。 - 数据处理与建图仍是可分别撤销的两个操作。 - -以下完整原生计划追加一个 Float64 列。将占位符替换为发现的身份或新 UUID。 -示例以 `unit: null` 明确表示未知单位;若 `y_left` 有明确单位,此处乘以无量纲常数, -应将源列的**整个 UnitSpec**复制到输出列。 - -```json -{ - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 7, - "tool_id": "data.transform", - "ids": ["DATASET_UUID"], - "parameters": { - "mode": "table_data_only", - "name": "Scaled signal", - "memory_limit_bytes": 16777216, - "plan": { - "version": 1, - "operation_id": "NEW_OPERATION_UUID", - "root": { - "op": "computed_column", - "input": { - "op": "snapshot_read", - "table": "TABLE_UUID", - "revision": "TABLE_REVISION_UUID", - "fingerprint": "SNAPSHOT_FINGERPRINT" - }, - "column": { - "id": "NEW_COLUMN_UUID", "name": "signal_x2", - "logical_type": {"kind": "float64"}, "nullable": true, "unit": null - }, - "expression": { - "expr": "call", "function": "multiply.v1", - "args": [ - {"expr": "cast", "input": {"expr": "column", "column": "Y_COLUMN_UUID"}, - "target": {"kind": "float64"}, "failure": "error"}, - {"expr": "literal", "value": {"type": "float64", - "value": {"kind": "finite", "value": 2.0}}} - ] - } - } - } - } -} -``` - -支持的关系节点只有 `snapshot_read`、`project`(有序 ColumnId)、`filter`(Boolean -谓词)、`stable_sort`(按优先级排列的键,含 `column`、 -`direction: ascending|descending` 和 `nulls: first|last`),以及 `computed_column` -(明确列 schema 和表达式)。将已有节点放入后一个节点的 `input` 即可组合。完成上述 -任务时,先用 `not.v1(eq.v1(column(X_COLUMN_UUID), literal(int64, 0)))` 包装计算节点 -进行筛选,再按 X 降序,最后投影 X、Y 和新 ColumnId;精确 JSON 形式由 schema 提供。 - -表达式使用 `column`、`literal`、`cast` 或带版本的 `call`。可用函数是 `is_null.v1`、 -`is_finite.v1`、`eq.v1`、`not.v1`、`and.v1`、`or.v1`、`add.v1`、`subtract.v1`、 -`multiply.v1` 和 `divide.v1`,不接受任意函数、SQL 或脚本。算术要求 Float64 操作数, -类型转换必须明确指定;`failure: error` 拒绝整次处理,`null` 将转换失败值置为缺失。 -原生 Int64 转 Float64 可能损失精度。计算列输出支持 Boolean、Int64、Float64 和 Utf8。 -单位由调用方明确声明,算术不会推导单位或自动换算。 - -筛选只保留 true,false 和 null 都被排除。排序保留 RowId,同键按 RowId 决胜,null -位置不受升降序影响;非 null 浮点值按 `-Inf < finite < +Inf < NaN` 排列。投影列保留 -原有 ID、类型和单位,计算列保留配方中的新 ID。源表数值、表格默认绑定、画布和已有 -人工样式不变。 - -输出元数据包含固定的原生配方、backend、输入 revision/fingerprint、列 lineage -和行映射契约。稍后可用 `plotium_table_columns` 的 `include_provenance: true` -读取;在 `plotium_table_read_rows` 中加同一参数,则每行返回 `sources`:已记录的源 -DatasetId、TableId、revision、fingerprint、原始 RowId 和从零开始的 `input_position`。 -它解码本页对应的原生存储映射,不跟随源表最新 revision。导入行没有派生来源;其他 -关系计划的来源形态在请求行来源分页时明确拒绝,不带该参数的普通读取保持既有行为。 - -准备工作不阻塞桌面线程。规划和执行均需 **Read and modify**;后台准备完成及实际 -提交前都会重新检查权限、文档 revision 和源快照。执行提交一次即消耗 plan,即使失败 -也不能重放。取消、停止连接、切换项目或输入过期会丢弃未提交结果;已经开始的原子 -提交使用普通 Undo 撤销。一次成功处理对应一次 Undo,Redo 恢复相同表和列身份。 - -每个连接同时最多一个处理预检。参数最多 64 KiB、64 个关系/表达式节点、深度 16 -(JSON 嵌套最多 48 层)。内存预算默认和上限均为 512 MiB,含义是 reference 执行器 -**求值后检查的物化结果估算**,不是进程峰值内存限制。最多保留四个待提交结果,共享 -512 MiB 预留预算,每项按请求声明的预算计费。完整响应最多 256 KiB;准备结果摘要最多 128 KiB,为请求和计划外层预留空间。限制也可用 -`plotium_capabilities_get {"section":"limits","key":"table_transform"}` 发现。预算失败返回 -`transform_budget_exceeded`,取消返回 `request_cancelled`,均不留下派生表或成功执行 -结果。修正输入或预算后重新规划。后续更新使用下述独立的单元格补丁及显式刷新操作。 - - -## 补丁修改单元格,再显式刷新派生表 - -`table.patch` 的顶层 `ids` 恰好指定一个 DatasetId,不传 `targets`;参数须包含 -当前表 revision。RowId、ColumnId 必须复制自表格读取结果,分页 offset、行号及 -列名不能代替身份。例如: - -```json -{ - "tool_id": "table.patch", - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 12, - "ids": ["DATASET_UUID"], - "parameters": { - "table_revision": "TABLE_REVISION_UUID", - "edits": [{ - "row_id": "RETURNED_ROW_UUID", - "column_id": "RETURNED_COLUMN_UUID", - "value": {"kind": "float64", "value": 2.5} - }] - } -} -``` - -值沿用读取结果的 `kind`/`value` 格式:Int64 及纳秒时间类型用十进制字符串; -Float64 用 JSON 数字或 `"NaN"`/`"+Inf"`/`"-Inf"`;缺失值为 -`{"kind":"null"}`。类型及 nullable 必须严格匹配,不能用 Float64 补丁隐式扩宽 -Int64 列;分类值只能指定已有 level 的索引。此操作不修改扩展类型或实时计算的区域表。 - -每批 1–1000 个不同单元格,参数最多 64 KiB。缺行、缺列、重复单元格、类型错误或 -旧 revision 均拒绝整批,不留下部分修改。不增删行、改 schema、重导入或回写源 -CSV/TSV。准备返回 `update:{status:"prepared",output,before_table_revision,changed}`, -执行前不修改项目。相同值返回 `changed:false`,不推进文档 revision 或增加 Undo。 -补丁或刷新提交前,其数值必须仍满足已有曲线绑定的要求。例如,用作 Y 误差的列 -不能包含负幅度。拒绝更新时,表格、图和 Undo 历史均保持不变。 - -表格元数据、行页和 Series 来源返回 -`freshness:{status,refreshable,reason,sources,mcp_refreshable,mcp_refresh_reason}`。 -`refreshable` 表示原生刷新能力;`mcp_refreshable` 另检查连接支持的配方范围, -不表示当前权限模式。数据集资源元数据分别暴露 `table_refreshable`、 -`table_mcp_refreshable` 和 `table_mcp_refresh_reason`,以及 `table_freshness` 及其原因。`source` 为没有派生配方的源表,`current` -为已记录输入 revision 仍匹配,`stale` 为直接或上游输入已变化,`unavailable` -为来源或受支持配方缺失。数据浏览器将受影响的关系派生表标为 **Out of date**, -数据表窗口说明原因。旧结果仍可读取、绘制,同时明确带有失效状态。修改表会清除 -该表的已存曲线拟合分析,Undo 恢复;失效派生表中的分析只描述旧结果,不代表当前源数据。 - -只有明确请求才刷新:以 `ids:["DERIVED_DATASET_UUID"]` 和 -`parameters:{"table_revision":"CURRENT_DERIVED_REVISION"}` 规划 `table.refresh`。 -仅支持已保存的单源 `snapshot_read`/`project`/`filter`/`stable_sort`/ -`computed_column` 配方,表达式和复杂度限制与 data-only 处理相同;按当前源快照, -沿既有 reference 执行器和 lineage 路径刷新。其他原生配方(包括 Pivot)会被 MCP -刷新明确拒绝;原生 GUI/core 的刷新能力不变。采用候选前验证 TableId、列 schema -(含 ColumnId、类型和单位)保留,每个输出 RowId 必须属于当前输入;不匹配时 -整次拒绝,不修改表、图绑定或 Undo。先刷新失效上游;缺来源或配方时说明原因,不自动重算其他数据。派生表已有人工 -单元格修改按稳定 RowId rebase,身份缺失或歧义时拒绝整次刷新,不回退到行位置; -连续刷新仍保留这些修改。`include_provenance:true` 返回当前 `operation`,以及 -沿编辑/rebase 历史解析的有效 `refresh_recipe`。 - -可选 `memory_limit_bytes` 依次采用显式值、配方已保存预算、512 MiB 默认值,范围 -1–536870912;仍表示物化结果估算,不是峰值内存。补丁/处理/刷新共享一个后台 -预检、四个待执行候选及 512 MiB 预留上限,每个补丁预留 64 KiB。准备摘要最多 -128 KiB,完整响应最多 256 KiB;schema 和限制见 `operation_constraints` 与 -`limits`(`table_update`)能力分区。 - -两项操作的预检和执行都要求 **Read and modify**;候选采用前重验权限、文档/表 -revision 及当前输入。取消、切换项目、停止连接或输入过期丢弃未提交结果,失败执行 -也消费 plan。响应丢失后先检查实际状态,不重放已提交操作。 - -补丁与刷新各自对应一次 Undo/Redo。DatasetId、TableId、ColumnId、已有 RowId -及原生图/Series 身份保留,筛选可改变结果包含哪些已有行。只更新 revision 和来源 -映射,不改人工颜色、轴范围或面板 frame。失效状态由保存的 provenance 与当前 -revision 计算,因此 Undo/Redo 同时恢复数值及对应失效状态。原生表格编辑与刷新 -使用同一个 typed revision 提交服务。 - -## 把派生曲线加入已有图 - -新计算的表需要与原曲线同图显示时,使用 `plot.series.append`,无需替换图对象。 -GUI 中选择已有显式坐标图,打开 **Data → Add curve**,选择源表、X/Y 与可选的 -Y 误差列,再按 **Append curve**。非显式图原有的默认字段 **Add series** 行为不变。 - -MCP 不传顶层 `ids`/`targets`,在参数内指定完整图对象目标: - -```json -{ - "expected_project_context": "<当前 context>", - "expected_revision": 23, - "tool_id": "plot.series.append", - "parameters": { - "plot": {"resource": {"id": "/", "kind": "plotium.canvas.object", "parent_id": "", "local_id": ""}}, - "series": [{"kind": "line", "source": { - "dataset_id": "<派生 DatasetId>", "field_id": 0, - "table_id": "<派生 TableId>", "table_revision": "<派生表 revision>", - "x_column_id": "", "y_column_id": "", - "y_error_column_id": null - }}] - } -} -``` - -目标、FieldId、表和列 ID 均从实际发现结果复制,名称不是身份。目标必须已有 -显式坐标;每批追加 1–200 条明确选择的折线/散点/柱状/箱线/小提琴曲线,追加后该图最多 200 条曲线;已有柱状曲线会与同槽位新追加的柱重新并排分组。 -共享绑定验证器在一次原子提交前检查全部源 revision、完整曲线数据、误差和单位。 -兼容单位转换到图的现有坐标单位;不兼容的整批失败,不部分添加。沿用绑定服务的 -2,000,000 曲线行及待执行计划预算和 256 KiB 响应限制,包含受影响图的已有曲线。 - -`preflight.binding_plan.appended` 返回拟新增的 Series 目标,`bindings` 同时包含 -未改变的已有绑定及新增绑定。执行采用预检冻结的 ID;一次 Undo 仅移除新增曲线, -Redo 恢复同一身份。Undo 后另行追加不会复用已退役 ID。已有 Series 样式、坐标含义、 -人工轴范围、plot/Panel 身份及 frame 均不改变。预检和执行都要求 Read and modify; -context、revision 和权限沿用绑定编辑的一次性计划生命周期。响应丢失后先查拟新增 -目标,不盲目再次追加。 - -## 精确重绑已有曲线,不影响另一张图 - -两个图可以引用同一张原生表,各自选择不同的数值 X、Y 和可选对称 Y 误差列。 -在 GUI 中选中图对象,展开其 Series 的 **Data → Curve columns**,选列后点击 -**Apply curve binding**。表格共享的默认绑定不会改变。 - -MCP 先通过 `plotium_document_inspect` 取得完整 Series target,再从 -`plotium_table_columns` 复制 DatasetId、TableId、FieldId、表 revision 和 ColumnId。 -使用项目 ColumnId,不使用 `source_column_id`、名称或显示 trace 的位置,也不猜字段 -资源地址。调用 `plotium_plan`: - -```json -{ - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 8, - "tool_id": "plot.series.bind", - "parameters": { - "edits": [{ - "target": { - "resource": {"id":"CANVAS_UUID/OBJECT_ID","kind":"plotium.canvas.object", - "parent_id":"CANVAS_UUID","local_id":"OBJECT_ID"}, - "component": {"kind":"series","id":0} - }, - "source": { - "dataset_id":"DATASET_UUID", "field_id":0, - "table_id":"TABLE_UUID", "table_revision":"TABLE_REVISION_UUID", - "x_column_id":"X_COLUMN_UUID", "y_column_id":"Y_COLUMN_UUID", - "y_error_column_id":null - } - }] - } -} -``` - -将占位符和示例中的数值 ID 全部换成实际发现结果。不要另传顶层 `ids` 或 -`targets`,每项编辑已携带完整目标。`y_error_column_id` 为 ColumnId,或 -null/省略,后两者移除误差绑定。检查 `preflight.binding_plan.bindings` 中的来源映射和 -逐行诊断,再以返回的一次性 `plan_id` 调用 `plotium_execute`。 - -一个默认表格 Series 可能代表多条显示曲线,须先调用 -`plot.series.materialize_default`,参数为 -`{"edits":[{"target":EXACT_SERIES_TARGET, -"retain_y_column_id":"EXISTING_Y_COLUMN_UUID", -"table_revision":"TABLE_REVISION_UUID"}]}`。 -GUI 对应 **Expand default curves**:选择保留原 SeriesId 的 Y 列,其余已有曲线 -获得新的对象内 SeriesId,预检和执行结果均返回映射。此操作只展开已有内容,不创建 -图对象。拟合叠加及归一化/偏移的多曲线默认组合无法无损展开,因而明确拒绝; -未展开的旧默认绘图入口仍可使用。 - -只接受 Int64 和 Float64 列;无法在 f64 图坐标中精确表达的整数明确拒绝。 -X/Y 为 null 或非有限值时形成断点,不补零、不跨断点连线。误差为 null 时保留 -有效点但不画该点误差线;零误差合法。负值或非有限误差使整批失败,即使该行的 -X/Y 缺失也不忽略非法误差。误差表示非负绝对幅度,不从列名赋予标准差、标准误或 -置信区间含义。诊断统计全部行,每条曲线最多附 20 个受影响 RowId;绑定校验和 -原生曲线提取不抽样行。 - -兼容单位换算到图对象持久化的坐标单位;误差幅度仅使用比例,不应用仿射偏移。 -已知单位与未知单位不能混用。重绑、删除首条曲线和重排后,手动范围及位移保持 -原坐标含义;不兼容时拒绝,而不是重新解释原数字。人工标签、颜色、线/散点编码、 -可见性、面板位置及轴设置随原目标保留。显式图保持线/散点编码,不切换到无关 -表格图型。 - -每批允许 1–200 项编辑,受影响图合计最多 2,000,000 次曲线行访问;待执行 MCP -曲线计划共享同样的行预算,完整响应最多 256 KiB。全部目标、列、单位、行和 -revision 检查通过后才一次原子提交、一次 Undo,不部分成功、不跳过无效目标。 -只读连接拒绝绑定预检和执行。失败或过期执行也消费计划,须重读状态并重新规划。 -GUI 保存重开保留原生绑定和单位;MCP `project.save` 需桌面单独批准;SVG/PDF/PNG 导出需另行桌面批准,新建图使用下文的 `plot.create`。 - -## 从已导入表格创建原生单图 - -可以要求 Agent:“导入这个 CSV,时间单位为 s,电流和误差单位为 mA, -创建一张可编辑折线图并显示对称 Y 误差。查看预览,再只把该曲线线宽改为 -1.5 pt 并再次预览。”提供绝对输入路径和明确单位。完整导入、创建参数可从 -`plotium_capabilities_get` 的 `operation_constraints` 分区发现。 - -仅数据导入后,从实际导入结果或列元数据读取 DatasetId、FieldId、TableId、 -表 revision 和 ColumnId。通过 `plotium_plan` 规划 `plot.create`,不传顶层 -`ids` 或 `targets`: - -```json -{ - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 1, - "tool_id": "plot.create", - "parameters": { - "parent": {"resource": {"id": "document", "kind": "plotium.document"}}, - "name": "Current", - "series": [{ - "kind": "line", - "source": { - "dataset_id": "RETURNED_DATASET_UUID", - "field_id": 0, - "table_id": "RETURNED_TABLE_UUID", - "table_revision": "RETURNED_TABLE_REVISION_UUID", - "x_column_id": "RETURNED_TIME_COLUMN_UUID", - "y_column_id": "RETURNED_CURRENT_COLUMN_UUID", - "y_error_column_id": "RETURNED_ERROR_COLUMN_UUID" - } - }] - } -} -``` - -示例中的每个身份(包括 FieldId)均须替换成实际返回值。`kind` 为 `line`、 -`scatter`、`bar`、`box` 或 `violin`;`y_error_column_id` 为 ColumnId、`null`,或省略表示没有误差棒。 -source 也可以按列名写:`{"dataset_id":"DATASET_UUID","x":"time","y":"signal","y_error":"sd"}`。 -`x`、`y` 和可选的 `y_error` 是精确(区分大小写)的列名或 ColumnId;Plotium 补上默认字段、 -表格和当前表格 revision。列名不存在或重复时返回 `invalid_parameters`,`error.details.field` -给出路径,`error.details.candidates` 列出该表的全部列。按列名解析的每个 source 会在计划响应的 -`resolved_sources` 中列出。`plot.series.append` 和 `plot.series.bind` 也接受同样的 source 写法。`bar` 曲线绘制从零起的 -实心柱,可带误差线,填充色即曲线颜色,并带细描边。误差线使用描边的颜色和宽度,横帽宽度为柱宽的 45%。按印刷尺寸,柱子过小、放不下描边时(宽度不足描边宽度的 4 倍,或高度不足 2 倍,例如接近 0 的值),只画填充、不画描边,误差线保留。数值型 x 上,槽位宽度取相邻位置的常见间距,只有相邻位置更近处才变窄。其 x 列可为数值列或 Utf8 文本列;文本值按 -表格行顺序成为类别,相同文本共用一个槽位。共用同一槽位的柱状曲线在槽位内 -并排分组;槽位内只有一根柱时占满整个宽度,因此每个类别一条柱状曲线即可得到居中、 -各自配色的柱。`box`(箱线图)和 `violin`(小提琴图)曲线汇总每个 x 上的原始 y 样本 -(箱线图:中位数、四分位距及 1.5 倍四分位距的须,并标出离群点;小提琴图:高斯核密度, -内含四分位条),不接受 y 误差列,与柱子共用槽位。`line` 和 `scatter` 曲线也可以用文本 -x,叠加在槽位上:第 k 条折线或散点曲线对齐第 k 条柱状、箱线或小提琴曲线的位置, -因此原始数据点会落在对应的柱上。`series.points.spread` 让同一 x 上的重复数据点在该 -柱宽度内按行顺序散开(0–1,占柱宽的比例);`series.value_labels` 在每根柱或每个点的 -末端(或误差线末端)之外用刻度字号写出数值。`object.chart.orientation` 设为 -`horizontal` 时把显式数据图横过来:类别沿纵轴排列、第一个在最上方,数值沿横轴;误差线、 -数值标签和轴标题随之转向,视图重置。同一图内所有曲线须同为文本 x 或同为数值 x。含柱状、 -箱线或小提琴曲线的图不支持对数坐标轴。折线或散点曲线可选 `y_axis`:`left`(默认)或 -`right`;柱状、箱线或小提琴曲线设为 `right` 会被拒绝。只要有曲线在右侧,图就会有一条右 -y 轴,拥有自己的自动范围、刻度类型和标题,标题初始为第一条右轴曲线的列名和单位,该曲线 -也决定右轴的单位。参考线、标注和箭头仍按左轴坐标。多条 `series` 表示 -同一图对象内相互独立的原生曲线,不是多张图。全行提取、数值、缺失值、 -误差和单位规则与上文显式曲线绑定相同;不修改表格共享默认 X/Y、不影响 -其他图,也不复制源表。 - -可选的 `intent: {purpose, claim}` 记录这张图要表达什么。`purpose` 取 `compare` -(比较各组大小)、`trend`(随连续变量的趋势)、`distribution`(分布或离散程度)、 -`relationship`(两个量的关系)、`composition`(组成占比)、`change`(变化、比值或倍数差) -或 `detail`(放大或插图);`claim` 是一句话,最多 500 个字符。建图前先请用户选目的、 -写 claim,不要自己猜;用户没填时,给出你的理解,让用户确认或修改。意图不会改变图的画法。 -它随项目保存,之后通过 `object.intent.purpose`(设为 `unspecified` 即清除)和 -`object.intent.claim` 修改,也显示在对象检查器 **Chart** 区的 **Advanced** 中。 - -完整 `parent` 决定新建范围: - -- document 根:新建画布、单面板和图对象。可选 - `canvas: {name, size_mm: [宽, 高]}`,每边为 10–1000 mm;或用 - `canvas: {name, size_preset}` 选内置页面尺寸,例如 `nature-1col`(89 mm)、 - `nature-1p5col`(136 mm)、`nature-2col`(183 mm),并采用该预设的默认高度和 - 边距(期刊栏宽 0 mm、纸张 15 mm、幻灯片 10 mm),结果中返回所用 `size_preset`;省略时在预检中冻结原生默认尺寸,画布名称使用图对象名称。 -- 没有面板或图对象的已有画布:按 GUI 共用的原生空画布放置服务及已有 - 布局设置、边距创建面板和图对象。不传 `canvas`。 -- 已有内容的画布:明确提供 `panel_frame_pt: [x,y,宽,高]`,以页面 pt 坐标 - 创建另一面板及图对象。已有面板、曲线和 loose 内容原位保留,允许重叠。 -- 该画布唯一的空、可见、未锁定且自由布局的面板:仅创建图对象,保留 - 面板的页坐标和尺寸。不传 `canvas`、`panel_name` 或 `panel_frame_pt`。 - -`panel_name` 仅用于新建面板,省略时使用图对象名称。名称不得空白,最长 -1024 UTF-8 字节。`panel_frame_pt` 只设置新建面板:X/Y 为有限页面 pt,宽高 -为有限正数。省略时保留原有空画布原生放置约定;已有成图的画布必须提供 -明确 frame。不重排已有内容,也不将已有图重建为替代对象。 - -MCP 计划返回 `plan_id`、`project_context` 和 `basis_revision`。 -`preflight` 包含 `required_authority`、`created_target_count`、异常 `targets` 和 `outputs`。 -`preflight.binding_plan.creation` 包含精确 `parent`、拟建完整目标 `canvas`、`panel`、 -`plot` 和 `created`(含全部 Series),以及 `size_mm`、所用 `size_preset`(如有)、 -`panel_frame_pt`(页坐标)、`frame_pt`(面板内局部坐标)、`coordinate_units` 和 -`series_defaults`(图型及 pt 线宽)。结果不确定时保留这些冻结身份用于核查。 - -`preflight.binding_plan.binding_count` 统计曲线数,`row_counts` 汇总各曲线的 -`total_rows` 和 `plotted_rows`。`binding_plan.bindings` 只列出数据缺失、非有限值或 -缺失误差的曲线,包含完整目标和全部诊断(含 `affected_rows` 样例)。空列表表示 -没有这些问题,不表示没有绑定。响应省略请求回显、冻结目标重复信息、来源映射和 -成功目标说明;存储的权威计划仍保留完整已验证来源及候选。 - -预检不创建对象。执行一次性计划后,`value.creation` 返回同一 canvas/panel/plot 和 -布局;`value.bindings` 返回**每条** Series 的完整目标及 `total_rows`、`plotted_rows`、 -`missing_xy`、`non_finite_xy` 和 `missing_error`。默认值仅在预检披露一次。 -`produced` 列出新建资源,`summary` 统计目标结果,`targets` 只保留异常项;诊断与验证 -继续保留。`project_context` 和 `after_revision` 标识已提交结果。 - -创建是原子的:来源错误、单位不兼容、非法误差或父目标/revision 变化时, -不留下新画布、面板或半成品图。只读连接拒绝创建预检和执行。每图 1–200 -条曲线、最多 2,000,000 曲线行访问;待执行创建和绑定计划共享 2,000,000 -行预算,每连接最多 32 个计划,结构化响应上限 256 KiB。失败提交也消费 -plan。执行响应丢失后,先查询当前状态及预检返回的目标,不能盲目重新创建。 - -使用返回目标进行结构发现与属性操作,以当前 revision 预览完整画布。 -结果可在 GUI 选择和继续编辑。一次 Undo 只移除本次新建子树,保留已有父 -容器及导入数据;Redo 恢复同一身份。后续原生尺寸和布局调整保留图对象、 -Series 身份和来源绑定。已知目标可复用同步提交结果的 context 与 revision;桌面编辑或 Undo/Redo 后先读取状态。 - -## 原子编辑页面、面板、文字与本地图片 - -以 `parameters: {canvas: 完整画布目标, edits: [...]}` 预检 `figure.edit`,不传顶层 -`ids`/`targets`。完整带 `op` 标签的 schema 可用 -`plotium_capabilities_get {"section":"operation_constraints","key":"figure.edit"}` 读取。 -一个批次按编辑顺序修改同一画布,合为一次 Undo/Redo: - -| `op` | 必需字段及含义 | -| --- | --- | -| `page` | 至少提供 `size_mm: [宽,高]` 或 `size_preset`、`margin_mm: [上,右,下,左]`、`gutter_mm` 之一,长度均为 mm。期刊 `size_preset` 设定栏宽,已有内容的页面保持原高度;纸张和幻灯片预设同时设定宽高。未给 `margin_mm` 时页边距改为预设值(期刊 0 mm、纸张 15 mm、幻灯片 10 mm);结果中返回 `size_preset` | -| `panel_frame` | `target: 完整面板目标`、`frame_pt: [x,y,宽,高]`,页面 pt | -| `content_frame` | `target: 完整内容目标`、完整 `frame_pt: [x,y,宽,高]`,父局部 pt;只改该内容 | -| `image_replace` | `target: 完整 raster 目标`、`path`;以冻结的本地 PNG/JPEG 仅替换资产引用 | -| `content_delete` | `target: 完整内容目标`;删除内容并保留空父 panel | -| `panel_delete` | `target: 完整 Panel 目标`;要求原始状态已为空 | -| `series_delete` | `target: 完整 Series 目标`;删除非末条显式 Series | -| `panel_label` | `target`、`text`、`visible`;写入原生手动面板标签,保留位置和字号 | -| `panel_stack` | `panel: 完整面板目标`、`shared_x: true\|false`;可选 `gap_pt`(0–144)和 `merge: [完整面板目标,...]`,二者仅限 `shared_x: true`。把面板中的图堆叠到同一条共享 x 轴上,或恢复为自由布局 | -| `align` | `panels: [完整面板目标,...]`、`edge: left\|center\|right\|top\|middle\|bottom`;至少两个面板 | -| `distribute` | `panels`、`axis: horizontal\|vertical`;至少三个面板 | -| `grid` | `panels`、`rows`、`cols`;按所给目标顺序分配原生 Frame-basis 网格格子 | -| `text_create` | `parent: 完整画布或面板目标`、`name`、`frame_pt`、`text`、`font_pt` | -| `text_set` | `target: 完整文字目标`、`text`;可选 `font_pt` | -| `image_create` | `parent`、`name`、`frame_pt`、`path: "/absolute/local/image.png"`(PNG 或 JPEG) | -| `annotation_create` | `target: 完整图目标`、`text`、`at: [x,y]`(该图的数据坐标)、`font_pt`;可选 `kind: "text"`、`color: "#rrggbb"` | -| `annotation_create`(参考线) | `target: 完整图目标`、`kind: "reference_line"`、`orientation: vertical\|horizontal`、`value`;可选 `label`、`font_pt`、`line: {color, width_pt, style}` | -| `annotation_create`(箭头) | `target: 完整图目标`、`kind: "arrow"`、箭尾 `at: [x,y]`、箭头 `to: [x,y]`;可选 `head: none\|open\|filled\|double`、`line_width_pt`、`color: "#rrggbb"` | -| `annotation_set` | `target: 完整图目标`、`annotation_id`;文字标注至少提供 `text`、`at`、`font_pt`、`color`、`offset_pt`、`placement` 之一,参考线至少提供 `orientation`、`value`、`label`、`font_pt`、`line`、`placement` 之一,箭头至少提供 `at`、`to`、`head`、`line_width_pt`、`color` 之一;可选 `override_hand_edits` | -| `annotation_delete` | `target: 完整图目标`、`annotation_id` | - -创建两张图后,可设置页面并排列明确选定的两个面板: - -```json -{ - "tool_id": "figure.edit", - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 3, - "parameters": { - "canvas": {"resource":{"id":"CANVAS_UUID","kind":"plotium.canvas"}}, - "edits": [ - {"op":"page","size_mm":[180,90],"margin_mm":[4,4,15,4],"gutter_mm":5}, - {"op":"grid","panels":[{"resource":{"id":"CANVAS_UUID/panels/PANEL_A_UUID","kind":"plotium.canvas.panel","parent_id":"CANVAS_UUID","local_id":"PANEL_A_UUID"}},{"resource":{"id":"CANVAS_UUID/panels/PANEL_B_UUID","kind":"plotium.canvas.panel","parent_id":"CANVAS_UUID","local_id":"PANEL_B_UUID"}}],"rows":1,"cols":2} - ] - } -} -``` - -将全部身份占位符换成实际发现的完整目标;名称不能代替身份。 -结果为 (4,4,83.5,71) 与 (92.5,4,83.5,71) mm。frame 原点在左上,X 向右、Y 向下, -1 pt = 1/72 inch。面板 frame 复用 **Object Geometry/拖动编辑**语义:移动保留 -子内容局部坐标,改尺寸按比例缩放全部子内容 frame,不改曲线身份、绑定、样式、 -轴范围或字号。这不同于自由 Panel inspector 仅修改容器尺寸的行为。 -新文字/图片 frame 使用父面板局部 pt;父目标为画布时则使用页面 pt。 - -`panel_stack` 的 `shared_x: true` 要求至少有两张图。`plot.create` 会把每张新图 -放进各自的面板,因此请在 `merge` 中列出其他图所在的面板:它们会先合并到 `panel`, -其中的图按页面上的上下位置从上到下堆叠,与桌面端 **Stack with Shared X** 相同。 -不传 `merge` 时保持面板内容顺序。堆叠填满面板内宽;高度 -保持当前 frame 的比例,用 `content_frame` 修改某张图的高度即可调整其所占比例。 -开启堆叠时间距默认为 0 pt。只有最下面的图绘制 x 刻度数字和 x 轴标题,只有 -最上面的图绘制图标题,内部边界紧贴且 x 刻度朝内,各绘图区共用左右边缘。进入堆叠 -时,会把覆盖所有成员数据的 x 范围(按各自坐标单位)和最上面成员的 x 主刻度间隔 -(按各自显示的单位)写入每个成员,因此各成员须先 -使用相同的 x 刻度类型;所有成员绘制最下面成员的 x 方向,但不保存该方向。各图共享 -x 视窗;之后在任一成员上修改 x 范围、x 刻度类型、x 显示单位、x 千位分隔符或 -x 主刻度间隔,都会 -写到所有成员,并合为一次 Undo;若任一成员不能接受该值则拒绝写入,`applied` 会 -列出各成员的修改。同一批次若请求相互冲突的共享 x 设置,会整批拒绝且不留下修改; -按兼容坐标单位表达的等价范围可以接受。 -`shared_x: false` 恢复为自由布局并保留各 frame。结果在 `panel_edits` 中列出 -每个操作的 `layout`、`gap_pt`、`members_top_to_bottom` 和 `merged_panels`。 -`plotium_document_inspect` 为每个面板返回 `layout`(`free`、`vertical_stack`、 -`horizontal_stack`、`grid` 或 `shared_x_stack`);堆叠面板另含 -`shared_x_stack: {members_top_to_bottom, gap_pt}`。`plotium_figure_diagnose` -和计划预览使用同一套堆叠几何。 - -图内标注按数据坐标定位,而不是页面 pt:文字居中显示在 `at` 点上方,画布和所有 -导出中都跟随该图的轴范围、缩放和平移移动;锚点在可见范围外时随图一起裁切。该位置 -压到数据、图例、数值标签或其他标签时,文字挪到约三个字高范围内最近的空位;指向它的 -箭头不算遮挡。`offset_pt: [dx, dy]`(pt,x 向右、y 向上)把文字固定在该偏移处, -`[0, 0]` 即正好在 `at`;`placement: "auto"` 恢复自动摆放。`color`(`#rrggbb`)设置 -文字颜色,默认黑色。用户在画布上拖过的标签在修改 `text`、`font_pt` 时保持原位;对它 -设置新的 `at`、`offset_pt` 或 `placement` 会被拒绝,除非以 `override_hand_edits: true` -表明是用户要求。`annotations` 中每个文字 -标注报告 `placement`(`auto`、`fixed` 或 `hand`)和实际绘制的 `offset_pt`; -`plotium_get_state` 在 `hand_edits` 中以键 `annotation.label_position` 列出拖过的标签。 -`annotation_id` 只在所属图内有效,删除后不会复用;可从结果的 `annotation_edits` -或 `plotium_document_inspect` 返回的图 `annotations` 列表读取。`at` 使用 -`coordinate_units` 给出的源单位,而不是刻度标签所选的显示单位。`text` 中的 `\n` -另起一行。标注文字最多 1024 -UTF-8 字节且不得空白,每张图最多 256 个标注。图及其父面板须未锁定;不要求关闭 -Auto height。 - -参考线是 `kind: "reference_line"` 的图内标注:在 x = `value` 处画竖线,或在 -y = `value` 处画横线,单位与 `at` 相同,贯穿整个绘图区。它跟随轴范围、缩放和平移, -`value` 不在可见范围内时不显示。`line` 设置 `color`(`#rrggbb`)、`width_pt` -(0.1–20)和 `style`(`solid`、`dashed`、`dotted` 或 `dash_dot`);新参考线默认 -`#000000`、0.75 pt(若主题规定了辅助线宽则用它,Nature 主题为 0.3 pt)、虚线,`annotation_set` 中省略的 `line` 字段保持原值。可选 -`label` 以线条颜色显示在竖线顶部附近或横线右端,那里压到数据、图例或其他标签时沿线 -挪到别处或换到线的另一侧;检查结果报告 `label_placement` 和实际的 -`label_position: {along, side}`,`placement: "auto"` 按同样的 `override_hand_edits` -规则把拖过的标签恢复为自动摆放;未设置 `font_pt` 时使用刻度标签 -字号,一旦用 `font_pt` 设定字号便保持该值直至再次修改;`label` 为空字符串时移除 -标签。参考线与文字标注共用同一 id 序列和 -每张图 256 个的上限,`plotium_document_inspect` 在 `annotations` 中同时列出二者, -并以 `kind` 区分。提供另一类标注的字段会被拒绝,而不是被忽略;参考线的颜色用 -`line.color` 设置,不用 `color`。 - -用户在画布上移动过的箭头或参考线报告 `hand_moved: true`,并在 `hand_edits` 中以键 -`annotation.position` 列出。可以改它的样式,但给这样的箭头设置新的 `at`、`to`,或给 -这样的参考线设置新的 `value`、`orientation` 会被拒绝,除非以 -`override_hand_edits: true` 表明是用户要求;改后位置重新算作 agent 的设置。 - -```json -{"op":"annotation_create","target":EXACT_PLOT_TARGET,"kind":"reference_line", - "orientation":"horizontal","value":0,"label":"baseline", - "line":{"color":"#7f7f7f","width_pt":0.5,"style":"dotted"}} -``` - -箭头标注(`kind: "arrow"`)是从箭尾 `at` 到箭头 `to` 的直线,两端使用同一数据 -坐标,因此与文字标注一样跟随坐标轴移动并裁切在绘图区内。`head` 默认为 `filled` -(`double` 两端均为实心箭头,`none` 为无箭头直线);`line_width_pt`(0.1–20 pt)默认 1 pt(若主题规定了辅助线宽则用它,Nature 主题为 -0.3 pt),`color` 默认黑色;两端不得重合。箭头不带文字,需要说明时另建一个 -文字标注(例如放在箭尾)。箭头与其他标注共用该图的 `annotation_id` 序列和每张图 256 个 -的上限,在 `annotations` 中以 `kind: "arrow"` 列出;提供其他类标注的字段会被拒绝。 - -Align 依据所选边界/中心;Distribute 在固定两端中心间等分中心位置,不等分边缘 -间隙。Grid 将已有原生格子算法与 authoring 尺寸 setter 组合用于明确子集,不表示 -GUI 已有子集 Grid 按钮;使用当前页面边距/gutter,不修改已保存的网格偏好或简化 -轴文字。仅改页面尺寸/边距不重排内容。非目标面板和 loose 内容原位保留,即使 -因此重叠或裁切,也不自动移动或缩字号。 - -面板目标须同属此画布、互不重复、未锁定,且为自由布局或共享 x 轴堆叠布局;新建文字和图片 -要求父面板为自由布局;锁定子内容也拒绝面板编辑。 -明确指定的隐藏目标仍可寻址。精确页面/布局编辑须先在 GUI 关闭 Auto height。尺寸须有限且为正,页面每边 10–1000 mm;边距/gutter -须非负并留出正空间。Grid 行列各 1–16、须容纳所有目标,且每格达到原生最小尺寸 1 pt。文字最多 16384 UTF-8 -字节、字号 1–72 pt;名称/手动标签最多 1024 字节且不得空白。每批 1–200 项, -每次布局最多 200 个面板。 - -图片预检仅读取明确指定的绝对路径普通文件:每批最多 8 次图片输入(创建与替换合计,重复输入也计数)、每文件编码大小 1 MiB、 -每批编码合计 4 MiB,每张解码 RGBA8 最多 4 MiB。PNG/JPEG 探测和解码复用原生 I/O; -预检冻结字节,提交后嵌入原生资产库,不依赖外部路径,相同编码资产复用。资产缺失、 -损坏或格式不支持使整批以 `invalid_parameters` 及明确资产错误拒绝。不扫描目录、 -访问网络或回写源文件。 - -`preflight.figure_plan` 返回拟建 `created`/`modified` 完整目标及 `result` 中的页面 -尺寸、边距/gutter 和精确 `panel_frames`;执行在 `ToolResult.value` 返回该结果。 -预检不提交内容;非法目标、几何、资产或旧 revision 不留下半成品。预检及执行都要求 -Read and modify。失败执行也消费一次性计划;沿用 32 个计划及 256 KiB 响应限制。 -一次 Undo 恢复整批,Redo 恢复同一原生内容/资产身份。执行响应丢失后先检查拟建目标, -不能盲目重复创建。可继续用普通 GUI Geometry、文字和图片 inspector 编辑,并查看 -实际 PNG;原生文字 frame 过小时可能裁切,布局不自动消除冲突。 - -## 移动已有内容或原位换图 - -需要扩宽已有说明框,或只替换两份共享资产图片中的一份时,先用 -`plotium_document_inspect(view:"self")` 读取该内容。复制完整目标,不用名称、选择状态 -或集合位置;使用当前 context/revision 预检 `figure.edit`,例如: - -```json -[ - {"op":"content_frame","target":{"resource":{"id":"CANVAS_UUID/CONTENT_ID","kind":"plotium.canvas.object","parent_id":"CANVAS_UUID","local_id":"CONTENT_ID"}},"frame_pt":[12,18,140,30]}, - {"op":"image_replace","target":{"resource":{"id":"CANVAS_UUID/IMAGE_ID","kind":"plotium.canvas.object","parent_id":"CANVAS_UUID","local_id":"IMAGE_ID"}},"path":"/absolute/local/replacement.png"} -] -``` - -将数组放入 `parameters.edits`,同级 `parameters.canvas` 使用发现的完整画布目标, -不传顶层 `ids/targets`。示例为两个不同内容;移动并替换同一图片时重复其完整目标。 -文字内容/字号仍用 `text_set`。 - -`content_frame` 支持 plot、text、raster 及已有 rect/ellipse/line/arrow,不创建或 -改父级。输入必须是完整 frame,不是相对增量。面板内使用父局部 pt,页直属使用页面 -pt;左上原点,X 向右、Y 向下。读取新增完整 `parent`、`frame_space`、原生平移换算的 -`page_frame` 和 `geometry` 限制。位置允许超出面板/页面,不自动钳制或吸附。 -分量及换算边界须有限,宽高至少 1 pt;不改变 GUI 拖拽下限。 - -只改目标内容(在共享 x 轴堆叠中,兄弟会按新比例重排):其余情况下父级、兄弟 frame/顺序,plot 的绑定、Series 身份、来源、单位、 -手动轴范围和样式,以及文字内容/字号均保留。目标和父级须解锁,父面板须为 Free -布局,Auto height 须关闭;无关兄弟锁定不阻止编辑。`geometry.frame_editable` 和 -`frame_edit_error` 返回原生限制,与连接修改权限独立。 - -图片 `preserve_aspect:true` 保持**现有 frame 比例**,不是替换图片的像素比例。 -复用原生算法:宽/高相对缩放中与 1 偏离较大者决定等比缩放(相等时取宽),并满足 -1 pt 下限;请求 X/Y 固定为左上锚点。预检明确返回可能不同的 `requested_frame_pt` -与 `effective_frame_pt`。`geometry` 同时提供 `min_size_pt`、`preserve_aspect`、 -`aspect_ratio`。`fit` 独立控制框内 contain/cover/stretch。 - -`image_replace` 仅赋值目标 AssetId,保留 ContentId、父级、frame、z-order、名称、 -可见性及全部图片属性:`page_index`、crop、fit、90°步进旋转、opacity、interpolation、 -preserve_aspect。其他旧资产引用不变。保留的 crop/fit 可能使新图呈现不同,不自动清空 -设置。PNG/JPEG 要求既有 `page_index=0`;非零页整批拒绝,不静默归零。换图要求目标/ -父级解锁,但不要求 Free 布局或关闭 Auto height;`image.replaceable`、`replace_error` -返回适用性。 - -创建和替换共享上述图片预算、字节冻结、编码资产去重、嵌入及 Undo 生命周期。 -预检后改动/删除源文件不影响候选或 Redo,不回写源文件、不回收资产。坏文件、不支持 -格式、错误/失效目标、锁定或无效几何均拒绝整批。 - -`preflight.figure_plan.result.content_edits` 按输入顺序逐项提供 `edit_index`、`op`、 -`target`、`parent`、`frame_space`、`before_frame_pt`、`effective_frame_pt`、`page_frame` -和 `geometry`;frame 修改另有 `requested_frame_pt`,换图另有 `asset_change`,包含 -前后 AssetId(`before/after`)、`format` 和 `pixel_size`。这些值表示该编辑步骤的状态。 -`result.content_frames` 返回各不同目标在整批完成后的最终几何,包含后续显式父面板缩放的影响。 -执行在 `ToolResult.value` 返回同一结果。两项沿用原有权限、context/revision 屏障和 -一次性计划;一次 Undo 恢复整批 frame/资产引用,Redo 恢复同一身份和冻结图片。 -提交后重新读取并查看实际图像。 - -## 精确删除内容或指定 Series - -可以要求 Agent:“删除这段重复说明和这条冗余曲线,保留另一条同名曲线。”先发现完整 -canvas/content 目标及所属 plot 的 Series 目标,不用名称、下标、显示 trace 序号或 GUI 当前选中项定位。 - -使用限定一个 canvas、只包含删除操作的 `figure.edit` 批次: - -```json -{"tool_id":"figure.edit","expected_project_context":"PROJECT_CONTEXT","expected_revision":12,"parameters":{ - "canvas":{"resource":{"id":"CANVAS_UUID","kind":"plotium.canvas"}}, - "edits":[ - {"op":"content_delete","target":{"resource":{"id":"CANVAS_UUID/CONTENT_ID","kind":"plotium.canvas.object","parent_id":"CANVAS_UUID","local_id":"CONTENT_ID"}}}, - {"op":"series_delete","target":{"resource":{"id":"CANVAS_UUID/PLOT_ID","kind":"plotium.canvas.object","parent_id":"CANVAS_UUID","local_id":"PLOT_ID"},"component":{"kind":"series","id":2}}} - ] -}} -``` - -`content_delete` 删除一份完整原生 plot、text、raster 或已有 rect/ellipse/line/arrow shape。 -删 plot 不删来源 Dataset。`panel_delete` 接收完整 Panel 目标,要求预检原始状态已为空; -同批先删全部子内容不能让非空 panel 变成合法目标。删除内容保留空父 panel,不重排兄弟。 - -`series_delete` 只删除所属 plot 内的指定 SeriesId。支持有既定坐标合同和显式列绑定的 -line/scatter plot,包括绑定派生表的 Series。拒绝删除末条 Series;移除整图须明确使用 -`content_delete`。拒绝 table_default 和动态多通道显示,不自动物化、换绑或修改 Dataset。 -剩余 Series 的身份、来源、顺序、encoding、坐标单位和手动范围保留,删除首条也不重新定义坐标。 - -重复目标、整 plot 与其 Series 重叠、跨 canvas、目标或父级锁定,以及删除和非删除操作混批 -均整批拒绝。隐藏目标仍可精确寻址,锁定兄弟不阻碍无关删除。原有 Auto height 开启时保留 -该设置,预检报告其原生派生高度变化,不擅自关闭。 - -执行前检查 `preflight.figure_plan.deleted` 和 `result.deleted_targets`。 -`result.deletions` 包含父级、顺序及随整 plot 移除的全部所属 Series。 -`parent_changes`、`group_changes`、`viewport_link_changes`、`selection_change` 列出必要 -关系更新;分组/链接保留幸存成员,不足两个成员时解除该关系。 -`remaining_series` 给出剩余顺序和 active Series 身份,`retained_asset_ids` 列出被删 raster 所引用但保留的资产, -`auto_height` 在开启时给出派生前后高度。这些是元数据,不是候选图像。 -执行回执 `ToolResult.value` 返回同一删除清单。 - -预检不提交。一次成功执行对应一次原子 Undo/Redo,失败不半删除。Undo 恢复精确身份、父级、 -对象/面板顺序、分组、链接和必要选择;ID 分配高水位不回退。不删除原文件、Dataset 或资产。 -运行期 Undo 保留嵌入资产;保存沿既有可达资产策略,重开项目不恢复 Undo 历史。 - -沿用修改权限、project context/revision 和一次性 plan 规则。GUI 选择不推进 revision, -但若变化会改变预检列出的删除选择影响,也须重新规划。每批最多 200 个显式删除目标; -Series 候选批次最多访问 200 万剩余 curve-row;共享最多 32 个 pending plans,完整响应 -不超过 256 KiB。清单超限拒绝,不截断后执行。目标或合同错误返回带原因的 -`invalid_parameters`;`stale_revision`、`project_changed`、`permission_denied`、 -`expired_plan`、`plan_limit`、`response_too_large` 沿用原含义。 - -执行结果未知时先重新发现当前 context、revision 和精确目标,不自动重放删除。 -提交后查看实际 PNG,再用原生 Undo/Redo、保存重开核对结果。 - -## 按输出尺寸诊断图面几何 - -可以说:“按 180 × 90 mm 检查出界、裁切、文字溢出、这两段说明的有意重叠,以及 -普通折线/散点与图例的潜在遮挡。不要修改内容;按返回 target 定位,并实际查看原生 PNG。” - -发现画布后直接调用 `plotium_figure_diagnose`,无需编辑计划: - -```json -{ - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 7, - "canvas": {"resource":{"id":"CANVAS_UUID","kind":"plotium.canvas"}}, - "output": {"size_mm":[180,90]}, - "checks": ["bounds","clipping","text_overflow","content_overlap","legend_occlusion","data_shape","layout_aesthetics","intent"], - "detail": "full", - "limit": 100 -} -``` - -可用 `targets` 限定完整的 content 或 Series target;Series target 还包含所属 plot 的 frame 和 guide 上下文。省略即扫描画布,绝不使用 GUI -选区。`content_overlap` 另需至少两个完整内容的 `overlap_targets`,比较可见且经过 -页面裁剪的 frame,不判断不透明像素。`view` 可取 `issues`(默认,返回问题)、`layout`(改为返回测得的几何行)或 `both`。 -`detail` 可取 `compact`(默认)或 `full`:精简的问题行保留 `target`、`component`、 -`code`、`severity`、`message`、`measurement_basis` 和 `suggestions`,`evidence` 只留 -`other_target`、`other_component`、`point_range` 和 `interpretation`,也不列已完成 -检查的覆盖行;`full` 返回全部证据几何和所有覆盖行。报告局限的覆盖行始终返回。 - -`output.size_mm` 须为正数并保持画布宽高比(高度容差 0.001 mm)。与原生导出一致, -它等比缩放既有页面,不重排布局;每个初始查询重新计算几何。结果使用 -`output_page_pt`:72 pt/inch,左上原点、X 向右、Y 向下。`output` 包含原生尺寸与 -尺度,文字、线宽和 bounds 一起缩放。panel-local frame 经原生 page-frame 服务换算。 -数据使用实际 plot 裁剪区;panel 边框**不是**所有内容的裁剪区。原生 raster frame -和 `clip_children` 的裁剪另行列明。 - -`ToolResult.value` 包含 `project_context`、`basis_revision`、`canvas`、`summary`、 -`output`、`items`、`coverage`、`truncated` 和 `continuation`。默认的 compact 详情中, -`output` 只含 `size_mm` 和 `size_pt`,`coverage` 给出状态、扫描计数以及不可用或不支持的 -条目数。`detail: "full"` 时 `output` 另含页面坐标说明,`coverage` 另含请求、支持和不支持的 -检查列表,并附 `budget`、`preview_request` 和 `read_policy`。`summary` -统计本页的问题(`issues`、`by_code`、`by_severity`);分页扫描时把各页计数相加。 -每个问题带完整原生 `target`、所属对象内的 `component`、`code`、`severity` 和说明; -`detail: "full"` 时证据另带 bounds、clip 和交集几何。 -将 `target` 直接用于 `plotium_document_inspect` 的 `view: "self"`;重名不影响定位。 -`guide.legend` 属于 plot,并非新资源。曲线冲突指向现有 Series,并通过 -`evidence.other_target` / `other_component` 关联所属 plot 的图例。 - -- `out_of_canvas`、`partially_clipped`、`fully_clipped`、`curve_primitives_clipped`/`shape_clipped` - 是信息性事实,包括有意的手动范围裁切;曲线证据只覆盖所列原生 run 的点范围。 -- `text_container_overflow` 是基于原生宽度/行距**估计**的警告,不是精确字形边界; - 文字不会自动换行或缩小。 -- `content_frame_overlap` 是信息性事实,允许有意重叠。 -- `axis_ticks_sparse` 是警告:在输出尺寸下,显示刻度标签的坐标轴画出的刻度少于两个, - 读不出刻度比例。增大面板,或调小 `object.figure.typography.tick_pt`。 -- `right_axis_untitled` 是警告:有曲线使用右 y 轴,但右轴没有显示标题。设置 - `object.axes.y2_label`(或重新打开 `object.axes.y2_show_label`)。 -- `legend_occlusion_potential` 表示潜在视觉冲突,不表示数据必然不可见。逐段/逐点 - 检查实际投影、有效裁剪后的线与 marker,分批保留虚线相位,不使用整条曲线包围盒, - 不抽样。线条包络与图例布局矩形是保守边界;圆角、半透明和抗锯齿可能有所不同。 - -`data_shape`、`layout_aesthetics` 和 `intent` 检查报告 `severity` 为 `hint` 的问题:图可以表达得 -更清楚,但没有错误。省略 `checks` 时包含这三项。提示从不修改文档。每条提示带 -`suggestions`,即 `{action, property, target, reason}` 列表;`property` 是要在 `target` -上设置的属性,没有则两者都为 null。长度按请求的 `output.size_mm` 测量;阈值是暂定值。 -限定到 Series 的查询只报告这些 Series 的提示。 - -| 代码 | 触发条件 | -| --- | --- | -| `small_values_invisible` | 某根柱的数值不到数值轴跨度的 1 %,或打印长度不到 0.5 mm,而旁边有至少 5 mm 长的柱 | -| `bars_too_narrow` | 某根柱打印宽度不到 0.6 mm | -| `few_samples_hidden` | 箱线、小提琴 Series,或每个 x 有多行的柱状 Series,每组都少于 10 个值;或每个 x 只有一行的柱状 Series 的 `series.replicates` 为 1–9;且图中没有散点 Series | -| `too_many_categories` | 类别轴显示标签,但省略了部分标签,或相邻标签相互重叠 | -| `log_scale_candidate` | 不含柱、箱线或小提琴的图,线性数值轴上的折线或散点值全为正,且跨越三个及以上数量级 | -| `bar_baseline_not_zero` | 数值轴范围不包含柱的基线 | -| `labels_overlap` | 画布上两个文字框在两个方向上都重叠超过 0.2 mm;证据给出两者和第二个的移动方向。同一图例的条目之间、同一坐标轴的刻度标签之间不互相比较 | -| `text_over_data` | 标注或数值标签压在柱、箱线、小提琴、折线或标记上 | -| `intent_mismatch` | 图型不适合这张图的 `object.intent.purpose`(见下文) | -| `panels_misaligned` | 同一列(左边缘相差 1 mm 以内)或同一行(下边缘相差 1 mm 以内)的两个框,绘图区左边缘或下边缘相差超过 0.5 mm;或同一行/列三个及以上框之间的间距相差超过 0.5 mm | - -同类提示超过 50 条,或检查用完预算时,会增加一条 `unavailable` 覆盖行。 - -`intent` 检查对照作者声明的目的看每张按列绑定的图;`detail` 从不报告。没有声明目的的图 -会得到一条 `not_applicable` 覆盖行 `no_purpose_stated`:这时请询问用户这张图要表达什么。 -表格图表类型得到 `chart_type_not_covered`。`intent_mismatch` 的证据在 -`interpretation` 中给出原因;`detail: "full"` 时还给出目的、claim 和读到的图表特征。 -建议里只列 Plotium 能画出的图型;请转告用户,由用户选择。 - -| 目的 | 报告条件 | -| --- | --- | -| `compare` | 折线连接了各类别 | -| `trend` | 类别方向的轴是类别轴,或图中画了柱 | -| `distribution` | 类别轴上只有柱或折线,没有箱线、小提琴或散点 Series | -| `relationship` | 类别方向的轴是类别轴,或图中画了柱、箱线或小提琴 | -| `composition` | 图中有折线或点,但没有柱 | -| `change` | 两个及以上柱状 Series 并排,或正的柱值跨十倍及以上;或图中没有柱、箱线和小提琴时,左轴上为正的折线或散点值在线性轴上跨十倍及以上 | - -原生 guide 布局本身使用文字宽度估计。字体可用性沿用原生导出的字体发现;实际字形 -覆盖和跨后端 ink 边界仍未验证。图像视口几何使用头部尺寸、整数裁剪、旋转及 fit; -是否成功解码、透明像素分布需看原生预览。首轮不覆盖非普通折线/散点的内部几何、 -误差棒裁剪/遮挡、科研派生标注及不透明像素遮挡;原生矩形、椭圆、直线和箭头的极值边界使用实际页面裁剪区;仍可观察其 frame/guide,覆盖 -结果会说明限制。除上述提示外,不做审美评分、科研正确性或统计意义判断。 - -**没有问题时也必须读 coverage。** 各目标区分 `complete`、`unsupported`、 -`unavailable`、`not_applicable`(如隐藏、空渲染数据或无图例)。整体 `partial` -表示尚有分页;`limited` 表示遍历结束但存在未支持/不可用部分。遍历完成不会把估计 -变为精确测量。数量是扫描对象、源点和重叠对数,不是像素覆盖百分比。缺资产/字体、 -失效来源和排除的几何会明确报告,不当作“图面无问题”。 - -`continuation` 非 null 时,仅用以下参数继续: - -```json -{"expected_project_context":"PROJECT_CONTEXT","expected_revision":7,"cursor":"RETURNED_CURSOR"} -``` - -一次性 cursor 绑定原目标、输出、检查及分页配置,闲置 300 秒失效。新的初始查询 -替换旧扫描。完成所有分页才可说明覆盖;问题行为空也可能截断。每个桌面连接仅保留 -一个执行中 batch 和一个未读快照。原生 stdio facade 为诊断续页保留一个 transport, -stdio 结束时关闭;其他工具仍使用原来的单次调用 transport,绝不重放。限制:200 个指定目标、200 个重叠目标/19,900 -对,每批 200 个对象和 1,000,000 个源点,每个 plot 最多 4,096 个渲染 run 与 polygon,1 MiB -文字、64 MiB 估算快照 payload、16 MiB 已编码资产探测。默认每页 100 行、最多 200 -行,页面值 96 KiB、JSON-RPC 响应 256 KiB。这些是 payload/工作量限制,不是进程 -总内存上限。快照/文字超限返回 `diagnostic_budget_exceeded`,需缩小目标;batch/ -行数用尽则返回 `truncated: true` 和 cursor,不抽样。 - -交付前重查 context、revision、busy 屏障和连接权限。编辑、项目变化、取消、停止连接 -及传输关闭会使相关工作失效;过期/已消费 cursor 返回 `expired_cursor`。 -遇到 `stale_revision` 或 `project_changed`,重新读状态并开始扫描,不混合新旧页。 -只读权限即可使用;对象、绑定、手动范围、几何、Undo 历史和 automation revision -以及 dirty、edit generation 不变,不追加项目审计记录。不持久化诊断几何、问题、cursor 或 PNG 副本。 - -用画布、上下文和 `basis_revision` 调用 `plotium_render_preview` 取得并实际查看原生 PNG。 -X 坐标转像素为 -`x * width_px / output.size_pt[0]`,Y 使用对应高度;核对其 -`render_revision` 与 `basis_revision` 一致。编辑器 zoom 不影响上述坐标。直接 core -`figure.diagnose` 只返回一个有界 batch,不保留 cursor;MCP 查询提供继续读取。 -诊断不会自动修图。 - -## 读取实际画布图像 - -可以请 agent:“预览这张画布,描述文字、曲线和本地图片。”先通过 -`plotium_document_inspect` 取得完整画布 target,再以当前 revision 调用 -`plotium_render_preview`: - -```json -{ - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 7, - "target": {"resource":{"id":"CANVAS_UUID","kind":"plotium.canvas"}}, - "max_edge": 1440 -} -``` - -将 `CANVAS_UUID` 换成发现返回的画布 ID;不接受面板、内容、当前选择或 Series。 -结果包含标准 MCP PNG **image 内容块**,以及 `ToolResult.value` 中的 -`target`、`render_revision`、`width_px`、`height_px` 和 `mime_type`。 -无需打开文件或自行渲染 SVG 文本。点数超过预览所能显示的曲线以最小/最大包络 -绘制:每个像素列保留四对最小/最大值点,整个绘图区至少 2,048 对(标记则每个像素 -一个);`downsampled` 以 `{target, source_points, drawn_points}` 列出每条这样的 -曲线,没有降采样时省略。放大后可见的数据点全部保留。 -导出始终绘制全部数据点。MCP 客户端须将图像内容交给 agent;纯文本 -客户端无法读取此预览。 - -图像覆盖整页,使用原生版式、背景、面板裁剪、文字、曲线及项目内嵌栅格资产。 -渲染基于不可变快照在后台执行,`render_revision` 标识该快照;截取后发生的人工 -修改不会被标成图像内容。执行后续修改前请重新读取状态。只读连接也允许预览。 -预览不追加项目运行记录,也不改变 dirty、edit generation 或 automation revision。 - -`max_edge` 默认 1440 px,可取 1–2048;保持宽高比,按像素取整,每轴至少一个 -像素。预算为输出 4,194,304 像素、引用资产编码数据合计 16 MiB、按实际文件头 -探测的资产页 RGBA8 合计 64 MiB、中间 SVG 8 MiB、PNG 4 MiB、JSON-RPC 预览响应 -6 MiB(包含请求 ID)。同一资产编码数据只计一次,同一资产页解码只计一次。 -这些限制约束负载和图像缓冲区,不代表整个进程的内存上限。所有引用资产均校验,包括隐藏项。 -`plotium_capabilities_get {"section":"limits","key":"image_preview"}` 也提供这些预算。 - -资产缺失、损坏或图片页不可用时返回 `preview_asset_unavailable`,不会以占位图 -或缺图结果报告成功。超过预算返回 `preview_budget_exceeded`,不静默降质;输出 -超限时降低 `max_edge`,资产超限时缩小源资产。无效完整身份返回 -`invalid_parameters`,过期 revision 返回 `stale_revision`。 -每连接最多同时渲染一张预览,重复请求返回 `busy`;渲染期间其他已有工具仍可用。 -取消请求或停止连接后不交付图像;停止连接、切换项目会丢弃旧任务。 - -## 提交前读取计划候选 - -`plotium_plan` 返回后,用**原** plan ID、context、revision 和一个受影响的完整画布 -target 调用 `plotium_preview_plan`: - -```json -{ - "plan_id": "RETURNED_PLAN_ID", - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 7, - "target": {"resource":{"id":"CANVAS_UUID","kind":"plotium.canvas"}}, - "max_edge": 1440 -} -``` - -响应包含实际 MCP PNG image 内容块。`ToolResult.value` 返回 `plan_id`、 -`basis_project_context`、`basis_revision`、`candidate: true`、`target`、 -`width_px`、`height_px`、`mime_type` 和 `output`(`size_mm`、`size_pt`、`max_edge`)。 -没有 `render_revision`:候选尚未提交。读取结果的 `before_revision` 和 `after_revision` -均指向基线。实际读图后,再明确以原 `plan_id` 调用 `plotium_execute`;随后读取 -`plotium_render_preview` 和 fresh `plotium_figure_diagnose`。候选预览不增加候选诊断 -或自动修图循环。保留诊断的 `measurement_basis`、`coverage` 和 `unsupported`; -估计文字边界不是字形墨迹,潜在图例冲突不是已确认遮挡。 - -| 已有计划 | 候选支持范围 | -| --- | --- | -| `properties.set` / `properties.reset` / `properties.set_many` | 文档和图对象的显示属性及原生多目标批次;不含画布属性、应用偏好、数据处理,以及图表类型和堆叠方式的修改 | -| `figure.edit` 局部编辑 | `content_frame`、`image_replace`、`text_set`、`annotation_create`/`annotation_set`/`annotation_delete`(文字标注与参考线)及原生批次 | -| `figure.edit` 纯删除批次 | `content_delete`、原本为空的 `panel_delete`、显式列绑定 `series_delete`;原拒绝规则不变 | -| 其他操作,包括保存和导出 | 返回 `unsupported_operation`,不改变其正常 execute 合同 | - -想让用户挑选样式(配色、线宽、图例位置、标签布局等)时,规划两三个备选计划,逐个预览, -把图并排给用户看。只执行用户选中的计划。其余计划从不提交,之后会返回 `stale_revision`, -但在提交或连接重置前仍占用 32 个待执行计划的名额。 - -受影响画布须使用普通折线/散点、原生文字、形状和栅格内容;预览不启动科学计算。 -跨画布属性计划在隔离原生上下文应用完整批次,可逐个请求受影响画布,仍是一个计划、 -一个 Undo 步骤。自动轴、guide 依赖和派生页高复用原生 action 与 renderer,不另建布局模型。 -基线、输出设置和字体相同时,候选内容和几何与 execute 一致;不保证跨机器字体/renderer -不同情况下的像素相等。 - -候选读取需要 **Read and modify**;截取和后台交付时均检查 context、revision、空闲状态、 -当前权限及计划仍未提交。渲染中撤权再授权也会阻止交付。预览不消费计划、不延长生命周期、 -不赋予执行权限。普通编辑计划没有时钟 TTL,共享每会话 32 个计划上限,context/连接变化 -会清空。execute 提交只可一次,包括失败提交。`expired_plan` 表示计划不存在或已消费; -其他拒绝由 `stale_revision`、`project_changed`、`permission_denied`、`busy`、 -`request_cancelled` 及上述图像错误表达。人工编辑或切项目后须重新发现和规划;连接中断后 -不要重放结果未知的 execute。 - -预览借用冻结输入和图像字节,不重读换图路径、不重分配已规划身份,也不在真实项目执行 -再 Undo。它不改变 authored 内容、数据、绑定、选择、历史、automation revision 或持久 -资产、dirty 或 edit generation。不追加项目审计记录,**不保存 PNG 字节**。无候选文件或缓存。 -候选与真实预览共享单个渲染槽、取消和上述图像预算;另以 64 MiB 原生快照估计约束候选 -构造(画布几何、来源字段按每元素 64 字节、元数据及冻结资产),不表示整个进程内存上限。 -切项目取消的任务在有界 renderer 退出前继续占用渲染槽。 - -## 精确放置单图图例 - -Guide 属性使用 `ids:[PLOT_OBJECT_ID]`,不接受 Series 组件。按完整画布/对象身份 -发现目标,不依赖唯一名称。每次用 `properties.set` 设置一个 key/value,检查计划后 -再执行返回的单次 plan ID: - -```json -{ - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 7, - "tool_id": "properties.set", - "ids": ["CANVAS_UUID/OBJECT_ID"], - "parameters": {"key":"object.guides.position","value":[0,1]} -} -``` - -`position` 接受恰好两个 [0,1] 内的有限数,或 `null`。坐标表示图例框左上角在 -坐标轴绘图区内可供整个图例框移动的空间中的比例,x 向右、y 向下: -`origin = plot_origin + [x,y] * max(plot_size - legend_size, 0)`。 -它不是屏幕像素、整页比例或数据坐标。[0,0] 为左上角;能够容纳时,[1,1] 使 -右下角对齐。输出尺寸、图例内容或布局改变时,由 renderer 重新换算。 - -原生属性及必要联动如下: - -- `visibility`:`auto`、`show`、`hide`。Auto 在至少两个原生条目时显示普通图例, - Show 允许单条目,Hide 隐藏 guide 而非数据。 -- `placement`:`auto`、`inside`、`outside_right`、`outside_bottom`、`custom`。 - Custom 保留已有原点,没有则从 [1,0] 开始,同时设置 Inside;其他模式清除自定义原点。 -- `position`:[x,y] 设置 Inside/custom。`null`、position reset、placement Auto - 和 placement reset 都清除原点及 placement override,与 GUI 双击一致。 - 读取 `null` 仅表示无自定义原点;实际模式由 placement 决定,也可能位于图外。 -- `layout`:`auto`、`vertical`、`horizontal`,保留原生布局规则。 -- `title`:文本;空白文本沿用原生规范化,清除标题 override。 - -visibility/layout/title 各自只重置自己的 override。位置修改及重置保留这些字段、 -字号、绑定、曲线样式和手动轴范围。同名同色等条目仍按原生规则合并,因此六条曲线 -不一定形成六个图例条目。已有四项属性保留 color scale 行为;二维位置仅适用于 -原生普通图例内容,不受 guide 显示开关限制;无内容时仍可读取/重置保留的原点, -但不能设置新坐标,也不独立移动 colorbar。 - -适用属性的查询 readings 增加 `guide_geometry`,包含 -`coordinate_space:"object_local_pt"`、`scale:1`、`plot_rect`、可空的 -`legend_rect`/`color_scale_rect`(x/y/width/height)、`entry_count`、可空的 -`available_travel_pt`、`effective_position`、`fits_plot`(两个尺寸容纳布尔值), -以及 `not_rendered_reason`(`hidden`、`no_entries`、`auto_single_entry` 或 null)。 -`measurement_basis:"renderer_layout_text_width_estimate"` 表明这是渲染使用的布局框, -文字宽度沿用原生估算,不是精确字形边界;这里不检测对象/父容器的可见性和裁切。 -实际位置按可移动距离解析,不钳制图外 -placement;零移动距离的轴返回零。guide 隐藏或自动省略时几何返回 null 并说明原因, -属性值仍保留配置的原点。 - -图例过大时不静默缩字:相应轴的可移动距离为零,`fits_plot` 为 false,实际位置 -可能不同于请求原点。尺寸能容纳不代表没有裁切或遮挡曲线,仍须查看原生 PNG 及 -最终导出。此信息仅观察 guide 布局,不是全图诊断。 - -Guide 写入在提交前验证全部显式目标;存在但不适用的目标以 `invalid_parameters` -拒绝整批,不沿用旧属性的跳过策略;旧属性行为不变。重复 ID 处理一次。每次一个属性、 -最多 200 个 ID、一次 Undo/Redo;标题最多 16,384 UTF-8 字节,结构化响应最多 -256 KiB(超限为 `response_too_large`),继续共享 32 个待执行计划上限。 -形状错误、非有限或越界值返回 `invalid_parameters`。查询仍报告不适用目标。 -只读连接可以查询及预检,execute 需要可撤销修改权限;context/revision 变化、撤权、 -busy 和过期计划保留原有单次生命周期。查询不追加项目审计记录,也不改变 dirty、 -edit generation、automation revision 或 Undo 历史。能力发现见 `plotium_capabilities_get {"section":"guide_contract"}`。 - -## 精确修改显示,不重建图对象 - -直接使用预检的 `creation.series_defaults[].target` 或执行的 `value.bindings[].target`, -或通过 `plotium_document_inspect` -发现完整目标。所属图对象与稳定 SeriesId 必须共同传递,同名曲线仍是不同目标。 -`plotium_properties_list` 列出允许的属性;`plotium_properties_inspect` 返回当前值、 -默认值、目标适用的单位选项和范围输入 schema。 - -先调用 `plotium_get_state`,取其 `project_context` 和当前 revision,再调用 -`plotium_plan`。将以下占位符和数值身份替换为实际发现结果: - -```json -{ - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 7, - "tool_id": "properties.set", - "targets": [{ - "resource": {"id":"CANVAS_UUID/OBJECT_ID","kind":"plotium.canvas.object", - "parent_id":"CANVAS_UUID","local_id":"OBJECT_ID"}, - "component": {"kind":"series","id":1} - }], - "parameters": {"key":"series.line.color","value":"#0072B2"} -} -``` - -检查预检后,仅以返回的 `plan_id` 调用 `plotium_execute`。 -只改变该曲线及其误差线的颜色,不改变线宽或来源列。轴和单图字号使用 -`ids:[PLOT_OBJECT_ID]`。 - -每次请求修改一个 key,可包含多个目标,原子提交并合为一次 Undo。已有但不适用 -的目标报告跳过;失效或伪造身份拒绝整次请求。非法颜色、非有限数值及非法范围 -在预检拒绝;执行重查 revision 和权限,失败执行也消费 plan,须重读并重新规划。 - -范围值明确区分: - -- `{"mode":"auto"}`:仅清除该轴手动范围。 -- `{"mode":"manual","min":0,"max":10,"unit":"mA"}`:在明确的兼容单位内设置 - 有限且递增的范围。`unit:null` 只用于坐标单位未知的图,不能凭显示修改引入单位。 -- 重置**全部**轴设置是另一个原生操作,不是 Auto 的副作用;`properties.reset` - 轴属性 reset 只清除指定 override;guide 原点/placement 按上文的联动规则重置。 - -显示单位接受属性查询返回的兼容代码,例如 s→ms、mA→A。图对象仍保持 R4 坐标单位契约: -原始数据、手动范围存储、位移及误差幅度的含义不变;刻度及自动派生的单位文字改变, -人工轴标题保持原文。重绑、重排和删除首条曲线不重新定义坐标。隐藏轴或分类轴不能 -设置数值手动范围,但可清除已保留的范围。属性查询中的 `unit_code.codes` 返回该目标的兼容选项; -`axis_range.input_schema` 描述输入,`view` 和 `unit` 表示当前显示窗口。 - -符号大小以 pt **直径**表示,显式设置后独立于线宽。没有覆盖时,原生点图仍沿用 -现有基于 width 的半径,原线宽接口含义不变;reset 恢复原生符号/大小。 -显式空图例文字使该图例项不显示。线型仅适用于折线,散点目标会按规则跳过。 -符号适用于折线和散点,不适用于 stick、柱状、箱线和小提琴曲线;柱宽和描边宽度适用于柱状、箱线和小提琴曲线,描边颜色仅适用于柱状曲线。符号填充色和边框色作用于闭合符号,未设置时跟随 -曲线颜色,reset 恢复跟随。空心符号不填充并保留边框,未设置边框宽度时为 0.5 pt。`marker_every` 从第一个源数据点起每 n 个点画一个符号,折线仍经过每个点。颜色由图型语义决定时,单曲线改色、改符号填充色或边框色按不适用跳过。 - -单图刻度、轴标题和图例字号在未覆盖时继承文档设置,reset 只移除相应覆盖; -改单图字体不影响其他图。字体/标题测量沿用原生渲染,不重排页面,不改变面板及 -内容的位置、尺寸。GUI 在现有 Line、Axes、Legend & scales 中使用同一属性控制,单图单位、范围及 -字号位于 Advanced。 -已有文档级字号仍保持项目范围。 - -修改后读取新 revision,再为实际画布调用 `plotium_render_preview`,查看 PNG 并 -核对 `render_revision`;用 GUI Undo/Redo 检查同一原生对象。MCP 保存需单独的桌面授权;导出另需独立桌面授权。 - -## 查询并修改一条明确曲线 - -示例任务:“找到我的线图,读取线宽,预检改为 1.5 pt,再执行保存的计划。” -工具调用顺序如下: - -1. 用 `{}` 调用 `plotium_get_state`,取得 `project_context`、`revision`、项目概况、选择和连接权限。 -2. `plotium_resources_search` 接受 `expected_project_context`、`expected_revision` 和 `query`,例如 - `{"kinds":["plotium.canvas.object"],"name_contains":"Plot"}`。先将结果解析为 - 显式稳定 ID;所有匹配理由相同(例如无筛选搜索)时,`value.reason` 只给出一次, - 不再返回 `value.reasons`。`plotium_resources_inspect` 用 `ids` 和 `expected_revision` 读取描述。 -3. 用 `{}` 调用 `plotium_properties_list` 列出支持的属性 ID 和值类型。 - 使用 `plotium_properties_inspect` 查询曲线地址: - - ```json - {"ids":["CANVAS_UUID/OBJECT_ID"],"key":"series.line.stroke_width","expected_project_context":"PROJECT_CONTEXT","expected_revision":7} - ``` - - 返回的 `value.readings` 为每条适用曲线提供一行;各行 schema 或默认值相同时,改为在 - `value.schema` 和 `value.default_value` 中给出一次。复制所选曲线的完整 - `value.readings[0].target`,例如: - - ```json - { - "resource": { - "id":"CANVAS_UUID/OBJECT_ID", - "kind":"plotium.canvas.object", - "parent_id":"CANVAS_UUID", - "local_id":"OBJECT_ID" - }, - "component":{"kind":"series","id":0} - } - ``` - -4. 将该 target 原样传入 `plotium_plan`,仅修改这一条曲线: - - ```json - { - "tool_id":"properties.set", - "parameters":{"key":"series.line.stroke_width","value":1.5}, - "targets":[{ - "resource":{ - "id":"CANVAS_UUID/OBJECT_ID", - "kind":"plotium.canvas.object", - "parent_id":"CANVAS_UUID", - "local_id":"OBJECT_ID" - }, - "component":{"kind":"series","id":0} - }], - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision":7 - } - ``` - -5. 查看 `preflight` 后,仅以 `{"plan_id":"RETURNED_PLAN_ID"}` 调用 - `plotium_execute`。桌面立即显示修改;**Undo** 恢复原值,**Redo** 重新应用。 - 相同值报告为跳过;整批修改合并为一次撤销。 - -属性查询和属性编辑预检必须且只能提供一个非空的 `ids` 或 `targets` 数组。 -`ids` 将每个资源展开为该属性对应的所有组件;`targets` 只操作指定的 Series 组件。 -Series ID 仅在所属图对象内唯一,因此务必复制包含资源信息的完整 target。 -重复目标仅处理一次;组件不存在或资源身份被伪造时整次请求拒绝;曲线存在但属性 -不适用时报告为跳过。查询会返回当前值、默认值、范围及可用性;只查询一条曲线时, -也可将查询参数改为 `targets`。恢复默认值时,用同一 target 预检 `properties.reset`, -参数为 `{"key":"series.line.stroke_width"}`。组件寻址仅支持所列显示属性, -处理参数使用独立的 `processing.edit` 操作。`resource.rename` 仍须使用 `ids`。 - -`dataset.delete` 的参数为 `{}`,在 `ids` 中给出 DatasetId。如果仍有图、投影、 -派生数据集或分析报告使用该数据集,预检会拒绝,并指出使用它的页面与面板、 -数据集或报告;请先删除这些内容。派生数据集需单独一次请求先删除,再删除其来源。一次撤销即可按原 ID 和原位置恢复全部被删除的数据集。 - -工具结果同时提供结构化内容及 JSON 文本。项目读取与预检要求当前 -`expected_revision`;需要动态值、桌面编辑或撤销后重新获取状态。已知精确目标时可按上述规则 -复用同步提交结果。执行时重新检查保存的 revision -和当前权限。计划仅可提交一次,失败后也需重新预检;最多保留 32 个待执行计划, -重启连接会清空计划。桌面开始执行前已取消的请求不会修改项目;已进入原子 -提交的修改无法通过取消回滚,请使用 **Undo**。 - -稳定错误码包括 `project_changed`、`unavailable`、`connection_lost`、`permission_denied`、`expired_plan`、`stale_revision`、`busy`、 -`invalid_parameters`、`unsupported_operation`、`unsupported_property`、`plan_limit`、 -`request_cancelled`、`connection_stopped`、`response_too_large` 和 `execution_failed`。 -无效的能力分区或键会指向静态发现,并在 `error.details` 给出合法候选。 -无效的规划参数指向该操作的 `operation_constraints`,而不是要求读取项目状态。 -输入错误在已解析的请求边界提供 `error.details.field`,例如 `plan_id`、 -`parameters` 或 `parameters.writes[0].key`。过期 revision 和项目切换仍须读取状态并重规划; -这些指引不允许重放。嵌套的 source 和目标错误给出完整路径,例如 -`parameters.series[0].source.y`。 - -错误提供 `error.recovery`,异步保存、导出和任务回执提供 `recovery`。 -`retryable: false` 表示不要重复失败的调用,应遵循下一步动作。`busy` 执行可能已经 -消费计划。revision 冲突需读取状态并审核新计划;过期计划可能已经执行,必须先核查结果。 -AI connections (MCP) 设置页面显示最近操作和错误,后台反馈不会自行打开设置页面。 - - -## 恢复动作与未知结果 - -`recovery` 描述本次请求,不授予执行另一次请求的权限: - -| 字段 | 含义 | -| --- | --- | -| `plan_consumed` | 确知时为 `true` 或 `false`,未知时为 `null`。已消费的计划不能重用。 | -| `submission` | `submitted`、`not_submitted` 或 `unknown`;后台工作被接受不代表完成。 | -| `committed` | 确知时为 `true` 或 `false`,副作用或持久化结果不确定时为 `null`。 | -| `completion` | `pending`、`succeeded`、`failed`、`partial` 或 `unknown`。 | -| `receipt` | 状态工具及 `arguments` 中的准确 ID;`retained` 找到时为 `true`,缺失时为 `false`,未知时为 `null`。整个 `receipt` 为 `null` 表示没有已知的回执查询。 | -| `next_action` | 一个下一步:带准确参数的 `call_tool`、`desktop_file_confirmation`、`check_desktop_connection`、`inspect_outcome` 或 `none`。 | -| `replay_allowed` | 始终为 `false`,恢复信息不授权重放或自动重新提交。 | - -`call_tool` 只调用指定的读取工具。桌面确认时,在 Plotium 审核待处理请求的准确路径和 -覆盖范围,再查询回执。`check_desktop_connection` 要求在桌面检查 AI connections (MCP) -及访问模式,然后读取状态。`inspect_outcome` 要求对照保留的回执、预检目标/路径和 -当前状态;证据不足时,重新计算科学任务或请求文件写入前需人工审核。 - -- **Busy:**预检在提交前失败。执行可能先消费计划,再检查 busy;结束桌面操作、读取 - 状态并审核新计划,不能重用已消费的 ID。 -- **Revision 冲突/项目切换/撤权:**刷新状态并在桌面检查权限。切换项目后重新发现 - 新 context 中的目标;计划 ID 和文件权限不能转移到新项目。 -- **安装前保存拒绝或取消:**已消费计划的回执为终态,`phase: not_installed`、 - `committed: false`、`completion: failed`。关闭确认框也表示拒绝。先检查状态并询问 - 是否仍需保存;新的保存意图需新计划和新的桌面确认。 - Worker 启动后的取消必须根据最终阶段判断,不会撤销已经安装的输出。 -- **保存/任务尚未完成:**被接受、排队、运行或保存中都是 `pending`,不是成功。 - 查询回执,不提交替代任务或保存。保存 worker 终止后,`installed_unconfirmed` - 仍表示未知结果。 -- **导出:**只有批次完成且每个文件都成功,整批才成功。混合终态为 `partial`;逐个 - 核查准确路径及错误。文件可能已安装后才发生持久化错误,因此失败不证明路径未变。 - 不能自动重试整批,也不能重写其中已成功的文件。 -- **断连/计划过期/回执未知或淘汰:**保留计划消费、提交和持久化状态的未知性。 - 重连后在同一桌面进程查询已知回执 ID;不存在时核查保存的目标/路径。回执缺失 - 不证明未执行,也不授权重算或覆盖。桌面重启后不保留回执。 - -这些动作保留服务端权限、revision/context 检查、一次性计划和逐次桌面文件确认。 -工具 annotations 既不授权,也不是重试依据。桌面和连接器一起升级后,重新连接客户端 -并刷新工具目录。 - -## 一次计划设置多条曲线的样式 - -`properties.set` 每次只写一个值。要给每条曲线分别设置颜色和图例标签,请改为预检 -`properties.set_many`:每一项写入指定一个明确目标、一个受支持的 key 和一个值。 -省略顶层 `ids` 和 `targets`;曲线属性使用查询得到的完整 Series 目标,坐标轴标题、 -图例等对象级属性使用图对象的资源目标,不带 component。 - -```json -{ - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 7, - "tool_id": "properties.set_many", - "parameters": {"writes": [ - {"target": SERIES_0_TARGET, "key": "series.line.color", "value": "#0072B2"}, - {"target": SERIES_0_TARGET, "key": "series.label", "value": "Sample 1"}, - {"target": SERIES_1_TARGET, "key": "series.line.color", "value": "#D55E00"}, - {"target": SERIES_1_TARGET, "key": "series.label", "value": "Sample 2"}, - {"target": {"resource": PLOT_OBJECT_RESOURCE}, "key": "object.axes.x_label", "value": "Temperature (°C)"} - ]} -} -``` - -`plot.create` 执行后,可以直接复用它返回的完整稳定目标。例如,将解码后的创建 -`ToolResult` 存为 `created`,原状态存为 `state`,构造以下 `plotium_plan` 参数: - -```js -const request = { - expected_project_context: state.project_context, - expected_revision: created.after_revision, - tool_id: "properties.set_many", - parameters: { writes: [ - ...created.value.bindings.map((binding, index) => ({ - target: binding.target, - key: "series.label", - value: `Sample ${index + 1}` - })), - { target: created.value.creation.plot, - key: "object.axes.x_label", value: "Temperature (°C)" } - ] } -}; -``` - -复制整个 `target`,保留所属资源的 `kind`、`id`、`parent_id`、`local_id` 和存在时的 -组件身份。单独的 SeriesId、名称或数组下标不是目标选择器。总写入数保持在 200 以内。 -预检上述对象,审核后仅执行一次新 `plan_id`。`unsupported_operation` 表示操作不可用; -`unsupported_property` 在 `error.details.write_index`(从零开始)和 `key` 指出不支持 -的属性。查询 `plotium_properties_list`,修正整个批次后再预检。 - -一个批次包含 1–200 项写入,可使用上文列出的显示属性。只要有一项写入的目标不存在、属性不适用于该目标、值无效, -或同一目标的同一 key 写了两次,预检就拒绝整个批次,不提交任何修改。目标已是该值的 -写入会报告为跳过,其余写入照常生效。`plotium_execute` 把全部写入作为一个**撤销** -步骤提交;`value.writes` 列出被跳过的写入,含序号、key、结果和 `skip_reason`。 - -写属性的返回很短。`properties.set`、`properties.set_many` 和 `properties.reset` -的预检返回 `required_authority`、`estimated_changes`、`summary`(`compatible`、 -`skipped`、`failed`),`targets` 只列出不会写入的目标。执行结果加上 `summary` -(`succeeded`、`skipped`、`failed`,以及按 `skip_reason` 计数的 `by_reason`); -`targets` 和批次的 `value.writes` 只列没有成功的项。全部生效时两者都为空。 -`plotium_preview_plan` 仍按完整计划渲染。 - -## 用户手动设置的值 - -用户在 Plotium 中修改图形值(在属性面板中设置、在控件上滚动调整或拖动图例)时, -Plotium 会把它记为手动设置。`plotium_get_state` 在 `hand_edits` 中列出这些值, -`properties.inspect` 为每个这样的读数标注 `"hand_set": true`。 - -`properties.set`、`properties.set_many` 和 `properties.reset` 不会改动手动设置的值: -该目标在预检和结果中都报告为跳过,`skip_reason` 为 `"hand_set"`,其余目标照常生效。 -图例的位置选项和拖动后的位置算作同一个值。只有用户要求修改时,才在 `parameters` 中 -传入 `"override_hand_edits": true`;修改后的新值仍算作用户的设置。 - -不带该参数写入的值不会被记录,之后的主题或写入可能会替换它们。主题会保留手动设置的值, -见下一节。 - -## 为画布套用主题或已保存的风格 - -`figure.apply_theme` 用 Plotium 的内置主题(例如 `nature`)或在 Plotium 中保存的画布 -风格整体重设画布样式。`theme_id` 可以填 -`plotium_capabilities_get {"section":"operation_constraints","key":"figure.apply_theme"}` -返回的 `builtin_themes` 中的内置主题 id,也可以填 -已保存风格的名称。已保存的风格不在固定的能力说明里:未知的 `theme_id` 会在预检时以 -`invalid_parameters` 失败,`error.details.themes` 列出当前可用的全部内置主题和已保存 -风格。预检时把画布 id 放在顶层 `ids`: - -```json -{ - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 7, - "ids": ["CANVAS_ID"], - "tool_id": "figure.apply_theme", - "parameters": {"theme_id": "nature"} -} -``` - -预检只需只读权限,执行需要 **读取并修改**。未知的 `theme_id`、Series `targets`, -以及不含任何画布的 `ids` 会在预检时被拒绝;其余不是画布的 id 会被跳过。已保存的风格 -会在执行时重新读取。执行时把每张画布的背景、文字和形状颜色,以及主题规定的每条曲线 -颜色、符号填充与描边、符号大小和线宽作为一个**撤销**步骤一起修改。手动设置的曲线和符号颜色在 -重新套用主题时会保留;重置曲线颜色后,曲线重新使用主题颜色。文档的样式默认值也会被替换:图的文字字号、坐标轴线和 -刻度是整个文档共用的,所以其他画布上的图也会随之改变;新建文字、面板字母和形状的 -默认样式同样改用主题的设置。用户手动设置的值(包括图形排版)会保留,`diagnostics` 会附一条 -说明保留了几处。按期刊栏宽设计的主题(目前为 `nature`)不会改变画布尺寸; -画布宽度不符合任一栏宽预设时,结果的 `diagnostics` 会为该画布附一条提示,列出预设宽度 -(89 / 136 / 183 mm)。 - -## 保存当前桌面项目 - -保存复用 **Save project** 的原生快照、后台 worker、备份和完成回调,保存当前 -桌面实际状态,不另开 CLI 项目。先读 `plotium_get_state`;`save_state` 给出当前路径、 -已存档案 revision、dirty、edit_generation 和最多 16 个保留的 `receipt_ids`。 -逐个用 `plotium_save_status` 查询完整回执和恢复动作;仅有 ID 不代表提交成功或已经完成。 - -首次保存或另存时,不带 `ids`/`targets`: - -```json -{ - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 46, - "tool_id": "project.save", - "parameters": {"path": "/absolute/path/figure.plotium"} -} -``` - -省略 `path` 保存当前文件;未命名项目必须给出路径。父目录须已存在,目标为普通、 -非符号链接的 `.plotium` 文件或尚不存在的路径。预检解析父目录并冻结已观察的目标。 -可选 `include_view_snapshots` 覆盖当前项目的原生保存配置。计划返回 `save_id`、 -实际路径及 `overwrite_required`,不授予磁盘写权限。 - -用 `plotium_execute {"plan_id":"PLAN_ID"}` 提交一次性计划,结果为 -`save.status: "awaiting_authorization"`。在 Plotium 核对准确路径,点击 -**Allow save**;已有文件还必须勾选 **Replace the existing file at this exact path**。 -**Deny** 不改目标。这与 **Read and modify** 独立,只授权本次保存,不能通过工具 -参数代为批准。Read only 模式也可发起此授权请求。目标变化须重新规划并确认; -同时最多一个外部保存请求。 - -序列化使用独占创建的私有唯一同目录临时文件,不写固定 `.tmp`。 -已有目标在备份准备完成后、实际替换前再次复验预检冻结的文件元数据;发现变化即拒绝 -安装,保留后来版本。一次性权限准入与文件复验是两个边界;复验加替换并非跨进程 -compare-and-swap。非协作写入若发生在最后复验之后,或保留了所检查的元数据, -仍可能无法察觉;应避免并发保存到同一路径。 - -用 `plotium_save_status {"save_id":"SAVE_ID"}` 查询,不带项目 revision/context, -保存中也可读取且不使项目 dirty。`awaiting_authorization`、`queued`、`saving` -均未完成,`phase` 为 null;只有 `completed` 带最终阶段: - -| phase | 文件状态与下一步 | -| --- | --- | -| `not_installed` | 本次未把快照安装到目标。处理拒绝或错误、检查实际状态;仍需保存时重新取得授权。 | -| `installed_unconfirmed` | 快照已替换/创建目标,但备份收尾或持久同步失败。保持项目打开,检查目标及存储后再明确授权重试;不能假定旧文件还在。 | -| `committed` | 捕获的快照完成原生持久提交;后来的编辑仍可能未保存。 | - -Windows 替换部分失败时,即使新快照为 `not_installed`,旧目标仍可能已被移走或删除。 -Plotium 保留已序列化的候选文件,并报告准确恢复路径。只有不覆盖现有目标时才尝试 -从已知备份恢复原文件;无法完成时,保留并报告该备份及更早的暂存备份。如果 Windows -移走原文件却未返回其位置,错误会明确说明。保持项目打开,检查所列文件后再决定是否 -重试;此类失败不会清除 dirty 状态。 - -回执包含原始 `project_context`、`snapshot.document_revision`、 -`snapshot.edit_generation`、`persisted_revision`、准确路径、`state_applied`、 -`dirty_after_completion`、错误及恢复说明。查询结果另给当前 context/path/revision/dirty -和 `matches_current_project`。快照在桌面批准后、后台工作前捕获;之后的新编辑 -保持 dirty,完成不等于当前所有编辑已落盘。 -已安装但未确认同步时仍保持 dirty,并记录已安装基线供原生恢复使用。 -保存规划/提交和状态查询仅用临时桌面回执,不加审计记录;普通项目读取同样不追加 -项目审计记录,也不改变 dirty。 - -切项目或停止连接撤销待写权限。worker 只持有原项目快照和路径,并在安装边界检查 -授权;即便 document revision 相同,旧完成也不能装入另一项目或清它的 dirty。 -worker 原子确认授权并进入安装后,停止不保证取消这次原文件写入,须查回执; -在此之前撤销则阻止安装。保存不加入 Undo,Undo 不删除或还原磁盘文件。 - -桌面进程保留最近 16 条回执,跨连接恢复和项目切换有效,退出应用后不保留。响应丢失后 -先查询原 `save_id`,不要重放已提交调用。应用重启或 `unknown_save` 时,检查目标和 -新打开的项目,不自行假定成功或失败。稳定 stdio 配置继续可用;重开/重启后仍须 -重新读取状态、发现目标并规划。连接恢复不是保存成功的证据。 - - -## 将捕获画布导出为 SVG、PDF 和 PNG - -用 `figure.export` 指定一张准确的完整画布 TargetRef,不带顶层 `ids`/`targets`。 -复用原生导出器,保留背景、完整页面、曲线、绝对 Y 误差幅度、原生文字和嵌入图片; -不裁切、不套主题、不改项目。成品之外仍须保留可编辑 `.plotium` 项目。 - -```json -{ - "expected_project_context": "PROJECT_CONTEXT", - "expected_revision": 48, - "tool_id": "figure.export", - "parameters": { - "canvas": {"resource":{"id":"CANVAS_ID","kind":"plotium.canvas"}}, - "size_mm": [180,90], - "dpi": 300, - "outputs": [ - {"format":"svg","path":"/absolute/path/figure.svg"}, - {"format":"pdf","path":"/absolute/path/figure.pdf"}, - {"format":"png","path":"/absolute/path/figure.png"} - ] - } -} -``` - -`size_mm` 默认原生页面尺寸;显式尺寸等比缩放整图,须保留宽高比(高度误差容许 -0.001 mm),不改变可编辑页面。`dpi` 默认 300,范围 1–2400,仅控制 PNG。 -每轴按原生物理 pt / 72 × DPI × 等比缩放系数四舍五入,最小 1 像素; -180 × 90 mm、300 DPI 得到 **2126 × 1063 像素**。SVG/PDF 保留物理页尺寸。 -文字使用原生通用 sans-serif 字族;无可用系统字体时报错。SVG 在另一台机器的 -字形取决于当地可用 sans-serif 字体。 - -每批 1–8 个输出,绝对路径须带匹配的小写扩展名,父目录已存在;目标必须是普通 -非符号链接文件或尚不存在。重复的解析后输出路径拒绝。预检返回 `export_id`、 -物理/像素尺寸,以及逐文件准确目标或错误;坏目录不会掩盖其他文件的结果。 -`overwrite` 默认 false,已有目标报告 `overwrite_not_requested` 并保留原字节。 -确需替换时显式设 `overwrite:true`,这仍不授予写入权限。 - -用 `plotium_execute` 提交一次性计划。有效文件等待 Plotium 的 -**Allow AI to export this figure?** 提示,其中列出画布、revision、尺寸及路径。 -核对后点击 **Allow export**;已有文件还必须勾选默认未勾选的 -**Replace the listed existing output files**。**Deny** 不安装任何输出。 -**Read and modify** 不等于导出授权;只读可请求新的独立导出授权。 -全无效批次直接逐文件报错,不弹授权窗。 - -用 `plotium_export_status {"export_id":"EXPORT_ID"}` 查询,不带 context/revision, -渲染中也可查询且不生成审计。返回 `export`、当前 context/revision 和 -`matches_current_project`。批次状态为 `awaiting_authorization`、`rendering`、 -`completed`;`files[]` 每项包含格式、准确路径、覆盖要求、`status`、`error_code`、 -`message` 和已安装字节数。文件状态为 `pending`、`succeeded`、`failed` 或 -`unknown`(worker 失败,先检查该路径再决定下一步)。批次完成不等于全部成功。 -缺失/损坏图片、字体、目标变化、权限拒绝和渲染/预算错误会准确报告且不替换 -该输出;同批此前成功文件保留。 - -渲染在后台使用桌面批准后捕获的画布/资产,绑定原 `project_context`、`canvas` -和 `render_revision`,后续编辑不改变快照。切项目、停止连接或修改访问权限会撤销 -待安装权限。逐文件原子权限准入先于实际安装:准入前撤销阻止安装;已准入文件 -仍可能完成,须查回执。旧完成不改变新项目的文档、保存路径、dirty 或状态。 -独占唯一同目录暂存及原子不覆盖创建保护未授权文件;已有目标在实际替换前复验 -元数据,但并非跨进程 compare-and-swap,应避免并发写相同路径。 -导出成功表示输出已安装,不等于原生项目保存的持久提交阶段;Undo 不删除或还原磁盘文件。 - -预算:一个运行批次,共享待执行计划最多 32 个;路径最多 4096 字节;PNG 单边 -16,384、总计 16,777,216 像素;引用的嵌入资产 16 MiB、解码后 RGBA 64 MiB、 -SVG 8 MiB、逐文件编码结果 64 MiB。不查找外部资产、不替换成占位图。 -完整 schema 和限制可从 `limits` 与 `operation_constraints` 能力分区发现。 - -桌面进程保留最近 16 批导出回执,跨重连及项目切换有效,退出应用即丢失。 -响应丢失后先查原 `export_id`,不重放导出。重启或 `unknown_export` 时先检查 -准确输出文件。重开可编辑项目后重新读取状态、发现目标;仅为新意图重新规划。 - - -## 科学操作与任务 - -`plotium_processing_inspect`、`plotium_diffusion_inspect` 和 -`plotium_analysis_results_inspect` 是只读查询,使用显式 `ids`、 -`expected_project_context` 和 `expected_revision`。结果检查接受 `offset`、 -`limit`(1–100);ILT 网格较大时请减小页长。发现信息中的 -`scientific_operations` 来自核心操作定义,含参数 schema、能力、权限及执行方式。 - -以下写操作继续通过 `plotium_plan` / `plotium_execute`: - -| 操作 | 参数与目标 | -| --- | --- | -| `processing.edit` | 一个数据集;`edits` 中使用 `replace`、`enable`、`add`、`remove` 或 `move`;已有步骤使用稳定 StepId | -| `processing.apply_scheme` | `path`,可选 `compatible_only`;方案字节、指纹和兼容目标配置在预检时冻结 | -| `diffusion.set_input` | 一个数据集;完整 `input`;非法输入错误带结构化校验报告 | -| `analysis.regions.extract` | 一个支持区域序列的字段;`regions` 引用已有 RegionId 或给出边界和指标;可选显式 `input` | -| `analysis.diffusion.fit` | 一个原生表格;`response_column` 为稳定 ColumnId;可选原生 `options`;x 列单位必须为 `s/m²` | -| `analysis.dosy.build` | 一个扩散来源字段;`method` 为 `mono_exp` 或 `ilt`;可选 `input` 和 ILT `params` | - -显式区域格式为 -`{"source":"explicit","bounds":[0.8,1.2],"metric":"Height","name":"Signal"}`; -引用已有区域使用 `{"source":"existing","id":0}`。指标还包括 `Area`、 -`Mean`、`Max` 和 `Min`。区域提取生成独立原生表格,保留来源、区域到列的 -对应及扩散增量证据,不自动创建绘图。 - -除输入设置外,上述写操作返回 `ToolResult.value.task`。预检即分配 -`task_id`;`queued` 只表示已登记。使用 `plotium_tasks_get({task_id})`、 -`plotium_tasks_list({offset,limit})` 查询,使用 -`plotium_tasks_cancel({task_id})` 取消(需要修改权限)。状态为 -`queued / running / committing / succeeded / failed / cancelled / stale`。 -回执包括原始 plan_id、项目归属、起止版本、来源字段版本、阶段、已完成列数、 -失败代码、资源引用和终态摘要;未知总量为 `null`。回执查询不受忙碌或项目切换阻塞。 - -回执由应用进程持有,断线不会取消已提交任务;同一进程内重连可继续查询。 -保留所有活跃任务及最近 128 个终态回执,进程退出后不保证保留。 -`task_not_found` 表示未知或已淘汰,不能据此自动重算。重复执行已消费的科学 -计划只返回现有回执。取消幂等,提交前取消保证不写入,终态后取消返回已有终态。 - -计算冻结输入后进入原有 ComputeService。主线程严格复核项目、文档版本、 -字段版本、代次、取消状态及调用权限;计算期间任何文档编辑都会使任务过期。 -成功时一次提交配置、结果和关联表格,形成一个 Undo 步骤;Redo 复用计算结果。 -后台完成不会打开或关闭面板。同步工作流保留 `processing.apply_scheme`,等待其提交后 -才执行后续节点;其他后台科学操作请使用单步调用并等待终态。 - -扩散检查区分可执行、缺失参数、证据待确认和输入非法,报告问题代码、参数路径、 -预期单位、实际值、证据和修复建议。b 值按 IncrementId 对齐并统一为 `s/m²`, -D 为 `m²/s`;原始输入单位及换算来源保留。解析优先级为显式输入、目标结果 -来源、已存默认值/采集信息。JEOL 检查完整程序身份、梯度形状、时间及厂商系数。 - -单指数结果包括 D、I₀、D 标准误、有效点数、R²、残差和拒绝原因。 -ILT 返回 D 网格、λ、非负解、重建残差及求解终止信息,不附单指数置信度。 -`empty` 表示没有可接受的科学结果;不可用数值为 `null`,附原因。 -结果检查分页返回逐列诊断,来源记录保留算法版本、实际参数及输入指纹。 - -衰减拟合任务完成后,任务的 `produced` 列表包含稳定的 `plotium.analysis` 资源。将其 ID 传给 `plotium_analysis_results_inspect`,即可直接读取该项分析。任务状态 `succeeded` 表示计算与结果提交完成;科学收敛情况须另查 `converged`、`termination` 和 `notices`。外层 `converged` 与最低有限代价的尝试一致。耗尽迭代预算且未满足收敛条件,或因信赖域坍缩终止的尝试,仍为未收敛,其估计会保留供诊断并附警告。 - -## 科学结果原生建图 - -通过 `plotium_plan`、`plotium_execute` 调用以下可撤销操作。两者的 -`parameters` 都为 `{source: ResourceRef, name: string}`,省略顶层 `ids`、 -`targets`;先发现完整来源引用和 schema。 - -| 操作 | 来源与原生产物 | -| --- | --- | -| `plot.field.create` | 一个原生字段,包括单指数 `nmr.dosy_map` 或 ILT `nmr.ilt_map`;新建画布,固定绑定该字段及其原生编码。 | -| `analysis.diffusion.plot` | 一个仅含单组响应数据的扩散拟合分析;新建冻结表格及画布,包含 b–强度散点、已存拟合曲线、残差面板、D 标准误、R² 和有效点数。 | - -预检的 `preflight.scientific_plot.summary` 返回拟议的 `canvas`、`source`、 -`produced`、科学 `evidence`,执行后 `value` 返回同一摘要。建图不重新计算科学结果。 -过期或空 DOSY 结果,以及过期、未收敛、多组响应拟合,须先修正。 -无法估计的 D 不确定度明确标为不可用。字段准备最多 4,000,000 个元素、200 条序列, -支持 20,480 点光谱的默认 128 行 ILT;拟合图最多 20,000 行。 -图中的点、等高线顶点和热图单元与显式曲线行共享 2,000,000 的待执行预算; -等高线图按生成的顶点数计入该预算,热图按单元数计入。 -一次 Undo 移除新资源,Redo 恢复相同身份及数据。切换数据集显示模式不改变字段图来源。 -冻结拟合表格保留来源表格血缘;自动化运行记录保留所选分析、行选择、提取证据和扩散输入。 - -将 `value.canvas` 传给 `plotium_figure_diagnose`、`plotium_render_preview`, -并实际查看 PNG。图像有效并不代表科学结果有效: - -1. 从欢迎页调用 `plotium_get_state`,导入采集数据,检查处理状态,等待处理任务成功。 -2. 检查扩散单位、IncrementId 对应关系、缺失参数和实验依据;只有证据充分时才提交已确认输入。 -3. 提取前明确区域规则、边界、指标和重叠处理策略。等待提取完成,再按返回的响应 ColumnId 拟合。 -4. 检查准确的分析资源:有效性、`m²/s` 单位的 D、标准误、有效点数、R²、残差、拒绝行和来源,再生成原生图。独立计算并检查单指数或 ILT DOSY,核对接受/拒绝列、算法设置、输入指纹及与区域拟合的数值一致性;ILT 使用求解诊断,不使用单指数置信度。 -5. 为 DOSY 结果字段建图,检查资源身份与状态、几何诊断及两张 PNG 的坐标轴、曲线、等高线、残差和标签可读性,明确报告科学或图像问题。 diff --git a/docs/src/content/docs/zh-cn/reference/mcp/discovery.md b/docs/src/content/docs/zh-cn/reference/mcp/discovery.md new file mode 100644 index 00000000..4ec3c155 --- /dev/null +++ b/docs/src/content/docs/zh-cn/reference/mcp/discovery.md @@ -0,0 +1,199 @@ +--- +title: MCP 状态与发现 +description: 读取当前状态、发现能力并找到精确目标。 +--- + +## 读取状态与按需发现能力 + +`plotium_get_state {}` 读取最新动态状态,返回 `project_context`、`revision`、 +`availability`、`permissions`、`save_state`、`capability_fingerprint`、项目数量摘要 +和有上限的选择分页,不附带完整能力清单或项目蓝图。用绑定 revision 的 +`plotium_document_inspect` 分页或 `plotium_resources_search` 发现精确目标, +再用 `plotium_resources_inspect` 按明确 ID 读取详情。复制返回的完整目标,不用名称或集合位置代替。 + +有两种简写可以少抄 ID。资源引用可以省略 `parent_id` 和 `local_id`,Plotium 会从 +`CANVAS_UUID/OBJECT_ID` 这类嵌套 ID 推出。规划和属性查询的 `targets`、曲线绑定和 +`properties.set_many` 的写入目标可以把 Series 写成 +`{"plot":"CANVAS_UUID/OBJECT_ID","series":0}`。两种简写都在规划前展开成完整目标; +计划、结果和审计记录仍保存完整形式。 + +空闲时 `selection` 为 `{items,total,next_offset}`,默认最多返回 16 个稳定资源引用。 +传入 `selection_offset`(默认 0)和 `selection_limit`(1–50)读取后续页,例如: + +```json +{"selection_offset":16,"selection_limit":50} +``` + +`selection.canvas` 报告用户在当前页面上选中的内容:`{items,total,part}`。`items` +最多 `selection_limit` 项,是所选 Panel 和对象的摘要(`target`、`kind`、`name`、 +`visible`)。`part` 是用户在首个所选图中点中的图例、标签或标注,没有时为 `null`。图例为 +`{target,part:"legend",property:"object.guides.position",value}`,`value` 为 `null` +表示自动位置;标签为 `{target,part:"label",kind,annotation_id,edit:"figure.edit annotation_set",…}` +并带当前位置;箭头或参考线本身为 `{target,part:"annotation",kind,annotation_id,edit,…}`, +带位置和 `hand_moved`。用户说“这个”时,改的就是这个目标或部件。 + +每次调用都读取当前选择,分页不是冻结快照;GUI 选择变化不一定改变文档 revision。 +不能将多页视作原子选择或把选择当作执行授权。 + +`hand_edits` 以 `{items,total,next_offset}` 列出用户在 Plotium 中手动设置的图形值, +每项包含 `target`、属性 `key`、`label` 和当前 `value`。传入 `hand_edits_offset` 和 +`hand_edits_limit`(1–50,默认 16)读取后续页。继续编辑时请保留这些值,见 +[用户手动设置的值](/zh-cn/reference/mcp/styling/#用户手动设置的值)。 + +忙碌时 `project`、`selection` 与 `hand_edits` 为 `null`;仍可读取可用性、权限、能力指纹 +和保存回执 ID。 + +调用 `plotium_capabilities_get {}` 获取精简索引 +`{capability_fingerprint,connection_capabilities}`。索引列出各工具的操作和所需权限、 +按预检与执行权限分组的可编辑操作、科学操作、恢复/revision/属性批量契约、文档根和 +`sections`。工具说明、输入 schema 和 annotations 见 `tools/list`;属性定义见 +`plotium_properties_list`。 + +`sections` 列出每个详情分区的字节大小及是否接受 `key`。`operation_constraints` 和 +`operation_details` 为每个 key 附一句用途,便于先按任务找到操作再读取详情。用 `{"section":...,"key":...}` +读取单项详情,返回 `{capability_fingerprint,section,key,contract}`: + +| 分区 | key | 内容 | +| --- | --- | --- | +| `tools` | 可选,工具名 | 结果约定和目标规则;指定 key 时也返回工具输入 schema | +| `operation_constraints` | 必填,操作 id | 单个可编辑操作的 schema、权限和结果约定 | +| `operation_details` | 必填,操作/子操作 key,或 `keys` | 聚焦的图形编辑 schema、权限、结果约定和示例 | +| `scientific_operations` | 必填,操作 id | 描述符和所需权限;可编辑操作引用其规范输入 schema | +| `guide_contract` | 无 | 图例和色标定位规则 | +| `candidate_preview` | 无 | 未提交计划的预览约定 | +| `limits` | 可选,限制名 | 连接预算 | + +例如读取 `figure.edit` 的 schema: + +```json +{"section":"operation_constraints","key":"figure.edit"} +``` + +已知操作可直接查询详情,无须先读索引。例如页面编辑使用 +`{"section":"operation_details","key":"figure.edit/page"}`。多项编辑用 `keys` 代替 `key`, +例如 `{"section":"operation_details","keys":["figure.edit/panel_label","figure.edit/annotation_create.arrow"]}`。 +响应包含 `keys` 和以请求名称为键的 `contract` 映射。此分区每次接受 1–32 个不重复的 key; +其他分区只接受 `key`。每项详情包含一个精确的编辑 schema,以及只适用于该编辑的限制和 +结果字段;请将示例目标替换为文档检查返回的完整稳定引用。混合编辑的 +完整 schema 仍见 `operation_constraints`。可编辑科学描述符通过 +`input_schema_ref: {section,key}` 引用规范输入 schema,不重复返回该 schema。 + +未知分区或 key 返回 `invalid_parameters`,`error.details.sections` 或 +`error.details.keys` 列出有效值。 + +指纹是完整静态发现契约(索引、全部分区、MCP 工具定义和属性目录)按规范 JSON +对象键顺序计算的 SHA-256。按响应中的指纹缓存索引和已读取的分区;状态中的指纹不同时重新发现。 +若读取状态后、能力查询完成前状态已变化,以能力响应随附的指纹标识该契约。 +项目编辑、项目切换、选择或权限变化均不改变静态能力。 + +静态发现提供所需权限,不返回 `currently_permitted` 标记;当前权限和可用性始终从状态读取。 +执行仍检查服务端权限、上下文、revision 和一次性计划。指纹、缓存的 schema 及 annotations +不授予权限,也不允许自动重试。保存和导出仍须对每个精确请求取得新的桌面确认。 +升级时一起更新桌面与连接器,并重连客户端以刷新工具目录。 + +规划、属性检查、文档检查与图形诊断的工具输入直接列出字段,便于客户端展示完整签名。 +Plotium 仍在服务端检查条件约束:需要选择器时只提供一个非空 `ids` 或 `targets`; +操作在参数内部指定目标时省略二者;表操作只接收一个数据集 ID。只有 +`properties.set` 和 `properties.reset` 接收 Series 目标。文档分页仅适用于 +`view: "children"`;诊断续页只接收 `cursor`、context 和 revision,首次诊断必须提供 +`canvas` 与 `output`。 + +同步提交的 `plotium_execute` 结果包含 `project_context`、`before_revision` 和 +`after_revision`。已知该上下文中的精确目标时,可直接将返回的 context 和 +`after_revision` 用于下一次查询或规划,无须额外读取状态。这不刷新选择、手动值、 +可用性或权限;首次访问、桌面编辑或 Undo/Redo 后、需要这些动态值时,以及 +stale/context 错误或结果不确定时,仍须读取状态。执行继续检查上下文、revision 与权限。 + +图形编辑、曲线追加/绑定/展开、科学结果绘图、重命名、主题和删除数据集的计划返回 +`plan_id`、`project_context`、`basis_revision` 和 `preflight`,不再回显请求和冻结目标集。 +`preflight.summary` 统计可执行、跳过和失败的目标数,`preflight.targets` 只列出将被跳过或 +失败的目标。它们的执行结果用 `summary` 统计成功、跳过和失败数,`targets` 只列跳过或 +失败的行,已修改资源见 `produced` 和 `modified`。 + +`plotium_apply` 的输入与 `plotium_plan` 相同,一次调用完成一项可撤销编辑的规划和提交, +返回 `plotium_execute` 的结果。它接受 `properties.set`、`properties.set_many`、 +`properties.reset`、不含删除的 `figure.edit`、`plot.create`、`plot.series.append`、 +`plot.series.bind`、`plot.series.materialize_default`、`resource.rename` 和 +`figure.apply_theme`,需要“读取和修改”权限。预检、revision 与权限检查、Undo 和运行记录 +都与两步形式相同,且不保留计划。保存、导出、删除、导入、表格和科学操作仍用 +`plotium_plan` 加 `plotium_execute`,预览候选图也是如此。被拒绝的 apply 不提交任何内容。 +断线后先读状态:revision 等于请求的 `expected_revision` 表示编辑没有提交,否则检查目标; +不要重放这次调用。 + +科学任务排队或提交并不代表修改已提交,不可复用即时响应的 `after_revision`。 +只有已知项目上下文中终态为 `succeeded` 且包含 `end_revision` 的回执才允许复用。 +科学有效性与收敛情况须单独检查:任务成功并不证明拟合有效。失败、取消、失效、 +缺失或不确定的回执继续遵循恢复流程,绝不授权自动重放。保存/导出回执描述文件操作, +不提供新的文档 revision。 + +## 不依赖名称发现结构 + +资源描述中的能力属于 **core** 的数据和渲染语义;资源列出某项能力,不代表此连接 +已开放该操作。可规划的操作以能力索引为准。 + +使用返回的 revision 列举文档画布: + +```json +{ + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 7, + "target": {"resource":{"id":"document","kind":"plotium.document"}}, + "view": "children", + "offset": 0, + "limit": 50 +} +``` + +将此请求传给 `plotium_document_inspect`。复制完整的 `value.items[].target` +作为下一次请求目标,依次进入画布、面板、内容和 Series。画布先列面板,再列未归属 +面板的内容;面板内的内容只在所属面板下列出。使用 `view: "self"` 并省略分页参数, +读取目标详情、`ancestors` 归属链和 `child_count`。内容类型包括图、文字、形状和 +栅格图片,不返回图片像素或数据行。frame 使用 pt:面板相对页面,面板内内容相对 +面板;画布尺寸使用 mm。 + +Series 发现与属性寻址一样,使用图对象的当前显示绑定。非当前通道或显示模式的 +替代 Series 仍保存在项目中,但在重新激活前不列出、也不可寻址。当前绑定中由 +用户隐藏的 Series 仍会列出,`visible` 为 false。切换通道或显示模式后,须读取 +当前 revision,再发现当前有效目标。 + +`encoding` 表示原生编码家族:`line` 同时包含折线和散点;`plot.create` 的 +`series_defaults[].kind` 返回创建时的具体类型。 + +Series 详情包含可直接用于属性查询的完整 target、编码、可见性、显式标签,以及 +`source` 中的数据集和字段资源引用、所属数据集内的 `field_id`、可选 `item_id`、 +单位和绑定状态。用返回的资源 ID 调用 `plotium_resources_inspect`,可读取字段和 +列的描述。字段失效时保留 `field_id`,但不提供可解析的字段引用。来源状态包括 +`resolved`、`missing_dataset`、`missing_field`、`missing_item`、 +`incompatible_encoding`、`unbound` 和 `missing_column`。 + +表格的 `binding_mode: "table_default"` 返回共享的 `x_column` 和全部 +`series_columns` Y/误差列绑定。一个逻辑 Series 可能展开为多条表格显示曲线, +这些显示曲线不会因此获得独立 Series ID。 +显式来源返回 `binding_mode: "table_explicit"`、TableId、当前表 revision、 +`x_column`、`y_column` 和可选 `error_column`,不把默认值误报为其来源。 +`coordinate_units` 返回图坐标单位契约。 +名称(包括同名曲线)仅作显示,不能代替身份。面板地址为 +`CANVAS_UUID/panels/PANEL_ID`;内容与 Series 保持下文既有地址。 + +子项查询默认每页 50 项,允许 1–200,返回 `total`、`next_offset` 和 `truncated`。 +保持**相同 revision 和 target**,按 `next_offset` 继续读取;256 KiB 结构化响应 +预算可能使一页提前结束。详情或单个条目超过预算时返回 `response_too_large`。 +不提供递归展开整个项目的接口。revision 变化会拒绝续页,须重读状态并重新列举。 +目标失效或身份伪造返回 `invalid_parameters`,不会改用当前选择。 + +`plotium_properties_list {}` 默认以紧凑形式浏览全部支持属性,每个属性一行:`id`、`label`、 +值类型 `type`,以及适用时的 `min`/`max`、`unit`、`format`、枚举 `values`、曲线 `encoding` +和所需字段能力 `requires`。以 `document.` 开头的 ID 属于文档范围,其他 ID 属于对象范围, +`series.` 开头的 ID 以 Series 为目标。标为 `requires_full` 的行(嵌套输入和显示单位代码) +需要读取完整定义。可一次读取多个属性的完整定义: + +```json +{"keys":["series.line.stroke_width","series.line.color"],"detail":"full"} +``` + +`scope` 使用目录中的范围名称筛选,`prefix` 按属性 ID 开头筛选,例如 `series.line` 或 +`object.axes`;没有匹配的前缀会报错,并在 `error.details.prefixes` 中列出可用前缀。`keys` 必须非空且不重复;不支持的键、未知 scope +和键与 scope 冲突均明确报错,不会静默省略请求项。无筛选的 `detail: "full"` 返回完整目录。 +两种形式均为静态查询,忙碌时也可调用,不包含当前目标值。完整详情保留复杂输入约束、 +颜色格式 `#rrggbb` 和全部已注册单位代码。用 `plotium_properties_inspect` 查询目标值、 +默认值、范围和适用性;坐标轴只接受与其坐标单位兼容的代码。静态适用能力不授予连接修改权限。 diff --git a/docs/src/content/docs/zh-cn/reference/mcp/index.md b/docs/src/content/docs/zh-cn/reference/mcp/index.md new file mode 100644 index 00000000..d1463235 --- /dev/null +++ b/docs/src/content/docs/zh-cn/reference/mcp/index.md @@ -0,0 +1,111 @@ +--- +title: MCP 配置与权限 +description: 在本机 MCP 客户端中注册 Plotium,以及每次工具调用都遵守的规则。 +--- + +本组页面面向编写自定义 MCP 客户端、或需要核对单个工具调用行为的读者。 +要连接 Codex、Claude Code 或 Claude Desktop 并用日常语言使用 Plotium,请看 +[连接 AI 客户端](/zh-cn/ai/connect/)。 + +| 页面 | 内容 | +| --- | --- | +| 本页 | 手动注册、权限、所有计划共同遵守的规则、工具 annotations | +| [状态与发现](/zh-cn/reference/mcp/discovery/) | `plotium_get_state`、能力发现、文档结构、属性目录 | +| [数据导入与表格](/zh-cn/reference/mcp/tables/) | 原生与 CSV/TSV/XLSX 导入、表格读取、派生、单元格补丁、刷新 | +| [建图与曲线](/zh-cn/reference/mcp/plots/) | `plot.create`、追加和重绑曲线 | +| [样式修改](/zh-cn/reference/mcp/styling/) | 显示属性、批量写入、手动设置的值、图例、主题 | +| [页面布局与删除](/zh-cn/reference/mcp/layout/) | `figure.edit`:页面、面板、文字、图片、标注和删除 | +| [预览、诊断与恢复](/zh-cn/reference/mcp/review/) | 画布与候选预览、图面诊断、恢复动作、错误码 | +| [保存与导出](/zh-cn/reference/mcp/save-and-export/) | `project.save`、`figure.export` | +| [科学运算](/zh-cn/reference/mcp/scientific/) | 处理、扩散、DOSY、任务以及结果建图 | + +## 手动配置与诊断 + +Windows 上,Plotium 从 `PATH` 查找独立的客户端可执行文件。对于通过 npm 安装的 +Codex,会在 `PATH` 中的 npm 前缀和默认的 `%APPDATA%\npm` 前缀内查找包中的原生 +可执行文件,支持 x64 和 ARM64 安装。使用自定义 npm 前缀时,请将它加入 `PATH` +并重启 Plotium,或通过 **Choose executable…** 选择包内的 `codex.exe`。 +添加 Codex 客户端需要先安装 Codex CLI。 + +在 **Preferences → AI connections (MCP)** 中展开 **Manual configuration and diagnostics**, +点击 **Copy stable stdio configuration**。复制的 JSON 含实际连接器绝对路径; +下例中的路径仅为占位符: + +```json +{"mcpServers":{"plotium":{"command":"/ABSOLUTE/USER/DATA/bin/plotium-mcp","args":[]}}} +``` + +请使用页面复制的真实路径,Windows 文件名为 `plotium-mcp.exe`。启用时连接器会 +复制到用户数据目录,应用升级时更新。发行安装目录中请将 `plotium-mcp` 保留在主 +程序旁。官方 CLI 注册形式为: + +```sh +codex mcp add plotium -- /ABSOLUTE/USER/DATA/bin/plotium-mcp +claude mcp add --transport stdio --scope user plotium -- /ABSOLUTE/USER/DATA/bin/plotium-mcp +``` + +参见 [Codex MCP](https://learn.chatgpt.com/docs/extend/mcp?surface=cli)、 +[Claude Code MCP](https://code.claude.com/docs/en/mcp) 和 +[MCP Bundle manifest](https://github.com/modelcontextprotocol/mcpb/blob/main/MANIFEST.md)。 +临时 HTTP 诊断信息包含密钥,服务重启后失效,仅用于高级诊断,不是保存的客户端 +配置。发现文件只面向当前用户和本机;不支持远程或 WSL 跨环境访问。 + +升级 Plotium 后,请重启 AI 客户端中的 Plotium MCP 连接,以加载更新后的工具。 +如果连接器安装失败,请打开 **AI connections (MCP)** 查看错误并点击 **Retry**。 + +## 权限与支持范围 + +支持的修改使用 Plotium 的 **Undo** 与 **Redo**。只读立即阻止后续修改执行,包括 +待执行计划;表格读取及属性预检仍可用,导入、原生曲线绑定、创建及处理/补丁/刷新预检要求读取和 +修改权限。权限会记住,直到手动更改。 + +项目查询及计划创建须同时提交 `expected_revision` 和 `expected_project_context`, +后者取自 `plotium_get_state` 的 `project_context`;各页示例用 `PROJECT_CONTEXT` +占位。每次打开、新建、关闭或恢复项目都会更换上下文,即使 revision 相同也不可 +混用。切换清空计划并拒绝旧队列工作;切换期间的 `busy` 表示需等待完成或取消。 +收到 `project_changed` 后重新读取状态、发现目标并规划,不沿用旧目标或计划。 +执行计划绑定创建时的上下文。 + +项目编辑、科学计算和数据变换保留持久运行溯源,使项目进入未保存状态。普通查询(状态、 +资源/属性/表格/文档浏览、科学结果查看、预览及诊断)不追加项目审计记录,也不改变 +dirty、edit generation 或 automation revision。纯查询工作流同样不改变项目;包含修改 +操作的工作流仍保留完整运行记录,包括复现操作所需的查询输入。握手、工具发现、 +已认证状态查询、每五秒心跳、静态属性目录以及保存协调(预检、提交与 +`plotium_save_status`),以及导出预检/提交/状态查询均不生成审计记录。 + +连接支持的操作见上表各页。[`plotium_properties_list`](/zh-cn/reference/mcp/discovery/#不依赖名称发现结构) 列出可写的属性及完整 schema; +[设置 ID](/zh-cn/reference/settings-ids/#图形) 列出面板中各图形设置对应的 ID。`object.axes.y2_*` 属性只在图中有曲线的 +`series.y_axis` 为 `right` 时适用。应用偏好、新格式解析、科学结果自动建图及内置 +聊天不在此接口范围内。 + +## 所有计划共同遵守的规则 + +工具结果同时提供结构化内容及 JSON 文本。项目读取与预检要求当前 +`expected_revision`;需要动态值、桌面编辑或撤销后重新获取状态。已知精确目标时可按 +[状态与发现](/zh-cn/reference/mcp/discovery/#读取状态与按需发现能力)中的规则复用同步提交结果。执行时重新检查保存的 revision +和当前权限。计划仅可提交一次,失败后也需重新预检;最多保留 32 个待执行计划, +重启连接会清空计划。桌面开始执行前已取消的请求不会修改项目;已进入原子 +提交的修改无法通过取消回滚,请使用 **Undo**。 + +## 工具 annotations 与客户端审批 + +每个工具都在 `tools/list` 中提供 MCP +`annotations`,不随当前 **Access** 设置变化。`readOnlyHint` 表示是否改变环境; +`destructiveHint` 区分可能破坏性写入与仅追加操作;`idempotentHint` 表示相同参数的 +重复调用是否产生额外影响;`openWorldHint` 表示是否与外部实体交互,包括本地输入/ +输出文件。破坏性和幂等提示仅对非只读工具有意义。参见 +[MCP 注解定义](https://modelcontextprotocol.io/specification/2025-11-25/schema#toolannotations)。 + +查询、预览和回执查看均为只读,仅访问原生项目/应用状态。诊断也是只读,但续查游标 +仅可使用一次。`plotium_plan` 不是只读:每次成功调用都会保留新的可执行计划,部分 +操作会读取外部数据、schema、处理方案或图片文件,并准备计算;它不提交候选结果, +也不写出保存/导出目标文件。`plotium_execute` 覆盖编辑、删除、科学任务提交及保存/ +导出请求,因此整个工具保守声明为可能破坏性、非幂等、开放交互域。任务取消会改变任务 +状态,属于可能破坏性写操作;对同一保留任务重复取消不会产生额外影响。 + +客户端可以依据策略使用可信服务端的提示来决定是否询问审批,但仍可能询问;不可信 +注解不能作为授权依据。客户端审批、Plotium **Access** 与桌面文件确认是独立决定。 +注解不授予权限:revision/context 检查、撤权与一次性计划规则仍然生效。每次保存/导出 +请求仍保留独立桌面确认及准确的文件/覆盖范围,包括 **Read only** 模式。断连或结果 +未知后绝不重放调用,即使标为幂等;应查询状态或保留回执。升级 Plotium 及其连接器后, +重新连接客户端以刷新工具目录。 diff --git a/docs/src/content/docs/zh-cn/reference/mcp/layout.md b/docs/src/content/docs/zh-cn/reference/mcp/layout.md new file mode 100644 index 00000000..3f22dd13 --- /dev/null +++ b/docs/src/content/docs/zh-cn/reference/mcp/layout.md @@ -0,0 +1,263 @@ +--- +title: MCP 页面布局与删除 +description: 通过 MCP 安排页面、面板、文字和图片,精确删除内容。 +--- + +## 原子编辑页面、面板、文字与本地图片 + +以 `parameters: {canvas: 完整画布目标, edits: [...]}` 预检 `figure.edit`,不传顶层 +`ids`/`targets`。完整带 `op` 标签的 schema 可用 +`plotium_capabilities_get {"section":"operation_constraints","key":"figure.edit"}` 读取。 +一个批次按编辑顺序修改同一画布,合为一次 Undo/Redo: + +| `op` | 必需字段及含义 | +| --- | --- | +| `page` | 至少提供 `size_mm: [宽,高]` 或 `size_preset`、`margin_mm: [上,右,下,左]`、`gutter_mm` 之一,长度均为 mm。期刊 `size_preset` 设定栏宽,已有内容的页面保持原高度;纸张和幻灯片预设同时设定宽高。未给 `margin_mm` 时页边距改为预设值(期刊 0 mm、纸张 15 mm、幻灯片 10 mm);结果中返回 `size_preset` | +| `panel_frame` | `target: 完整面板目标`、`frame_pt: [x,y,宽,高]`,页面 pt | +| `content_frame` | `target: 完整内容目标`、完整 `frame_pt: [x,y,宽,高]`,父局部 pt;只改该内容 | +| `image_replace` | `target: 完整 raster 目标`、`path`;以冻结的本地 PNG/JPEG 仅替换资产引用 | +| `content_delete` | `target: 完整内容目标`;删除内容并保留空父 panel | +| `panel_delete` | `target: 完整 Panel 目标`;要求原始状态已为空 | +| `series_delete` | `target: 完整 Series 目标`;删除非末条显式 Series | +| `panel_label` | `target`、`text`、`visible`;写入原生手动面板标签,保留位置和字号 | +| `panel_stack` | `panel: 完整面板目标`、`shared_x: true\|false`;可选 `gap_pt`(0–144)和 `merge: [完整面板目标,...]`,二者仅限 `shared_x: true`。把面板中的图堆叠到同一条共享 x 轴上,或恢复为自由布局 | +| `align` | `panels: [完整面板目标,...]`、`edge: left\|center\|right\|top\|middle\|bottom`;至少两个面板 | +| `distribute` | `panels`、`axis: horizontal\|vertical`;至少三个面板 | +| `grid` | `panels`、`rows`、`cols`;按所给目标顺序分配原生 Frame-basis 网格格子 | +| `text_create` | `parent: 完整画布或面板目标`、`name`、`frame_pt`、`text`、`font_pt` | +| `text_set` | `target: 完整文字目标`、`text`;可选 `font_pt` | +| `image_create` | `parent`、`name`、`frame_pt`、`path: "/absolute/local/image.png"`(PNG 或 JPEG) | +| `annotation_create` | `target: 完整图目标`、`text`、`at: [x,y]`(该图的数据坐标)、`font_pt`;可选 `kind: "text"`、`color: "#rrggbb"` | +| `annotation_create`(参考线) | `target: 完整图目标`、`kind: "reference_line"`、`orientation: vertical\|horizontal`、`value`;可选 `label`、`font_pt`、`line: {color, width_pt, style}` | +| `annotation_create`(箭头) | `target: 完整图目标`、`kind: "arrow"`、箭尾 `at: [x,y]`、箭头 `to: [x,y]`;可选 `head: none\|open\|filled\|double`、`line_width_pt`、`color: "#rrggbb"` | +| `annotation_set` | `target: 完整图目标`、`annotation_id`;文字标注至少提供 `text`、`at`、`font_pt`、`color`、`offset_pt`、`placement` 之一,参考线至少提供 `orientation`、`value`、`label`、`font_pt`、`line`、`placement` 之一,箭头至少提供 `at`、`to`、`head`、`line_width_pt`、`color` 之一;可选 `override_hand_edits` | +| `annotation_delete` | `target: 完整图目标`、`annotation_id` | + +创建两张图后,可设置页面并排列明确选定的两个面板: + +```json +{ + "tool_id": "figure.edit", + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 3, + "parameters": { + "canvas": {"resource":{"id":"CANVAS_UUID","kind":"plotium.canvas"}}, + "edits": [ + {"op":"page","size_mm":[180,90],"margin_mm":[4,4,15,4],"gutter_mm":5}, + {"op":"grid","panels":[{"resource":{"id":"CANVAS_UUID/panels/PANEL_A_UUID","kind":"plotium.canvas.panel","parent_id":"CANVAS_UUID","local_id":"PANEL_A_UUID"}},{"resource":{"id":"CANVAS_UUID/panels/PANEL_B_UUID","kind":"plotium.canvas.panel","parent_id":"CANVAS_UUID","local_id":"PANEL_B_UUID"}}],"rows":1,"cols":2} + ] + } +} +``` + +将全部身份占位符换成实际发现的完整目标;名称不能代替身份。 +结果为 (4,4,83.5,71) 与 (92.5,4,83.5,71) mm。frame 原点在左上,X 向右、Y 向下, +1 pt = 1/72 inch。面板 frame 复用 **Object Geometry/拖动编辑**语义:移动保留 +子内容局部坐标,改尺寸按比例缩放全部子内容 frame,不改曲线身份、绑定、样式、 +轴范围或字号。这不同于自由 Panel inspector 仅修改容器尺寸的行为。 +新文字/图片 frame 使用父面板局部 pt;父目标为画布时则使用页面 pt。 + +`panel_stack` 的 `shared_x: true` 要求至少有两张图。`plot.create` 会把每张新图 +放进各自的面板,因此请在 `merge` 中列出其他图所在的面板:它们会先合并到 `panel`, +其中的图按页面上的上下位置从上到下堆叠,与桌面端 **Stack with Shared X** 相同。 +不传 `merge` 时保持面板内容顺序。堆叠填满面板内宽;高度 +保持当前 frame 的比例,用 `content_frame` 修改某张图的高度即可调整其所占比例。 +开启堆叠时间距默认为 0 pt。只有最下面的图绘制 x 刻度数字和 x 轴标题,只有 +最上面的图绘制图标题,内部边界紧贴且 x 刻度朝内,各绘图区共用左右边缘。进入堆叠 +时,会把覆盖所有成员数据的 x 范围(按各自坐标单位)和最上面成员的 x 主刻度间隔 +(按各自显示的单位)写入每个成员,因此各成员须先 +使用相同的 x 刻度类型;所有成员绘制最下面成员的 x 方向,但不保存该方向。各图共享 +x 视窗;之后在任一成员上修改 x 范围、x 刻度类型、x 显示单位、x 千位分隔符或 +x 主刻度间隔,都会 +写到所有成员,并合为一次 Undo;若任一成员不能接受该值则拒绝写入,`applied` 会 +列出各成员的修改。同一批次若请求相互冲突的共享 x 设置,会整批拒绝且不留下修改; +按兼容坐标单位表达的等价范围可以接受。 +`shared_x: false` 恢复为自由布局并保留各 frame。结果在 `panel_edits` 中列出 +每个操作的 `layout`、`gap_pt`、`members_top_to_bottom` 和 `merged_panels`。 +`plotium_document_inspect` 为每个面板返回 `layout`(`free`、`vertical_stack`、 +`horizontal_stack`、`grid` 或 `shared_x_stack`);堆叠面板另含 +`shared_x_stack: {members_top_to_bottom, gap_pt}`。`plotium_figure_diagnose` +和计划预览使用同一套堆叠几何。 + +图内标注按数据坐标定位,而不是页面 pt:文字居中显示在 `at` 点上方,画布和所有 +导出中都跟随该图的轴范围、缩放和平移移动;锚点在可见范围外时随图一起裁切。该位置 +压到数据、图例、数值标签或其他标签时,文字挪到约三个字高范围内最近的空位;指向它的 +箭头不算遮挡。`offset_pt: [dx, dy]`(pt,x 向右、y 向上)把文字固定在该偏移处, +`[0, 0]` 即正好在 `at`;`placement: "auto"` 恢复自动摆放。`color`(`#rrggbb`)设置 +文字颜色,默认黑色。用户在画布上拖过的标签在修改 `text`、`font_pt` 时保持原位;对它 +设置新的 `at`、`offset_pt` 或 `placement` 会被拒绝,除非以 `override_hand_edits: true` +表明是用户要求。`annotations` 中每个文字 +标注报告 `placement`(`auto`、`fixed` 或 `hand`)和实际绘制的 `offset_pt`; +`plotium_get_state` 在 `hand_edits` 中以键 `annotation.label_position` 列出拖过的标签。 +`annotation_id` 只在所属图内有效,删除后不会复用;可从结果的 `annotation_edits` +或 `plotium_document_inspect` 返回的图 `annotations` 列表读取。`at` 使用 +`coordinate_units` 给出的源单位,而不是刻度标签所选的显示单位。`text` 中的 `\n` +另起一行。标注文字最多 1024 +UTF-8 字节且不得空白,每张图最多 256 个标注。图及其父面板须未锁定;不要求关闭 +Auto height。 + +参考线是 `kind: "reference_line"` 的图内标注:在 x = `value` 处画竖线,或在 +y = `value` 处画横线,单位与 `at` 相同,贯穿整个绘图区。它跟随轴范围、缩放和平移, +`value` 不在可见范围内时不显示。`line` 设置 `color`(`#rrggbb`)、`width_pt` +(0.1–20)和 `style`(`solid`、`dashed`、`dotted` 或 `dash_dot`);新参考线默认 +`#000000`、0.75 pt(若主题规定了辅助线宽则用它,Nature 主题为 0.3 pt)、虚线,`annotation_set` 中省略的 `line` 字段保持原值。可选 +`label` 以线条颜色显示在竖线顶部附近或横线右端,那里压到数据、图例或其他标签时沿线 +挪到别处或换到线的另一侧;检查结果报告 `label_placement` 和实际的 +`label_position: {along, side}`,`placement: "auto"` 按同样的 `override_hand_edits` +规则把拖过的标签恢复为自动摆放;未设置 `font_pt` 时使用刻度标签 +字号,一旦用 `font_pt` 设定字号便保持该值直至再次修改;`label` 为空字符串时移除 +标签。参考线与文字标注共用同一 id 序列和 +每张图 256 个的上限,`plotium_document_inspect` 在 `annotations` 中同时列出二者, +并以 `kind` 区分。提供另一类标注的字段会被拒绝,而不是被忽略;参考线的颜色用 +`line.color` 设置,不用 `color`。 + +用户在画布上移动过的箭头或参考线报告 `hand_moved: true`,并在 `hand_edits` 中以键 +`annotation.position` 列出。可以改它的样式,但给这样的箭头设置新的 `at`、`to`,或给 +这样的参考线设置新的 `value`、`orientation` 会被拒绝,除非以 +`override_hand_edits: true` 表明是用户要求;改后位置重新算作 agent 的设置。 + +```json +{"op":"annotation_create","target":EXACT_PLOT_TARGET,"kind":"reference_line", + "orientation":"horizontal","value":0,"label":"baseline", + "line":{"color":"#7f7f7f","width_pt":0.5,"style":"dotted"}} +``` + +箭头标注(`kind: "arrow"`)是从箭尾 `at` 到箭头 `to` 的直线,两端使用同一数据 +坐标,因此与文字标注一样跟随坐标轴移动并裁切在绘图区内。`head` 默认为 `filled` +(`double` 两端均为实心箭头,`none` 为无箭头直线);`line_width_pt`(0.1–20 pt)默认 1 pt(若主题规定了辅助线宽则用它,Nature 主题为 +0.3 pt),`color` 默认黑色;两端不得重合。箭头不带文字,需要说明时另建一个 +文字标注(例如放在箭尾)。箭头与其他标注共用该图的 `annotation_id` 序列和每张图 256 个 +的上限,在 `annotations` 中以 `kind: "arrow"` 列出;提供其他类标注的字段会被拒绝。 + +Align 依据所选边界/中心;Distribute 在固定两端中心间等分中心位置,不等分边缘 +间隙。Grid 将已有原生格子算法与 authoring 尺寸 setter 组合用于明确子集,不表示 +GUI 已有子集 Grid 按钮;使用当前页面边距/gutter,不修改已保存的网格偏好或简化 +轴文字。仅改页面尺寸/边距不重排内容。非目标面板和 loose 内容原位保留,即使 +因此重叠或裁切,也不自动移动或缩字号。 + +面板目标须同属此画布、互不重复、未锁定,且为自由布局或共享 x 轴堆叠布局;新建文字和图片 +要求父面板为自由布局;锁定子内容也拒绝面板编辑。 +明确指定的隐藏目标仍可寻址。精确页面/布局编辑须先在 GUI 关闭 Auto height。尺寸须有限且为正,页面每边 10–1000 mm;边距/gutter +须非负并留出正空间。Grid 行列各 1–16、须容纳所有目标,且每格达到原生最小尺寸 1 pt。文字最多 16384 UTF-8 +字节、字号 1–72 pt;名称/手动标签最多 1024 字节且不得空白。每批 1–200 项, +每次布局最多 200 个面板。 + +图片预检仅读取明确指定的绝对路径普通文件:每批最多 8 次图片输入(创建与替换合计,重复输入也计数)、每文件编码大小 1 MiB、 +每批编码合计 4 MiB,每张解码 RGBA8 最多 4 MiB。PNG/JPEG 探测和解码复用原生 I/O; +预检冻结字节,提交后嵌入原生资产库,不依赖外部路径,相同编码资产复用。资产缺失、 +损坏或格式不支持使整批以 `invalid_parameters` 及明确资产错误拒绝。不扫描目录、 +访问网络或回写源文件。 + +`preflight.figure_plan` 返回拟建 `created`/`modified` 完整目标及 `result` 中的页面 +尺寸、边距/gutter 和精确 `panel_frames`;执行在 `ToolResult.value` 返回该结果。 +预检不提交内容;非法目标、几何、资产或旧 revision 不留下半成品。预检及执行都要求 +Read and modify。失败执行也消费一次性计划;沿用 32 个计划及 256 KiB 响应限制。 +一次 Undo 恢复整批,Redo 恢复同一原生内容/资产身份。执行响应丢失后先检查拟建目标, +不能盲目重复创建。可继续用普通 GUI Geometry、文字和图片 inspector 编辑,并查看 +实际 PNG;原生文字 frame 过小时可能裁切,布局不自动消除冲突。 + +## 移动已有内容或原位换图 + +需要扩宽已有说明框,或只替换两份共享资产图片中的一份时,先用 +`plotium_document_inspect(view:"self")` 读取该内容。复制完整目标,不用名称、选择状态 +或集合位置;使用当前 context/revision 预检 `figure.edit`,例如: + +```json +[ + {"op":"content_frame","target":{"resource":{"id":"CANVAS_UUID/CONTENT_ID","kind":"plotium.canvas.object","parent_id":"CANVAS_UUID","local_id":"CONTENT_ID"}},"frame_pt":[12,18,140,30]}, + {"op":"image_replace","target":{"resource":{"id":"CANVAS_UUID/IMAGE_ID","kind":"plotium.canvas.object","parent_id":"CANVAS_UUID","local_id":"IMAGE_ID"}},"path":"/absolute/local/replacement.png"} +] +``` + +将数组放入 `parameters.edits`,同级 `parameters.canvas` 使用发现的完整画布目标, +不传顶层 `ids/targets`。示例为两个不同内容;移动并替换同一图片时重复其完整目标。 +文字内容/字号仍用 `text_set`。 + +`content_frame` 支持 plot、text、raster 及已有 rect/ellipse/line/arrow,不创建或 +改父级。输入必须是完整 frame,不是相对增量。面板内使用父局部 pt,页直属使用页面 +pt;左上原点,X 向右、Y 向下。读取新增完整 `parent`、`frame_space`、原生平移换算的 +`page_frame` 和 `geometry` 限制。位置允许超出面板/页面,不自动钳制或吸附。 +分量及换算边界须有限,宽高至少 1 pt;不改变 GUI 拖拽下限。 + +只改目标内容(在共享 x 轴堆叠中,兄弟会按新比例重排):其余情况下父级、兄弟 frame/顺序,plot 的绑定、Series 身份、来源、单位、 +手动轴范围和样式,以及文字内容/字号均保留。目标和父级须解锁,父面板须为 Free +布局,Auto height 须关闭;无关兄弟锁定不阻止编辑。`geometry.frame_editable` 和 +`frame_edit_error` 返回原生限制,与连接修改权限独立。 + +图片 `preserve_aspect:true` 保持**现有 frame 比例**,不是替换图片的像素比例。 +复用原生算法:宽/高相对缩放中与 1 偏离较大者决定等比缩放(相等时取宽),并满足 +1 pt 下限;请求 X/Y 固定为左上锚点。预检明确返回可能不同的 `requested_frame_pt` +与 `effective_frame_pt`。`geometry` 同时提供 `min_size_pt`、`preserve_aspect`、 +`aspect_ratio`。`fit` 独立控制框内 contain/cover/stretch。 + +`image_replace` 仅赋值目标 AssetId,保留 ContentId、父级、frame、z-order、名称、 +可见性及全部图片属性:`page_index`、crop、fit、90°步进旋转、opacity、interpolation、 +preserve_aspect。其他旧资产引用不变。保留的 crop/fit 可能使新图呈现不同,不自动清空 +设置。PNG/JPEG 要求既有 `page_index=0`;非零页整批拒绝,不静默归零。换图要求目标/ +父级解锁,但不要求 Free 布局或关闭 Auto height;`image.replaceable`、`replace_error` +返回适用性。 + +创建和替换共享上述图片预算、字节冻结、编码资产去重、嵌入及 Undo 生命周期。 +预检后改动/删除源文件不影响候选或 Redo,不回写源文件、不回收资产。坏文件、不支持 +格式、错误/失效目标、锁定或无效几何均拒绝整批。 + +`preflight.figure_plan.result.content_edits` 按输入顺序逐项提供 `edit_index`、`op`、 +`target`、`parent`、`frame_space`、`before_frame_pt`、`effective_frame_pt`、`page_frame` +和 `geometry`;frame 修改另有 `requested_frame_pt`,换图另有 `asset_change`,包含 +前后 AssetId(`before/after`)、`format` 和 `pixel_size`。这些值表示该编辑步骤的状态。 +`result.content_frames` 返回各不同目标在整批完成后的最终几何,包含后续显式父面板缩放的影响。 +执行在 `ToolResult.value` 返回同一结果。两项沿用原有权限、context/revision 屏障和 +一次性计划;一次 Undo 恢复整批 frame/资产引用,Redo 恢复同一身份和冻结图片。 +提交后重新读取并查看实际图像。 + +## 精确删除内容或指定 Series + +可以要求 Agent:“删除这段重复说明和这条冗余曲线,保留另一条同名曲线。”先发现完整 +canvas/content 目标及所属 plot 的 Series 目标,不用名称、下标、显示 trace 序号或 GUI 当前选中项定位。 + +使用限定一个 canvas、只包含删除操作的 `figure.edit` 批次: + +```json +{"tool_id":"figure.edit","expected_project_context":"PROJECT_CONTEXT","expected_revision":12,"parameters":{ + "canvas":{"resource":{"id":"CANVAS_UUID","kind":"plotium.canvas"}}, + "edits":[ + {"op":"content_delete","target":{"resource":{"id":"CANVAS_UUID/CONTENT_ID","kind":"plotium.canvas.object","parent_id":"CANVAS_UUID","local_id":"CONTENT_ID"}}}, + {"op":"series_delete","target":{"resource":{"id":"CANVAS_UUID/PLOT_ID","kind":"plotium.canvas.object","parent_id":"CANVAS_UUID","local_id":"PLOT_ID"},"component":{"kind":"series","id":2}}} + ] +}} +``` + +`content_delete` 删除一份完整原生 plot、text、raster 或已有 rect/ellipse/line/arrow shape。 +删 plot 不删来源 Dataset。`panel_delete` 接收完整 Panel 目标,要求预检原始状态已为空; +同批先删全部子内容不能让非空 panel 变成合法目标。删除内容保留空父 panel,不重排兄弟。 + +`series_delete` 只删除所属 plot 内的指定 SeriesId。支持有既定坐标合同和显式列绑定的 +line/scatter plot,包括绑定派生表的 Series。拒绝删除末条 Series;移除整图须明确使用 +`content_delete`。拒绝 table_default 和动态多通道显示,不自动物化、换绑或修改 Dataset。 +剩余 Series 的身份、来源、顺序、encoding、坐标单位和手动范围保留,删除首条也不重新定义坐标。 + +重复目标、整 plot 与其 Series 重叠、跨 canvas、目标或父级锁定,以及删除和非删除操作混批 +均整批拒绝。隐藏目标仍可精确寻址,锁定兄弟不阻碍无关删除。原有 Auto height 开启时保留 +该设置,预检报告其原生派生高度变化,不擅自关闭。 + +执行前检查 `preflight.figure_plan.deleted` 和 `result.deleted_targets`。 +`result.deletions` 包含父级、顺序及随整 plot 移除的全部所属 Series。 +`parent_changes`、`group_changes`、`viewport_link_changes`、`selection_change` 列出必要 +关系更新;分组/链接保留幸存成员,不足两个成员时解除该关系。 +`remaining_series` 给出剩余顺序和 active Series 身份,`retained_asset_ids` 列出被删 raster 所引用但保留的资产, +`auto_height` 在开启时给出派生前后高度。这些是元数据,不是候选图像。 +执行回执 `ToolResult.value` 返回同一删除清单。 + +预检不提交。一次成功执行对应一次原子 Undo/Redo,失败不半删除。Undo 恢复精确身份、父级、 +对象/面板顺序、分组、链接和必要选择;ID 分配高水位不回退。不删除原文件、Dataset 或资产。 +运行期 Undo 保留嵌入资产;保存沿既有可达资产策略,重开项目不恢复 Undo 历史。 + +沿用修改权限、project context/revision 和一次性 plan 规则。GUI 选择不推进 revision, +但若变化会改变预检列出的删除选择影响,也须重新规划。每批最多 200 个显式删除目标; +Series 候选批次最多访问 200 万剩余 curve-row;共享最多 32 个 pending plans,完整响应 +不超过 256 KiB。清单超限拒绝,不截断后执行。目标或合同错误返回带原因的 +`invalid_parameters`;`stale_revision`、`project_changed`、`permission_denied`、 +`expired_plan`、`plan_limit`、`response_too_large` 沿用原含义。 + +执行结果未知时先重新发现当前 context、revision 和精确目标,不自动重放删除。 +提交后查看实际 PNG,再用原生 Undo/Redo、保存重开核对结果。 diff --git a/docs/src/content/docs/zh-cn/reference/mcp/plots.md b/docs/src/content/docs/zh-cn/reference/mcp/plots.md new file mode 100644 index 00000000..46fd3e6d --- /dev/null +++ b/docs/src/content/docs/zh-cn/reference/mcp/plots.md @@ -0,0 +1,225 @@ +--- +title: MCP 建图与曲线 +description: 通过 MCP 创建原生图,添加或重绑曲线。 +--- + +## 从已导入表格创建原生单图 + +可以要求 Agent:“导入这个 CSV,时间单位为 s,电流和误差单位为 mA, +创建一张可编辑折线图并显示对称 Y 误差。查看预览,再只把该曲线线宽改为 +1.5 pt 并再次预览。”提供绝对输入路径和明确单位。完整导入、创建参数可从 +`plotium_capabilities_get` 的 `operation_constraints` 分区发现。 + +仅数据导入后,从实际导入结果或列元数据读取 DatasetId、FieldId、TableId、 +表 revision 和 ColumnId。通过 `plotium_plan` 规划 `plot.create`,不传顶层 +`ids` 或 `targets`: + +```json +{ + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 1, + "tool_id": "plot.create", + "parameters": { + "parent": {"resource": {"id": "document", "kind": "plotium.document"}}, + "name": "Current", + "series": [{ + "kind": "line", + "source": { + "dataset_id": "RETURNED_DATASET_UUID", + "field_id": 0, + "table_id": "RETURNED_TABLE_UUID", + "table_revision": "RETURNED_TABLE_REVISION_UUID", + "x_column_id": "RETURNED_TIME_COLUMN_UUID", + "y_column_id": "RETURNED_CURRENT_COLUMN_UUID", + "y_error_column_id": "RETURNED_ERROR_COLUMN_UUID" + } + }] + } +} +``` + +示例中的每个身份(包括 FieldId)均须替换成实际返回值。`kind` 为 `line`、 +`scatter`、`bar`、`box` 或 `violin`;`y_error_column_id` 为 ColumnId、`null`,或省略表示没有误差棒。 +source 也可以按列名写:`{"dataset_id":"DATASET_UUID","x":"time","y":"signal","y_error":"sd"}`。 +`x`、`y` 和可选的 `y_error` 是精确(区分大小写)的列名或 ColumnId;Plotium 补上默认字段、 +表格和当前表格 revision。列名不存在或重复时返回 `invalid_parameters`,`error.details.field` +给出路径,`error.details.candidates` 列出该表的全部列。按列名解析的每个 source 会在计划响应的 +`resolved_sources` 中列出。`plot.series.append` 和 `plot.series.bind` 也接受同样的 source 写法。`bar` 曲线绘制从零起的 +实心柱,可带误差线,填充色即曲线颜色,并带细描边。误差线使用描边的颜色和宽度,横帽宽度为柱宽的 45%。按印刷尺寸,柱子过小、放不下描边时(宽度不足描边宽度的 4 倍,或高度不足 2 倍,例如接近 0 的值),只画填充、不画描边,误差线保留。数值型 x 上,槽位宽度取相邻位置的常见间距,只有相邻位置更近处才变窄。其 x 列可为数值列或 Utf8 文本列;文本值按 +表格行顺序成为类别,相同文本共用一个槽位。共用同一槽位的柱状曲线在槽位内 +并排分组;槽位内只有一根柱时占满整个宽度,因此每个类别一条柱状曲线即可得到居中、 +各自配色的柱。`box`(箱线图)和 `violin`(小提琴图)曲线汇总每个 x 上的原始 y 样本 +(箱线图:中位数、四分位距及 1.5 倍四分位距的须,并标出离群点;小提琴图:高斯核密度, +内含四分位条),不接受 y 误差列,与柱子共用槽位。`line` 和 `scatter` 曲线也可以用文本 +x,叠加在槽位上:第 k 条折线或散点曲线对齐第 k 条柱状、箱线或小提琴曲线的位置, +因此原始数据点会落在对应的柱上。`series.points.spread` 让同一 x 上的重复数据点在该 +柱宽度内按行顺序散开(0–1,占柱宽的比例);`series.value_labels` 在每根柱或每个点的 +末端(或误差线末端)之外用刻度字号写出数值。`object.chart.orientation` 设为 +`horizontal` 时把显式数据图横过来:类别沿纵轴排列、第一个在最上方,数值沿横轴;误差线、 +数值标签和轴标题随之转向,视图重置。同一图内所有曲线须同为文本 x 或同为数值 x。含柱状、 +箱线或小提琴曲线的图不支持对数坐标轴。折线或散点曲线可选 `y_axis`:`left`(默认)或 +`right`;柱状、箱线或小提琴曲线设为 `right` 会被拒绝。只要有曲线在右侧,图就会有一条右 +y 轴,拥有自己的自动范围、刻度类型和标题,标题初始为第一条右轴曲线的列名和单位,该曲线 +也决定右轴的单位。参考线、标注和箭头仍按左轴坐标。多条 `series` 表示 +同一图对象内相互独立的原生曲线,不是多张图。全行提取、数值、缺失值、 +误差和单位规则与下文显式曲线绑定相同;不修改表格共享默认 X/Y、不影响 +其他图,也不复制源表。 + +可选的 `intent: {purpose, claim}` 记录这张图要表达什么。`purpose` 取 `compare` +(比较各组大小)、`trend`(随连续变量的趋势)、`distribution`(分布或离散程度)、 +`relationship`(两个量的关系)、`composition`(组成占比)、`change`(变化、比值或倍数差) +或 `detail`(放大或插图);`claim` 是一句话,最多 500 个字符。建图前先请用户选目的、 +写 claim,不要自己猜;用户没填时,给出你的理解,让用户确认或修改。意图不会改变图的画法。 +它随项目保存,之后通过 `object.intent.purpose`(设为 `unspecified` 即清除)和 +`object.intent.claim` 修改,也显示在对象检查器 **Chart** 区的 **Advanced** 中。 + +完整 `parent` 决定新建范围: + +- document 根:新建画布、单面板和图对象。可选 + `canvas: {name, size_mm: [宽, 高]}`,每边为 10–1000 mm;或用 + `canvas: {name, size_preset}` 选内置页面尺寸,例如 `nature-1col`(89 mm)、 + `nature-1p5col`(136 mm)、`nature-2col`(183 mm),并采用该预设的默认高度和 + 边距(期刊栏宽 0 mm、纸张 15 mm、幻灯片 10 mm),结果中返回所用 `size_preset`;省略时在预检中冻结原生默认尺寸,画布名称使用图对象名称。 +- 没有面板或图对象的已有画布:按 GUI 共用的原生空画布放置服务及已有 + 布局设置、边距创建面板和图对象。不传 `canvas`。 +- 已有内容的画布:明确提供 `panel_frame_pt: [x,y,宽,高]`,以页面 pt 坐标 + 创建另一面板及图对象。已有面板、曲线和 loose 内容原位保留,允许重叠。 +- 该画布唯一的空、可见、未锁定且自由布局的面板:仅创建图对象,保留 + 面板的页坐标和尺寸。不传 `canvas`、`panel_name` 或 `panel_frame_pt`。 + +`panel_name` 仅用于新建面板,省略时使用图对象名称。名称不得空白,最长 +1024 UTF-8 字节。`panel_frame_pt` 只设置新建面板:X/Y 为有限页面 pt,宽高 +为有限正数。省略时保留原有空画布原生放置约定;已有成图的画布必须提供 +明确 frame。不重排已有内容,也不将已有图重建为替代对象。 + +MCP 计划返回 `plan_id`、`project_context` 和 `basis_revision`。 +`preflight` 包含 `required_authority`、`created_target_count`、异常 `targets` 和 `outputs`。 +`preflight.binding_plan.creation` 包含精确 `parent`、拟建完整目标 `canvas`、`panel`、 +`plot` 和 `created`(含全部 Series),以及 `size_mm`、所用 `size_preset`(如有)、 +`panel_frame_pt`(页坐标)、`frame_pt`(面板内局部坐标)、`coordinate_units` 和 +`series_defaults`(图型及 pt 线宽)。结果不确定时保留这些冻结身份用于核查。 + +`preflight.binding_plan.binding_count` 统计曲线数,`row_counts` 汇总各曲线的 +`total_rows` 和 `plotted_rows`。`binding_plan.bindings` 只列出数据缺失、非有限值或 +缺失误差的曲线,包含完整目标和全部诊断(含 `affected_rows` 样例)。空列表表示 +没有这些问题,不表示没有绑定。响应省略请求回显、冻结目标重复信息、来源映射和 +成功目标说明;存储的权威计划仍保留完整已验证来源及候选。 + +预检不创建对象。执行一次性计划后,`value.creation` 返回同一 canvas/panel/plot 和 +布局;`value.bindings` 返回**每条** Series 的完整目标及 `total_rows`、`plotted_rows`、 +`missing_xy`、`non_finite_xy` 和 `missing_error`。默认值仅在预检披露一次。 +`produced` 列出新建资源,`summary` 统计目标结果,`targets` 只保留异常项;诊断与验证 +继续保留。`project_context` 和 `after_revision` 标识已提交结果。 + +创建是原子的:来源错误、单位不兼容、非法误差或父目标/revision 变化时, +不留下新画布、面板或半成品图。只读连接拒绝创建预检和执行。每图 1–200 +条曲线、最多 2,000,000 曲线行访问;待执行创建和绑定计划共享 2,000,000 +行预算,每连接最多 32 个计划,结构化响应上限 256 KiB。失败提交也消费 +plan。执行响应丢失后,先查询当前状态及预检返回的目标,不能盲目重新创建。 + +使用返回目标进行结构发现与属性操作,以当前 revision 预览完整画布。 +结果可在 GUI 选择和继续编辑。一次 Undo 只移除本次新建子树,保留已有父 +容器及导入数据;Redo 恢复同一身份。后续原生尺寸和布局调整保留图对象、 +Series 身份和来源绑定。已知目标可复用同步提交结果的 context 与 revision;桌面编辑或 Undo/Redo 后先读取状态。 + +## 把派生曲线加入已有图 + +新计算的表需要与原曲线同图显示时,使用 `plot.series.append`,无需替换图对象。 + +MCP 不传顶层 `ids`/`targets`,在参数内指定完整图对象目标: + +```json +{ + "expected_project_context": "<当前 context>", + "expected_revision": 23, + "tool_id": "plot.series.append", + "parameters": { + "plot": {"resource": {"id": "/", "kind": "plotium.canvas.object", "parent_id": "", "local_id": ""}}, + "series": [{"kind": "line", "source": { + "dataset_id": "<派生 DatasetId>", "field_id": 0, + "table_id": "<派生 TableId>", "table_revision": "<派生表 revision>", + "x_column_id": "", "y_column_id": "", + "y_error_column_id": null + }}] + } +} +``` + +目标、FieldId、表和列 ID 均从实际发现结果复制,名称不是身份。目标必须已有 +显式坐标;每批追加 1–200 条明确选择的折线/散点/柱状/箱线/小提琴曲线,追加后该图最多 200 条曲线;已有柱状曲线会与同槽位新追加的柱重新并排分组。 +共享绑定验证器在一次原子提交前检查全部源 revision、完整曲线数据、误差和单位。 +兼容单位转换到图的现有坐标单位;不兼容的整批失败,不部分添加。沿用绑定服务的 +2,000,000 曲线行及待执行计划预算和 256 KiB 响应限制,包含受影响图的已有曲线。 + +`preflight.binding_plan.appended` 返回拟新增的 Series 目标,`bindings` 同时包含 +未改变的已有绑定及新增绑定。执行采用预检冻结的 ID;一次 Undo 仅移除新增曲线, +Redo 恢复同一身份。Undo 后另行追加不会复用已退役 ID。已有 Series 样式、坐标含义、 +人工轴范围、plot/Panel 身份及 frame 均不改变。预检和执行都要求 Read and modify; +context、revision 和权限沿用绑定编辑的一次性计划生命周期。响应丢失后先查拟新增 +目标,不盲目再次追加。 + +## 精确重绑已有曲线,不影响另一张图 + +两个图可以引用同一张原生表,各自选择不同的数值 X、Y 和可选对称 Y 误差列。 +表格共享的默认绑定不会改变。 + +MCP 先通过 `plotium_document_inspect` 取得完整 Series target,再从 +`plotium_table_columns` 复制 DatasetId、TableId、FieldId、表 revision 和 ColumnId。 +使用项目 ColumnId,不使用 `source_column_id`、名称或显示 trace 的位置,也不猜字段 +资源地址。调用 `plotium_plan`: + +```json +{ + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 8, + "tool_id": "plot.series.bind", + "parameters": { + "edits": [{ + "target": { + "resource": {"id":"CANVAS_UUID/OBJECT_ID","kind":"plotium.canvas.object", + "parent_id":"CANVAS_UUID","local_id":"OBJECT_ID"}, + "component": {"kind":"series","id":0} + }, + "source": { + "dataset_id":"DATASET_UUID", "field_id":0, + "table_id":"TABLE_UUID", "table_revision":"TABLE_REVISION_UUID", + "x_column_id":"X_COLUMN_UUID", "y_column_id":"Y_COLUMN_UUID", + "y_error_column_id":null + } + }] + } +} +``` + +将占位符和示例中的数值 ID 全部换成实际发现结果。不要另传顶层 `ids` 或 +`targets`,每项编辑已携带完整目标。`y_error_column_id` 为 ColumnId,或 +null/省略,后两者移除误差绑定。检查 `preflight.binding_plan.bindings` 中的来源映射和 +逐行诊断,再以返回的一次性 `plan_id` 调用 `plotium_execute`。 + +一个默认表格 Series 可能代表多条显示曲线,须先调用 +`plot.series.materialize_default`,参数为 +`{"edits":[{"target":EXACT_SERIES_TARGET, +"retain_y_column_id":"EXISTING_Y_COLUMN_UUID", +"table_revision":"TABLE_REVISION_UUID"}]}`。 +保留的 Y 列沿用原 SeriesId,其余已有曲线获得新的对象内 SeriesId,预检和执行结果均返回映射。此操作只展开已有内容,不创建 +图对象。拟合叠加及归一化/偏移的多曲线默认组合无法无损展开,因而明确拒绝; +未展开的旧默认绘图入口仍可使用。 + +只接受 Int64 和 Float64 列;无法在 f64 图坐标中精确表达的整数明确拒绝。 +X/Y 为 null 或非有限值时形成断点,不补零、不跨断点连线。误差为 null 时保留 +有效点但不画该点误差线;零误差合法。负值或非有限误差使整批失败,即使该行的 +X/Y 缺失也不忽略非法误差。误差表示非负绝对幅度,不从列名赋予标准差、标准误或 +置信区间含义。诊断统计全部行,每条曲线最多附 20 个受影响 RowId;绑定校验和 +原生曲线提取不抽样行。 + +兼容单位换算到图对象持久化的坐标单位;误差幅度仅使用比例,不应用仿射偏移。 +已知单位与未知单位不能混用。重绑、删除首条曲线和重排后,手动范围及位移保持 +原坐标含义;不兼容时拒绝,而不是重新解释原数字。人工标签、颜色、线/散点编码、 +可见性、面板位置及轴设置随原目标保留。显式图保持线/散点编码,不切换到无关 +表格图型。 + +每批允许 1–200 项编辑,受影响图合计最多 2,000,000 次曲线行访问;待执行 MCP +曲线计划共享同样的行预算,完整响应最多 256 KiB。全部目标、列、单位、行和 +revision 检查通过后才一次原子提交、一次 Undo,不部分成功、不跳过无效目标。 +只读连接拒绝绑定预检和执行。失败或过期执行也消费计划,须重读状态并重新规划。 +GUI 保存重开保留原生绑定和单位;MCP `project.save` 需桌面单独批准;SVG/PDF/PNG 导出需另行桌面批准,新建图使用上文的 `plot.create`。 diff --git a/docs/src/content/docs/zh-cn/reference/mcp/review.md b/docs/src/content/docs/zh-cn/reference/mcp/review.md new file mode 100644 index 00000000..b59cd004 --- /dev/null +++ b/docs/src/content/docs/zh-cn/reference/mcp/review.md @@ -0,0 +1,298 @@ +--- +title: MCP 预览、诊断与恢复 +description: 渲染预览、诊断图面几何,以及出错后的恢复。 +--- + +## 读取实际画布图像 + +可以请 agent:“预览这张画布,描述文字、曲线和本地图片。”先通过 +`plotium_document_inspect` 取得完整画布 target,再以当前 revision 调用 +`plotium_render_preview`: + +```json +{ + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 7, + "target": {"resource":{"id":"CANVAS_UUID","kind":"plotium.canvas"}}, + "max_edge": 1440 +} +``` + +将 `CANVAS_UUID` 换成发现返回的画布 ID;不接受面板、内容、当前选择或 Series。 +结果包含标准 MCP PNG **image 内容块**,以及 `ToolResult.value` 中的 +`target`、`render_revision`、`width_px`、`height_px` 和 `mime_type`。 +无需打开文件或自行渲染 SVG 文本。点数超过预览所能显示的曲线以最小/最大包络 +绘制:每个像素列保留四对最小/最大值点,整个绘图区至少 2,048 对(标记则每个像素 +一个);`downsampled` 以 `{target, source_points, drawn_points}` 列出每条这样的 +曲线,没有降采样时省略。放大后可见的数据点全部保留。 +导出始终绘制全部数据点。MCP 客户端须将图像内容交给 agent;纯文本 +客户端无法读取此预览。 + +图像覆盖整页,使用原生版式、背景、面板裁剪、文字、曲线及项目内嵌栅格资产。 +渲染基于不可变快照在后台执行,`render_revision` 标识该快照;截取后发生的人工 +修改不会被标成图像内容。执行后续修改前请重新读取状态。只读连接也允许预览。 +预览不追加项目运行记录,也不改变 dirty、edit generation 或 automation revision。 + +`max_edge` 默认 1440 px,可取 1–2048;保持宽高比,按像素取整,每轴至少一个 +像素。预算为输出 4,194,304 像素、引用资产编码数据合计 16 MiB、按实际文件头 +探测的资产页 RGBA8 合计 64 MiB、中间 SVG 8 MiB、PNG 4 MiB、JSON-RPC 预览响应 +6 MiB(包含请求 ID)。同一资产编码数据只计一次,同一资产页解码只计一次。 +这些限制约束负载和图像缓冲区,不代表整个进程的内存上限。所有引用资产均校验,包括隐藏项。 +`plotium_capabilities_get {"section":"limits","key":"image_preview"}` 也提供这些预算。 + +资产缺失、损坏或图片页不可用时返回 `preview_asset_unavailable`,不会以占位图 +或缺图结果报告成功。超过预算返回 `preview_budget_exceeded`,不静默降质;输出 +超限时降低 `max_edge`,资产超限时缩小源资产。无效完整身份返回 +`invalid_parameters`,过期 revision 返回 `stale_revision`。 +每连接最多同时渲染一张预览,重复请求返回 `busy`;渲染期间其他已有工具仍可用。 +取消请求或停止连接后不交付图像;停止连接、切换项目会丢弃旧任务。 + +## 提交前读取计划候选 + +`plotium_plan` 返回后,用**原** plan ID、context、revision 和一个受影响的完整画布 +target 调用 `plotium_preview_plan`: + +```json +{ + "plan_id": "RETURNED_PLAN_ID", + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 7, + "target": {"resource":{"id":"CANVAS_UUID","kind":"plotium.canvas"}}, + "max_edge": 1440 +} +``` + +响应包含实际 MCP PNG image 内容块。`ToolResult.value` 返回 `plan_id`、 +`basis_project_context`、`basis_revision`、`candidate: true`、`target`、 +`width_px`、`height_px`、`mime_type` 和 `output`(`size_mm`、`size_pt`、`max_edge`)。 +没有 `render_revision`:候选尚未提交。读取结果的 `before_revision` 和 `after_revision` +均指向基线。实际读图后,再明确以原 `plan_id` 调用 `plotium_execute`;随后读取 +`plotium_render_preview` 和 fresh `plotium_figure_diagnose`。候选预览不增加候选诊断 +或自动修图循环。保留诊断的 `measurement_basis`、`coverage` 和 `unsupported`; +估计文字边界不是字形墨迹,潜在图例冲突不是已确认遮挡。 + +| 已有计划 | 候选支持范围 | +| --- | --- | +| `properties.set` / `properties.reset` / `properties.set_many` | 文档和图对象的显示属性及原生多目标批次;不含画布属性、应用偏好、数据处理,以及图表类型和堆叠方式的修改 | +| `figure.edit` 局部编辑 | `content_frame`、`image_replace`、`text_set`、`annotation_create`/`annotation_set`/`annotation_delete`(文字标注与参考线)及原生批次 | +| `figure.edit` 纯删除批次 | `content_delete`、原本为空的 `panel_delete`、显式列绑定 `series_delete`;原拒绝规则不变 | +| 其他操作,包括保存和导出 | 返回 `unsupported_operation`,不改变其正常 execute 合同 | + +想让用户挑选样式(配色、线宽、图例位置、标签布局等)时,规划两三个备选计划,逐个预览, +把图并排给用户看。只执行用户选中的计划。其余计划从不提交,之后会返回 `stale_revision`, +但在提交或连接重置前仍占用 32 个待执行计划的名额。 + +受影响画布须使用普通折线/散点、原生文字、形状和栅格内容;预览不启动科学计算。 +跨画布属性计划在隔离原生上下文应用完整批次,可逐个请求受影响画布,仍是一个计划、 +一个 Undo 步骤。自动轴、guide 依赖和派生页高复用原生 action 与 renderer,不另建布局模型。 +基线、输出设置和字体相同时,候选内容和几何与 execute 一致;不保证跨机器字体/renderer +不同情况下的像素相等。 + +候选读取需要 **Read and modify**;截取和后台交付时均检查 context、revision、空闲状态、 +当前权限及计划仍未提交。渲染中撤权再授权也会阻止交付。预览不消费计划、不延长生命周期、 +不赋予执行权限。普通编辑计划没有时钟 TTL,共享每会话 32 个计划上限,context/连接变化 +会清空。execute 提交只可一次,包括失败提交。`expired_plan` 表示计划不存在或已消费; +其他拒绝由 `stale_revision`、`project_changed`、`permission_denied`、`busy`、 +`request_cancelled` 及上述图像错误表达。人工编辑或切项目后须重新发现和规划;连接中断后 +不要重放结果未知的 execute。 + +预览借用冻结输入和图像字节,不重读换图路径、不重分配已规划身份,也不在真实项目执行 +再 Undo。它不改变 authored 内容、数据、绑定、选择、历史、automation revision 或持久 +资产、dirty 或 edit generation。不追加项目审计记录,**不保存 PNG 字节**。无候选文件或缓存。 +候选与真实预览共享单个渲染槽、取消和上述图像预算;另以 64 MiB 原生快照估计约束候选 +构造(画布几何、来源字段按每元素 64 字节、元数据及冻结资产),不表示整个进程内存上限。 +切项目取消的任务在有界 renderer 退出前继续占用渲染槽。 + +## 按输出尺寸诊断图面几何 + +可以说:“按 180 × 90 mm 检查出界、裁切、文字溢出、这两段说明的有意重叠,以及 +普通折线/散点与图例的潜在遮挡。不要修改内容;按返回 target 定位,并实际查看原生 PNG。” + +发现画布后直接调用 `plotium_figure_diagnose`,无需编辑计划: + +```json +{ + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 7, + "canvas": {"resource":{"id":"CANVAS_UUID","kind":"plotium.canvas"}}, + "output": {"size_mm":[180,90]}, + "checks": ["bounds","clipping","text_overflow","content_overlap","legend_occlusion","data_shape","layout_aesthetics","intent"], + "detail": "full", + "limit": 100 +} +``` + +可用 `targets` 限定完整的 content 或 Series target;Series target 还包含所属 plot 的 frame 和 guide 上下文。省略即扫描画布,绝不使用 GUI +选区。`content_overlap` 另需至少两个完整内容的 `overlap_targets`,比较可见且经过 +页面裁剪的 frame,不判断不透明像素。`view` 可取 `issues`(默认,返回问题)、`layout`(改为返回测得的几何行)或 `both`。 +`detail` 可取 `compact`(默认)或 `full`:精简的问题行保留 `target`、`component`、 +`code`、`severity`、`message`、`measurement_basis` 和 `suggestions`,`evidence` 只留 +`other_target`、`other_component`、`point_range` 和 `interpretation`,也不列已完成 +检查的覆盖行;`full` 返回全部证据几何和所有覆盖行。报告局限的覆盖行始终返回。 + +`output.size_mm` 须为正数并保持画布宽高比(高度容差 0.001 mm)。与原生导出一致, +它等比缩放既有页面,不重排布局;每个初始查询重新计算几何。结果使用 +`output_page_pt`:72 pt/inch,左上原点、X 向右、Y 向下。`output` 包含原生尺寸与 +尺度,文字、线宽和 bounds 一起缩放。panel-local frame 经原生 page-frame 服务换算。 +数据使用实际 plot 裁剪区;panel 边框**不是**所有内容的裁剪区。原生 raster frame +和 `clip_children` 的裁剪另行列明。 + +`ToolResult.value` 包含 `project_context`、`basis_revision`、`canvas`、`summary`、 +`output`、`items`、`coverage`、`truncated` 和 `continuation`。默认的 compact 详情中, +`output` 只含 `size_mm` 和 `size_pt`,`coverage` 给出状态、扫描计数以及不可用或不支持的 +条目数。`detail: "full"` 时 `output` 另含页面坐标说明,`coverage` 另含请求、支持和不支持的 +检查列表,并附 `budget`、`preview_request` 和 `read_policy`。`summary` +统计本页的问题(`issues`、`by_code`、`by_severity`);分页扫描时把各页计数相加。 +每个问题带完整原生 `target`、所属对象内的 `component`、`code`、`severity` 和说明; +`detail: "full"` 时证据另带 bounds、clip 和交集几何。 +将 `target` 直接用于 `plotium_document_inspect` 的 `view: "self"`;重名不影响定位。 +`guide.legend` 属于 plot,并非新资源。曲线冲突指向现有 Series,并通过 +`evidence.other_target` / `other_component` 关联所属 plot 的图例。 + +- `out_of_canvas`、`partially_clipped`、`fully_clipped`、`curve_primitives_clipped`/`shape_clipped` + 是信息性事实,包括有意的手动范围裁切;曲线证据只覆盖所列原生 run 的点范围。 +- `text_container_overflow` 是基于原生宽度/行距**估计**的警告,不是精确字形边界; + 文字不会自动换行或缩小。 +- `content_frame_overlap` 是信息性事实,允许有意重叠。 +- `axis_ticks_sparse` 是警告:在输出尺寸下,显示刻度标签的坐标轴画出的刻度少于两个, + 读不出刻度比例。增大面板,或调小 `object.figure.typography.tick_pt`。 +- `right_axis_untitled` 是警告:有曲线使用右 y 轴,但右轴没有显示标题。设置 + `object.axes.y2_label`(或重新打开 `object.axes.y2_show_label`)。 +- `legend_occlusion_potential` 表示潜在视觉冲突,不表示数据必然不可见。逐段/逐点 + 检查实际投影、有效裁剪后的线与 marker,分批保留虚线相位,不使用整条曲线包围盒, + 不抽样。线条包络与图例布局矩形是保守边界;圆角、半透明和抗锯齿可能有所不同。 + +`data_shape`、`layout_aesthetics` 和 `intent` 检查报告 `severity` 为 `hint` 的问题:图可以表达得 +更清楚,但没有错误。省略 `checks` 时包含这三项。提示从不修改文档。每条提示带 +`suggestions`,即 `{action, property, target, reason}` 列表;`property` 是要在 `target` +上设置的属性,没有则两者都为 null。长度按请求的 `output.size_mm` 测量;阈值是暂定值。 +限定到 Series 的查询只报告这些 Series 的提示。 + +| 代码 | 触发条件 | +| --- | --- | +| `small_values_invisible` | 某根柱的数值不到数值轴跨度的 1 %,或打印长度不到 0.5 mm,而旁边有至少 5 mm 长的柱 | +| `bars_too_narrow` | 某根柱打印宽度不到 0.6 mm | +| `few_samples_hidden` | 箱线、小提琴 Series,或每个 x 有多行的柱状 Series,每组都少于 10 个值;或每个 x 只有一行的柱状 Series 的 `series.replicates` 为 1–9;且图中没有散点 Series | +| `too_many_categories` | 类别轴显示标签,但省略了部分标签,或相邻标签相互重叠 | +| `log_scale_candidate` | 不含柱、箱线或小提琴的图,线性数值轴上的折线或散点值全为正,且跨越三个及以上数量级 | +| `bar_baseline_not_zero` | 数值轴范围不包含柱的基线 | +| `labels_overlap` | 画布上两个文字框在两个方向上都重叠超过 0.2 mm;证据给出两者和第二个的移动方向。同一图例的条目之间、同一坐标轴的刻度标签之间不互相比较 | +| `text_over_data` | 标注或数值标签压在柱、箱线、小提琴、折线或标记上 | +| `intent_mismatch` | 图型不适合这张图的 `object.intent.purpose`(见下文) | +| `panels_misaligned` | 同一列(左边缘相差 1 mm 以内)或同一行(下边缘相差 1 mm 以内)的两个框,绘图区左边缘或下边缘相差超过 0.5 mm;或同一行/列三个及以上框之间的间距相差超过 0.5 mm | + +同类提示超过 50 条,或检查用完预算时,会增加一条 `unavailable` 覆盖行。 + +`intent` 检查对照作者声明的目的看每张按列绑定的图;`detail` 从不报告。没有声明目的的图 +会得到一条 `not_applicable` 覆盖行 `no_purpose_stated`:这时请询问用户这张图要表达什么。 +表格图表类型得到 `chart_type_not_covered`。`intent_mismatch` 的证据在 +`interpretation` 中给出原因;`detail: "full"` 时还给出目的、claim 和读到的图表特征。 +建议里只列 Plotium 能画出的图型;请转告用户,由用户选择。 + +| 目的 | 报告条件 | +| --- | --- | +| `compare` | 折线连接了各类别 | +| `trend` | 类别方向的轴是类别轴,或图中画了柱 | +| `distribution` | 类别轴上只有柱或折线,没有箱线、小提琴或散点 Series | +| `relationship` | 类别方向的轴是类别轴,或图中画了柱、箱线或小提琴 | +| `composition` | 图中有折线或点,但没有柱 | +| `change` | 两个及以上柱状 Series 并排,或正的柱值跨十倍及以上;或图中没有柱、箱线和小提琴时,左轴上为正的折线或散点值在线性轴上跨十倍及以上 | + +原生 guide 布局本身使用文字宽度估计。字体可用性沿用原生导出的字体发现;实际字形 +覆盖和跨后端 ink 边界仍未验证。图像视口几何使用头部尺寸、整数裁剪、旋转及 fit; +是否成功解码、透明像素分布需看原生预览。首轮不覆盖非普通折线/散点的内部几何、 +误差棒裁剪/遮挡、科研派生标注及不透明像素遮挡;原生矩形、椭圆、直线和箭头的极值边界使用实际页面裁剪区;仍可观察其 frame/guide,覆盖 +结果会说明限制。除上述提示外,不做审美评分、科研正确性或统计意义判断。 + +**没有问题时也必须读 coverage。** 各目标区分 `complete`、`unsupported`、 +`unavailable`、`not_applicable`(如隐藏、空渲染数据或无图例)。整体 `partial` +表示尚有分页;`limited` 表示遍历结束但存在未支持/不可用部分。遍历完成不会把估计 +变为精确测量。数量是扫描对象、源点和重叠对数,不是像素覆盖百分比。缺资产/字体、 +失效来源和排除的几何会明确报告,不当作“图面无问题”。 + +`continuation` 非 null 时,仅用以下参数继续: + +```json +{"expected_project_context":"PROJECT_CONTEXT","expected_revision":7,"cursor":"RETURNED_CURSOR"} +``` + +一次性 cursor 绑定原目标、输出、检查及分页配置,闲置 300 秒失效。新的初始查询 +替换旧扫描。完成所有分页才可说明覆盖;问题行为空也可能截断。每个桌面连接仅保留 +一个执行中 batch 和一个未读快照。原生 stdio facade 为诊断续页保留一个 transport, +stdio 结束时关闭;其他工具仍使用原来的单次调用 transport,绝不重放。限制:200 个指定目标、200 个重叠目标/19,900 +对,每批 200 个对象和 1,000,000 个源点,每个 plot 最多 4,096 个渲染 run 与 polygon,1 MiB +文字、64 MiB 估算快照 payload、16 MiB 已编码资产探测。默认每页 100 行、最多 200 +行,页面值 96 KiB、JSON-RPC 响应 256 KiB。这些是 payload/工作量限制,不是进程 +总内存上限。快照/文字超限返回 `diagnostic_budget_exceeded`,需缩小目标;batch/ +行数用尽则返回 `truncated: true` 和 cursor,不抽样。 + +交付前重查 context、revision、busy 屏障和连接权限。编辑、项目变化、取消、停止连接 +及传输关闭会使相关工作失效;过期/已消费 cursor 返回 `expired_cursor`。 +遇到 `stale_revision` 或 `project_changed`,重新读状态并开始扫描,不混合新旧页。 +只读权限即可使用;对象、绑定、手动范围、几何、Undo 历史和 automation revision +以及 dirty、edit generation 不变,不追加项目审计记录。不持久化诊断几何、问题、cursor 或 PNG 副本。 + +用画布、上下文和 `basis_revision` 调用 `plotium_render_preview` 取得并实际查看原生 PNG。 +X 坐标转像素为 +`x * width_px / output.size_pt[0]`,Y 使用对应高度;核对其 +`render_revision` 与 `basis_revision` 一致。编辑器 zoom 不影响上述坐标。直接 core +`figure.diagnose` 只返回一个有界 batch,不保留 cursor;MCP 查询提供继续读取。 +诊断不会自动修图。 + +## 恢复动作与未知结果 + +`recovery` 描述本次请求,不授予执行另一次请求的权限: + +| 字段 | 含义 | +| --- | --- | +| `plan_consumed` | 确知时为 `true` 或 `false`,未知时为 `null`。已消费的计划不能重用。 | +| `submission` | `submitted`、`not_submitted` 或 `unknown`;后台工作被接受不代表完成。 | +| `committed` | 确知时为 `true` 或 `false`,副作用或持久化结果不确定时为 `null`。 | +| `completion` | `pending`、`succeeded`、`failed`、`partial` 或 `unknown`。 | +| `receipt` | 状态工具及 `arguments` 中的准确 ID;`retained` 找到时为 `true`,缺失时为 `false`,未知时为 `null`。整个 `receipt` 为 `null` 表示没有已知的回执查询。 | +| `next_action` | 一个下一步:带准确参数的 `call_tool`、`desktop_file_confirmation`、`check_desktop_connection`、`inspect_outcome` 或 `none`。 | +| `replay_allowed` | 始终为 `false`,恢复信息不授权重放或自动重新提交。 | + +`call_tool` 只调用指定的读取工具。桌面确认时,在 Plotium 审核待处理请求的准确路径和 +覆盖范围,再查询回执。`check_desktop_connection` 要求在桌面检查 AI connections (MCP) +及访问模式,然后读取状态。`inspect_outcome` 要求对照保留的回执、预检目标/路径和 +当前状态;证据不足时,重新计算科学任务或请求文件写入前需人工审核。 + +- **Busy:**预检在提交前失败。执行可能先消费计划,再检查 busy;结束桌面操作、读取 + 状态并审核新计划,不能重用已消费的 ID。 +- **Revision 冲突/项目切换/撤权:**刷新状态并在桌面检查权限。切换项目后重新发现 + 新 context 中的目标;计划 ID 和文件权限不能转移到新项目。 +- **安装前保存拒绝或取消:**已消费计划的回执为终态,`phase: not_installed`、 + `committed: false`、`completion: failed`。关闭确认框也表示拒绝。先检查状态并询问 + 是否仍需保存;新的保存意图需新计划和新的桌面确认。 + Worker 启动后的取消必须根据最终阶段判断,不会撤销已经安装的输出。 +- **保存/任务尚未完成:**被接受、排队、运行或保存中都是 `pending`,不是成功。 + 查询回执,不提交替代任务或保存。保存 worker 终止后,`installed_unconfirmed` + 仍表示未知结果。 +- **导出:**只有批次完成且每个文件都成功,整批才成功。混合终态为 `partial`;逐个 + 核查准确路径及错误。文件可能已安装后才发生持久化错误,因此失败不证明路径未变。 + 不能自动重试整批,也不能重写其中已成功的文件。 +- **断连/计划过期/回执未知或淘汰:**保留计划消费、提交和持久化状态的未知性。 + 重连后在同一桌面进程查询已知回执 ID;不存在时核查保存的目标/路径。回执缺失 + 不证明未执行,也不授权重算或覆盖。桌面重启后不保留回执。 + +这些动作保留服务端权限、revision/context 检查、一次性计划和逐次桌面文件确认。 +工具 annotations 既不授权,也不是重试依据。桌面和连接器一起升级后,重新连接客户端 +并刷新工具目录。 + +## 错误码 + +稳定错误码包括 `project_changed`、`unavailable`、`connection_lost`、`permission_denied`、`expired_plan`、`stale_revision`、`busy`、 +`invalid_parameters`、`unsupported_operation`、`unsupported_property`、`plan_limit`、 +`request_cancelled`、`connection_stopped`、`response_too_large` 和 `execution_failed`。 +无效的能力分区或键会指向静态发现,并在 `error.details` 给出合法候选。 +无效的规划参数指向该操作的 `operation_constraints`,而不是要求读取项目状态。 +输入错误在已解析的请求边界提供 `error.details.field`,例如 `plan_id`、 +`parameters` 或 `parameters.writes[0].key`。过期 revision 和项目切换仍须读取状态并重规划; +这些指引不允许重放。嵌套的 source 和目标错误给出完整路径,例如 +`parameters.series[0].source.y`。 + +错误提供 `error.recovery`,异步保存、导出和任务回执提供 `recovery`。 +`retryable: false` 表示不要重复失败的调用,应遵循下一步动作。`busy` 执行可能已经 +消费计划。revision 冲突需读取状态并审核新计划;过期计划可能已经执行,必须先核查结果。 +AI connections (MCP) 设置页面显示最近操作和错误,后台反馈不会自行打开设置页面。 diff --git a/docs/src/content/docs/zh-cn/reference/mcp/save-and-export.md b/docs/src/content/docs/zh-cn/reference/mcp/save-and-export.md new file mode 100644 index 00000000..d7e36f57 --- /dev/null +++ b/docs/src/content/docs/zh-cn/reference/mcp/save-and-export.md @@ -0,0 +1,145 @@ +--- +title: MCP 保存与导出 +description: 经桌面端确认后保存项目、导出图形。 +--- + +## 保存当前桌面项目 + +保存复用 **Save project** 的原生快照、后台 worker、备份和完成回调,保存当前 +桌面实际状态,不另开 CLI 项目。先读 `plotium_get_state`;`save_state` 给出当前路径、 +已存档案 revision、dirty、edit_generation 和最多 16 个保留的 `receipt_ids`。 +逐个用 `plotium_save_status` 查询完整回执和恢复动作;仅有 ID 不代表提交成功或已经完成。 + +首次保存或另存时,不带 `ids`/`targets`: + +```json +{ + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 46, + "tool_id": "project.save", + "parameters": {"path": "/absolute/path/figure.plotium"} +} +``` + +省略 `path` 保存当前文件;未命名项目必须给出路径。父目录须已存在,目标为普通、 +非符号链接的 `.plotium` 文件或尚不存在的路径。预检解析父目录并冻结已观察的目标。 +可选 `include_view_snapshots` 覆盖当前项目的原生保存配置。计划返回 `save_id`、 +实际路径及 `overwrite_required`,不授予磁盘写权限。 + +用 `plotium_execute {"plan_id":"PLAN_ID"}` 提交一次性计划,结果为 +`save.status: "awaiting_authorization"`。在 Plotium 核对准确路径,点击 +**Allow save**;已有文件还必须勾选 **Replace the existing file at this exact path**。 +**Deny** 不改目标。这与 **Read and modify** 独立,只授权本次保存,不能通过工具 +参数代为批准。Read only 模式也可发起此授权请求。目标变化须重新规划并确认; +同时最多一个外部保存请求。 + +序列化使用独占创建的私有唯一同目录临时文件,不写固定 `.tmp`。 +已有目标在备份准备完成后、实际替换前再次复验预检冻结的文件元数据;发现变化即拒绝 +安装,保留后来版本。一次性权限准入与文件复验是两个边界;复验加替换并非跨进程 +compare-and-swap。非协作写入若发生在最后复验之后,或保留了所检查的元数据, +仍可能无法察觉;应避免并发保存到同一路径。 + +用 `plotium_save_status {"save_id":"SAVE_ID"}` 查询,不带项目 revision/context, +保存中也可读取且不使项目 dirty。`awaiting_authorization`、`queued`、`saving` +均未完成,`phase` 为 null;只有 `completed` 带最终阶段: + +| phase | 文件状态与下一步 | +| --- | --- | +| `not_installed` | 本次未把快照安装到目标。处理拒绝或错误、检查实际状态;仍需保存时重新取得授权。 | +| `installed_unconfirmed` | 快照已替换/创建目标,但备份收尾或持久同步失败。保持项目打开,检查目标及存储后再明确授权重试;不能假定旧文件还在。 | +| `committed` | 捕获的快照完成原生持久提交;后来的编辑仍可能未保存。 | + +Windows 替换部分失败时,即使新快照为 `not_installed`,旧目标仍可能已被移走或删除。 +Plotium 保留已序列化的候选文件,并报告准确恢复路径。只有不覆盖现有目标时才尝试 +从已知备份恢复原文件;无法完成时,保留并报告该备份及更早的暂存备份。如果 Windows +移走原文件却未返回其位置,错误会明确说明。保持项目打开,检查所列文件后再决定是否 +重试;此类失败不会清除 dirty 状态。 + +回执包含原始 `project_context`、`snapshot.document_revision`、 +`snapshot.edit_generation`、`persisted_revision`、准确路径、`state_applied`、 +`dirty_after_completion`、错误及恢复说明。查询结果另给当前 context/path/revision/dirty +和 `matches_current_project`。快照在桌面批准后、后台工作前捕获;之后的新编辑 +保持 dirty,完成不等于当前所有编辑已落盘。 +已安装但未确认同步时仍保持 dirty,并记录已安装基线供原生恢复使用。 +保存规划/提交和状态查询仅用临时桌面回执,不加审计记录;普通项目读取同样不追加 +项目审计记录,也不改变 dirty。 + +切项目或停止连接撤销待写权限。worker 只持有原项目快照和路径,并在安装边界检查 +授权;即便 document revision 相同,旧完成也不能装入另一项目或清它的 dirty。 +worker 原子确认授权并进入安装后,停止不保证取消这次原文件写入,须查回执; +在此之前撤销则阻止安装。保存不加入 Undo,Undo 不删除或还原磁盘文件。 + +桌面进程保留最近 16 条回执,跨连接恢复和项目切换有效,退出应用后不保留。响应丢失后 +先查询原 `save_id`,不要重放已提交调用。应用重启或 `unknown_save` 时,检查目标和 +新打开的项目,不自行假定成功或失败。稳定 stdio 配置继续可用;重开/重启后仍须 +重新读取状态、发现目标并规划。连接恢复不是保存成功的证据。 + +## 将捕获画布导出为 SVG、PDF 和 PNG + +用 `figure.export` 指定一张准确的完整画布 TargetRef,不带顶层 `ids`/`targets`。 +复用原生导出器,保留背景、完整页面、曲线、绝对 Y 误差幅度、原生文字和嵌入图片; +不裁切、不套主题、不改项目。成品之外仍须保留可编辑 `.plotium` 项目。 + +```json +{ + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 48, + "tool_id": "figure.export", + "parameters": { + "canvas": {"resource":{"id":"CANVAS_ID","kind":"plotium.canvas"}}, + "size_mm": [180,90], + "dpi": 300, + "outputs": [ + {"format":"svg","path":"/absolute/path/figure.svg"}, + {"format":"pdf","path":"/absolute/path/figure.pdf"}, + {"format":"png","path":"/absolute/path/figure.png"} + ] + } +} +``` + +`size_mm` 默认原生页面尺寸;显式尺寸等比缩放整图,须保留宽高比(高度误差容许 +0.001 mm),不改变可编辑页面。`dpi` 默认 300,范围 1–2400,仅控制 PNG。 +每轴按原生物理 pt / 72 × DPI × 等比缩放系数四舍五入,最小 1 像素; +180 × 90 mm、300 DPI 得到 **2126 × 1063 像素**。SVG/PDF 保留物理页尺寸。 +文字使用原生通用 sans-serif 字族;无可用系统字体时报错。SVG 在另一台机器的 +字形取决于当地可用 sans-serif 字体。 + +每批 1–8 个输出,绝对路径须带匹配的小写扩展名,父目录已存在;目标必须是普通 +非符号链接文件或尚不存在。重复的解析后输出路径拒绝。预检返回 `export_id`、 +物理/像素尺寸,以及逐文件准确目标或错误;坏目录不会掩盖其他文件的结果。 +`overwrite` 默认 false,已有目标报告 `overwrite_not_requested` 并保留原字节。 +确需替换时显式设 `overwrite:true`,这仍不授予写入权限。 + +用 `plotium_execute` 提交一次性计划。有效文件等待 Plotium 的 +**Allow AI to export this figure?** 提示,其中列出画布、revision、尺寸及路径。 +核对后点击 **Allow export**;已有文件还必须勾选默认未勾选的 +**Replace the listed existing output files**。**Deny** 不安装任何输出。 +**Read and modify** 不等于导出授权;只读可请求新的独立导出授权。 +全无效批次直接逐文件报错,不弹授权窗。 + +用 `plotium_export_status {"export_id":"EXPORT_ID"}` 查询,不带 context/revision, +渲染中也可查询且不生成审计。返回 `export`、当前 context/revision 和 +`matches_current_project`。批次状态为 `awaiting_authorization`、`rendering`、 +`completed`;`files[]` 每项包含格式、准确路径、覆盖要求、`status`、`error_code`、 +`message` 和已安装字节数。文件状态为 `pending`、`succeeded`、`failed` 或 +`unknown`(worker 失败,先检查该路径再决定下一步)。批次完成不等于全部成功。 +缺失/损坏图片、字体、目标变化、权限拒绝和渲染/预算错误会准确报告且不替换 +该输出;同批此前成功文件保留。 + +渲染在后台使用桌面批准后捕获的画布/资产,绑定原 `project_context`、`canvas` +和 `render_revision`,后续编辑不改变快照。切项目、停止连接或修改访问权限会撤销 +待安装权限。逐文件原子权限准入先于实际安装:准入前撤销阻止安装;已准入文件 +仍可能完成,须查回执。旧完成不改变新项目的文档、保存路径、dirty 或状态。 +独占唯一同目录暂存及原子不覆盖创建保护未授权文件;已有目标在实际替换前复验 +元数据,但并非跨进程 compare-and-swap,应避免并发写相同路径。 +导出成功表示输出已安装,不等于原生项目保存的持久提交阶段;Undo 不删除或还原磁盘文件。 + +预算:一个运行批次,共享待执行计划最多 32 个;路径最多 4096 字节;PNG 单边 +16,384、总计 16,777,216 像素;引用的嵌入资产 16 MiB、解码后 RGBA 64 MiB、 +SVG 8 MiB、逐文件编码结果 64 MiB。不查找外部资产、不替换成占位图。 +完整 schema 和限制可从 `limits` 与 `operation_constraints` 能力分区发现。 + +桌面进程保留最近 16 批导出回执,跨重连及项目切换有效,退出应用即丢失。 +响应丢失后先查原 `export_id`,不重放导出。重启或 `unknown_export` 时先检查 +准确输出文件。重开可编辑项目后重新读取状态、发现目标;仅为新意图重新规划。 diff --git a/docs/src/content/docs/zh-cn/reference/mcp/scientific.md b/docs/src/content/docs/zh-cn/reference/mcp/scientific.md new file mode 100644 index 00000000..f3a42253 --- /dev/null +++ b/docs/src/content/docs/zh-cn/reference/mcp/scientific.md @@ -0,0 +1,93 @@ +--- +title: MCP 科学运算 +description: 通过 MCP 运行处理、扩散拟合和 DOSY,并为结果建图。 +--- + +这些操作与桌面端的[处理](/zh-cn/guides/processing/)和 [DOSY](/zh-cn/guides/dosy/) +相同,命令行也可以通过 [`plotium-cli tool run`](/zh-cn/reference/cli/#单步科学操作)运行。 + +## 科学操作与任务 + +`plotium_processing_inspect`、`plotium_diffusion_inspect` 和 +`plotium_analysis_results_inspect` 是只读查询,使用显式 `ids`、 +`expected_project_context` 和 `expected_revision`。结果检查接受 `offset`、 +`limit`(1–100);ILT 网格较大时请减小页长。发现信息中的 +`scientific_operations` 来自核心操作定义,含参数 schema、能力、权限及执行方式。 + +以下写操作继续通过 `plotium_plan` / `plotium_execute`: + +| 操作 | 参数与目标 | +| --- | --- | +| `processing.edit` | 一个数据集;`edits` 中使用 `replace`、`enable`、`add`、`remove` 或 `move`;已有步骤使用稳定 StepId | +| `processing.apply_scheme` | `path`,可选 `compatible_only`;方案字节、指纹和兼容目标配置在预检时冻结 | +| `diffusion.set_input` | 一个数据集;完整 `input`;非法输入错误带结构化校验报告 | +| `analysis.regions.extract` | 一个支持区域序列的字段;`regions` 引用已有 RegionId 或给出边界和指标;可选显式 `input` | +| `analysis.diffusion.fit` | 一个原生表格;`response_column` 为稳定 ColumnId;可选原生 `options`;x 列单位必须为 `s/m²` | +| `analysis.dosy.build` | 一个扩散来源字段;`method` 为 `mono_exp` 或 `ilt`;可选 `input` 和 ILT `params` | + +显式区域格式为 +`{"source":"explicit","bounds":[0.8,1.2],"metric":"Height","name":"Signal"}`; +引用已有区域使用 `{"source":"existing","id":0}`。指标还包括 `Area`、 +`Mean`、`Max` 和 `Min`。区域提取生成独立原生表格,保留来源、区域到列的 +对应及扩散增量证据,不自动创建绘图。 + +除输入设置外,上述写操作返回 `ToolResult.value.task`。预检即分配 +`task_id`;`queued` 只表示已登记。使用 `plotium_tasks_get({task_id})`、 +`plotium_tasks_list({offset,limit})` 查询,使用 +`plotium_tasks_cancel({task_id})` 取消(需要修改权限)。状态为 +`queued / running / committing / succeeded / failed / cancelled / stale`。 +回执包括原始 plan_id、项目归属、起止版本、来源字段版本、阶段、已完成列数、 +失败代码、资源引用和终态摘要;未知总量为 `null`。回执查询不受忙碌或项目切换阻塞。 + +回执由应用进程持有,断线不会取消已提交任务;同一进程内重连可继续查询。 +保留所有活跃任务及最近 128 个终态回执,进程退出后不保证保留。 +`task_not_found` 表示未知或已淘汰,不能据此自动重算。重复执行已消费的科学 +计划只返回现有回执。取消幂等,提交前取消保证不写入,终态后取消返回已有终态。 + +计算冻结输入后进入原有 ComputeService。主线程严格复核项目、文档版本、 +字段版本、代次、取消状态及调用权限;计算期间任何文档编辑都会使任务过期。 +成功时一次提交配置、结果和关联表格,形成一个 Undo 步骤;Redo 复用计算结果。 +后台完成不会打开或关闭面板。同步工作流保留 `processing.apply_scheme`,等待其提交后 +才执行后续节点;其他后台科学操作请使用单步调用并等待终态。 + +扩散检查区分可执行、缺失参数、证据待确认和输入非法,报告问题代码、参数路径、 +预期单位、实际值、证据和修复建议。b 值按 IncrementId 对齐并统一为 `s/m²`, +D 为 `m²/s`;原始输入单位及换算来源保留。解析优先级为显式输入、目标结果 +来源、已存默认值/采集信息。JEOL 检查完整程序身份、梯度形状、时间及厂商系数。 + +单指数结果包括 D、I₀、D 标准误、有效点数、R²、残差和拒绝原因。 +ILT 返回 D 网格、λ、非负解、重建残差及求解终止信息,不附单指数置信度。 +`empty` 表示没有可接受的科学结果;不可用数值为 `null`,附原因。 +结果检查分页返回逐列诊断,来源记录保留算法版本、实际参数及输入指纹。 + +衰减拟合任务完成后,任务的 `produced` 列表包含稳定的 `plotium.analysis` 资源。将其 ID 传给 `plotium_analysis_results_inspect`,即可直接读取该项分析。任务状态 `succeeded` 表示计算与结果提交完成;科学收敛情况须另查 `converged`、`termination` 和 `notices`。外层 `converged` 与最低有限代价的尝试一致。耗尽迭代预算且未满足收敛条件,或因信赖域坍缩终止的尝试,仍为未收敛,其估计会保留供诊断并附警告。 + +## 科学结果原生建图 + +通过 `plotium_plan`、`plotium_execute` 调用以下可撤销操作。两者的 +`parameters` 都为 `{source: ResourceRef, name: string}`,省略顶层 `ids`、 +`targets`;先发现完整来源引用和 schema。 + +| 操作 | 来源与原生产物 | +| --- | --- | +| `plot.field.create` | 一个原生字段,包括单指数 `nmr.dosy_map` 或 ILT `nmr.ilt_map`;新建画布,固定绑定该字段及其原生编码。 | +| `analysis.diffusion.plot` | 一个仅含单组响应数据的扩散拟合分析;新建冻结表格及画布,包含 b–强度散点、已存拟合曲线、残差面板、D 标准误、R² 和有效点数。 | + +预检的 `preflight.scientific_plot.summary` 返回拟议的 `canvas`、`source`、 +`produced`、科学 `evidence`,执行后 `value` 返回同一摘要。建图不重新计算科学结果。 +过期或空 DOSY 结果,以及过期、未收敛、多组响应拟合,须先修正。 +无法估计的 D 不确定度明确标为不可用。字段准备最多 4,000,000 个元素、200 条序列, +支持 20,480 点光谱的默认 128 行 ILT;拟合图最多 20,000 行。 +图中的点、等高线顶点和热图单元与显式曲线行共享 2,000,000 的待执行预算; +等高线图按生成的顶点数计入该预算,热图按单元数计入。 +一次 Undo 移除新资源,Redo 恢复相同身份及数据。切换数据集显示模式不改变字段图来源。 +冻结拟合表格保留来源表格血缘;自动化运行记录保留所选分析、行选择、提取证据和扩散输入。 + +将 `value.canvas` 传给 `plotium_figure_diagnose`、`plotium_render_preview`, +并实际查看 PNG。图像有效并不代表科学结果有效: + +1. 从欢迎页调用 `plotium_get_state`,导入采集数据,检查处理状态,等待处理任务成功。 +2. 检查扩散单位、IncrementId 对应关系、缺失参数和实验依据;只有证据充分时才提交已确认输入。 +3. 提取前明确区域规则、边界、指标和重叠处理策略。等待提取完成,再按返回的响应 ColumnId 拟合。 +4. 检查准确的分析资源:有效性、`m²/s` 单位的 D、标准误、有效点数、R²、残差、拒绝行和来源,再生成原生图。独立计算并检查单指数或 ILT DOSY,核对接受/拒绝列、算法设置、输入指纹及与区域拟合的数值一致性;ILT 使用求解诊断,不使用单指数置信度。 +5. 为 DOSY 结果字段建图,检查资源身份与状态、几何诊断及两张 PNG 的坐标轴、曲线、等高线、残差和标签可读性,明确报告科学或图像问题。 diff --git a/docs/src/content/docs/zh-cn/reference/mcp/styling.md b/docs/src/content/docs/zh-cn/reference/mcp/styling.md new file mode 100644 index 00000000..98cf479d --- /dev/null +++ b/docs/src/content/docs/zh-cn/reference/mcp/styling.md @@ -0,0 +1,301 @@ +--- +title: MCP 样式修改 +description: 通过 MCP 修改显示属性、图例和主题。 +--- + +## 精确修改显示,不重建图对象 + +直接使用预检的 `creation.series_defaults[].target` 或执行的 `value.bindings[].target`, +或通过 `plotium_document_inspect` +发现完整目标。所属图对象与稳定 SeriesId 必须共同传递,同名曲线仍是不同目标。 +`plotium_properties_list` 列出允许的属性;`plotium_properties_inspect` 返回当前值、 +默认值、目标适用的单位选项和范围输入 schema。 + +先调用 `plotium_get_state`,取其 `project_context` 和当前 revision,再调用 +`plotium_plan`。将以下占位符和数值身份替换为实际发现结果: + +```json +{ + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 7, + "tool_id": "properties.set", + "targets": [{ + "resource": {"id":"CANVAS_UUID/OBJECT_ID","kind":"plotium.canvas.object", + "parent_id":"CANVAS_UUID","local_id":"OBJECT_ID"}, + "component": {"kind":"series","id":1} + }], + "parameters": {"key":"series.line.color","value":"#0072B2"} +} +``` + +检查预检后,仅以返回的 `plan_id` 调用 `plotium_execute`。 +只改变该曲线及其误差线的颜色,不改变线宽或来源列。轴和单图字号使用 +`ids:[PLOT_OBJECT_ID]`。 + +每次请求修改一个 key,可包含多个目标,原子提交并合为一次 Undo。已有但不适用 +的目标报告跳过;失效或伪造身份拒绝整次请求。非法颜色、非有限数值及非法范围 +在预检拒绝;执行重查 revision 和权限,失败执行也消费 plan,须重读并重新规划。 + +范围值明确区分: + +- `{"mode":"auto"}`:仅清除该轴手动范围。 +- `{"mode":"manual","min":0,"max":10,"unit":"mA"}`:在明确的兼容单位内设置 + 有限且递增的范围。`unit:null` 只用于坐标单位未知的图,不能凭显示修改引入单位。 +- 重置**全部**轴设置是另一个原生操作,不是 Auto 的副作用;`properties.reset` + 轴属性 reset 只清除指定 override;guide 原点/placement 按[精确放置单图图例](#精确放置单图图例)中的联动规则重置。 + +显示单位接受属性查询返回的兼容代码,例如 s→ms、mA→A。图对象仍保持 R4 坐标单位契约: +原始数据、手动范围存储、位移及误差幅度的含义不变;刻度及自动派生的单位文字改变, +人工轴标题保持原文。重绑、重排和删除首条曲线不重新定义坐标。隐藏轴或分类轴不能 +设置数值手动范围,但可清除已保留的范围。属性查询中的 `unit_code.codes` 返回该目标的兼容选项; +`axis_range.input_schema` 描述输入,`view` 和 `unit` 表示当前显示窗口。 + +符号大小以 pt **直径**表示,显式设置后独立于线宽。没有覆盖时,原生点图仍沿用 +现有基于 width 的半径,原线宽接口含义不变;reset 恢复原生符号/大小。 +显式空图例文字使该图例项不显示。线型仅适用于折线,散点目标会按规则跳过。 +符号适用于折线和散点,不适用于 stick、柱状、箱线和小提琴曲线;柱宽和描边宽度适用于柱状、箱线和小提琴曲线,描边颜色仅适用于柱状曲线。符号填充色和边框色作用于闭合符号,未设置时跟随 +曲线颜色,reset 恢复跟随。空心符号不填充并保留边框,未设置边框宽度时为 0.5 pt。`marker_every` 从第一个源数据点起每 n 个点画一个符号,折线仍经过每个点。颜色由图型语义决定时,单曲线改色、改符号填充色或边框色按不适用跳过。 + +单图刻度、轴标题和图例字号在未覆盖时继承文档设置,reset 只移除相应覆盖; +改单图字体不影响其他图。字体/标题测量沿用原生渲染,不重排页面,不改变面板及 +内容的位置、尺寸。GUI 在现有 Line、Axes、Legend & scales 中使用同一属性控制,单图单位、范围及 +字号位于 Advanced。 +已有文档级字号仍保持项目范围。 + +修改后读取新 revision,再为实际画布调用 `plotium_render_preview`,查看 PNG 并 +核对 `render_revision`;用 GUI Undo/Redo 检查同一原生对象。MCP 保存需单独的桌面授权;导出另需独立桌面授权。 + +## 查询并修改一条明确曲线 + +示例任务:“找到我的线图,读取线宽,预检改为 1.5 pt,再执行保存的计划。” +工具调用顺序如下: + +1. 用 `{}` 调用 `plotium_get_state`,取得 `project_context`、`revision`、项目概况、选择和连接权限。 +2. `plotium_resources_search` 接受 `expected_project_context`、`expected_revision` 和 `query`,例如 + `{"kinds":["plotium.canvas.object"],"name_contains":"Plot"}`。先将结果解析为 + 显式稳定 ID;所有匹配理由相同(例如无筛选搜索)时,`value.reason` 只给出一次, + 不再返回 `value.reasons`。`plotium_resources_inspect` 用 `ids` 和 `expected_revision` 读取描述。 +3. 用 `{}` 调用 `plotium_properties_list` 列出支持的属性 ID 和值类型。 + 使用 `plotium_properties_inspect` 查询曲线地址: + + ```json + {"ids":["CANVAS_UUID/OBJECT_ID"],"key":"series.line.stroke_width","expected_project_context":"PROJECT_CONTEXT","expected_revision":7} + ``` + + 返回的 `value.readings` 为每条适用曲线提供一行;各行 schema 或默认值相同时,改为在 + `value.schema` 和 `value.default_value` 中给出一次。复制所选曲线的完整 + `value.readings[0].target`,例如: + + ```json + { + "resource": { + "id":"CANVAS_UUID/OBJECT_ID", + "kind":"plotium.canvas.object", + "parent_id":"CANVAS_UUID", + "local_id":"OBJECT_ID" + }, + "component":{"kind":"series","id":0} + } + ``` + +4. 将该 target 原样传入 `plotium_plan`,仅修改这一条曲线: + + ```json + { + "tool_id":"properties.set", + "parameters":{"key":"series.line.stroke_width","value":1.5}, + "targets":[{ + "resource":{ + "id":"CANVAS_UUID/OBJECT_ID", + "kind":"plotium.canvas.object", + "parent_id":"CANVAS_UUID", + "local_id":"OBJECT_ID" + }, + "component":{"kind":"series","id":0} + }], + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision":7 + } + ``` + +5. 查看 `preflight` 后,仅以 `{"plan_id":"RETURNED_PLAN_ID"}` 调用 + `plotium_execute`。桌面立即显示修改;**Undo** 恢复原值,**Redo** 重新应用。 + 相同值报告为跳过;整批修改合并为一次撤销。 + +属性查询和属性编辑预检必须且只能提供一个非空的 `ids` 或 `targets` 数组。 +`ids` 将每个资源展开为该属性对应的所有组件;`targets` 只操作指定的 Series 组件。 +Series ID 仅在所属图对象内唯一,因此务必复制包含资源信息的完整 target。 +重复目标仅处理一次;组件不存在或资源身份被伪造时整次请求拒绝;曲线存在但属性 +不适用时报告为跳过。查询会返回当前值、默认值、范围及可用性;只查询一条曲线时, +也可将查询参数改为 `targets`。恢复默认值时,用同一 target 预检 `properties.reset`, +参数为 `{"key":"series.line.stroke_width"}`。组件寻址仅支持所列显示属性, +处理参数使用独立的 `processing.edit` 操作。`resource.rename` 仍须使用 `ids`。 + +## 一次计划设置多条曲线的样式 + +`properties.set` 每次只写一个值。要给每条曲线分别设置颜色和图例标签,请改为预检 +`properties.set_many`:每一项写入指定一个明确目标、一个受支持的 key 和一个值。 +省略顶层 `ids` 和 `targets`;曲线属性使用查询得到的完整 Series 目标,坐标轴标题、 +图例等对象级属性使用图对象的资源目标,不带 component。 + +```json +{ + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 7, + "tool_id": "properties.set_many", + "parameters": {"writes": [ + {"target": SERIES_0_TARGET, "key": "series.line.color", "value": "#0072B2"}, + {"target": SERIES_0_TARGET, "key": "series.label", "value": "Sample 1"}, + {"target": SERIES_1_TARGET, "key": "series.line.color", "value": "#D55E00"}, + {"target": SERIES_1_TARGET, "key": "series.label", "value": "Sample 2"}, + {"target": {"resource": PLOT_OBJECT_RESOURCE}, "key": "object.axes.x_label", "value": "Temperature (°C)"} + ]} +} +``` + +`plot.create` 执行后,可以直接复用它返回的完整稳定目标。例如,将解码后的创建 +`ToolResult` 存为 `created`,原状态存为 `state`,构造以下 `plotium_plan` 参数: + +```js +const request = { + expected_project_context: state.project_context, + expected_revision: created.after_revision, + tool_id: "properties.set_many", + parameters: { writes: [ + ...created.value.bindings.map((binding, index) => ({ + target: binding.target, + key: "series.label", + value: `Sample ${index + 1}` + })), + { target: created.value.creation.plot, + key: "object.axes.x_label", value: "Temperature (°C)" } + ] } +}; +``` + +复制整个 `target`,保留所属资源的 `kind`、`id`、`parent_id`、`local_id` 和存在时的 +组件身份。单独的 SeriesId、名称或数组下标不是目标选择器。总写入数保持在 200 以内。 +预检上述对象,审核后仅执行一次新 `plan_id`。`unsupported_operation` 表示操作不可用; +`unsupported_property` 在 `error.details.write_index`(从零开始)和 `key` 指出不支持 +的属性。查询 `plotium_properties_list`,修正整个批次后再预检。 + +一个批次包含 1–200 项写入,可使用 `plotium_properties_list` 返回的属性。只要有一项写入的目标不存在、属性不适用于该目标、值无效, +或同一目标的同一 key 写了两次,预检就拒绝整个批次,不提交任何修改。目标已是该值的 +写入会报告为跳过,其余写入照常生效。`plotium_execute` 把全部写入作为一个**撤销** +步骤提交;`value.writes` 列出被跳过的写入,含序号、key、结果和 `skip_reason`。 + +写属性的返回很短。`properties.set`、`properties.set_many` 和 `properties.reset` +的预检返回 `required_authority`、`estimated_changes`、`summary`(`compatible`、 +`skipped`、`failed`),`targets` 只列出不会写入的目标。执行结果加上 `summary` +(`succeeded`、`skipped`、`failed`,以及按 `skip_reason` 计数的 `by_reason`); +`targets` 和批次的 `value.writes` 只列没有成功的项。全部生效时两者都为空。 +`plotium_preview_plan` 仍按完整计划渲染。 + +## 用户手动设置的值 + +用户在 Plotium 中修改图形值(在属性面板中设置、在控件上滚动调整或拖动图例)时, +Plotium 会把它记为手动设置。`plotium_get_state` 在 `hand_edits` 中列出这些值, +`properties.inspect` 为每个这样的读数标注 `"hand_set": true`。 + +`properties.set`、`properties.set_many` 和 `properties.reset` 不会改动手动设置的值: +该目标在预检和结果中都报告为跳过,`skip_reason` 为 `"hand_set"`,其余目标照常生效。 +图例的位置选项和拖动后的位置算作同一个值。只有用户要求修改时,才在 `parameters` 中 +传入 `"override_hand_edits": true`;修改后的新值仍算作用户的设置。 + +不带该参数写入的值不会被记录,之后的主题或写入可能会替换它们。主题会保留手动设置的值, +见下一节。 + +## 精确放置单图图例 + +Guide 属性使用 `ids:[PLOT_OBJECT_ID]`,不接受 Series 组件。按完整画布/对象身份 +发现目标,不依赖唯一名称。每次用 `properties.set` 设置一个 key/value,检查计划后 +再执行返回的单次 plan ID: + +```json +{ + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 7, + "tool_id": "properties.set", + "ids": ["CANVAS_UUID/OBJECT_ID"], + "parameters": {"key":"object.guides.position","value":[0,1]} +} +``` + +`position` 接受恰好两个 [0,1] 内的有限数,或 `null`。坐标表示图例框左上角在 +坐标轴绘图区内可供整个图例框移动的空间中的比例,x 向右、y 向下: +`origin = plot_origin + [x,y] * max(plot_size - legend_size, 0)`。 +它不是屏幕像素、整页比例或数据坐标。[0,0] 为左上角;能够容纳时,[1,1] 使 +右下角对齐。输出尺寸、图例内容或布局改变时,由 renderer 重新换算。 + +原生属性及必要联动如下: + +- `visibility`:`auto`、`show`、`hide`。Auto 在至少两个原生条目时显示普通图例, + Show 允许单条目,Hide 隐藏 guide 而非数据。 +- `placement`:`auto`、`inside`、`outside_right`、`outside_bottom`、`custom`。 + Custom 保留已有原点,没有则从 [1,0] 开始,同时设置 Inside;其他模式清除自定义原点。 +- `position`:[x,y] 设置 Inside/custom。`null`、position reset、placement Auto + 和 placement reset 都清除原点及 placement override,与 GUI 双击一致。 + 读取 `null` 仅表示无自定义原点;实际模式由 placement 决定,也可能位于图外。 +- `layout`:`auto`、`vertical`、`horizontal`,保留原生布局规则。 +- `title`:文本;空白文本沿用原生规范化,清除标题 override。 + +visibility/layout/title 各自只重置自己的 override。位置修改及重置保留这些字段、 +字号、绑定、曲线样式和手动轴范围。同名同色等条目仍按原生规则合并,因此六条曲线 +不一定形成六个图例条目。已有四项属性保留 color scale 行为;二维位置仅适用于 +原生普通图例内容,不受 guide 显示开关限制;无内容时仍可读取/重置保留的原点, +但不能设置新坐标,也不独立移动 colorbar。 + +适用属性的查询 readings 增加 `guide_geometry`,包含 +`coordinate_space:"object_local_pt"`、`scale:1`、`plot_rect`、可空的 +`legend_rect`/`color_scale_rect`(x/y/width/height)、`entry_count`、可空的 +`available_travel_pt`、`effective_position`、`fits_plot`(两个尺寸容纳布尔值), +以及 `not_rendered_reason`(`hidden`、`no_entries`、`auto_single_entry` 或 null)。 +`measurement_basis:"renderer_layout_text_width_estimate"` 表明这是渲染使用的布局框, +文字宽度沿用原生估算,不是精确字形边界;这里不检测对象/父容器的可见性和裁切。 +实际位置按可移动距离解析,不钳制图外 +placement;零移动距离的轴返回零。guide 隐藏或自动省略时几何返回 null 并说明原因, +属性值仍保留配置的原点。 + +图例过大时不静默缩字:相应轴的可移动距离为零,`fits_plot` 为 false,实际位置 +可能不同于请求原点。尺寸能容纳不代表没有裁切或遮挡曲线,仍须查看原生 PNG 及 +最终导出。此信息仅观察 guide 布局,不是全图诊断。 + +Guide 写入在提交前验证全部显式目标;存在但不适用的目标以 `invalid_parameters` +拒绝整批,不沿用旧属性的跳过策略;旧属性行为不变。重复 ID 处理一次。每次一个属性、 +最多 200 个 ID、一次 Undo/Redo;标题最多 16,384 UTF-8 字节,结构化响应最多 +256 KiB(超限为 `response_too_large`),继续共享 32 个待执行计划上限。 +形状错误、非有限或越界值返回 `invalid_parameters`。查询仍报告不适用目标。 +只读连接可以查询及预检,execute 需要可撤销修改权限;context/revision 变化、撤权、 +busy 和过期计划保留原有单次生命周期。查询不追加项目审计记录,也不改变 dirty、 +edit generation、automation revision 或 Undo 历史。能力发现见 `plotium_capabilities_get {"section":"guide_contract"}`。 + +## 为画布套用主题或已保存的风格 + +`figure.apply_theme` 用 Plotium 的内置主题(例如 `nature`)或在 Plotium 中保存的画布 +风格整体重设画布样式。`theme_id` 可以填 +`plotium_capabilities_get {"section":"operation_constraints","key":"figure.apply_theme"}` +返回的 `builtin_themes` 中的内置主题 id,也可以填 +已保存风格的名称。已保存的风格不在固定的能力说明里:未知的 `theme_id` 会在预检时以 +`invalid_parameters` 失败,`error.details.themes` 列出当前可用的全部内置主题和已保存 +风格。预检时把画布 id 放在顶层 `ids`: + +```json +{ + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 7, + "ids": ["CANVAS_ID"], + "tool_id": "figure.apply_theme", + "parameters": {"theme_id": "nature"} +} +``` + +预检只需只读权限,执行需要 **读取并修改**。未知的 `theme_id`、Series `targets`, +以及不含任何画布的 `ids` 会在预检时被拒绝;其余不是画布的 id 会被跳过。已保存的风格 +会在执行时重新读取。执行时把每张画布的背景、文字和形状颜色,以及主题规定的每条曲线 +颜色、符号填充与描边、符号大小和线宽作为一个**撤销**步骤一起修改。手动设置的曲线和符号颜色在 +重新套用主题时会保留;重置曲线颜色后,曲线重新使用主题颜色。文档的样式默认值也会被替换:图的文字字号、坐标轴线和 +刻度是整个文档共用的,所以其他画布上的图也会随之改变;新建文字、面板字母和形状的 +默认样式同样改用主题的设置。用户手动设置的值(包括图形排版)会保留,`diagnostics` 会附一条 +说明保留了几处。按期刊栏宽设计的主题(目前为 `nature`)不会改变画布尺寸; +画布宽度不符合任一栏宽预设时,结果的 `diagnostics` 会为该画布附一条提示,列出预设宽度 +(89 / 136 / 183 mm)。 diff --git a/docs/src/content/docs/zh-cn/reference/mcp/tables.md b/docs/src/content/docs/zh-cn/reference/mcp/tables.md new file mode 100644 index 00000000..0f8b8b19 --- /dev/null +++ b/docs/src/content/docs/zh-cn/reference/mcp/tables.md @@ -0,0 +1,327 @@ +--- +title: MCP 数据导入与表格 +description: 通过 MCP 导入数据、读取表格、派生和修改表格。 +--- + +## 从欢迎页导入原生数据 + +只打开 Plotium 即可调用 `plotium_get_state {}`;后台工作、恢复或保存阻塞项目访问时也可查询。 +响应包含 `availability` 中的 `project_read`、`project_modify`、 +`native_import`,各项包含 `available` 和可为空的 `{code,message}` 原因。 +可直接从欢迎页导入原生数据或表格。空闲时 `project` 返回数据集和画布数量,即使尚未导入数据; +忙碌时 `project` 与 `selection` 均为 `null`。规划操作前请检查 `availability`。 +查询不会新增文档审计记录或未保存修改。 +所有状态下均可通过 `plotium_capabilities_get {}` 发现连接能力。 + +启用 **读取并修改**,从状态复制 `project_context` 和 `revision`,再调用 `plotium_plan`: + +```json +{ + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 0, + "tool_id": "data.import", + "parameters": {"paths": ["C:/Data/experiment.jdf"]} +} +``` + +请使用实际绝对路径。原生导入接受桌面加载器支持的明确数据文件及原子采集目录, +例如 Bruker 采集或处理数据目录;可读取采集必需的伴随文件,不递归批量发现或扫描相邻实验。 +此操作不支持 ZIP 归档、项目文件或新格式。可选 `sampling_declaration` 沿用核心导入约定。 +完整共享 schema 可用 +`plotium_capabilities_get {"section":"operation_constraints","key":"data.import"}` 读取。 + +预检在后台完成,`import.items[].metadata` 返回各输入的格式、维度、警告、失败原因和拟创建的 +数据集/画布 ID。预检不创建资源或修改文档。调用 `plotium_execute {"plan_id":"PLAN_ID"}` +提交冻结数据;预检后修改或删除源文件不影响执行。成功后向当前项目添加原生数据集和默认画布, +保留项目上下文和当前选择。 + +结果为 `succeeded`、`partial` 或 `failed`;所有成功项一次原子提交、一次撤销。 +撤销首批内容后移除导入的内容;重做恢复相同资源 ID。全部输入失败或导入取消时, +不新增资源、撤销记录或未保存修改。 +成功导入仍保留科学溯源记录。 +提交时重新检查权限、上下文和版本;即使执行被拒绝,计划也已消耗,不能重复使用。 +遇到 `project_changed` 后重新查询状态并预检。 + +每批最多 16 个输入、1 个预检在途、最多 4 个保留的 prepared import(与表格导入共享)。 +所有保留计划及在途预检的原生冻结负载保守预留合计最多 512 MiB;超限返回 +`import_budget_exceeded`。超过 16 个路径时调用失败,报错写明收到的数量;其余文件请分批 +导入。预检响应最多 256 KiB。科学处理与 DOSY 使用独立的共享科学操作。 +CSV、TSV 和 XLSX 文件是表格,用 `mode: "table_data_only"` 导入;原生导入收到它们会报错并给出这一提示。 + +## 导入 CSV/TSV/XLSX 数据,不创建图 + +让 agent 导入明确指定的 UTF-8 CSV/TSV 或 XLSX 工作簿,检查列信息,再分页读完整张表。先调用 +`plotium_get_state {}`,然后调用 `plotium_plan`: + +```json +{ + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 7, + "tool_id": "data.import", + "parameters": { + "mode": "table_data_only", + "paths": ["/absolute/path/measurement.csv"], + "header": "present" + } +} +``` + +导入不提供 `ids` 或 `targets`。`header` 可为默认的 `auto`、`present` 或 `absent`; +自动判断有歧义则失败。`.csv` 与 `.tsv` 分别选择逗号和制表符;可显式用 +`format: "csv" | "tsv"` 指定。`.xlsx` 文件(或 `format: "xlsx"`)把每个有内容的可见 +工作表各导入成一张表,表名取工作表名,工作簿只有一张表时取文件名,与桌面端导入一致。 +`sheets: ["Figure 3", …]` 只导入列出的工作表;名字不存在时该文件失败,并列出可见工作表。 +每个工作表单独准备:没有表格或超出限制的工作表作为单独一项失败,其余照常导入。一个文件 +最多读取 8,000,000 个工作表单元格,按各工作表的已用范围计算。`header`、`schema` 和 +`schema_path` 只用于 CSV/TSV。含 XLSX 的批次摘要超过 128 KiB 时预检失败,并按文件列出 +工作表,可每次导入一个工作簿并减少 `sheets` 中的工作表。只读所列普通文件,不扫描目录、不自动寻找邻接 +sidecar、不回写源文件、不创建图或 X/Y 绑定。 + +预检在后台完成准备后才返回。`import.items` 逐文件(XLSX 逐工作表,带 `sheet`)报告 `prepared` 或 `failed`, +包含拟建原生 ID、元数据和诊断,此时项目尚未新增数据集。确认结果后调用 +`plotium_execute {"plan_id":"RETURNED_PLAN_ID"}`。执行使用预检冻结的字节和 typed +snapshot,不重新读取可能已变化的文件;提交前重验 revision 和权限,将全部已准备 +成功项作为一次原子修改提交。`value.status` 为 `succeeded`、`partial` 或 `failed`, +须逐项查看结果和已创建 ID;失败文件不留下半成品。一次 Undo 移除本批成功项, +Redo 恢复同一 DatasetId、FieldId、ColumnId 和 RowId。既有 GUI/CLI 导入行为不变。 + +元数据包含 DatasetId、TableId、表 RevisionId、字段身份、稳定 ColumnId、逻辑 +类型、nullable、单位、总行数及诊断。字段和列是不同的原生身份。缺失值保持 null, +混合数值/文本列保留文本;超出有符号 64 位范围的整数字样保留文本,不舍入。 +不根据数值或表头拼写猜单位。`type_source` 区分 `file/user/inferred/unknown`, +`unit_source` 区分 `file/user/unknown`。 + +可选 `schema` 为有序原生 TableSchema,包含 typed ColumnSchema ID、逻辑类型、 +nullable 和可选 UnitSpec;也可用 `schema_path` 明确指定 v1 PlotiumDelimitedSchema +JSON 文件。声明必须与表头及顺序完全对应,非法值明确失败,不回退自动推断。 +支持声明 null、boolean、int64、float64、utf8、date 和 timestamp;本导入不接受 +唯一性/业务键约束及不确定度关系,也不从 `_sigma` 列名赋予科研误差含义。每次 +导入分配新的原生 ID,文件/用户 schema 中的 ID 仅描述来源,不寻址已有项目目标。 + +每批最多 16 个文件、每文件 16 MiB、指定输入合计 64 MiB,每文件最多 256 列、 +1000000 行;明确指定的元数据文件最多 256 KiB。已准备项摘要上限 128 KiB, +完整预检响应上限 256 KiB,超出时缩小批次或 schema。每连接最多保留 4 个已准备导入 +和总计 32 个计划,同时只运行一个导入预检。这些是输入预算,不是进程总内存 +上限。取消、切换项目、撤销权限或期间发生编辑,都会阻止待完成预检成为可执行 +计划。排队或运行不代表完成;失败或过期提交也会消费计划,须重新读状态并预检, +不能盲目重放创建请求。 + +## 有界分页读完整张表 + +从导入元数据或数据集资源描述符复制 DatasetId 和表 RevisionId。将它们与 +`expected_revision` 传给 `plotium_table_columns` 查看元数据,再调用 +`plotium_table_read_rows`: + +```json +{ + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 8, + "dataset_id": "DATASET_UUID", + "table_revision": "TABLE_REVISION_UUID", + "offset": 0, + "limit": 200 +} +``` + +用返回的 ID 替换占位符。可选 `column_ids` 按稳定 ColumnId 投影并保持所给顺序; +省略或空数组表示 schema 顺序的全部列。行按不可变原生 snapshot 顺序读取。 +结果包含 `column_ids`、`rows: [{row_id, values}]`、`total_rows`、`requested_rows`、 +`returned_rows`、`next_offset` 和 `end`。每个值以 `kind` 标明类型,null 无 value。 +Int64、time、timestamp 和 duration 用十进制字符串避免 JSON 舍入;date 为 Unix +纪元以来天数,后三种时间类型为纳秒。非有限浮点值明确返回 `NaN/+Inf/-Inf` +字符串,不转为 null。 + +保持数据集、文档 revision、表 revision 和投影不变,沿 `next_offset` 连续读取, +直到 `end: true` 且 `next_offset: null`。默认每页 200 行,最多 1000 行和 20000 个 +投影单元格;完整结构化 ToolResult 上限 256 KiB。字节预算可缩短整页,但不截断 +单元格;以实际数量和继续位置为准。单行超预算返回 `response_too_large`。 +offset 等于总量时返回空的结束页,大于总量时失败。非法 limit、重复/不存在列及 +超预算请求直接拒绝,不静默裁剪参数。 + +每次读取都检查两个 revision。人工编辑、Undo/Redo 会使旧文档 revision 失效, +须重新读状态并重启分页,不能混读。无效 ID 不回退当前选择。只读连接可查询 +已有表格,但不可导入。预算见 `limits` 能力分区,导入权限条件见索引。 + +## 派生表格而不修改源数据 + +可以让 Agent:“计算 `signal_x2 = y_left * 2`,排除 `x_left` 等于零的行,按 X +降序排列,再把结果绑定到这条已有曲线。”处理操作只创建一张原生表格,不创建图。 +重绑使用[现有曲线绑定操作](/zh-cn/reference/mcp/plots/#精确重绑已有曲线不影响另一张图)。 + +1. 读取 `plotium_get_state`,再用 DatasetId 和表 revision 调用 + `plotium_table_columns`。复制实际 ColumnId、`table_id`、`table_revision` + 和 `snapshot_fingerprint`;名称和 `source_column_id` 不能作为身份。 +2. 用 `plotium_capabilities_get {"section":"operation_constraints","key":"data.transform"}` + 发现原生计划格式。`ids` 恰好指定一个 DatasetId,模式为 `table_data_only`。 + 叶节点必须固定该数据集的当前快照;为 `operation_id` 和每个计算列的 `id` + 提供新的 UUID。 +3. 调用 `plotium_plan`,检查 `transform.status: "prepared"` 及其 `output`,再将 + 返回的 `plan_id` 交给 `plotium_execute`。准备完成不代表已插入数据。成功执行返回 + `value.status: "succeeded"`、`value.output` 和一个 `produced` 数据集;提交保留 + 准备阶段返回的输出身份。 +4. 用 `plotium_table_read_rows` 读取完整结果,再将实际 DatasetId、FieldId、TableId、 + revision 和 X/Y ColumnId 绑定到已有曲线,用 `plotium_render_preview` 检查原生图像。若要新建图, + 则将相同输出身份交给 [`plot.create`](/zh-cn/reference/mcp/plots/#从已导入表格创建原生单图),再预览返回的画布。 + 数据处理与建图仍是可分别撤销的两个操作。 + +以下完整原生计划追加一个 Float64 列。将占位符替换为发现的身份或新 UUID。 +示例以 `unit: null` 明确表示未知单位;若 `y_left` 有明确单位,此处乘以无量纲常数, +应将源列的**整个 UnitSpec**复制到输出列。 + +```json +{ + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 7, + "tool_id": "data.transform", + "ids": ["DATASET_UUID"], + "parameters": { + "mode": "table_data_only", + "name": "Scaled signal", + "memory_limit_bytes": 16777216, + "plan": { + "version": 1, + "operation_id": "NEW_OPERATION_UUID", + "root": { + "op": "computed_column", + "input": { + "op": "snapshot_read", + "table": "TABLE_UUID", + "revision": "TABLE_REVISION_UUID", + "fingerprint": "SNAPSHOT_FINGERPRINT" + }, + "column": { + "id": "NEW_COLUMN_UUID", "name": "signal_x2", + "logical_type": {"kind": "float64"}, "nullable": true, "unit": null + }, + "expression": { + "expr": "call", "function": "multiply.v1", + "args": [ + {"expr": "cast", "input": {"expr": "column", "column": "Y_COLUMN_UUID"}, + "target": {"kind": "float64"}, "failure": "error"}, + {"expr": "literal", "value": {"type": "float64", + "value": {"kind": "finite", "value": 2.0}}} + ] + } + } + } + } +} +``` + +支持的关系节点只有 `snapshot_read`、`project`(有序 ColumnId)、`filter`(Boolean +谓词)、`stable_sort`(按优先级排列的键,含 `column`、 +`direction: ascending|descending` 和 `nulls: first|last`),以及 `computed_column` +(明确列 schema 和表达式)。将已有节点放入后一个节点的 `input` 即可组合。完成上述 +任务时,先用 `not.v1(eq.v1(column(X_COLUMN_UUID), literal(int64, 0)))` 包装计算节点 +进行筛选,再按 X 降序,最后投影 X、Y 和新 ColumnId;精确 JSON 形式由 schema 提供。 + +表达式使用 `column`、`literal`、`cast` 或带版本的 `call`。可用函数是 `is_null.v1`、 +`is_finite.v1`、`eq.v1`、`not.v1`、`and.v1`、`or.v1`、`add.v1`、`subtract.v1`、 +`multiply.v1` 和 `divide.v1`,不接受任意函数、SQL 或脚本。算术要求 Float64 操作数, +类型转换必须明确指定;`failure: error` 拒绝整次处理,`null` 将转换失败值置为缺失。 +原生 Int64 转 Float64 可能损失精度。计算列输出支持 Boolean、Int64、Float64 和 Utf8。 +单位由调用方明确声明,算术不会推导单位或自动换算。 + +筛选只保留 true,false 和 null 都被排除。排序保留 RowId,同键按 RowId 决胜,null +位置不受升降序影响;非 null 浮点值按 `-Inf < finite < +Inf < NaN` 排列。投影列保留 +原有 ID、类型和单位,计算列保留配方中的新 ID。源表数值、表格默认绑定、画布和已有 +人工样式不变。 + +输出元数据包含固定的原生配方、backend、输入 revision/fingerprint、列 lineage +和行映射契约。稍后可用 `plotium_table_columns` 的 `include_provenance: true` +读取;在 `plotium_table_read_rows` 中加同一参数,则每行返回 `sources`:已记录的源 +DatasetId、TableId、revision、fingerprint、原始 RowId 和从零开始的 `input_position`。 +它解码本页对应的原生存储映射,不跟随源表最新 revision。导入行没有派生来源;其他 +关系计划的来源形态在请求行来源分页时明确拒绝,不带该参数的普通读取保持既有行为。 + +准备工作不阻塞桌面线程。规划和执行均需 **Read and modify**;后台准备完成及实际 +提交前都会重新检查权限、文档 revision 和源快照。执行提交一次即消耗 plan,即使失败 +也不能重放。取消、停止连接、切换项目或输入过期会丢弃未提交结果;已经开始的原子 +提交使用普通 Undo 撤销。一次成功处理对应一次 Undo,Redo 恢复相同表和列身份。 + +每个连接同时最多一个处理预检。参数最多 64 KiB、64 个关系/表达式节点、深度 16 +(JSON 嵌套最多 48 层)。内存预算默认和上限均为 512 MiB,含义是 reference 执行器 +**求值后检查的物化结果估算**,不是进程峰值内存限制。最多保留四个待提交结果,共享 +512 MiB 预留预算,每项按请求声明的预算计费。完整响应最多 256 KiB;准备结果摘要最多 128 KiB,为请求和计划外层预留空间。限制也可用 +`plotium_capabilities_get {"section":"limits","key":"table_transform"}` 发现。预算失败返回 +`transform_budget_exceeded`,取消返回 `request_cancelled`,均不留下派生表或成功执行 +结果。修正输入或预算后重新规划。后续更新使用下述独立的单元格补丁及显式刷新操作。 + +## 补丁修改单元格,再显式刷新派生表 + +`table.patch` 的顶层 `ids` 恰好指定一个 DatasetId,不传 `targets`;参数须包含 +当前表 revision。RowId、ColumnId 必须复制自表格读取结果,分页 offset、行号及 +列名不能代替身份。例如: + +```json +{ + "tool_id": "table.patch", + "expected_project_context": "PROJECT_CONTEXT", + "expected_revision": 12, + "ids": ["DATASET_UUID"], + "parameters": { + "table_revision": "TABLE_REVISION_UUID", + "edits": [{ + "row_id": "RETURNED_ROW_UUID", + "column_id": "RETURNED_COLUMN_UUID", + "value": {"kind": "float64", "value": 2.5} + }] + } +} +``` + +值沿用读取结果的 `kind`/`value` 格式:Int64 及纳秒时间类型用十进制字符串; +Float64 用 JSON 数字或 `"NaN"`/`"+Inf"`/`"-Inf"`;缺失值为 +`{"kind":"null"}`。类型及 nullable 必须严格匹配,不能用 Float64 补丁隐式扩宽 +Int64 列;分类值只能指定已有 level 的索引。此操作不修改扩展类型或实时计算的区域表。 + +每批 1–1000 个不同单元格,参数最多 64 KiB。缺行、缺列、重复单元格、类型错误或 +旧 revision 均拒绝整批,不留下部分修改。不增删行、改 schema、重导入或回写源 +CSV/TSV。准备返回 `update:{status:"prepared",output,before_table_revision,changed}`, +执行前不修改项目。相同值返回 `changed:false`,不推进文档 revision 或增加 Undo。 +补丁或刷新提交前,其数值必须仍满足已有曲线绑定的要求。例如,用作 Y 误差的列 +不能包含负幅度。拒绝更新时,表格、图和 Undo 历史均保持不变。 + +表格元数据、行页和 Series 来源返回 +`freshness:{status,refreshable,reason,sources,mcp_refreshable,mcp_refresh_reason}`。 +`refreshable` 表示原生刷新能力;`mcp_refreshable` 另检查连接支持的配方范围, +不表示当前权限模式。数据集资源元数据分别暴露 `table_refreshable`、 +`table_mcp_refreshable` 和 `table_mcp_refresh_reason`,以及 `table_freshness` 及其原因。`source` 为没有派生配方的源表,`current` +为已记录输入 revision 仍匹配,`stale` 为直接或上游输入已变化,`unavailable` +为来源或受支持配方缺失。数据浏览器将受影响的关系派生表标为 **Out of date**, +数据表窗口说明原因。旧结果仍可读取、绘制,同时明确带有失效状态。修改表会清除 +该表的已存曲线拟合分析,Undo 恢复;失效派生表中的分析只描述旧结果,不代表当前源数据。 + +只有明确请求才刷新:以 `ids:["DERIVED_DATASET_UUID"]` 和 +`parameters:{"table_revision":"CURRENT_DERIVED_REVISION"}` 规划 `table.refresh`。 +仅支持已保存的单源 `snapshot_read`/`project`/`filter`/`stable_sort`/ +`computed_column` 配方,表达式和复杂度限制与 data-only 处理相同;按当前源快照, +沿既有 reference 执行器和 lineage 路径刷新。其他原生配方(包括 Pivot)会被 MCP +刷新明确拒绝;原生 GUI/core 的刷新能力不变。采用候选前验证 TableId、列 schema +(含 ColumnId、类型和单位)保留,每个输出 RowId 必须属于当前输入;不匹配时 +整次拒绝,不修改表、图绑定或 Undo。先刷新失效上游;缺来源或配方时说明原因,不自动重算其他数据。派生表已有人工 +单元格修改按稳定 RowId rebase,身份缺失或歧义时拒绝整次刷新,不回退到行位置; +连续刷新仍保留这些修改。`include_provenance:true` 返回当前 `operation`,以及 +沿编辑/rebase 历史解析的有效 `refresh_recipe`。 + +可选 `memory_limit_bytes` 依次采用显式值、配方已保存预算、512 MiB 默认值,范围 +1–536870912;仍表示物化结果估算,不是峰值内存。补丁/处理/刷新共享一个后台 +预检、四个待执行候选及 512 MiB 预留上限,每个补丁预留 64 KiB。准备摘要最多 +128 KiB,完整响应最多 256 KiB;schema 和限制见 `operation_constraints` 与 +`limits`(`table_update`)能力分区。 + +两项操作的预检和执行都要求 **Read and modify**;候选采用前重验权限、文档/表 +revision 及当前输入。取消、切换项目、停止连接或输入过期丢弃未提交结果,失败执行 +也消费 plan。响应丢失后先检查实际状态,不重放已提交操作。 + +补丁与刷新各自对应一次 Undo/Redo。DatasetId、TableId、ColumnId、已有 RowId +及原生图/Series 身份保留,筛选可改变结果包含哪些已有行。只更新 revision 和来源 +映射,不改人工颜色、轴范围或面板 frame。失效状态由保存的 provenance 与当前 +revision 计算,因此 Undo/Redo 同时恢复数值及对应失效状态。原生表格编辑与刷新 +使用同一个 typed revision 提交服务。 + +## 删除数据集 + +`dataset.delete` 的参数为 `{}`,在 `ids` 中给出 DatasetId。如果仍有图、投影、 +派生数据集或分析报告使用该数据集,预检会拒绝,并指出使用它的页面与面板、 +数据集或报告;请先删除这些内容。派生数据集需单独一次请求先删除,再删除其来源。一次撤销即可按原 ID 和原位置恢复全部被删除的数据集。 diff --git a/docs/src/content/docs/zh-cn/reference/preferences.md b/docs/src/content/docs/zh-cn/reference/preferences.md index 69e15bdb..1c70e91d 100644 --- a/docs/src/content/docs/zh-cn/reference/preferences.md +++ b/docs/src/content/docs/zh-cn/reference/preferences.md @@ -76,10 +76,5 @@ AI 连接启用状态和权限会持久保存,详见下文。 | **Add to Claude Desktop…** | 在 macOS 和 Windows 上打开扩展安装包,请在 Claude Desktop 中确认安装 | | **Manual configuration and diagnostics** | 提供其他客户端所需的配置和排查连接问题的信息 | -权限对所有已连接客户端和项目统一生效,重启 Plotium 后仍保留。关闭设置或切换 -项目不会停止访问。关闭 MCP 会立即停止访问并丢弃待执行修改,同时保留客户端配置; -退出 Plotium 也会停止访问。 - -**Configured** 表示客户端配置已完成;最近的客户端活动则表明客户端是否实际访问 -过 Plotium。页面也会显示最近操作和错误。连接步骤、示例请求、机器人状态和排障 -方法见 [AI 客户端连接](/zh-cn/guides/automation/#本机-agent-连接mcp)。 +这些设置在重启后保留。连接步骤见[连接 AI 客户端](/zh-cn/ai/connect/);各权限允许 +什么、机器人图标和排障见[权限、审阅与撤销](/zh-cn/ai/control-and-review/)。 diff --git a/docs/src/content/docs/zh-cn/reference/settings-ids.md b/docs/src/content/docs/zh-cn/reference/settings-ids.md new file mode 100644 index 00000000..918ea6dd --- /dev/null +++ b/docs/src/content/docs/zh-cn/reference/settings-ids.md @@ -0,0 +1,204 @@ +--- +title: 设置 ID +description: 自动化窗口、工作流、命令行和 AI 客户端使用的稳定设置标识。 +--- + +对象检查器、处理步骤和偏好设置里的每项设置都有一个稳定 ID,例如 +`series.contour.count`。只有在面板之外指定设置时才需要它:自动化窗口的属性工具、 +工作流文件、[命令行](/zh-cn/reference/cli/),或你自己编写的 +[MCP 客户端](/zh-cn/reference/mcp/)。AI 客户端会自己查找这些 ID。 + +完整列表及取值类型和范围可用 `plotium-cli tool properties` 或 MCP 工具 +`plotium_properties_list` 获取。下面各表列出最常用的设置。命令面板也能按 ID 匹配设置。 + +## 读取和写入设置 + +自动化窗口和工作流通过三个工具访问设置: + +| 工具 | 作用 | +| --- | --- | +| **Inspect a property** | 读取当前值、默认值,以及该参数允许的范围 | +| **Set a property** | 写入一个值 | +| **Reset a property** | 按当前数据重新推导该值,与面板上的重置按钮一致 | + +在工具参数中用 ID 指定设置:**Set a property** 用 +`{"key": "series.contour.count", "value": 12}`,另外两个用 +`{"key": "series.contour.count"}`。该指定哪个资源由设置本身决定:等高线和线条 +设置在图对象上,切趾设置在数据集上,图形排印在文档上(列为 +**Plotium document**),页面尺寸在画布上,偏好设置在应用上(列为 +**Plotium application**)。 + +## 图形 + +这些 ID 对应[图形](/zh-cn/guides/plots-and-charts/)各指南中介绍的图和图形设置。图设置 +(`object.*`)作用于一张图,序列设置(`series.*`)作用于一条曲线,排印设置 +(`document.figure.typography.*`)作用于文档中的所有图。 + +### 坐标轴 + +| 设置 | ID | +| --- | --- | +| X / Y 轴标题 | `object.axes.x_label`、`object.axes.y_label` | +| X / Y 范围 | `object.axes.x_range`、`object.axes.y_range` | +| X / Y 显示单位 | `object.axes.x_display_unit`、`object.axes.y_display_unit` | +| 是否显示 X / Y 刻度标签 | `object.axes.x_show_tick_labels`、`object.axes.y_show_tick_labels` | +| 是否显示 X / Y 轴标题 | `object.axes.x_show_label`、`object.axes.y_show_label` | +| X / Y 刻度类型 | `object.axes.x_scale`、`object.axes.y_scale` | +| 等比例坐标(1:1) | `object.axes.equal_scale` | +| 边框 | `object.axes.frame` | +| X / Y 主刻度间隔 | `object.axes.x_major_step`、`object.axes.y_major_step` | +| X / Y 千位分隔符 | `object.axes.x_thousands_separator`、`object.axes.y_thousands_separator` | +| X / Y 断口 | `object.axes.x_break`、`object.axes.y_break` | +| X / Y 下段占比 | `object.axes.x_break_lower_fraction`、`object.axes.y_break_lower_fraction` | +| 右 y 轴标题、范围、显示单位 | `object.axes.y2_label`、`object.axes.y2_range`、`object.axes.y2_display_unit` | +| 是否显示右 y 轴刻度标签 / 标题 | `object.axes.y2_show_tick_labels`、`object.axes.y2_show_label` | +| 右 y 轴刻度类型、主刻度间隔 | `object.axes.y2_scale`、`object.axes.y2_major_step` | +| 曲线放在右 y 轴 | `series.y_axis` | + +断口写作 `{"mode":"manual","min":…,"max":…,"unit":…}`,或 `{"mode":"auto"}` 表示 +不断开。图形诊断会报告被断口隐藏的数据点。 + +### 图例、线条与符号 + +| 设置 | ID | +| --- | --- | +| 图例显示、位置、排列、标题 | `object.guides.visibility`、`object.guides.position`、`object.guides.layout`、`object.guides.title` | +| 图例摆放位置 | `object.guides.placement` | +| 图例文字 | `series.label` | +| 曲线是否可见 | `series.visible` | +| 线色、线宽、线型 | `series.line.color`、`series.line.stroke_width`、`series.line.style` | +| 符号及符号大小 | `series.line.marker`、`series.line.marker_size` | +| 符号填充色、边框色、边框宽度 | `series.line.marker_fill`、`series.line.marker_edge_color`、`series.line.marker_edge_width` | +| 空心符号、每 N 个点画一个符号 | `series.line.marker_hollow`、`series.line.marker_every` | +| 柱宽、柱边框色、柱边框宽度 | `series.bar.width`、`series.bar.edge_color`、`series.bar.edge_width` | +| 误差棒含义、重复次数 | `series.error_bars`(`unspecified`、`sd`、`sem`、`ci95`)、`series.replicates` | + +### 排印 + +| 设置 | ID | +| --- | --- | +| 字体、字重 | `document.figure.typography.typeface`、`document.figure.typography.font_weight` | +| 刻度标签、轴标题、图标题和图例字号 | `document.figure.typography.tick_pt`、`document.figure.typography.label_pt`、`document.figure.typography.title_pt`、`document.figure.typography.legend_pt` | +| 图例文字颜色 | `document.figure.typography.legend_color` | +| 坐标轴线宽、刻度长度、刻度方向 | `document.figure.typography.axis_line_pt`、`document.figure.typography.tick_length_pt`、`document.figure.typography.tick_direction` | +| 子刻度 | `document.figure.typography.minor_ticks` | +| 单张图的字号 | `object.figure.typography.tick_pt`、`object.figure.typography.label_pt`、`object.figure.typography.legend_pt` | + +### 图表与色图 + +| 设置 | ID | +| --- | --- | +| 图表类型 | `object.chart.type_id` | +| 自动分箱、箱数 | `object.chart.bins.auto`、`object.chart.bins.count` | +| 堆叠柱 | `object.chart.stacked` | +| 色图 | `object.chart.colormap` | +| 用途、结论 | `object.intent.purpose`、`object.intent.claim` | +| 热图颜色范围、范围中心 | `series.heatmap.range_span`、`series.heatmap.range_center` | + +### 等高线层级 + +| 对象检查器中的设置 | id | 取值 | +| --- | --- | --- | +| **Lowest level** | `series.contour.base.magnitude` | 大于 0 的数;究竟以什么计量取决于 **Anchor** | +| **Anchor** | `series.contour.base.policy` | `absolute`、`noise_floor`、`background_scale`、`fraction_of_range` | +| **Levels** | `series.contour.count` | 1 到 256 | +| **Level ratio** | `series.contour.ratio` | 大于 1,最大 10 | +| **Negative contours** | `series.contour.negative.enabled` | `true` 或 `false` | +| **Positive colour** | `series.contour.positive_color` | `"#rrggbb"` | +| **Negative colour** | `series.contour.negative_color` | `"#rrggbb"` | +| **Line width** | `series.contour.line_width` | 0.05 到 10 pt;默认 0.5 | + +各等高线设置的含义以及每种锚定方式需要什么数据,见[等高线层级](/zh-cn/guides/contour-levels/)。 + +## 处理设置 + +| 切趾步骤上的设置 | id | 取值 | +| --- | --- | --- | +| **Window** | `dataset.processing.apodization.kind` | `none`、`cosine_bell`、`exponential`、`gaussian` | +| **LB** | `dataset.processing.apodization.lb_hz` | −10000 到 10000 | +| **GB** | `dataset.processing.apodization.gb_hz` | 大于 0,最大 10000 | + +各行的说明见[数据处理](/zh-cn/guides/processing/)。 + +## 应用偏好 + +偏好设置在 **Plotium application** 上使用同样三个工具。对于 +`settings.appearance.accent.color`,**Set a property** 接受 `"#rrggbb"`,把画布 +强调色固定为该颜色;**Reset a property** 清除它,强调色重新跟随主题。 + +## 批处理结果 + +### 勾选的目标会展开成什么 + +被勾选的资源往往并不是真正被写入的对象——展开成什么由参数决定:图对象展开 +为它的各条序列,数据集展开为它的各个处理步骤,文档就是它自己。预检和结果列 +表按展开后的部件逐行列出,因此一个含三条序列的图会给出三行,并指明是哪个图 +对象里的哪条序列。 + +参数够不到的部件会标为 **Skipped** 并给出原因,其余部件照常应用:等高线下方 +的热图、参数属于切趾时列表里的零填充步骤,或对一个窗函数为 *Exponential* 的 +步骤索取 **GB**,都是这种情况。完全没有可寻址内容的资源(文本框、没有管线的 +数据集)同样被跳过。 + +结果行和运行记录会在资源旁写出部件: + +```json +{ + "resource": { "id": "…", "kind": "plotium.dataset" }, + "component": { "kind": "processing_step", "id": 3 } +} +``` + +序列部件写作 `{"kind": "series", "id": 2}`。两种 id 都只在它所属的资源内有 +意义,换一个数据集,同一个步骤 id 就什么也不代表。 + +### 为什么某个目标被跳过 + +每一条被跳过的行都带有一句供人阅读的说明。由写入本身跳过的行还带有 +`skip_reason`——一个稳定的标记,工作流据此分支即可,不必去匹配文字: + +| `skip_reason` | 含义 | +| --- | --- | +| `already_at_value` | 目标本来就是这个值,没有写入任何内容 | +| `not_applicable` | 该参数不适用于这个目标 | +| `target_missing` | 这个地址在文档里已经指不到任何东西 | + +在预检阶段就被排除的行只有那句说明。它们绝不会是「值本来就一样」这种情况, +因此没有这个标记本身就是区分。 + +如果 **Set a property** 的所有目标已存储所请求的值和覆盖状态,则不再写入: +每个目标报告跳过,文档版本号不变,也不增加撤销步骤。把继承值固定为显式覆盖, +仍会记录这项人工选择。 + +超出范围的值在 **Preflight** 阶段、也就是确认之前就会被拒绝,并同时给出你 +填的值和拒绝它的边界。过了这一步,列出的部件要么全部生效,要么全部不变, +写入的改动合并为一次 **Undo automation** 撤销。 + +**Inspect a property** 把读数返回给调用方:作为工作流的一步运行时,读数会 +进入运行记录,[命令行](/zh-cn/reference/cli/)写出的清单文件里也是同一份内容。 +在自动化窗口里,数值显示在逐部件结果下方的 **Result value (JSON)** 区域。 + +## 读数与 schema + +每条读数写出自己的 `target`,并带上当前值 `value`、参数有默认值时的 +`default_value`、表示当前值是否偏离默认值的 `modified`、可用状态 +`availability`,以及约束取值的 `schema`。 + +当前状态下不允许写入的参数照样会被读出:`availability` 为 `"disabled"`, +`disabled_reason` 说明要先改什么——例如设置 φ0 之前,先把相位模式切到 +*Manual*。 + +schema 以 `type` 标记,取值为 `bool`、`text`、`int`、`stepped_int`、`float`、 +`enum`、`color`、`unit_code` 或 `axis_range`。 + +- `int` 与 `stepped_int` 带 `min` 与 `max`,参数有单位时还带 `unit`。 + `stepped_int` 另有取值必须落在的格点 `step`——例如 Savitzky-Golay 窗口为 + 3 到 201,步长为 2。 +- `float` 带 `min`、`max` 与 `exclusive_min`;若参数拒绝某些取值,还带 + `excluded`(单个取值)或 `excluded_magnitude`(绝对值不超过该阈值的全部 + 取值)。其 `display`(`linear`、`degrees` 或 `log10`)说明面板如何显示这个 + 数;旁边的 `unit` 与 `log` 只是同一件事的另一种写法。 +- `enum` 列出各变体,每个都带稳定 id 和标签。 + +无论 `display` 是什么,边界和取值始终使用参数自身的单位:`display` 为 +`degrees` 的相位值,在线格式中仍是弧度。 diff --git a/docs/src/content/docs/zh-cn/reference/troubleshooting.md b/docs/src/content/docs/zh-cn/reference/troubleshooting.md index eeaca587..b8ee61be 100644 --- a/docs/src/content/docs/zh-cn/reference/troubleshooting.md +++ b/docs/src/content/docs/zh-cn/reference/troubleshooting.md @@ -5,24 +5,20 @@ description: 导入、分析、导出或更新不符合预期时的检查清单 ## 导入 -**图片无法导入。** 请确认文件实际内容为 PNG、JPEG、TIFF、WebP 或 BMP; -Plotium 检查文件签名,而不只看扩展名。Plotium 不支持 SVG;若是动画 PNG 或 WebP, -请使用 **Add Animated Image First Frame…**。打开 **Operation and Diagnostic -History** 可查看文件名、检测到的格式、失败环节和原因。导入失败不会改动项目。 +**图片无法导入。** Plotium 检查文件实际内容,而不只看扩展名;可接受的格式以及 +动画图片、多页图片的导入命令见[图中的图片](/zh-cn/guides/images/)。打开 **Operation and +Diagnostic History** 可查看文件名、检测到的格式、失败环节和原因。导入失败不会改动项目。 -**ABF 文件打不开。** Plotium 读取 int16 或 float32 采样的 ABF 2.x。ABF1 -文件和压缩的 ABF2 数据目前不支持——请在采集软件中重新导出为未压缩的 -ABF2。 +**ABF 文件打不开。** ABF1 文件和压缩的 ABF2 数据目前不支持——请在采集软件中 +重新导出为未压缩的 ABF2。见[电生理(ABF2)](/zh-cn/guides/supported-formats/#电生理abf2)。 -**数值列被导入成了文本。** Plotium 只对无歧义的值自动定型: -`true`/`false`、十进制整数、`YYYY-MM-DD` 日期和 UTC 时间戳。区域性格式 -(逗号小数、地区日期)和数字文本混排的列保持为文本,而不是被猜测。查看 -**Review table import** 对话框的诊断信息,修正源文件,或导入后再转换该 -列。 +**数值列被导入成了文本。** Plotium 只对无歧义的值自动定型,因此区域性格式 +(逗号小数、地区日期)和数字文本混排的列保持为文本。查看 **Review table import** +对话框的诊断信息,修正源文件,或导入后再转换该列。见 +[列类型如何确定](/zh-cn/guides/importing-data/#列类型如何确定)。 **Excel 表格里的单元格导入后是空的。** Plotium 读取 Excel 为每个公式缓存 -的值,但从不重新计算公式。没有缓存值的公式单元格导入为空,并列在导入 -诊断中——在 Excel 里打开工作簿保存一次即可刷新缓存值。 +的值,但从不重新计算公式。在 Excel 里打开工作簿保存一次即可刷新缓存值。 ## 处理与分析 @@ -39,11 +35,6 @@ ABF2。 ## 导出 -**打开项目后出现缺失图片占位项。** 嵌入资源缺失、损坏,或未通过完整性校验。 -请查看 **Operation and Diagnostic History**,选中占位项并使用 **Replace Image…**。 -Plotium 会保留页面供继续编辑,但阻止常规保存和导出,避免损坏状态被静默发布;若只需 -审阅稿,可在导出对话框中明确生成带标签的占位图。 - **导出预检标记了我的图。** 字号或线宽违反所选期刊预设。在画板上修正 ——**Figure Typography…** 可一次设定全部坐标轴文字尺寸——或改选符合 预期尺寸的预设。 @@ -57,9 +48,17 @@ copies** 已开启,历史保存以隐藏文件保留在项目文件旁。 **Preferences → General** 中用 **Check now** 获得明确结果,并检查更新 通道——切换到更稳定的通道不会降级,而是等待该通道的下一个版本。 +**打开项目后出现缺失图片占位项。** 嵌入资源缺失、损坏,或未通过完整性校验。 +请查看 **Operation and Diagnostic History**,选中占位项并使用 **Replace Image…**。 +Plotium 会保留页面供继续编辑,但阻止常规保存和导出,避免损坏状态被静默发布;若只需 +审阅稿,可在导出对话框中明确生成带标签的占位图。见 +[图片缺失或损坏](/zh-cn/guides/images/#图片缺失或损坏)。 + ## 报告问题 以上都无法解决时,请在 [GitHub issue 跟踪器](https://github.com/nmrtist/plotium/issues)报告,附上 Plotium 版本(见 **Preferences → General**)、平台,以及(可能时)能复现 -问题的文件。 +问题的文件。崩溃后请附上 `crashes` 文件夹中最新的崩溃报告;其他问题请附上旁边 +`logs` 文件夹中最新的会话日志。macOS 上两者都在 `~/Library/Application Support/plotium` +中;其他平台见[报告问题](/zh-cn/reference/reporting-problems/)。 diff --git a/docs/src/content/docs/zh-cn/reference/ui-overview.md b/docs/src/content/docs/zh-cn/reference/ui-overview.md index 46601e7c..f825a2b8 100644 --- a/docs/src/content/docs/zh-cn/reference/ui-overview.md +++ b/docs/src/content/docs/zh-cn/reference/ui-overview.md @@ -53,6 +53,8 @@ Plotium 的界面为英文;手册中加粗的英文词即界面上的原文标 状态变化,**Diagnostics** 显示结构化操作报告。 **Clear history** 清空结果、消息和诊断记录,运行中的任务会继续。 悬停图标可查看当前状态和结果数量,错误与警告也会出现在反馈横幅中。 +- **跟随按钮**——位于 AI 连接按钮旁,显示工作区是否跟随 AI 客户端的结果(跟随中、 + 已暂停或已关闭),角标计数尚未查看的结果。见[跟随 AI 结果](/zh-cn/ai/control-and-review/#跟随-ai-结果)。 **Results** 中的科学计算任务会区分完成、失败、取消和**结果未应用**。 计算运行期间编辑项目,可能导致结果无法应用;任务记录会说明具体原因。 @@ -60,27 +62,6 @@ Plotium 的界面为英文;手册中加粗的英文词即界面上的原文标 悬停可查看所需的下一步操作。重新计算始终需要主动点击。 计算完成仍可能带有科学警告,例如拟合未收敛或结果为空;使用结果前请检查这些警告。 -默认跟随 AI 结果:工作区聚焦最近一次已完成操作所影响的画布;同一次操作涉及多个画布时, -这些画布一起显示。AI 连接按钮旁的跟随按钮显示正在跟随、 -已暂停或已关闭;**Results** 中提供 **Pause**、**Resume**、**Stop following** 和 **View latest**。 -当前画布的持续更新会保留缩放视野。 -打开或选择其他内容、平移、缩放或编辑会暂停跟随;悬停和查看操作详情不会。 -希望继续自动显示新结果时,可主动恢复跟随;也可关闭跟随,自行浏览。 -暂停期间,跟随按钮上的角标显示尚未查看的新增或更新成果数量;同一对象反复修改只计一次。 -可打开 **Results** 查看,不会恢复跟随。当前正在查看的对象发生更新时,也会显示可关闭的短暂提示。 -查看某项成果后,该项不再计数;**View latest** 不会清除其他尚未查看的成果。恢复跟随后计数清零。 -暂停期间还会显示提醒,提供 **Resume following**(恢复跟随)、**Dismiss**(忽略本次)和 -**Don't remind again**(不再提醒)。忽略只收起当前提醒,不会把成果标记为已查看。 -同一对象反复修改不会再次弹出提醒;出现新的成果对象时可以再次提醒。提醒约八秒后自动关闭。 -**Don't remind again** 的选择会跨重启保存;可在 **Preferences → General → Remind me about -results while following is paused** 中重新开启。成果计数和错误提示仍然保留。 -暂停会立即冻结当前视野,包括尚未结束的自动缩放。恢复或查看最新结果时,只定位最近一次操作的结果, -不会累积此前的画布。单次查看最新结果不会重新开启跟随。只读请求和空画布不会切换工作区,暂停或关闭跟随不会取消任务。 -切换项目或 AI 连接中断会停止跟随;新项目或连接准备好后,需要主动恢复。 - -AI 连接按钮上的旋转标记表示有科学计算正在运行。悬停可查看具体操作、可用的进度, -以及运行期间编辑的风险。它表示应用已知的计算活动,不代表 AI 整个任务的完成状态。 - 两个侧栏随时可以显示或隐藏:点击 Ribbon 任务行右端的一对布局按钮,按 Ctrl+B(左)或 Ctrl+Shift+B (右;macOS 上为 Cmd),或将侧栏内缘拖向同一侧的窗口边缘,看到