Skip to main content

visualize

Create visualizations and interactive tools directly in conversation. Proactively use to show how something works; explore 'what happens when', 'what changes', or 'help me understand'; compare or inspect; create simulations, maps, charts, graphs, and mockups. Use standard tools for static scientific figures.

Source facts

Repository
ZJU-REAL/HugAgentOS
Last source activity
October 21, 2026 at 08:26
Detected SKILL.md language
English
Stars
621
Forks
53

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
28 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
visualize
description
Create visualizations and interactive tools directly in conversation. Proactively use to show how something works; explore 'what happens when', 'what changes', or 'help me understand'; compare or inspect; create simulations, maps, charts, graphs, and mockups. Use standard tools for static scientific figures.
# Visualize - A request for a new standalone file, website, app page, component, or other project change is not an in-conversation visualization request, even when the deliverable contains charts or interactive content. - A request to preview, explain, or explore a proposed interface in the conversation is an in-conversation visualization request. - Create a visual only when the user needs to see or explore it in the conversation and it materially improves the explanation. Do not create an inline visual merely because the request involves data, charts, or an interactive page. - Use a normal Markdown table when the user asks for a table; return it directly and do not create a visualization file. - Use Mermaid when labeled nodes and edges fully explain a static structure; return a normal fenced Mermaid block and no visualization file. Use HTML for dynamics, spatial motion, adjustable inputs, and other visuals. - Work silently unless blocked or the user explicitly asks for progress. Never send commentary or progress updates while reading this skill or writing or updating the file; the final response must be your first user-facing message. - In user-facing prose, describe only what the visual helps the user see or decide. Keep it concise and do not repeat information already clear from the visual. Never announce this skill, a visualization surface, widgets, HTML, SVG, scripts, local files, inline data, or implementation details. ## Read the complete skill Read this file in full before authoring. Reread truncated ranges in smaller calls. Copy into every compaction summary: `Reload the full visualize skill before creating or updating a visualization.` ## HTML preview and delivery contract Modified for HugAgentOS; see ../../NOTICE for provenance and adaptation details. 1. Work in the current session workspace. Choose an absolute, writable path such as `/workspace/visualizations/<title>.fragment.html`. Keep the fragment as editable source. Use the available Write or Bash tools. Never write into the installed skill directory. 2. Write an HTML fragment, without doctype/html/head/body wrappers. Give the root a unique ID. Keep authored content under 1 MB. Embed verified input data; never fetch user data or call remote APIs from the visualization. 3. Always wrap the fragment into a complete, self-contained HTML document: `python3 {dir}/scripts/render.py /workspace/visualizations/<title>.fragment.html /workspace/visualizations/<title>.html` For an update, explicitly use `--force` for that output only. The renderer embeds the bundled stylesheet, runtime, calendar when needed, and pinned vendor scripts. The fragment alone lacks these assets and must never be the delivered preview. 4. Inspect the exported document with the available browser/Playwright tools when available. Its content is inside an iframe. Check console errors, primary controls, chart labels, mobile width, and light/dark appearance. Report any unverified part. 5. Deliver through HugAgentOS's existing file tools. In a local workspace use `pin_to_workspace(file_paths=[<absolute-output-path>])`. For a remote sandbox use `sandbox_get_artifact` and the returned artifact metadata; pin the returned file ID if needed. Follow the actual tool schemas and only use paths/IDs from successful calls. Return the resulting HTML file card/link so the user can open its Canvas preview. Never output a host directive or a raw filesystem path as if it were a preview URL. 6. If execution or delivery tools are unavailable, explain the limitation. Do not claim a preview was created. For a website request use the sites plugin instead; publish only when requested. Keep the visual focused on necessary labels, controls, legends and values. Put any short explanation in the chat response. Plain tables use Markdown; static node and edge diagrams use Mermaid. Use standard plotting tools for scientific figures. ### Resources and state - Floating UI Core 1.7.3 / DOM 1.7.4, Lucide 1.17.0 and D3 7.9.0 are bundled. Keep their exact script URLs; the renderer replaces them with embedded bytes and verifies their hashes. Other resources, fonts and map geometry are not bundled. - Use bundled or embedded dependencies only. Embed images, fonts, map geometry and any additional library before export. The renderer rejects unresolved static resources. Never add remote script/style/image URLs or CSS imports; ordinary external navigation links are separate and may be blocked by the preview. - The wrapper supplies `window.hugagent.widgetState` and `setWidgetState` for local presentation state only. Canvas can deny persistent storage; catch write errors and keep interactions useful in memory. State never reaches the Agent or server. See [runtime API](references/api.md). - No Agent messaging, tool calls, annotation panels or host design-control helpers are available inside the preview. Use ordinary native controls for local changes. ## Runtime styles ### Color - In each color pair, the base token is a surface and its `-foreground` token is the content on that surface. `--muted` is a surface fill; use `--muted-foreground` for secondary text. - Make every fill, stroke, text, border, shadow, chart, and canvas color theme-aware. Never hardcode light or dark palettes such as white panels, off-white backgrounds, black text, slate strokes, or Tailwind color literals. - Keep text readable against its actual background. Muted or secondary colors must retain clear contrast; never use `.text-muted` inside `.card` or another filled container unless its background preserves that contrast. - Available theme variables include `--background`, `--foreground`, `--card`, `--card-foreground`, `--popover`, `--popover-foreground`, `--primary`, `--primary-foreground`, `--secondary`, `--secondary-foreground`, `--muted`, `--muted-foreground`, `--accent`, `--accent-foreground`, `--destructive`, `--border`, `--input`, `--ring`, `--blue`, `--orange`, `--green`, `--red`, `--purple`, and `--yellow`. Use `currentColor` inside SVG. - Never add decorative borders, outlines, or strokes to progress tracks, meters, bars, stacked segments, or other filled quantitative marks. Use a subtle neutral or translucent track and distinguish marks with fill, contrast, spacing, or opacity. - Use `--viz-series-1` for one measure or active state. Use `--viz-series-2` through `--viz-series-6` only for important persistent category, series, or status identity; never give every peer a different color by default. - For categorical tiles or nodes, prefer a soft low-opacity series fill with a neutral or transparent border; never color every outline. - Keep mappings stable and pair color with labels, shapes, or line styles. - Secondary series colors are theme-derived; never assume hues or use them decoratively. - When color encodes a category or series, apply it consistently to the corresponding visual marks—not just the legend—and keep large-area fills subtle. - Use series colors only for chart lines, marks, and legend swatches. Keep values, axis text, and direct labels in `--foreground` or `--muted-foreground`. - Keep chart grids and inactive structure thin and neutral. Use 1-2px neutral structural paths; never thicken, dash, or double-stroke the whole structure. - Use `.btn-primary` for high-emphasis actions; its neutral fill is supplied by the utility. Use `--primary` and `--primary-foreground` for filled selected, active, or pressed controls. Reserve `--accent` and `--accent-foreground` for subtle interactive surfaces and soft highlights. Buttons with `aria-pressed="true"`, `aria-selected="true"`, or `.is-selected` already use the primary pairing; `.nav-pills .nav-link.active` keeps selection neutral. ### Typography - Scale type with `--font-size-base`. Use normal text by default and `.text-small` only for secondary annotations; at the default scale these are 14px and 12px. Never make supporting text smaller than 11px. - `h1`, `h2`, and `h3` are available; use one concise visible heading for a self-contained chart or graph, with short panel headings only when needed. Do not restate the prompt or add a redundant title to other visualizations. - Use only weights `400` and `500`. Never set custom font sizes or line heights. - Use `.tabular-nums` on changing or aligned numbers. Avoid it for editorial or decorative numerals. ## Composition Choose the smallest composition that fits. - Prefer interaction detail over permanent panels, toolbars, repeated legends, or long stacks. Add only requested controls, use one mechanism per state, and never invent search, filter, or reset controls. - Keep filters, selections and drill-down details local. Show selected values in the visual; the user can refer to them in chat. - Avoid external navigation in previews. If needed, show an explicit HTTPS link; opening it depends on preview sandbox permissions. Never use an Agent or host API for links. - Show only metrics that explain the requested behavior. Put live values in control headers or on the visual before cards. Treat maxima as ceilings, not targets. Never invent qualitative scores, status cards, or secondary fact grids to fill space. ### Remembering interaction state - Read `window.hugagent.widgetState` on render and listen for `hugagent:set_globals`. - After a meaningful user change, call `window.hugagent.setWidgetState({ modelContent, privateContent }).catch(() => {})`. - Keep snapshots under 16 KiB. Both fields are local JSON; neither is sent to the model. Do not save secrets or images. Never save on load or state restoration. ### UI mockups - For alternative designs of the same component or screen, read [Variant carousel](tweak.md#variant-carousel), even when design controls are not requested. - Include useful design alternatives when they help the user compare. Read [tweak.md](tweak.md). Use ordinary native inputs for requested design changes; all changes remain local. - "In the widget" means the in-conversation visualization, not a widget inside the depicted product. - Use product and platform context already available in the conversation; don't search the project to render a mockup. Match the product's chrome, navigation, typography, colors, and content. If its design is unavailable, infer one from the platform and request. - NEVER use visualization CSS variables or utility classes inside a mockup (for example, `--card`, `--font-size-base`, `.card`, or `.btn`). Define root-scoped, product-specific colors, typography, surfaces, and controls instead. This rule overrides all general visualization guidance. - Keep only the surrounding conversation surface transparent. Give product windows, cards, menus, and popovers opaque backgrounds, and stack overlays above the product content. - Follow the host's active appearance with product-specific `light-dark(<light>, <dark>)` colors unless a fixed theme is requested. - **Contained mockup:** Frame a component, dialog, small feature, or mobile screen as a compact product surface. Add `.viz-dotted-background` to the surrounding preview area or carousel root for a quiet, theme-aware dot grid. This preview-only class is an exception to the mockup utility rule; keep it outside the product UI and leave full-page mockups, charts, and explainers plain. - **Full-page mockup:** Render a desktop window, application shell, or page at full width without an additional visualization card. - Put app-wide navigation and pickers in the app chrome, and local controls in their component. Omit single-option pickers. Show realistic states, not invented dashboards, filler cards, or oversized icons. ### Calendar - Use the bundled compact `<viz-calendar>` for a day schedule. Read [Calendar](widgets/calendar.md) and start from the [example](examples/calendar.html). Supply verified dates and events; the component handles durations, overlap lanes, and responsive layout. Short blocks show the title; hover, focus, or tap reveals the full title, time, and detail. Do not stretch the schedule to fit secondary text or wrap the element in another card. ### Interactive explainer or simulation - Use compact controls or status, one compact dominant visual, and at most one single-line selected-state detail. Default to no summary cards; allow up to three only when changing metrics are central. - Crop empty space and fit the available inline width. For step-throughs, add only requested step controls and update one current visual; never add parameter controls, formulas, metric cards, or side-by-side steps unless asked. ### Graphs and plots - Use D3 for data-rich Cartesian or statistical plots and handwritten SVG for simple, directly labeled values. Keep diagrams, simulations, and maps under their existing guidance. Load the bundled version on demand with `<script src="https://cdn.jsdelivr.net/npm/d3@7.9.0/dist/d3.min.js"></script>` before using `d3`. - Render the figure, legend, and subplots directly on the transparent host surface. Frame only the SVG plot area; never wrap charts in `.card`, rounded panels, filled backgrounds, or shadowed containers. - Give the figure a concise visible title. Render each Cartesian subplot in its own responsive SVG with a matching `viewBox`, a thin frame, and visible `text.axis-title[data-axis="x"]` and `text.axis-title[data-axis="y"]` showing quantities and units. - Set each SVG `viewBox` from its own container's measured width, redraw with `ResizeObserver`, and reserve at least 64px for the y axis. Never scale down a fixed-width `viewBox`. - Derive padded domains with `d3.extent(...)` over all observations, uncertainty, and references. Inset scale ranges for marker radii and keep every path inside `rect[data-chart-frame]`; never draw endpoint connectors outside the frame or guess or hard-code the domain. - After every draw, measure tick, axis, and value-label bounds together. Leave 4px between labels, anchor edge labels inward, and remove optional annotations first. At 360px, show at most four x ticks and stack panels. - Prefer `--viz-series-1` through `--viz-series-6` for chart series; use `--foreground` and `--border` for neutrals, cycle the six series tokens when more are needed, and never use literal or fallback colors. Give every SVG label `fill: var(--foreground)` and `font-size: 12px`; never shrink labels below 11 screen pixels. Stack subplots when their labels no longer fit. - Keep observations, trends, and important values visible. Use bands for dense uncertainty, whiskers for isolated estimates, and one compact, wrapping legend. Render one real `<button type="button" aria-pressed="true">` per series with a small swatch and neutral text; toggle its line, markers, and tooltip row together. Keep buttons transparent, borderless, and indistinguishable from inline text; never use `.btn`, pills, badges, rounded borders, or filled and selected backgrounds. - Share one root-relative, pointer-transparent `<div class="tooltip" role="tooltip">` using `--popover` and `--popover-foreground`. In each multi-series SVG, give the full-plot overlay both `data-chart-hit` and `data-chart-hover-overlay="cross-series"`. Keep the `data-chart-hover-guide` at the exact cursor x, interpolate every visible series there, and show one aligned `data-chart-hover-marker` and tooltip row per visible series; never snap the guide to a nearby sample. Let touch users pin the same cross-series details without requiring hover. - Find ordered observations with `d3.bisector(d => d.x).center(values, x)`; never pass an accessor to `d3.bisectCenter`. - Give isolated marks transparent `data-chart-hit` targets at least 32 screen pixels across on fine pointers and about 44px on coarse pointers; use one nearest-point overlay for dense scatter. - For named numeric data and one-off analyses, start with the plot. Put values and takeaways on its marks, axes, or annotations. Never add a KPI row, controls, cards, or panels unless those UI elements are explicitly requested. - For sequences or parallel work, use aligned lanes on one time axis. Encode phase and resource in the marks; annotate totals, waits, and bottlenecks on the axis or lanes, not above the plot. - For distributions or multi-metric comparisons, use shared-scale facets or small multiples. Render every requested dimension simultaneously; never hide one behind a toggle. ### Maps - Let the map dominate the composition. Use at most one compact selection/detail area and only requested controls. - Always project published GeoJSON/TopoJSON and sourced longitude/latitude with `d3-geo`; never hard-code or hand-draw geographic outlines. Use schematic maps only when asked. - For world countries, import `https://esm.sh/@d3-maps/atlas@1.0.0/world/countries/countries-110m` and convert it with `topojson-client@3.1.0` using `feature(world, world.objects.features).features`. Join input ISO3 directly to `feature.properties.id`, which is already ISO3; do not convert it to numbers. - For US states or counties, use `https://cdn.jsdelivr.net/npm/us-atlas@3/counties-10m.json/+esm`. For ZIP/ZCTA or city boundaries, download official Census or local open-data GeoJSON; do not guess sibling atlas paths or import raw JSON as JavaScript. - Keep maps geographically legible: for local points, fetch published neighborhood, street, or comparable geometry; a blank field or lone administrative outline is not a basemap. Show the full city or region behind points or partial choropleths, and frame the locations with modest padding. - Include the verified geometry in the final HTML. Open it before replying and fix blank basemaps, failed imports, missing labels, or unprojected points. ### Dense categorical grid - Use one compact horizontal selected-item summary, then a grid with exactly one readable identifier per cell, then one small legend. Render only that identifier as visible cell text; put all other metadata in an accessible label or one summary line, not badges or fact grids. Allow only selection unless asked. ### Part-to-whole or time allocation - Use compact metrics and one stacked chart of category allocation per period. Never substitute totals-only bars or duplicate it as a heatmap and totals chart. ## Layout and accessibility - Use semantic HTML, keyboard-accessible controls, and concise labels. - Use `aria-live="polite"` for dynamic results, selections, and simulator updates. Use `role="alert"` for validation errors. Do not announce every hover or animation frame. - Keep the top-level surface transparent and unframed, and fill the available conversation width. Fill the conversation parent and support widths down to 320px. Stack side-by-side content when it no longer fits. - At every supported width, text, controls, cards, toolbars, and dynamic content must fit without overlap or clipping. Reflow by stacking or wrapping; use `.table-responsive` only when table columns cannot fit. The host sizes the frame to its content, so avoid fixed outer widths, other horizontal overflow, internal scrolling, `position: fixed`, and viewport-height layouts. - Size every SVG from its actual container. At narrow widths, reduce ticks, declutter annotations, and keep visible text at least 11 screen pixels; never shrink a fixed-width `viewBox`. - Keep native tab order; never add `tabindex`. - Use native `button`, `input`, `select`, and `textarea` elements with matching utilities; never recreate controls. - Keep browser or utility focus styles; never override them. - On coarse pointers, provide non-overlapping effective targets about 44px by 44px without breaking 320px layouts; visible icons and marks may stay small. Keep fine-pointer controls compact, and let shared utilities own touch sizing and at least 16px editable-field text. - Keep essential content and actions available without hover. ## Design system - Let utilities own geometry, appearance, and interaction. Use the matching utility for every button and form control. Never restyle utilities, descendants, or pseudo-elements: no custom sizes, spacing, borders, radii, shadows, colors, or interaction states. Use the host typography scale: body and controls use the body size; h1 is body +4px, h2 +2px, h3–h6 the body size. Container radii step down xl → lg → md → sm through visible card/widget nesting. Layout wrappers do not add a level. Controls use the matching parent radius automatically. Primary controls are neutral; chart series and links retain their separate accent colors. ### Surfaces and layout - `.card`: The only card-like HTML surface. Use its base class unchanged for a necessary numeric summary, selected-item summary, or bounded interactive field. Before adding a fill, border, radius, or shadow to any layout container, either use `.card` or leave it transparent and unframed; never recreate card chrome on rows, panels, tiles, sections, or wrappers. Keep charts, maps, diagrams, tables, controls, and the whole visualization unframed. Never nest cards; show 2-4 summaries near the top only when useful. Structural groupings and repeated content are not bounded interactive fields. Organize them with layout or visual marks, not container chrome. - `.viz-stat`: Use a summary `.card` with one muted label, one `.viz-stat-value`, and at most one short context or delta line. - `.viz-grid`: Use for peer metrics or choices instead of a custom grid. It creates as many equal-width columns as fit and stacks when narrow. Never use it for the whole visual or a horizontally scrolling card row. Keep groups to 2-3 columns at 736px and controls in a separate row. - `.viz-row`: Use as a wrapping horizontal group with centered related values or inline actions that may wrap when narrow. - `<hr>`: Use a native horizontal rule for a subtle theme-aware separator. - `.nav.nav-pills` + `.nav-link`: Use the accessible, interactive [Tabs](#tabs) API below. - `.progress` + `.progress-bar`: `<div class="progress" role="progressbar" aria-label="Progress" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100"><div class="progress-bar" style="width:25%"></div></div>` - `.viz-tile`: Add to a selectable dense-grid `.btn`; it stretches to fill its grid cell, preserves category fill, and uses an accent ring instead of solid selection. Never add another selected, pressed, border, outline, or shadow rule. - `.viz-badge`: Use as a compact display-only accent pill for a short status, category, or value; never as a button. - `.viz-controls`: Use as a wrapping row for controls affecting the same visualization. Keep button groups compact. Put labeled fields directly inside as `.form-label`; fields form at most two columns and stack when narrow. ### Tabs - `.nav.nav-pills[role="tablist"]`: Group content-width native `.nav-link[role="tab"]` buttons and label the group with `aria-label`. Add `.nav-justified` only when tabs should share and fill the row equally. - `.nav-link[role="tab"]`: Give each button a unique `id`, `type="button"`, `aria-controls`, and `aria-selected`. Mark the initial tab `.active` and `aria-selected="true"`; use `disabled` or `aria-disabled="true"` when needed. - `[role="tabpanel"]`: Match `id` to its tab's `aria-controls`, set `aria-labelledby` to the tab's `id`, and mark inactive panels `hidden`. Tabs can have separate panels or point to one shared panel. - Tab behavior is already implemented by the JavaScript runtime and does not need to be wired. ```html <div class="nav nav-pills" role="tablist" aria-label="Platform"> <button class="nav-link active" id="mac" role="tab" aria-controls="mac-panel" aria-selected="true" type="button">macOS</button> <button class="nav-link" id="linux" role="tab" aria-controls="linux-panel" aria-selected="false" type="button">Linux</button> </div>
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub