Skip to content

feat(visualization): export the tables, ranges and embedded documents - #8366

Open
kz930 wants to merge 12 commits into
apache:mainfrom
kz930:feat/standalone-viz-a3
Open

kz930 wants to merge 12 commits into
apache:mainfrom
kz930:feat/standalone-viz-a3

Conversation

@kz930

@kz930 kz930 commented Sep 2, 2026 •

Copy link
Copy Markdown
Contributor

What changes were proposed in this PR?

Nine of them, and what they have in common is that the output is not a plot
drawn from numbers: a table rendered as a figure, a range a reader moves, an
image or an HTML document passed through, and the waterfall, which reads as a
chart but is built by accumulating rows rather than plotting them.

The waterfall plots every row and appends the total as a bar of its own,
rather than consuming the last row to make one.

One of these also changes what the engine does. URL Visualizer wrote the cell
straight into the iframe's src, so a quote in it closed the attribute and left
the rest of the cell standing as attributes of the iframe. Both paths escape it
now, the same five characters in the same order. Image Visualizer's exported
script reads a string as ready base64 only where the column was declared BINARY,
which is where the executor's own b64encode would have accepted it.

Any related issues, documentation, discussions?

Part of #8325, 15 of 27; that issue lists the set in order. It needs the Plotly mixin from #8365, so it does not compile until that lands.

Closes #7974.

Closes #8418, the task this change is the whole of.

How was this PR tested?

Each operator asserts the block it emits in its own spec. All nine have also been run through the engine and through their generated scripts, on every configuration their schemas offer, on a branch that carries this change together with the verification runner from #8362, and the two answers agreed for each of the nine. The rows these operators add to that runner arrive with it rather than as whole new files here.

Was this PR authored or co-authored using generative AI tooling?

Generated-by: Claude Code (Opus 5)

Nine of them, and what they have in common is that the output is not a plot
drawn from numbers: a table rendered as a figure, a range a reader moves, an
image or an HTML document passed through, and the waterfall, which reads as a
chart but is built by accumulating rows rather than plotting them.

The waterfall plots every row and appends the total as a bar of its own,
rather than consuming the last row to make one.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 2, 2026 •

Copy link
Copy Markdown
Contributor

Automated Reviewer Suggestions

Based on the git blame history of the changed files, we recommend the following reviewers:

  • Contributors with relevant context: @eugenegujing, @Yicong-Huang, @aglinxinyuan
    You can notify them by mentioning @eugenegujing, @Yicong-Huang, @aglinxinyuan in a comment.

@codecov-commenter

codecov-commenter commented Sep 2, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 35.29412% with 55 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.50%. Comparing base (4184858) to head (cceffa3).

Files with missing lines Patch % Lines
.../visualization/rangeSlider/RangeSliderOpDesc.scala 7.14% 13 Missing ⚠️
.../visualization/nestedTable/NestedTableOpDesc.scala 8.33% 11 Missing ⚠️
.../figureFactoryTable/FigureFactoryTableOpDesc.scala 10.00% 9 Missing ⚠️
...oordinatesPlot/ParallelCoordinatesPlotOpDesc.scala 11.11% 8 Missing ⚠️
...r/visualization/tablesChart/TablesPlotOpDesc.scala 16.66% 5 Missing ⚠️
...lization/waterfallChart/WaterfallChartOpDesc.scala 42.85% 4 Missing ⚠️
...r/operator/visualization/urlviz/UrlVizOpDesc.scala 25.00% 3 Missing ⚠️
...visualization/ImageViz/ImageVisualizerOpDesc.scala 90.90% 1 Missing ⚠️
...operator/visualization/htmlviz/HtmlVizOpDesc.scala 50.00% 1 Missing ⚠️

❌ Your patch status has failed because the patch coverage (35.29%) is below the target coverage (60.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files
@@             Coverage Diff              @@
##               main    #8366      +/-   ##
============================================
- Coverage     92.60%   92.50%   -0.11%     
- Complexity     5046     5047       +1     
============================================
  Files          1258     1258              
  Lines         53663    53736      +73     
  Branches       6683     6686       +3     
============================================
+ Hits          49697    49708      +11     
- Misses         2312     2369      +57     
- Partials       1654     1659       +5     
Flag Coverage Δ *Carryforward flag
access-control-service 77.38% <ø> (ø)
agent-service 99.16% <ø> (ø) Carriedforward from ed724eb
amber 87.80% <35.29%> (-0.27%) ⬇️
computing-unit-managing-service 60.48% <ø> (ø)
config-service 87.37% <ø> (ø)
file-service 82.00% <ø> (ø)
frontend 96.59% <ø> (-0.02%) ⬇️ Carriedforward from ed724eb
notebook-migration-service 83.73% <ø> (ø)
pyamber 98.50% <ø> (ø) Carriedforward from ed724eb
workflow-compiling-service 72.43% <ø> (ø)

*This pull request uses carry forward flags. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented Sep 2, 2026 •

Copy link
Copy Markdown
Contributor

⚠️ Benchmark changes need a look

🟢 0 better · 🔴 7 worse · ⚪ 8 noise (<±5%) · 0 without baseline

Compared against main 4184858 benchmarked on this same runner, so the delta is largely free of cross-runner hardware noise. The "7d avg" column still reflects the gh-pages dashboard. Treat <±5% as noise unless repeated.

Dashboard · Run

config throughput MB/s latency max Δ latest / 7d
🔴 bs=10 sw=10 sl=64 561 0.342 16,355/27,309/27,309 us 🔴 +14.0% / 🔴 +76.5%
🔴 bs=100 sw=10 sl=64 1,487 0.908 64,196/97,594/97,594 us 🔴 +22.1% / 🟢 +40.6%
⚪ bs=1000 sw=10 sl=64 1,867 1.139 531,227/604,647/604,647 us ⚪ within ±5% / 🟢 +69.9%
Baseline details

Latest main 4184858 from same runner

config metric PR latest main 7d avg Δ latest Δ 7d
bs=10 sw=10 sl=64 throughput 561 tuples/sec 634 tuples/sec 822.11 tuples/sec -11.5% -31.8%
bs=10 sw=10 sl=64 MB/s 0.342 MB/s 0.387 MB/s 0.502 MB/s -11.6% -31.8%
bs=10 sw=10 sl=64 p50 16,355 us 15,857 us 12,129 us +3.1% +34.8%
bs=10 sw=10 sl=64 p95 27,309 us 23,949 us 15,469 us +14.0% +76.5%
bs=10 sw=10 sl=64 p99 27,309 us 23,949 us 18,357 us +14.0% +48.8%
bs=100 sw=10 sl=64 throughput 1,487 tuples/sec 1,562 tuples/sec 1,058 tuples/sec -4.8% +40.6%
bs=100 sw=10 sl=64 MB/s 0.908 MB/s 0.954 MB/s 0.646 MB/s -4.8% +40.6%
bs=100 sw=10 sl=64 p50 64,196 us 60,120 us 97,399 us +6.8% -34.1%
bs=100 sw=10 sl=64 p95 97,594 us 79,911 us 104,184 us +22.1% -6.3%
bs=100 sw=10 sl=64 p99 97,594 us 79,911 us 117,615 us +22.1% -17.0%
bs=1000 sw=10 sl=64 throughput 1,867 tuples/sec 1,926 tuples/sec 1,099 tuples/sec -3.1% +69.9%
bs=1000 sw=10 sl=64 MB/s 1.139 MB/s 1.176 MB/s 0.671 MB/s -3.1% +69.8%
bs=1000 sw=10 sl=64 p50 531,227 us 514,577 us 946,743 us +3.2% -43.9%
bs=1000 sw=10 sl=64 p95 604,647 us 578,119 us 985,437 us +4.6% -38.6%
bs=1000 sw=10 sl=64 p99 604,647 us 578,119 us 1,012,622 us +4.6% -40.3%
Raw CSV
config_idx,batch_size,schema_width,string_len,num_batches,total_ms,total_tuples,total_bytes,tuples_per_sec,mb_per_sec,lat_p50_us,lat_p95_us,lat_p99_us
0,10,10,64,20,356.43,200,128000,561,0.342,16354.52,27309.02,27309.02
1,100,10,64,20,1344.65,2000,1280000,1487,0.908,64196.35,97594.33,97594.33
2,1000,10,64,20,10713.21,20000,12800000,1867,1.139,531227.11,604646.63,604646.63

@carloea2 carloea2 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The table and embedded output exports look good.

@kz930
kz930 marked this pull request as draft September 4, 2026 17:12
The translator no longer emits plotly into every script; it asks the operators
in the plan what they need beyond pandas. Five of the nine here draw with
plotly and mix in `PlotlyStandaloneCode`, which the hierarchy and graph charts
introduce.

The other four state nothing, which is the point of asking: an image, an HTML
document, a nested table and a passed-through URL name none of plotly's
modules, so a script built from them runs wherever pandas is installed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@carloea2 carloea2 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked the new import declarations. They look good.

Figure Factory Table imports `plotly.figure_factory` inside its own generated code, and
uses none of the three modules the mixin declares. Mixing it in would put an
import in the script that the script never reads.

The mixin states what a script has to import at module scope. An operator that
imports what it needs inside its own code has nothing to add there.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@carloea2 carloea2 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The import cleanup looks good.

kz930 and others added 3 commits September 8, 2026 13:58
…e default

Both say `producesDataFrame = true`, which the trait already returns. They sit
among charts that override it to false, which is what made saying it look like a
distinction; the comment beside it said the same thing a second time.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Every chart wrote output.html and output.json, and the whole plan runs as
one program in one directory, so a workflow ending in two charts kept a
single picture. The name is a placeholder now, outputHtml and outputJson,
and the translator hands each operator a stem of its own.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The engine's operator says 'Figure Factory Table is not available' on one
line; the exported script still said 'Figure factory table' across three,
so the same refusal reached a reader as two different pages. Tables Plot
had the same split without the wording difference.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@kz930

kz930 commented Sep 11, 2026 •

Copy link
Copy Markdown
Contributor Author

@carloea2 this moved after your approval: each chart names its own output files, both paths now write the same reason page, and a producesDataFrame override that only restated the default is gone. Would you take another look when you have a moment?

@carloea2 carloea2 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The charts now use separate files and give the same error page on both paths. Looks good.

@carloea2 carloea2 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image Visualizer handles string input differently. The native path returns an invalid binary error page, but standalone treats the string as ready base64 image data. Please make both paths agree and test string input.

@carloea2 carloea2 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Url Viz writes the value directly inside an iframe attribute. Quotes in the value can add another HTML attribute. Please escape HTML attribute values in both paths and add a hostile value test.

kz930 and others added 2 commits September 18, 2026 13:29
…Viz writes

Image Visualizer read any string as ready base64, where the executor hands the
same value to b64encode and shows its reason page when the value is not bytes.
The exported script reads a BINARY column as the base64 text JSONL carries, so
the text is the image only where the column was declared BINARY; a column of
any other type now fails in the same call, on the same page.

URL Visualizer wrote the cell straight into the iframe's src attribute, so a
quote in it closed the attribute and left the rest of the cell standing as
attributes of the iframe. Both paths escape it now, the same five characters
in the same order, which is what html.escape(quote=True) writes. An ampersand
in a URL is written &amp; from here on, which the browser reads back as one.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@kz930

kz930 commented Sep 18, 2026

Copy link
Copy Markdown
Contributor Author

Both fixed in c614ca5: a column's text is read as the image only where the column was declared BINARY, so a string gets the reason page on both paths, and Url Viz escapes the cell before it lands in the src attribute, so a quote can no longer add an attribute. Both sides escape what html.escape(quote=True) writes, which means an ordinary URL's ampersand is now written &amp;.

@carloea2 carloea2 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The image input handling and URL escaping are fixed in the reviewed paths. Looks good.

kz930 and others added 2 commits September 26, 2026 15:27
…-integration

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…d one every row leaves

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

@carloea2 carloea2 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The non-security update passes review. Production files are unchanged from the earlier reviewed head. All 53 focused tests across 8 operator suites pass. I also ran both updated table charts through the real #8766 SDK lifecycle and their exported code: empty and fully holed inputs give matching error pages, and filled Unicode tables give matching figures. Formatting passes. Only the merged Plotly helper was supplied locally.

sbt -batch 'WorkflowOperator/testOnly *ImageVisualizerOpDescSpec *FigureFactoryTableOpDescSpec *HtmlVizOpDescSpec *NestedTableOpDescSpec *ParallelCoordinatesPlotOpDescSpec *RangeSliderOpDescSpec *TablesPlotOpDescSpec *WaterfallChartOpDescSpec *TableSdkReviewSpec -- -oDF' 'scalafmtCheckAll'

No new finding. Current CI still needs to be cleared before merging.

Python's open() defaults to the locale's encoding, which is cp1252 on
Windows, while the spec writes these files as UTF-8.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@carloea2 carloea2 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Retested with current upstream main merged locally. All 53 focused tests across 8 suites and formatting checks pass, including the updated UTF-8 drivers. The PR's production files are unchanged from the reviewed version. CI failed downloading dependencies in computing-unit-managing-service, not in these tests. Code looks good; CI and the stated merge order still need clearing. Leaving the draft unchanged.

@kz930
kz930 marked this pull request as ready for review October 15, 2026 00:17

@aglinxinyuan aglinxinyuan left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@aglinxinyuan
aglinxinyuan added this pull request to the merge queue Oct 19, 2026
kz930 added a commit to kz930/texera that referenced this pull request Oct 19, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 19, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Export the tables, ranges and embedded documents Waterfall Chart consumes the last data row as its total bar, so that row's value is never plotted

4 participants