This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/texera.git
The following commit(s) were added to refs/heads/main by this push:
new 5914ae077f feat(workflow-operator): stop forcing a color column on
every Bubble Chart (#7396)
5914ae077f is described below
commit 5914ae077fee211ba89af55ac7fea86bde2e0b72
Author: Kary Zheng <[email protected]>
AuthorDate: Sun Aug 9 17:11:54 2026 -0700
feat(workflow-operator): stop forcing a color column on every Bubble Chart
(#7396)
### What changes were proposed in this PR?
Bubble Chart's Color-Column was declared `required = true` with
`@NotNull`, but the generated Python reads it only inside the Enable
Color branch. The effect was that a freshly dropped Bubble Chart stayed
invalid until the user picked a color column, even when they wanted
plain bubbles — and the column they picked was then never used.
This PR makes the field optional and puts it behind the toggle via
`toggleHidden`, so it disappears from the panel when Enable Color is
off. That matches Ternary Plot, which has the same toggle-plus-column
pair and already declares its color field optional.
The color decision also moves out of the generated Python and into
Scala. The old template emitted an `if '...' == 'true':` comparison over
a Scala Boolean; it is now a `colorArg` computed at build time, guarded
on both the toggle and the column being non-empty. That second half
matters: with the required flag gone, an empty column would otherwise
reach `px.scatter(color='')`, which plotly rejects — the same failure
fixed for Bar Chart in #6792.
Behavior for existing workflows is unchanged. `enableColor` keeps its
meaning, so no saved chart changes appearance.
The operator reference page is updated to match the new requirement and
description.
### Any related issues, documentation, discussions?
Closes #7395
### How was this PR tested?
Existing `BubbleChartOpDescSpec` passes unchanged, including the
assertion that pins the no-color output line. Three cases were added to
it, covering the toggle-and-column matrix: enabled with a column chosen
(color is emitted), enabled with no column (color is omitted rather than
emitted empty), and disabled with a column chosen (the column is not
emitted).
### Was this PR authored or co-authored using generative AI tooling?
Generated-by: Claude Code (Claude Opus 5)
Co-authored-by: Meng Wang <[email protected]>
---
.../bubbleChart/BubbleChartOpDesc.scala | 15 +++++-----
.../bubbleChart/BubbleChartOpDescSpec.scala | 32 ++++++++++++++++++++++
.../operators/visualization/basic/bubble-chart.md | 2 +-
3 files changed, 41 insertions(+), 8 deletions(-)
diff --git
a/common/workflow-operator/src/main/scala/org/apache/texera/amber/operator/visualization/bubbleChart/BubbleChartOpDesc.scala
b/common/workflow-operator/src/main/scala/org/apache/texera/amber/operator/visualization/bubbleChart/BubbleChartOpDesc.scala
index ad31361064..edb83c2bbb 100644
---
a/common/workflow-operator/src/main/scala/org/apache/texera/amber/operator/visualization/bubbleChart/BubbleChartOpDesc.scala
+++
b/common/workflow-operator/src/main/scala/org/apache/texera/amber/operator/visualization/bubbleChart/BubbleChartOpDesc.scala
@@ -75,13 +75,15 @@ class BubbleChartOpDesc extends PythonOperatorDescriptor {
@JsonProperty(value = "enableColor", defaultValue = "false")
@JsonSchemaTitle("Enable Color")
@JsonPropertyDescription("Colors bubbles using a data column")
+ @JsonSchemaInject(json = """{"toggleHidden" : ["colorCategory"]}""")
var enableColor: Boolean = false
- @JsonProperty(value = "colorCategory", required = true)
+ @JsonProperty(value = "colorCategory", required = false)
@JsonSchemaTitle("Color-Column")
- @JsonPropertyDescription("Picks data column to color bubbles with if color
is enabled")
+ @JsonPropertyDescription(
+ "Optional data column to color bubbles with; leave empty for uniform
bubbles"
+ )
@AutofillAttributeName
- @NotNull(message = "Color-Column cannot be empty")
var colorCategory: EncodableString = ""
override def getOutputSchemas(
@@ -114,11 +116,10 @@ class BubbleChartOpDesc extends PythonOperatorDescriptor {
assert(xValue.nonEmpty, "X-Column cannot be empty")
assert(yValue.nonEmpty, "Y-Column cannot be empty")
assert(zValue.nonEmpty, "Z-Column cannot be empty")
+ // An unset column counts as "no color" even with the toggle on, else
px.scatter(color='') fails.
+ val colorArg = if (enableColor && colorCategory.nonEmpty) pyb",
color=$colorCategory" else pyb""
pyb"""
- | if '$enableColor' == 'true':
- | fig = go.Figure(px.scatter(table, x=$xValue, y=$yValue,
size=$zValue, size_max=100, color=$colorCategory))
- | else:
- | fig = go.Figure(px.scatter(table, x=$xValue, y=$yValue,
size=$zValue, size_max=100))
+ | fig = go.Figure(px.scatter(table, x=$xValue, y=$yValue,
size=$zValue$colorArg, size_max=100))
|"""
}
diff --git
a/common/workflow-operator/src/test/scala/org/apache/texera/amber/operator/visualization/bubbleChart/BubbleChartOpDescSpec.scala
b/common/workflow-operator/src/test/scala/org/apache/texera/amber/operator/visualization/bubbleChart/BubbleChartOpDescSpec.scala
index 85fbd1fa3f..37c4197b6b 100644
---
a/common/workflow-operator/src/test/scala/org/apache/texera/amber/operator/visualization/bubbleChart/BubbleChartOpDescSpec.scala
+++
b/common/workflow-operator/src/test/scala/org/apache/texera/amber/operator/visualization/bubbleChart/BubbleChartOpDescSpec.scala
@@ -53,6 +53,38 @@ class BubbleChartOpDescSpec extends AnyFlatSpec with
BeforeAndAfter with Matcher
)
}
+ it should "color by the chosen column when color is enabled" in {
+ opDesc.xValue = "column1"
+ opDesc.yValue = "column2"
+ opDesc.zValue = "column3"
+ opDesc.enableColor = true
+ opDesc.colorCategory = "column4"
+
+ opDesc.createPlotlyFigure().plain should include(
+ "fig = go.Figure(px.scatter(table, x=column1, y=column2, size=column3,
color=column4, size_max=100))"
+ )
+ }
+
+ // px.scatter(color='') raises, so an unset column has to fall back to
uniform bubbles.
+ it should "omit color when color is enabled but no column is chosen" in {
+ opDesc.xValue = "column1"
+ opDesc.yValue = "column2"
+ opDesc.zValue = "column3"
+ opDesc.enableColor = true
+
+ opDesc.createPlotlyFigure().plain should not include "color="
+ }
+
+ it should "omit color when a column is chosen but color is disabled" in {
+ opDesc.xValue = "column1"
+ opDesc.yValue = "column2"
+ opDesc.zValue = "column3"
+ opDesc.enableColor = false
+ opDesc.colorCategory = "column4"
+
+ opDesc.createPlotlyFigure().plain should not include "column4"
+ }
+
it should "throw assertion error if variable xValue is empty" in {
assertThrows[AssertionError] {
opDesc.createPlotlyFigure()
diff --git a/docs/reference/operators/visualization/basic/bubble-chart.md
b/docs/reference/operators/visualization/basic/bubble-chart.md
index e1dde75f62..4489cacedd 100644
--- a/docs/reference/operators/visualization/basic/bubble-chart.md
+++ b/docs/reference/operators/visualization/basic/bubble-chart.md
@@ -35,7 +35,7 @@ tags: [visualization, basic]
| Y-Column | ✓ | String | - | Data column for the y-axis |
| Z-Column | ✓ | String | - | Data column to determine bubble size |
| Enable Color | | Boolean | false | Colors bubbles using a data column |
-| Color-Column | ✓ | String | - | Picks data column to color bubbles with if
color<br>is enabled |
+| Color-Column | | String | - | Optional data column to color bubbles with;
leave<br>empty for uniform bubbles |
### Output Ports