跳到正文
cccskills
免费在 GitHub 公开

datagrok-viewers

Add a viewer, configure a viewer, change viewer options, find viewer, close viewer, view a scatter plot, bar chart, histogram, line chart, box plot, pie chart, heat map, correlation plot, 3D scatter, trellis, density plot, statistics, on a Datagrok TableView via the datagrok_exec tool. Use whenever the user asks to plot, chart, visualize, show a graph, draw a distribution, color by a column, swap a viewer's axis, toggle a legend / regression line / log scale, replace one viewer with another, close every chart, reset the view to just the grid, or find an existing viewer by type. Plugin viewers like "Chem space", "sequence space", "activity cliffs" are NOT viewer types — they're registered functions — route those to `grok.functions.call`. Does NOT cover filtering (separate skill `datagrok-filtering`), selection (`datagrok-selection`), grid cell rendering (`datagrok-grid-customization`), layout save/restore, or custom-viewer authoring.

中文简介正在准备中。当前显示原文说明。

查看安装方法

包含的文件(1)

  • SKILL.md16.5 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

datagrok-viewers

Add, configure, find, and close viewers on a DG.TableView via the datagrok_exec tool. Globals injected by the runtime: grok, ui, DG, view, t (the current DG.DataFrame, when the view is a TableView).

Quick reference

NeedCall
Add a viewerview.addViewer(DG.VIEWER.SCATTER_PLOT, {xColumnName: 'a', ...})
Configure an existing viewerviewer.setOptions({colorColumnName: 'logP'})
All non-grid viewersArray.from(view.viewers).slice(1)
First viewer of a typeArray.from(view.viewers).slice(1).find((v) => v.type === DG.VIEWER.SCATTER_PLOT)
Close one viewerviewer.close() (wrap in try/catch — throws if never attached)
Close every non-grid viewerArray.from(view.viewers).slice(1).forEach((v) => { try { v.close(); } catch {} })
Inspect a viewer's option schemaviewer.getProperties() → DG.Property[] (each has .name)
Standalone (detached) viewerDG.Viewer.fromType(DG.VIEWER.SCATTER_PLOT, t, {...})

THE viewer footgun: column-binding properties always end in ColumnName(s)

Users say "x is mw, y is logp". You must emit xColumnName / yColumnName — never bare x / y / color. Bare aliases are inconsistent across viewer types and may silently do nothing for the canonical addViewer/setOptions path. Always use the full *ColumnName(s) form.

User saysEmit (single column)Emit (multiple columns)
x is mwxColumnName: 'mw'xColumnNames: ['mw', ...]
y is logpyColumnName: 'logp'yColumnNames: ['logp', ...]
color by activitycolorColumnName: 'activity'—
size by mwsizeColumnName: 'mw'—
label by smileslabelColumnName: 'smiles'—
split by classsplitColumnName: 'class'splitColumnNames: ['class']
value is ic50valueColumnName: 'ic50'valueColumnNames: ['ic50']
category is classcategoryColumnName: 'class'categoryColumnNames: ['class']
columns are a, b—columnNames: ['a', 'b']
  • Single column properties: singular <role>ColumnName (string).
  • Multi-column properties: plural <role>ColumnNames (array of strings).
  • Some viewers take both forms for different roles (Line chart has xColumnName for the x axis and yColumnNames for the series).
  • When in doubt, inspect the live schema: viewer.getProperties() returns DG.Property[]. Each has .name (canonical), .propertyType, .choices.

Other naming conventions across viewers:

  • Boolean toggles start with show: showRegressionLine, showXAxis, showLegend, showStatistics, showColorSelector. Not regressionLine / legend / statistics.
  • Axis scale: xAxisType: 'linear' | 'logarithmic' (and y, z, colorAxisType). Not logX, not logScale.
  • Axis bounds: xMin, xMax, yMin, yMax. Not xRange: [a, b].

Unconfirmed options

Options not documented here must be confirmed against the live schema before setting: viewer.getProperties() → match .name, respect .propertyType and .choices. Values are scalars — never objects/arrays: a wrong-typed value is stored unchecked.

The viewers array

view.viewers is a synchronous array snapshot:

  • view.viewers[0] is always the grid. Closing it breaks the table widget. Every iteration must .slice(1) (or filter out v.type === DG.VIEWER.GRID).
  • Every other entry is a non-grid viewer. Each has .type (a string equal to one of the DG.VIEWER.* constants) and .dataFrame.

Viewer types catalog

Always use the DG.VIEWER.* constants, never literal strings:

ConstantString valuePrimary properties
DG.VIEWER.SCATTER_PLOT'Scatter plot'xColumnName, yColumnName, colorColumnName, sizeColumnName, showRegressionLine
DG.VIEWER.HISTOGRAM'Histogram'valueColumnName, splitColumnName, bins
DG.VIEWER.LINE_CHART'Line chart'xColumnName, yColumnNames (array)
DG.VIEWER.BAR_CHART'Bar chart'splitColumnName, valueColumnName, valueAggrType
DG.VIEWER.PIE_CHART'Pie chart'categoryColumnName
DG.VIEWER.BOX_PLOT'Box plot'valueColumnName, categoryColumnName
DG.VIEWER.HEAT_MAP'Heat map'(returns a Grid subclass — column tag-driven color coding)
DG.VIEWER.STATISTICS'Statistics'columnNames
DG.VIEWER.CORR_PLOT'Correlation plot'columnNames (or xs / ys)
DG.VIEWER.DENSITY_PLOT'Density plot'xColumnName, yColumnName
DG.VIEWER.SCATTER_PLOT_3D'3d scatter plot'xColumnName, yColumnName, zColumnName, colorColumnName
DG.VIEWER.TRELLIS_PLOT'Trellis plot'xColumnNames, yColumnNames, viewerType
DG.VIEWER.PC_PLOT'PC Plot'columnNames
DG.VIEWER.TREE_MAP'Tree map'splitColumnNames, sizeColumnName
DG.VIEWER.MATRIX_PLOT'Matrix plot'xColumnNames, yColumnNames
DG.VIEWER.FILTERS'Filters'columnNames (see datagrok-filtering for the real filtering API)
DG.VIEWER.FORM'Form'columnNames
DG.VIEWER.MARKUP'Markup'content (string)
DG.VIEWER.NETWORK_DIAGRAM'Network diagram'node1ColumnName, node2ColumnName
DG.VIEWER.WORD_CLOUD'Word cloud'column
DG.VIEWER.TILE_VIEWER'Tile Viewer'per-row cards
DG.VIEWER.PIVOT_TABLE'Pivot table'grouped aggregates
DG.VIEWER.SHAPE_MAP'Shape Map'choropleth
DG.VIEWER.CALENDAR'Calendar'dateColumnName
DG.VIEWER.GLOBE'Globe'latitudeColumnName, longitudeColumnName
DG.VIEWER.GOOGLE_MAP'Google map'latitudeColumnName, longitudeColumnName
DG.VIEWER.TIMELINES'Timelines'startColumnName, endColumnName
DG.VIEWER.RADAR_VIEWER'Radar'columnNames
DG.VIEWER.GRID'Grid'(the main grid — view.grid is the typed accessor)

Full canonical list at runtime: Object.values(DG.VIEWER).

Adding viewers

Use the in-scope view global, not grok.shell.tv (the globally active view, which may be a different tab when the user has several open).

// Scatter plot of MW vs LogP, colored by activity, with regression line.
view.addViewer(DG.VIEWER.SCATTER_PLOT, {
  xColumnName: 'MW',
  yColumnName: 'LogP',
  colorColumnName: 'activity',
  showRegressionLine: true,
});
// Line chart with multiple y series — yColumnNames is the plural form (array).
view.addViewer(DG.VIEWER.LINE_CHART, {
  xColumnName: 'date',
  yColumnNames: ['revenue', 'expenses', 'profit'],
});
// Bar chart of count by category.
view.addViewer(DG.VIEWER.BAR_CHART, {
  splitColumnName: 'category',
  valueColumnName: 'count',
  valueAggrType: 'sum',
});

Configuring an existing viewer

viewer.setOptions({...}) applies a batch of property changes and re-renders once. Same property-name rules as addViewer.

// Recolor the existing scatter plot by a different column.
const sp = Array.from(view.viewers).slice(1)
  .find((v) => v.type === DG.VIEWER.SCATTER_PLOT);
if (sp)
  sp.setOptions({colorColumnName: 'logP'});

view.addViewer(...) returns the freshly attached viewer, so you can chain create + configure:

const sp = view.addViewer(DG.VIEWER.SCATTER_PLOT, {
  xColumnName: 'height',
  yColumnName: 'weight',
  showRegressionLine: true,
});
sp.setOptions({xMin: 150, xMax: 200, colorColumnName: 'age'});

To discover property names, ask the viewer:

const v = view.addViewer(DG.VIEWER.SCATTER_PLOT);
const names = v.getProperties().map((p) => p.name);
return ui.divText(names.join(', '));

Finding viewers

view.viewers is an array; index 0 is always the grid, so iteration always starts with .slice(1).

// First scatter plot on the view (or undefined).
const sp = Array.from(view.viewers).slice(1)
  .find((v) => v.type === DG.VIEWER.SCATTER_PLOT);
// All histograms.
const hs = Array.from(view.viewers).slice(1)
  .filter((v) => v.type === DG.VIEWER.HISTOGRAM);

Closing viewers

viewer.close() closes and detaches the viewer. It throws if the viewer was never attached to a view, so wrap in try/catch.

// Close every scatter plot on the view.
Array.from(view.viewers).slice(1)
  .filter((v) => v.type === DG.VIEWER.SCATTER_PLOT)
  .forEach((v) => { try { v.close(); } catch {} });
// Close every non-grid viewer (reset the view to just the grid).
Array.from(view.viewers).slice(1)
  .forEach((v) => { try { v.close(); } catch {} });

Close-and-replace pattern for "show me X instead of Y":

// Close all scatter plots, then add a histogram.
Array.from(view.viewers).slice(1)
  .filter((v) => v.type === DG.VIEWER.SCATTER_PLOT)
  .forEach((v) => { try { v.close(); } catch {} });
view.addViewer(DG.VIEWER.HISTOGRAM, {valueColumnName: 'activity'});

Plugin viewers — they are functions, not types

Some "viewers" users name are actually package-registered functions that create a viewer as a side effect. They aren't in DG.VIEWER. Route via grok.functions.call:

User phraseFunction call
"chem space" / "chemical space"grok.functions.call('Chem:chemSpaceTopMenu', {table: t, molecules: t.col('smiles'), methodName: 'UMAP', similarityMetric: 'Tanimoto', plotEmbeddings: true})
"sequence space"grok.functions.call('Bio:sequenceSpaceTopMenu', {table: t, molecules: t.col('sequence'), methodName: 'UMAP', similarityMetric: 'Levenshtein', plotEmbeddings: true})
"activity cliffs"grok.functions.call('Chem:activityCliffs', {table: t, molecules: t.col('smiles'), activities: t.col('activity'), similarity: 80, methodName: 'UMAP'})
"elemental analysis"grok.functions.call('Chem:elementalAnalysis', {table: t, molecules: t.col('smiles')})

Each mutates the DataFrame and attaches a viewer to the current TableView. Only the *Space functions return the freshly-attached viewer (Chem:chemSpaceTopMenu, Bio:sequenceSpaceTopMenu). Chem:activityCliffs and Chem:elementalAnalysis return void, so to keep configuring you must find the new viewer via view.viewers:

const sp = await grok.functions.call('Chem:chemSpaceTopMenu', {
  table: t, molecules: t.col('smiles'),
  methodName: 'UMAP', similarityMetric: 'Tanimoto', plotEmbeddings: true,
});
if (sp)
  sp.setOptions({colorColumnName: 'activity'});

Standalone (detached) viewers

Use DG.Viewer.fromType only when embedding a viewer in a custom UI element you return from the block. The caller is responsible for placing the result. For everything else, prefer view.addViewer.

// Build a scatter plot of t and embed its DOM root in the chat.
const sp = DG.Viewer.fromType(DG.VIEWER.SCATTER_PLOT, t, {
  xColumnName: 'mw', yColumnName: 'logp',
});
return sp.root;

Anti-patterns

  1. Bare x / y / color in options — {x: 'mw', y: 'logp'} silently does nothing. The property is xColumnName.
  2. Literal strings instead of DG.VIEWER.* — use DG.VIEWER.SCATTER_PLOT, not 'scatter plot'.
  3. view.scatterPlot(opts) / view.histogram(opts) / view.barChart(opts) — per-type shorthands are deprecated. Use view.addViewer(DG.VIEWER.*, opts).
  4. new DG.Viewer(...) — internal constructor over a Dart handle. Use view.addViewer(type, opts) or DG.Viewer.fromType(type, df, opts?).
  5. grok.shell.addViewer(...) — no such method. Use view.addViewer(...).
  6. grok.shell.tv when view is in scope — view is the in-scope TableView. grok.shell.tv is the globally active view and may be a different tab.
  7. Treating "chem space" / "sequence space" / "activity cliffs" as viewer types — they're functions called via grok.functions.call.
  8. Iterating view.viewers without .slice(1) — index 0 is the grid. view.viewers.forEach(v => v.close()) closes the grid.
  9. viewer.close() on a never-attached viewer — throws. Guard with try/catch.
  10. await view.addViewer(...) — synchronous for built-in types. Only plugin viewers via grok.functions.call(...) are async.

Out of scope

  • Row filtering (df.filter) — datagrok-filtering.
  • Grid customization (visibility, widths, pinning) — datagrok-grid-customization; column color coding — datagrok-df-and-columns.
  • The Filters viewer (DG.VIEWER.FILTERS) — view.getFiltersGroup() is the right API and is covered by datagrok-filtering. Only add a Filters viewer here if the user explicitly says "add a filter panel as a viewer".

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

同一仓库的技能

Add support for a new curve data format in the Curves package converter system

中文简介正在准备中。当前显示原文说明。

datagrok-ai/public742026年10月20日 更新

Create info panels that appear in the context panel based on semantic types

中文简介正在准备中。当前显示原文说明。

datagrok-ai/public742026年10月20日 更新

Add a new single-objective optimization algorithm to the sci-comp library. Use when the user asks to implement a new optimizer (e.g. gradient descent, BFGS, simulated annealing, differential evolution).

中文简介正在准备中。当前显示原文说明。

datagrok-ai/public742026年10月20日 更新

Add unit tests to a Datagrok package

中文简介正在准备中。当前显示原文说明。

datagrok-ai/public742026年10月20日 更新

Answer a "how do I …" question about the platform with a Gherkin scenario on @datagrok-libraries/bdd that is filmed into a how-to video (grok-bdd guide), so the answer is demonstrated, sent as a video plus numbered steps, and kept as a regression test; the same scenarios, filmed in help mode, are the GIFs of the help pages

中文简介正在准备中。当前显示原文说明。

datagrok-ai/public742026年10月20日 更新

Translate hand-written Playwright specs (or any existing UI tests) into Gherkin features on @datagrok-libraries/bdd, then prove the features test what they claim by backward-matching them against the originals with independent reviewers, and fix the gaps in the core, the library and the features

中文简介正在准备中。当前显示原文说明。

datagrok-ai/public742026年10月20日 更新

查看 datagrok-ai 的全部技能

报告此技能的问题