Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,20 @@ package org.apache.texera.amber.operator.visualization.DotPlot

import com.fasterxml.jackson.annotation.{JsonProperty, JsonPropertyDescription}
import com.kjetland.jackson.jsonSchema.annotations.JsonSchemaTitle
import org.apache.texera.amber.core.tuple.{AttributeType, Schema}
import org.apache.texera.amber.pybuilder.PythonTemplateBuilder.{
PythonTemplateBuilderStringContext,
pyStringLiteral
}
import org.apache.texera.amber.pybuilder.PyStringTypes.EncodableString
import org.apache.texera.amber.core.workflow.PortIdentity
import org.apache.texera.amber.operator.PythonOperatorDescriptor
import org.apache.texera.amber.operator.visualization.PlotlyStandaloneCode
import org.apache.texera.amber.operator.visualization.PythonVisualizationOpDesc
import org.apache.texera.amber.operator.metadata.annotations.AutofillAttributeName
import org.apache.texera.amber.operator.metadata.{OperatorGroupConstants, OperatorInfo}
import org.apache.texera.amber.pybuilder.PythonTemplateBuilder

import javax.validation.constraints.NotNull

class DotPlotOpDesc extends PythonOperatorDescriptor with PlotlyStandaloneCode {
class DotPlotOpDesc extends PythonVisualizationOpDesc with PlotlyStandaloneCode {

@JsonProperty(value = "Count Attribute", required = true)
@JsonSchemaTitle("Count Attribute")
Expand All @@ -45,14 +43,6 @@ class DotPlotOpDesc extends PythonOperatorDescriptor with PlotlyStandaloneCode {
@NotNull(message = "Count Attribute column cannot be empty")
var countAttribute: EncodableString = ""

override def getOutputSchemas(
inputSchemas: Map[PortIdentity, Schema]
): Map[PortIdentity, Schema] = {
val outputSchema = Schema()
.add("html-content", AttributeType.STRING)
Map(operatorInfo.outputPorts.head.id -> outputSchema)
}

override def operatorInfo: OperatorInfo =
OperatorInfo.forVisualization(
"Dot Plot",
Expand Down Expand Up @@ -104,10 +94,6 @@ class DotPlotOpDesc extends PythonOperatorDescriptor with PlotlyStandaloneCode {
finalCode.encode
}

// Output is an HTML chart, not a tabular DataFrame.
// The translator skips it in the leaf-DataFrame print block.
override def producesDataFrame(): Boolean = false

override def generateStandaloneCode(): String = {
val countLit = pyStringLiteral(countAttribute)
// The error page is written to the same file a plotted chart lands in, so a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,13 @@ package org.apache.texera.amber.operator.visualization.IcicleChart

import com.fasterxml.jackson.annotation.{JsonProperty, JsonPropertyDescription}
import com.kjetland.jackson.jsonSchema.annotations.{JsonSchemaInject, JsonSchemaTitle}
import org.apache.texera.amber.core.tuple.{AttributeType, Schema}
import org.apache.texera.amber.pybuilder.PythonTemplateBuilder.{
PythonTemplateBuilderStringContext,
pyStringLiteral
}
import org.apache.texera.amber.pybuilder.PyStringTypes.EncodableString
import org.apache.texera.amber.core.workflow.PortIdentity
import org.apache.texera.amber.operator.PythonOperatorDescriptor
import org.apache.texera.amber.operator.visualization.PlotlyStandaloneCode
import org.apache.texera.amber.operator.visualization.PythonVisualizationOpDesc
import org.apache.texera.amber.operator.metadata.annotations.AutofillAttributeName
import org.apache.texera.amber.operator.metadata.{OperatorGroupConstants, OperatorInfo}
import org.apache.texera.amber.operator.visualization.hierarchychart.HierarchySection
Expand All @@ -47,7 +45,7 @@ import javax.validation.constraints.{NotEmpty, NotNull}
}
}
""")
class IcicleChartOpDesc extends PythonOperatorDescriptor with PlotlyStandaloneCode {
class IcicleChartOpDesc extends PythonVisualizationOpDesc with PlotlyStandaloneCode {
@JsonProperty(required = true)
@JsonSchemaTitle("Hierarchy Path")
@JsonPropertyDescription(
Expand All @@ -63,14 +61,6 @@ class IcicleChartOpDesc extends PythonOperatorDescriptor with PlotlyStandaloneCo
@NotNull(message = "Value Column cannot be empty")
var value: EncodableString = ""

override def getOutputSchemas(
inputSchemas: Map[PortIdentity, Schema]
): Map[PortIdentity, Schema] = {
val outputSchema = Schema()
.add("html-content", AttributeType.STRING)
Map(operatorInfo.outputPorts.head.id -> outputSchema)
}

override def operatorInfo: OperatorInfo =
OperatorInfo.forVisualization(
"Icicle Chart",
Expand Down Expand Up @@ -136,10 +126,6 @@ class IcicleChartOpDesc extends PythonOperatorDescriptor with PlotlyStandaloneCo
finalCode.encode
}

// Output is an HTML chart, not a tabular DataFrame.
// The translator skips it in the leaf-DataFrame print block.
override def producesDataFrame(): Boolean = false

override def generateStandaloneCode(): String = {
val attributes = hierarchy.map(section => pyStringLiteral(section.attributeName)).mkString(", ")
val valueLit = pyStringLiteral(value)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ import org.apache.texera.amber.pybuilder.PythonTemplateBuilder.{
}
import org.apache.texera.amber.pybuilder.PyStringTypes.EncodableString
import org.apache.texera.amber.core.workflow.PortIdentity
import org.apache.texera.amber.operator.{PythonOperatorDescriptor, StandaloneCodeGenerator}
import org.apache.texera.amber.operator.visualization.PythonVisualizationOpDesc
import org.apache.texera.amber.operator.metadata.annotations.AutofillAttributeName
import org.apache.texera.amber.operator.metadata.{OperatorGroupConstants, OperatorInfo}
import org.apache.texera.amber.pybuilder.PythonTemplateBuilder

import javax.validation.constraints.NotNull
class ImageVisualizerOpDesc extends PythonOperatorDescriptor with StandaloneCodeGenerator {
class ImageVisualizerOpDesc extends PythonVisualizationOpDesc {

@JsonProperty(required = true)
@JsonSchemaTitle("image content column")
Expand All @@ -43,14 +43,6 @@ class ImageVisualizerOpDesc extends PythonOperatorDescriptor with StandaloneCode
@NotNull(message = "image content column cannot be empty")
var binaryContent: EncodableString = ""

override def getOutputSchemas(
inputSchemas: Map[PortIdentity, Schema]
): Map[PortIdentity, Schema] = {
val outputSchema = Schema()
.add("html-content", AttributeType.STRING)
Map(operatorInfo.outputPorts.head.id -> outputSchema)
}

override def operatorInfo: OperatorInfo =
OperatorInfo.forVisualization(
"Image Visualizer",
Expand Down Expand Up @@ -101,10 +93,6 @@ class ImageVisualizerOpDesc extends PythonOperatorDescriptor with StandaloneCode
finalCode.encode
}

// Output is an HTML visualization, not a tabular DataFrame.
// The translator skips it in the leaf-DataFrame print block.
override def producesDataFrame(): Boolean = false

override def generateStandaloneCode(): String = generateStandaloneCode(Map.empty)

/** The executor hands `b64encode` whatever the column holds, so a column of
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.apache.texera.amber.operator.visualization

import org.apache.texera.amber.core.tuple.{AttributeType, Schema}
import org.apache.texera.amber.core.workflow.PortIdentity
import org.apache.texera.amber.operator.{PythonOperatorDescriptor, StandaloneCodeGenerator}

/**
* A chart drawn by Python code.
*
* Its one output port carries a single `html-content` STRING column, whatever
* the input schemas are: that column is where the frontend finds the rendered
* chart. Its exported script writes the chart to a file rather than producing
* a table, so the translator does not print it as a leaf DataFrame.
*/
trait PythonVisualizationOpDesc extends PythonOperatorDescriptor with StandaloneCodeGenerator {

override def getOutputSchemas(
inputSchemas: Map[PortIdentity, Schema]
): Map[PortIdentity, Schema] =
Map(operatorInfo.outputPorts.head.id -> Schema().add("html-content", AttributeType.STRING))

override def producesDataFrame(): Boolean = false
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,13 @@ package org.apache.texera.amber.operator.visualization.ScatterMatrixChart

import com.fasterxml.jackson.annotation.{JsonProperty, JsonPropertyDescription}
import com.kjetland.jackson.jsonSchema.annotations.{JsonSchemaInject, JsonSchemaTitle}
import org.apache.texera.amber.core.tuple.{AttributeType, Schema}
import org.apache.texera.amber.pybuilder.PythonTemplateBuilder.{
PythonTemplateBuilderStringContext,
pyStringLiteral
}
import org.apache.texera.amber.pybuilder.PyStringTypes.EncodableString
import org.apache.texera.amber.core.workflow.PortIdentity
import org.apache.texera.amber.operator.PythonOperatorDescriptor
import org.apache.texera.amber.operator.visualization.PlotlyStandaloneCode
import org.apache.texera.amber.operator.visualization.PythonVisualizationOpDesc
import org.apache.texera.amber.operator.metadata.annotations.{
AutofillAttributeName,
AutofillAttributeNameList
Expand All @@ -50,7 +48,7 @@ import javax.validation.constraints.{NotEmpty, NotNull}
}
}
""")
class ScatterMatrixChartOpDesc extends PythonOperatorDescriptor with PlotlyStandaloneCode {
class ScatterMatrixChartOpDesc extends PythonVisualizationOpDesc with PlotlyStandaloneCode {

@JsonProperty(value = "Selected Attributes", required = true)
@JsonSchemaTitle("Selected Attributes")
Expand All @@ -66,14 +64,6 @@ class ScatterMatrixChartOpDesc extends PythonOperatorDescriptor with PlotlyStand
@NotNull(message = "Color Column cannot be empty")
var color: EncodableString = ""

override def getOutputSchemas(
inputSchemas: Map[PortIdentity, Schema]
): Map[PortIdentity, Schema] = {
val outputSchema = Schema()
.add("html-content", AttributeType.STRING)
Map(operatorInfo.outputPorts.head.id -> outputSchema)
}

override def operatorInfo: OperatorInfo =
OperatorInfo.forVisualization(
"Scatter Matrix Chart",
Expand Down Expand Up @@ -118,10 +108,6 @@ class ScatterMatrixChartOpDesc extends PythonOperatorDescriptor with PlotlyStand
finalcode.encode
}

// Output is an HTML visualization, not a tabular DataFrame.
// The translator skips it in the leaf-DataFrame print block.
override def producesDataFrame(): Boolean = false

override def generateStandaloneCode(): String = {
val dimensions = selectedAttributes.map(pyStringLiteral).mkString(", ")
// No empty-input guard, matching generatePythonCode: it goes straight to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,13 @@ package org.apache.texera.amber.operator.visualization.barChart

import com.fasterxml.jackson.annotation.{JsonProperty, JsonPropertyDescription}
import com.kjetland.jackson.jsonSchema.annotations.{JsonSchemaInject, JsonSchemaTitle}
import org.apache.texera.amber.core.tuple.{AttributeType, Schema}
import org.apache.texera.amber.pybuilder.PythonTemplateBuilder.{
PythonTemplateBuilderStringContext,
pyStringLiteral
}
import org.apache.texera.amber.pybuilder.PyStringTypes.EncodableString
import org.apache.texera.amber.core.workflow.PortIdentity
import org.apache.texera.amber.operator.PythonOperatorDescriptor
import org.apache.texera.amber.operator.visualization.PlotlyStandaloneCode
import org.apache.texera.amber.operator.visualization.PythonVisualizationOpDesc
import org.apache.texera.amber.operator.metadata.annotations.AutofillAttributeName
import org.apache.texera.amber.operator.metadata.{OperatorGroupConstants, OperatorInfo}
import org.apache.texera.amber.pybuilder.PythonTemplateBuilder
Expand All @@ -46,7 +44,7 @@ import javax.validation.constraints.NotNull
}
}
""")
class BarChartOpDesc extends PythonOperatorDescriptor with PlotlyStandaloneCode {
class BarChartOpDesc extends PythonVisualizationOpDesc with PlotlyStandaloneCode {

@JsonProperty(value = "value", required = true)
@JsonSchemaTitle("Value Column")
Expand Down Expand Up @@ -79,14 +77,6 @@ class BarChartOpDesc extends PythonOperatorDescriptor with PlotlyStandaloneCode
@AutofillAttributeName
var pattern: EncodableString = ""

override def getOutputSchemas(
inputSchemas: Map[PortIdentity, Schema]
): Map[PortIdentity, Schema] = {
val outputSchema = Schema()
.add("html-content", AttributeType.STRING)
Map(operatorInfo.outputPorts.head.id -> outputSchema)
}

override def operatorInfo: OperatorInfo =
OperatorInfo.forVisualization(
"Bar Chart",
Expand Down Expand Up @@ -159,10 +149,6 @@ class BarChartOpDesc extends PythonOperatorDescriptor with PlotlyStandaloneCode
finalCode.encode
}

// Output is an HTML chart, not a tabular DataFrame.
// The translator skips it in the leaf-DataFrame print block.
override def producesDataFrame(): Boolean = false

override def generateStandaloneCode(): String = {
val hasCategory = categoryColumn.nonEmpty && categoryColumn != "No Selection"
val colorArg = if (hasCategory) pyStringLiteral(categoryColumn) else "None"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,13 @@ package org.apache.texera.amber.operator.visualization.boxViolinPlot

import com.fasterxml.jackson.annotation.{JsonProperty, JsonPropertyDescription, JsonPropertyOrder}
import com.kjetland.jackson.jsonSchema.annotations.{JsonSchemaInject, JsonSchemaTitle}
import org.apache.texera.amber.core.tuple.{AttributeType, Schema}
import org.apache.texera.amber.pybuilder.PythonTemplateBuilder.{
PythonTemplateBuilderStringContext,
pyStringLiteral
}
import org.apache.texera.amber.pybuilder.PyStringTypes.EncodableString
import org.apache.texera.amber.core.workflow.PortIdentity
import org.apache.texera.amber.operator.PythonOperatorDescriptor
import org.apache.texera.amber.operator.visualization.PlotlyStandaloneCode
import org.apache.texera.amber.operator.visualization.PythonVisualizationOpDesc
import org.apache.texera.amber.operator.metadata.annotations.AutofillAttributeName
import org.apache.texera.amber.operator.metadata.{OperatorGroupConstants, OperatorInfo}
import org.apache.texera.amber.pybuilder.PythonTemplateBuilder
Expand All @@ -46,7 +44,7 @@ import javax.validation.constraints.NotNull
}
}
""")
class BoxViolinPlotOpDesc extends PythonOperatorDescriptor with PlotlyStandaloneCode {
class BoxViolinPlotOpDesc extends PythonVisualizationOpDesc with PlotlyStandaloneCode {

@JsonProperty(value = "value", required = true)
@JsonSchemaTitle("Value Column")
Expand Down Expand Up @@ -74,14 +72,6 @@ class BoxViolinPlotOpDesc extends PythonOperatorDescriptor with PlotlyStandalone
)
var violinPlot: Boolean = _

override def getOutputSchemas(
inputSchemas: Map[PortIdentity, Schema]
): Map[PortIdentity, Schema] = {
val outputSchema = Schema()
.add("html-content", AttributeType.STRING)
Map(operatorInfo.outputPorts.head.id -> outputSchema)
}

override def operatorInfo: OperatorInfo =
OperatorInfo.forVisualization(
"Box/Violin Plot",
Expand Down Expand Up @@ -156,10 +146,6 @@ class BoxViolinPlotOpDesc extends PythonOperatorDescriptor with PlotlyStandalone
finalCode.encode
}

// Output is a Plotly visualization, not a tabular DataFrame.
// The translator skips it in the leaf-DataFrame print block.
override def producesDataFrame(): Boolean = false

override def generateStandaloneCode(): String = {
val horizontal = if (horizontalOrientation) "True" else "False"
val violin = if (violinPlot) "True" else "False"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,13 @@ package org.apache.texera.amber.operator.visualization.bubbleChart

import com.fasterxml.jackson.annotation.{JsonProperty, JsonPropertyDescription}
import com.kjetland.jackson.jsonSchema.annotations.{JsonSchemaInject, JsonSchemaTitle}
import org.apache.texera.amber.core.tuple.{AttributeType, Schema}
import org.apache.texera.amber.pybuilder.PythonTemplateBuilder.{
PythonTemplateBuilderStringContext,
pyStringLiteral
}
import org.apache.texera.amber.pybuilder.PyStringTypes.EncodableString
import org.apache.texera.amber.core.workflow.PortIdentity
import org.apache.texera.amber.operator.PythonOperatorDescriptor
import org.apache.texera.amber.operator.visualization.PlotlyStandaloneCode
import org.apache.texera.amber.operator.visualization.PythonVisualizationOpDesc
import org.apache.texera.amber.operator.metadata.annotations.AutofillAttributeName
import org.apache.texera.amber.operator.metadata.{OperatorGroupConstants, OperatorInfo}
import org.apache.texera.amber.pybuilder.PythonTemplateBuilder
Expand All @@ -53,7 +51,7 @@ import javax.validation.constraints.NotNull
}
}
""")
class BubbleChartOpDesc extends PythonOperatorDescriptor with PlotlyStandaloneCode {
class BubbleChartOpDesc extends PythonVisualizationOpDesc with PlotlyStandaloneCode {

@JsonProperty(value = "xValue", required = true)
@JsonSchemaTitle("X-Column")
Expand Down Expand Up @@ -90,14 +88,6 @@ class BubbleChartOpDesc extends PythonOperatorDescriptor with PlotlyStandaloneCo
@AutofillAttributeName
var colorCategory: EncodableString = ""

override def getOutputSchemas(
inputSchemas: Map[PortIdentity, Schema]
): Map[PortIdentity, Schema] = {
val outputSchema = Schema()
.add("html-content", AttributeType.STRING)
Map(operatorInfo.outputPorts.head.id -> outputSchema)
}

override def operatorInfo: OperatorInfo =
OperatorInfo.forVisualization(
"Bubble Chart",
Expand Down Expand Up @@ -162,10 +152,6 @@ class BubbleChartOpDesc extends PythonOperatorDescriptor with PlotlyStandaloneCo
finalCode.encode
}

// Output is an HTML chart, not a tabular DataFrame.
// The translator skips it in the leaf-DataFrame print block.
override def producesDataFrame(): Boolean = false

override def generateStandaloneCode(): String = {
// Same rule as the platform path: an unset column is "no color" even with the
// toggle on, else px.scatter(color='') fails.
Expand Down
Loading
Loading