From 34dc08f47bf56eb4bc2cf01948e164a1f3fdf628 Mon Sep 17 00:00:00 2001 From: gspikehalo <2318002579@qq.com> Date: Wed, 21 May 2025 00:03:57 -0700 Subject: [PATCH 01/13] pass the count to the frontend --- .../websocket/event/OperatorStatisticsUpdateEvent.scala | 4 ++++ .../ics/texera/web/service/ExecutionStatsService.scala | 9 +++++++++ .../workflow-editor/workflow-editor.component.ts | 1 + .../service/workflow-status/workflow-status.service.ts | 2 ++ .../app/workspace/types/execute-workflow.interface.ts | 2 ++ 5 files changed, 18 insertions(+) diff --git a/core/amber/src/main/scala/edu/uci/ics/texera/web/model/websocket/event/OperatorStatisticsUpdateEvent.scala b/core/amber/src/main/scala/edu/uci/ics/texera/web/model/websocket/event/OperatorStatisticsUpdateEvent.scala index 3e66da4b946..335d5a7c215 100644 --- a/core/amber/src/main/scala/edu/uci/ics/texera/web/model/websocket/event/OperatorStatisticsUpdateEvent.scala +++ b/core/amber/src/main/scala/edu/uci/ics/texera/web/model/websocket/event/OperatorStatisticsUpdateEvent.scala @@ -19,12 +19,16 @@ package edu.uci.ics.texera.web.model.websocket.event +import edu.uci.ics.amber.engine.architecture.worker.statistics.TupleMetrics + case class OperatorAggregatedMetrics( operatorState: String, aggregatedInputRowCount: Long, aggregatedInputSize: Long, + inputPortMetrics: Map[String, TupleMetrics], aggregatedOutputRowCount: Long, aggregatedOutputSize: Long, + outputPortMetrics: Map[String, TupleMetrics], numWorkers: Long, aggregatedDataProcessingTime: Long, aggregatedControlProcessingTime: Long, diff --git a/core/amber/src/main/scala/edu/uci/ics/texera/web/service/ExecutionStatsService.scala b/core/amber/src/main/scala/edu/uci/ics/texera/web/service/ExecutionStatsService.scala index 13fc6fc8071..79485d05860 100644 --- a/core/amber/src/main/scala/edu/uci/ics/texera/web/service/ExecutionStatsService.scala +++ b/core/amber/src/main/scala/edu/uci/ics/texera/web/service/ExecutionStatsService.scala @@ -106,12 +106,21 @@ class ExecutionStatsService( OperatorStatisticsUpdateEvent(newState.operatorInfo.collect { case x => val metrics = x._2 + val inMap = metrics.operatorStatistics.inputMetrics + .map(pm => pm.portId.id.toString -> pm.tupleMetrics) + .toMap + val outMap = metrics.operatorStatistics.outputMetrics + .map(pm => pm.portId.id.toString -> pm.tupleMetrics) + .toMap + val res = OperatorAggregatedMetrics( Utils.aggregatedStateToString(metrics.operatorState), metrics.operatorStatistics.inputMetrics.map(_.tupleMetrics.count).sum, metrics.operatorStatistics.inputMetrics.map(_.tupleMetrics.size).sum, + inMap, metrics.operatorStatistics.outputMetrics.map(_.tupleMetrics.count).sum, metrics.operatorStatistics.outputMetrics.map(_.tupleMetrics.size).sum, + outMap, metrics.operatorStatistics.numWorkers, metrics.operatorStatistics.dataProcessingTime, metrics.operatorStatistics.controlProcessingTime, diff --git a/core/gui/src/app/workspace/component/workflow-editor/workflow-editor.component.ts b/core/gui/src/app/workspace/component/workflow-editor/workflow-editor.component.ts index 3ef1bece169..bccb2b11d3a 100644 --- a/core/gui/src/app/workspace/component/workflow-editor/workflow-editor.component.ts +++ b/core/gui/src/app/workspace/component/workflow-editor/workflow-editor.component.ts @@ -271,6 +271,7 @@ export class WorkflowEditorComponent implements AfterViewInit, OnDestroy { .getStatusUpdateStream() .pipe(untilDestroyed(this)) .subscribe(status => { + console.log("Operator stats update:", status); Object.keys(status).forEach(operatorID => { if (!this.workflowActionService.getTexeraGraph().hasOperator(operatorID)) { return; diff --git a/core/gui/src/app/workspace/service/workflow-status/workflow-status.service.ts b/core/gui/src/app/workspace/service/workflow-status/workflow-status.service.ts index 6072cc3c1ca..ba84733cd1c 100644 --- a/core/gui/src/app/workspace/service/workflow-status/workflow-status.service.ts +++ b/core/gui/src/app/workspace/service/workflow-status/workflow-status.service.ts @@ -56,7 +56,9 @@ export class WorkflowStatusService { accumulator[operatorId] = { operatorState: OperatorState.Uninitialized, aggregatedInputRowCount: 0, + inputPortMetrics: {}, aggregatedOutputRowCount: 0, + outputPortMetrics: {}, }; return accumulator; }, diff --git a/core/gui/src/app/workspace/types/execute-workflow.interface.ts b/core/gui/src/app/workspace/types/execute-workflow.interface.ts index 3ede29ab9a3..2147fea94ea 100644 --- a/core/gui/src/app/workspace/types/execute-workflow.interface.ts +++ b/core/gui/src/app/workspace/types/execute-workflow.interface.ts @@ -81,7 +81,9 @@ export interface OperatorStatistics extends Readonly<{ operatorState: OperatorState; aggregatedInputRowCount: number; + inputPortMetrics: Record; aggregatedOutputRowCount: number; + outputPortMetrics: Record; }> {} export interface OperatorStatsUpdate From 42b0eeaa45aba14b42ab3010949b53249c20781c Mon Sep 17 00:00:00 2001 From: gspikehalo <2318002579@qq.com> Date: Tue, 27 May 2025 21:34:43 -0700 Subject: [PATCH 02/13] display port count --- .../event/OperatorStatisticsUpdateEvent.scala | 4 ++-- .../web/service/ExecutionStatsService.scala | 4 ++-- .../workflow-editor.component.ts | 1 - .../service/joint-ui/joint-ui.service.ts | 21 +++++++++++++++++++ .../types/execute-workflow.interface.ts | 4 ++-- 5 files changed, 27 insertions(+), 7 deletions(-) diff --git a/core/amber/src/main/scala/edu/uci/ics/texera/web/model/websocket/event/OperatorStatisticsUpdateEvent.scala b/core/amber/src/main/scala/edu/uci/ics/texera/web/model/websocket/event/OperatorStatisticsUpdateEvent.scala index 335d5a7c215..0b730d7ee5f 100644 --- a/core/amber/src/main/scala/edu/uci/ics/texera/web/model/websocket/event/OperatorStatisticsUpdateEvent.scala +++ b/core/amber/src/main/scala/edu/uci/ics/texera/web/model/websocket/event/OperatorStatisticsUpdateEvent.scala @@ -25,10 +25,10 @@ case class OperatorAggregatedMetrics( operatorState: String, aggregatedInputRowCount: Long, aggregatedInputSize: Long, - inputPortMetrics: Map[String, TupleMetrics], + inputPortMetrics: Map[String, Long], aggregatedOutputRowCount: Long, aggregatedOutputSize: Long, - outputPortMetrics: Map[String, TupleMetrics], + outputPortMetrics: Map[String, Long], numWorkers: Long, aggregatedDataProcessingTime: Long, aggregatedControlProcessingTime: Long, diff --git a/core/amber/src/main/scala/edu/uci/ics/texera/web/service/ExecutionStatsService.scala b/core/amber/src/main/scala/edu/uci/ics/texera/web/service/ExecutionStatsService.scala index 79485d05860..0f76317a238 100644 --- a/core/amber/src/main/scala/edu/uci/ics/texera/web/service/ExecutionStatsService.scala +++ b/core/amber/src/main/scala/edu/uci/ics/texera/web/service/ExecutionStatsService.scala @@ -107,10 +107,10 @@ class ExecutionStatsService( case x => val metrics = x._2 val inMap = metrics.operatorStatistics.inputMetrics - .map(pm => pm.portId.id.toString -> pm.tupleMetrics) + .map(pm => pm.portId.id.toString -> pm.tupleMetrics.count) .toMap val outMap = metrics.operatorStatistics.outputMetrics - .map(pm => pm.portId.id.toString -> pm.tupleMetrics) + .map(pm => pm.portId.id.toString -> pm.tupleMetrics.count) .toMap val res = OperatorAggregatedMetrics( diff --git a/core/gui/src/app/workspace/component/workflow-editor/workflow-editor.component.ts b/core/gui/src/app/workspace/component/workflow-editor/workflow-editor.component.ts index bccb2b11d3a..3ef1bece169 100644 --- a/core/gui/src/app/workspace/component/workflow-editor/workflow-editor.component.ts +++ b/core/gui/src/app/workspace/component/workflow-editor/workflow-editor.component.ts @@ -271,7 +271,6 @@ export class WorkflowEditorComponent implements AfterViewInit, OnDestroy { .getStatusUpdateStream() .pipe(untilDestroyed(this)) .subscribe(status => { - console.log("Operator stats update:", status); Object.keys(status).forEach(operatorID => { if (!this.workflowActionService.getTexeraGraph().hasOperator(operatorID)) { return; diff --git a/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts b/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts index 700ca33e34f..603440d9610 100644 --- a/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts +++ b/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts @@ -113,6 +113,7 @@ export const operatorCoeditorChangedPropertyClass = "texera-operator-coeditor-ch export const operatorIconClass = "texera-operator-icon"; export const operatorNameClass = "texera-operator-name"; export const operatorFriendlyNameClass = "texera-operator-friendly-name"; +export const operatorPortMetricsClass = "texera-operator-port-metrics" export const linkPathStrokeColor = "#919191"; @@ -129,6 +130,7 @@ class TexeraCustomJointElement extends joint.shapes.devs.Model { + @@ -291,10 +293,15 @@ export class JointUIService { const processedCountText = isSource ? "" : abbreviateNumber(statistics.aggregatedInputRowCount); const outputCountText = isSink ? "" : abbreviateNumber(statistics.aggregatedOutputRowCount); const abbreviatedText = processedCountText + (isSource || isSink ? "" : " → ") + outputCountText; + const inputLines = Object.entries(statistics.inputPortMetrics) + .map(([portId, count]) => `Port ID ${portId}: ${count}`) + .join("\n"); + jointPaper.getModelById(operatorID).attr({ [`.${operatorProcessedCountClass}`]: isSink ? { text: processedText, "ref-y": -30 } : { text: processedText }, [`.${operatorOutputCountClass}`]: { text: outputText }, [`.${operatorAbbreviatedCountClass}`]: { text: abbreviatedText }, + [`.${operatorPortMetricsClass}`]: {text: inputLines}, }); } public foldOperatorDetails(jointPaper: joint.dia.Paper, operatorID: string): void { @@ -303,6 +310,7 @@ export class JointUIService { [`.${operatorProcessedCountClass}`]: { visibility: "hidden" }, [`.${operatorOutputCountClass}`]: { visibility: "hidden" }, [`.${operatorStateClass}`]: { visibility: "hidden" }, + [`.${operatorPortMetricsClass}`]: { visibility: "hidden" }, ".delete-button": { visibility: "hidden" }, ".add-input-port-button": { visibility: "hidden" }, ".add-output-port-button": { visibility: "hidden" }, @@ -317,6 +325,7 @@ export class JointUIService { [`.${operatorProcessedCountClass}`]: { visibility: "visible" }, [`.${operatorOutputCountClass}`]: { visibility: "visible" }, [`.${operatorStateClass}`]: { visibility: "visible" }, + [`.${operatorPortMetricsClass}`]: { visibility: "visible" }, ".delete-button": { visibility: "visible" }, ".add-input-port-button": { visibility: "visible" }, ".add-output-port-button": { visibility: "visible" }, @@ -352,6 +361,7 @@ export class JointUIService { [`.${operatorAbbreviatedCountClass}`]: { fill: fillColor }, [`.${operatorProcessedCountClass}`]: { fill: fillColor }, [`.${operatorOutputCountClass}`]: { fill: fillColor }, + [`.${operatorPortMetricsClass}`]: { fill: fillColor }, }); } @@ -670,6 +680,17 @@ export class JointUIService { "y-alignment": "middle", "x-alignment": "middle", }, + ".texera-operator-port-metrics": { + text: "", + fill: "green", + "font-size": "14px", + visibility: "hidden", + "ref-x": 0.5, + "ref-y": -70, + ref: "rect.body", + "y-alignment": "middle", + "x-alignment": "middle", + }, ".texera-operator-processed-count": { text: "", fill: "green", diff --git a/core/gui/src/app/workspace/types/execute-workflow.interface.ts b/core/gui/src/app/workspace/types/execute-workflow.interface.ts index 2147fea94ea..3580ac71022 100644 --- a/core/gui/src/app/workspace/types/execute-workflow.interface.ts +++ b/core/gui/src/app/workspace/types/execute-workflow.interface.ts @@ -81,9 +81,9 @@ export interface OperatorStatistics extends Readonly<{ operatorState: OperatorState; aggregatedInputRowCount: number; - inputPortMetrics: Record; + inputPortMetrics: Record; aggregatedOutputRowCount: number; - outputPortMetrics: Record; + outputPortMetrics: Record; }> {} export interface OperatorStatsUpdate From 0f6483ed83b74046ea4d7b067641aa3247478a61 Mon Sep 17 00:00:00 2001 From: gspikehalo <2318002579@qq.com> Date: Sat, 31 May 2025 01:02:59 -0700 Subject: [PATCH 03/13] update --- .../service/joint-ui/joint-ui.service.ts | 40 +++++++++++++++++-- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts b/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts index c1dc56dfb46..2c02e231fd9 100644 --- a/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts +++ b/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts @@ -303,15 +303,39 @@ export class JointUIService { const processedCountText = isSource ? "" : abbreviateNumber(statistics.aggregatedInputRowCount); const outputCountText = isSink ? "" : abbreviateNumber(statistics.aggregatedOutputRowCount); const abbreviatedText = processedCountText + (isSource || isSink ? "" : " → ") + outputCountText; - const inputLines = Object.entries(statistics.inputPortMetrics) - .map(([portId, count]) => `Port ID ${portId}: ${count}`) - .join("\n"); + + const element = jointPaper.getModelById(operatorID) as joint.shapes.devs.Model; + const allPorts = element.getPorts(); + const inPorts = allPorts.filter((p) => p.group === "in"); + const inputMetrics = statistics.inputPortMetrics; + + inPorts.forEach(portDef => { + const portId = portDef.id; + if (portId != null) { + const parts = portId.split("-"); + const numericSuffix = parts.length > 1 ? parts[1] : portId; + + const count: number = inputMetrics[numericSuffix] ?? 0; + const rawAttrs = (portDef.attrs as any) || {}; + const oldText: string = (rawAttrs[".port-label"] && rawAttrs[".port-label"].text) || ""; + let originalName = oldText.includes(":") + ? oldText.split(":", 1)[0].trim() + : oldText; + + if (!originalName) { + originalName = portId; + } + + const labelText = `${originalName}: ${count}`; + + element.portProp(portId, "attrs/.port-label/text", labelText); + } + }); jointPaper.getModelById(operatorID).attr({ [`.${operatorProcessedCountClass}`]: isSink ? { text: processedText, "ref-y": -30 } : { text: processedText }, [`.${operatorOutputCountClass}`]: { text: outputText }, [`.${operatorAbbreviatedCountClass}`]: { text: abbreviatedText }, - [`.${operatorPortMetricsClass}`]: {text: inputLines}, }); } public foldOperatorDetails(jointPaper: joint.dia.Paper, operatorID: string): void { @@ -373,6 +397,14 @@ export class JointUIService { [`.${operatorOutputCountClass}`]: { fill: fillColor }, [`.${operatorPortMetricsClass}`]: { fill: fillColor }, }); + const element = jointPaper.getModelById(operatorID) as joint.shapes.devs.Model; + const allPorts = element.getPorts(); + const inPorts = allPorts.filter(p => p.group === "in"); + inPorts.forEach(p => { + if (p.id != null) { + element.portProp(p.id, "attrs/.port-label/fill", fillColor); + } + }); } /** From 655b17fe7d62f835e854dc6a884b726043e6e452 Mon Sep 17 00:00:00 2001 From: Jae Yun Kim Date: Mon, 2 Jun 2025 15:32:52 -0700 Subject: [PATCH 04/13] Added code to make selected operator to show port information --- .../service/joint-ui/joint-ui.service.ts | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts b/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts index 2c02e231fd9..186efa49b48 100644 --- a/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts +++ b/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts @@ -351,6 +351,17 @@ export class JointUIService { ".remove-input-port-button": { visibility: "hidden" }, ".remove-output-port-button": { visibility: "hidden" }, }); + const element = jointPaper.getModelById(operatorID) as joint.shapes.devs.Model; + if (!element) { + return; + } + const ports = element.getPorts(); + ports.forEach(p => { + const pid = p.id; + if (pid) { + element.portProp(pid, "attrs/.port-label/visibility", "hidden"); + } + }); } public unfoldOperatorDetails(jointPaper: joint.dia.Paper, operatorID: string): void { @@ -366,6 +377,18 @@ export class JointUIService { ".remove-input-port-button": { visibility: "visible" }, ".remove-output-port-button": { visibility: "visible" }, }); + + const element = jointPaper.getModelById(operatorID) as joint.shapes.devs.Model; + if (!element) { + return; + } + const ports = element.getPorts(); + ports.forEach(p => { + const pid = p.id; + if (pid) { + element.portProp(pid, "attrs/.port-label/visibility", "visible"); + } + }); } public changeOperatorState(jointPaper: joint.dia.Paper, operatorID: string, operatorState: OperatorState): void { @@ -620,6 +643,7 @@ export class JointUIService { stroke: "none", }, ".port-label": { + visibility: "hidden", event: "input-label:evt", dblclick: "input-label:dbclick", pointerdblclick: "input-label:pointerdblclick", From 560a85e9f82c35532e09a9cd166aadf01aa596fe Mon Sep 17 00:00:00 2001 From: Jae Yun Kim Date: Mon, 9 Jun 2025 14:48:51 -0700 Subject: [PATCH 05/13] Made changes to let port show counts when there are multiple ports --- .../service/joint-ui/joint-ui.service.ts | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts b/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts index 186efa49b48..2379722db70 100644 --- a/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts +++ b/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts @@ -382,13 +382,18 @@ export class JointUIService { if (!element) { return; } - const ports = element.getPorts(); - ports.forEach(p => { - const pid = p.id; - if (pid) { - element.portProp(pid, "attrs/.port-label/visibility", "visible"); - } - }); + + const inPorts = element.getPorts().filter(p => p.group === "in"); + const outPorts = element.getPorts().filter(p => p.group === "out"); + + if (inPorts.length > 1) { + inPorts.forEach(p => element.portProp(p.id!, "attrs/.port-label/visibility", "visible")); + } + + if (outPorts.length > 1) { + outPorts.forEach(p => element.portProp(p.id!, "attrs/.port-label/visibility", "visible")); + } + } public changeOperatorState(jointPaper: joint.dia.Paper, operatorID: string, operatorState: OperatorState): void { From f0c1fe840ea972a3608e0e5c845393cff36c8d7b Mon Sep 17 00:00:00 2001 From: Jae Yun Kim Date: Sun, 15 Jun 2025 15:31:38 -0700 Subject: [PATCH 06/13] Temporary commit --- .../src/assets/operator_images/Histogram2D.png | Bin 0 -> 2866 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 core/gui/src/assets/operator_images/Histogram2D.png diff --git a/core/gui/src/assets/operator_images/Histogram2D.png b/core/gui/src/assets/operator_images/Histogram2D.png new file mode 100644 index 0000000000000000000000000000000000000000..25af78d6bf76567a15040f66390a31f1e178b90b GIT binary patch literal 2866 zcmb7`S5(tm7Ki^K)KDW;a=9Q?5Tpe{4N4P`BE5@*9;6cx49$Xo6hn*j-XVw*N!f9LG;u+OH>763K_U42~u1Ofoi`2o&mfJXoW zEgd}_EdxCrJp{tQ$jrsc%*4bD5Rb z`_$wZy1U7St{K{vDKp5lop^Sr;+uwu=~KRp?X|dlzXh9+pP)A%_Rde>o!9IwSdCI^ z2rA7*>3WrTY0xe@_p81}w2FDM@*i3ob8c_m=&o*oSOb-zwfpS@YGRhKJZXQHk$cZ7 zi&It|$CdViXGQ&}9MC#}ygvTZ#jr$G z%YuUv+XnE^oI=Vo&T?j?Vv-QjCxaY$Wu{;{mh zHfF2F8QYPjwpl@(%#af@4Wo;q?%7E_Zj`9r%7mA1yo;DjJ7M40z$@IT;Q0~hIdrLa zirM3{O+?ixwQ>~o=a72dsK+#Cz|6}tK)UCINlI}=1HYFTKs_~Fzwk4n;gmzZ>3ilh zgwo?0G=t%mC>FbX(oyCUpq{>hKbEhW9xrY-3Xz~4c%_aqyVskI$}E8IYL+%N9#({N z3Klzd4gdgn;d~exI;-TdYmKj-PnsW8%2vOJ4t`*25}jA5>ON9j%LwG_)g6 z!SKS(HGVBA*Zoe+%?FE_uU{=??mJ_)^F&~Kj(-kg4J;-nrApM`XTah~T9qfB8#+(h zaB#x%m(#}rXy3~Wc)_Ml_CqbXmBAsS{_>3|Jybpa?L~}BPnbeTQ(BoOd}T4x2fqRyA@ncH@Q|Y%hr`pvLf(}Z+ei6sb0TtA`@QSx#VKp3h&IDK zJGrvN1Uu|#J0$f>RZ{8|LQlH+Q>~AuW0|VD#fknyf5B3DrjNxgmVeV3_?3-XKw#S0 zNON(n#)U;b?m>~?IY@KyQ7GBAn~VX{RV;3jl8KY~cdk-=b`U#Vb3HOsOP!C~I$y%v z8=7I&qw@8R5)sHbpW70%Ug#lcaycy2MbA&ARFyAu#KGH_8Ys2Vq;}I7Z^26(y5U=I}`6~fs z1_Y$g8_}+7;dFal1M_q0ZEe!}o&1gmN$mNx9b+NtXZ_rDZAVCM*x z%!I%ucG*XAOqu&ngVgjQme_W(7PSPQjBu0dFOX-s|wK%PuN&xY65_&YZ#zd01N{ z+3^$bIv>u-;PfJ?+IN0)6>;z`pxA~hv#&!~ab!tZxPSGYUKVU9USz89reclz?E0TZ)t}10Np~4H zCaW*H(WRlAyxJL6k>e#V#edcXCnw*n-i{l0gebYRSZ_GR&i^tQt#giYDzQ%VXfUsx zA1m@9i3cWmx0t(9LXTJuy?@9WH+uPz_ch9{JZ8ou<22uf8g-l^om`-pFtdF=ZSp;? z4C2_Age}J{6SKI0=iyExPlux&UM5;tvGsc0pi_J}BcikVdEh~B+LDl}_JE|0fJnK| z#{IbX^|k|lnVepmcOJDG+S?TCu;9uDH6?0+v9M&G8PQ4K`a0H|Xf&b$`2;TyyKlZ3 zp5}k<#M)2WRE)eYDDo*D%aA(4w(FtG7e6|Y@y3Sng(gEupUC0t)0D|M&GedA4MkR& z8&?m%y3XVoujYQe7zr&dewxyk?@jQs7$E6SybJkAPF7Mq|HNT^+3D6M6}NAtFl7Fi zwDd5L^CRm9cx*ninr1G2sKB2SsGKwJ8QpyM0Bnd6^Z=byG45BJ1?bKAiZ>R8eEZJYdEU@IH zIT5drD@Mq^LP&j?RUi0VOjqUX#quAaVOOavU4V&M0wtMMA&H)~vOTN4WHE6ub4^&y>yp^igDW zasE;cmtiFd8o7f0!zlU-Z$zE4cz?DL)B9Vb8g7Q+#zD0bgicQUMQ;lQyxoMaSsO!= z*dTWqE7hP+cJfn%xCJp4W8BBVVYU#Gr}UGZRDA=znd^}^E(ES+sVw`3Y@H;gL<5)q z-fuwPnKfmbWwJt+b`|u0X$#DquvjV0{xS}NezVg9uD`wP6G9}0+EL;$)K7Nu?|%`9 zu52keY1A)B^IU3K!M!J~xp{$vd3sg6?&QW=E7$iLUPsC(JrP69j)=9)#l2*X89VaV Yk++*bH$FmPsTPZzy8wWX|LoJh0b{W(sQ>@~ literal 0 HcmV?d00001 From 4442df1e9e64ac9ecff9e84cd625b931457821ef Mon Sep 17 00:00:00 2001 From: Jae Yun Kim Date: Mon, 16 Jun 2025 15:44:29 -0700 Subject: [PATCH 07/13] Differentiated the layer of port statistics and links --- .../service/joint-ui/joint-ui.service.ts | 24 ++++--------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts b/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts index 2379722db70..9d08704fdb8 100644 --- a/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts +++ b/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts @@ -249,6 +249,7 @@ export class JointUIService { // set operator element ID to be operator ID operatorElement.set("id", operator.operatorID); + operatorElement.set("z", 1); // set the input ports and output ports based on operator predicate operator.inputPorts.forEach(port => @@ -355,13 +356,7 @@ export class JointUIService { if (!element) { return; } - const ports = element.getPorts(); - ports.forEach(p => { - const pid = p.id; - if (pid) { - element.portProp(pid, "attrs/.port-label/visibility", "hidden"); - } - }); + } public unfoldOperatorDetails(jointPaper: joint.dia.Paper, operatorID: string): void { @@ -382,18 +377,6 @@ export class JointUIService { if (!element) { return; } - - const inPorts = element.getPorts().filter(p => p.group === "in"); - const outPorts = element.getPorts().filter(p => p.group === "out"); - - if (inPorts.length > 1) { - inPorts.forEach(p => element.portProp(p.id!, "attrs/.port-label/visibility", "visible")); - } - - if (outPorts.length > 1) { - outPorts.forEach(p => element.portProp(p.id!, "attrs/.port-label/visibility", "visible")); - } - } public changeOperatorState(jointPaper: joint.dia.Paper, operatorID: string, operatorState: OperatorState): void { @@ -558,6 +541,7 @@ export class JointUIService { port: link.target.portID, }); jointLinkCell.set("id", link.linkID); + jointLinkCell.set("z", 0); return jointLinkCell; } @@ -648,7 +632,7 @@ export class JointUIService { stroke: "none", }, ".port-label": { - visibility: "hidden", + visibility: "visible", event: "input-label:evt", dblclick: "input-label:dbclick", pointerdblclick: "input-label:pointerdblclick", From 602fb5bbd933f69f157f532abdb83c4ecc4ece0b Mon Sep 17 00:00:00 2001 From: Jae Yun Kim Date: Wed, 18 Jun 2025 02:26:00 -0700 Subject: [PATCH 08/13] Made output count to be shown --- .../service/joint-ui/joint-ui.service.ts | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts b/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts index 9d08704fdb8..60459386664 100644 --- a/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts +++ b/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts @@ -308,6 +308,8 @@ export class JointUIService { const element = jointPaper.getModelById(operatorID) as joint.shapes.devs.Model; const allPorts = element.getPorts(); const inPorts = allPorts.filter((p) => p.group === "in"); + const outPorts = allPorts.filter((p) => p.group === "out"); + const inputMetrics = statistics.inputPortMetrics; inPorts.forEach(portDef => { @@ -333,11 +335,36 @@ export class JointUIService { } }); + outPorts.forEach(portDef => { + const portId = portDef.id; + if (portId != null) { + const parts = portId.split("-"); + const numericSuffix = parts.length > 1 ? parts[1] : portId; + + const count: number = inputMetrics[numericSuffix] ?? 0; + const rawAttrs = (portDef.attrs as any) || {}; + const oldText: string = (rawAttrs[".port-label"] && rawAttrs[".port-label"].text) || ""; + let originalName = oldText.includes(":") + ? oldText.split(":", 1)[0].trim() + : oldText; + + if (!originalName) { + originalName = portId; + } + + const labelText = `${originalName}: ${count}`; + + element.portProp(portId, "attrs/.port-label/text", labelText); + } + }); + jointPaper.getModelById(operatorID).attr({ [`.${operatorProcessedCountClass}`]: isSink ? { text: processedText, "ref-y": -30 } : { text: processedText }, [`.${operatorOutputCountClass}`]: { text: outputText }, [`.${operatorAbbreviatedCountClass}`]: { text: abbreviatedText }, }); + + this.changeOperatorState(jointPaper, operatorID, statistics.operatorState); } public foldOperatorDetails(jointPaper: joint.dia.Paper, operatorID: string): void { jointPaper.getModelById(operatorID).attr({ @@ -416,6 +443,13 @@ export class JointUIService { element.portProp(p.id, "attrs/.port-label/fill", fillColor); } }); + + const outPorts = allPorts.filter(p => p.group === "out"); + outPorts.forEach(p => { + if (p.id != null) { + element.portProp(p.id, "attrs/.port-label/fill", fillColor); + } + }); } /** @@ -737,7 +771,7 @@ export class JointUIService { }, ".texera-operator-port-metrics": { text: "", - fill: "green", + fill: "blue", "font-size": "14px", visibility: "hidden", "ref-x": 0.5, From 651ab8ef03e03a2946c351761b233437568174ba Mon Sep 17 00:00:00 2001 From: Jae Yun Kim Date: Wed, 18 Jun 2025 03:42:02 -0700 Subject: [PATCH 09/13] Lint and format check --- .../edu/uci/ics/texera/web/service/ExecutionStatsService.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/amber/src/main/scala/edu/uci/ics/texera/web/service/ExecutionStatsService.scala b/core/amber/src/main/scala/edu/uci/ics/texera/web/service/ExecutionStatsService.scala index 519b2fa4182..6aabe7c4eb5 100644 --- a/core/amber/src/main/scala/edu/uci/ics/texera/web/service/ExecutionStatsService.scala +++ b/core/amber/src/main/scala/edu/uci/ics/texera/web/service/ExecutionStatsService.scala @@ -107,7 +107,7 @@ class ExecutionStatsService( OperatorStatisticsUpdateEvent(newState.operatorInfo.collect { case x => val metrics = x._2 - val inMap = metrics.operatorStatistics.inputMetrics + val inMap = metrics.operatorStatistics.inputMetrics .map(pm => pm.portId.id.toString -> pm.tupleMetrics.count) .toMap val outMap = metrics.operatorStatistics.outputMetrics From 98b74d46b3f3e0468516945007a47dbebff1993c Mon Sep 17 00:00:00 2001 From: Jae Yun Kim Date: Wed, 18 Jun 2025 04:12:06 -0700 Subject: [PATCH 10/13] Changed test files to comply with past changes --- .../code-debugger.component.spec.ts | 36 ++++++++++++++++-- .../service/joint-ui/joint-ui.service.ts | 15 +++----- .../operator-debug/udf-debug.service.spec.ts | 2 + .../assets/operator_images/Histogram2D.png | Bin 2866 -> 0 bytes 4 files changed, 39 insertions(+), 14 deletions(-) delete mode 100644 core/gui/src/assets/operator_images/Histogram2D.png diff --git a/core/gui/src/app/workspace/component/code-editor-dialog/code-debugger.component.spec.ts b/core/gui/src/app/workspace/component/code-editor-dialog/code-debugger.component.spec.ts index 72d73f55de6..ec4e5a22dd4 100644 --- a/core/gui/src/app/workspace/component/code-editor-dialog/code-debugger.component.spec.ts +++ b/core/gui/src/app/workspace/component/code-editor-dialog/code-debugger.component.spec.ts @@ -98,7 +98,13 @@ describe("CodeDebuggerComponent", () => { // Emit a Running state event statusUpdateStream.next({ - [operatorId]: { operatorState: OperatorState.Running, aggregatedOutputRowCount: 0, aggregatedInputRowCount: 0 }, + [operatorId]: { + operatorState: OperatorState.Running, + aggregatedOutputRowCount: 0, + aggregatedInputRowCount: 0, + inputPortMetrics: {}, + outputPortMetrics: {}, + }, }); tick(); @@ -109,7 +115,13 @@ describe("CodeDebuggerComponent", () => { // Emit the same state again (should not trigger setup again) statusUpdateStream.next({ - [operatorId]: { operatorState: OperatorState.Running, aggregatedOutputRowCount: 0, aggregatedInputRowCount: 0 }, + [operatorId]: { + operatorState: OperatorState.Running, + aggregatedOutputRowCount: 0, + aggregatedInputRowCount: 0, + inputPortMetrics: {}, + outputPortMetrics: {}, + }, }); tick(); @@ -120,7 +132,13 @@ describe("CodeDebuggerComponent", () => { // Emit the paused state (should not trigger setup) statusUpdateStream.next({ - [operatorId]: { operatorState: OperatorState.Paused, aggregatedOutputRowCount: 0, aggregatedInputRowCount: 0 }, + [operatorId]: { + operatorState: OperatorState.Paused, + aggregatedOutputRowCount: 0, + aggregatedInputRowCount: 0, + inputPortMetrics: {}, + outputPortMetrics: {}, + }, }); tick(); @@ -131,7 +149,13 @@ describe("CodeDebuggerComponent", () => { // Emit the running state once more (should not trigger setup) statusUpdateStream.next({ - [operatorId]: { operatorState: OperatorState.Paused, aggregatedOutputRowCount: 0, aggregatedInputRowCount: 0 }, + [operatorId]: { + operatorState: OperatorState.Paused, + aggregatedOutputRowCount: 0, + aggregatedInputRowCount: 0, + inputPortMetrics: {}, + outputPortMetrics: {}, + }, }); tick(); @@ -150,6 +174,8 @@ describe("CodeDebuggerComponent", () => { operatorState: OperatorState.Uninitialized, aggregatedOutputRowCount: 0, aggregatedInputRowCount: 0, + inputPortMetrics: {}, + outputPortMetrics: {}, }, }); @@ -163,6 +189,8 @@ describe("CodeDebuggerComponent", () => { operatorState: OperatorState.Uninitialized, aggregatedOutputRowCount: 0, aggregatedInputRowCount: 0, + inputPortMetrics: {}, + outputPortMetrics: {}, }, }); diff --git a/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts b/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts index 60459386664..3b8a59f1733 100644 --- a/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts +++ b/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts @@ -113,7 +113,7 @@ export const operatorCoeditorChangedPropertyClass = "texera-operator-coeditor-ch export const operatorIconClass = "texera-operator-icon"; export const operatorNameClass = "texera-operator-name"; export const operatorFriendlyNameClass = "texera-operator-friendly-name"; -export const operatorPortMetricsClass = "texera-operator-port-metrics" +export const operatorPortMetricsClass = "texera-operator-port-metrics"; export const linkPathStrokeColor = "#919191"; @@ -307,8 +307,8 @@ export class JointUIService { const element = jointPaper.getModelById(operatorID) as joint.shapes.devs.Model; const allPorts = element.getPorts(); - const inPorts = allPorts.filter((p) => p.group === "in"); - const outPorts = allPorts.filter((p) => p.group === "out"); + const inPorts = allPorts.filter(p => p.group === "in"); + const outPorts = allPorts.filter(p => p.group === "out"); const inputMetrics = statistics.inputPortMetrics; @@ -321,9 +321,7 @@ export class JointUIService { const count: number = inputMetrics[numericSuffix] ?? 0; const rawAttrs = (portDef.attrs as any) || {}; const oldText: string = (rawAttrs[".port-label"] && rawAttrs[".port-label"].text) || ""; - let originalName = oldText.includes(":") - ? oldText.split(":", 1)[0].trim() - : oldText; + let originalName = oldText.includes(":") ? oldText.split(":", 1)[0].trim() : oldText; if (!originalName) { originalName = portId; @@ -344,9 +342,7 @@ export class JointUIService { const count: number = inputMetrics[numericSuffix] ?? 0; const rawAttrs = (portDef.attrs as any) || {}; const oldText: string = (rawAttrs[".port-label"] && rawAttrs[".port-label"].text) || ""; - let originalName = oldText.includes(":") - ? oldText.split(":", 1)[0].trim() - : oldText; + let originalName = oldText.includes(":") ? oldText.split(":", 1)[0].trim() : oldText; if (!originalName) { originalName = portId; @@ -383,7 +379,6 @@ export class JointUIService { if (!element) { return; } - } public unfoldOperatorDetails(jointPaper: joint.dia.Paper, operatorID: string): void { diff --git a/core/gui/src/app/workspace/service/operator-debug/udf-debug.service.spec.ts b/core/gui/src/app/workspace/service/operator-debug/udf-debug.service.spec.ts index 342aef39702..92a9a53848d 100644 --- a/core/gui/src/app/workspace/service/operator-debug/udf-debug.service.spec.ts +++ b/core/gui/src/app/workspace/service/operator-debug/udf-debug.service.spec.ts @@ -200,6 +200,8 @@ describe("UdfDebugServiceSpec", () => { operatorState: OperatorState.Uninitialized, aggregatedInputRowCount: 0, aggregatedOutputRowCount: 0, + inputPortMetrics: {}, + outputPortMetrics: {}, }, }); diff --git a/core/gui/src/assets/operator_images/Histogram2D.png b/core/gui/src/assets/operator_images/Histogram2D.png deleted file mode 100644 index 25af78d6bf76567a15040f66390a31f1e178b90b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2866 zcmb7`S5(tm7Ki^K)KDW;a=9Q?5Tpe{4N4P`BE5@*9;6cx49$Xo6hn*j-XVw*N!f9LG;u+OH>763K_U42~u1Ofoi`2o&mfJXoW zEgd}_EdxCrJp{tQ$jrsc%*4bD5Rb z`_$wZy1U7St{K{vDKp5lop^Sr;+uwu=~KRp?X|dlzXh9+pP)A%_Rde>o!9IwSdCI^ z2rA7*>3WrTY0xe@_p81}w2FDM@*i3ob8c_m=&o*oSOb-zwfpS@YGRhKJZXQHk$cZ7 zi&It|$CdViXGQ&}9MC#}ygvTZ#jr$G z%YuUv+XnE^oI=Vo&T?j?Vv-QjCxaY$Wu{;{mh zHfF2F8QYPjwpl@(%#af@4Wo;q?%7E_Zj`9r%7mA1yo;DjJ7M40z$@IT;Q0~hIdrLa zirM3{O+?ixwQ>~o=a72dsK+#Cz|6}tK)UCINlI}=1HYFTKs_~Fzwk4n;gmzZ>3ilh zgwo?0G=t%mC>FbX(oyCUpq{>hKbEhW9xrY-3Xz~4c%_aqyVskI$}E8IYL+%N9#({N z3Klzd4gdgn;d~exI;-TdYmKj-PnsW8%2vOJ4t`*25}jA5>ON9j%LwG_)g6 z!SKS(HGVBA*Zoe+%?FE_uU{=??mJ_)^F&~Kj(-kg4J;-nrApM`XTah~T9qfB8#+(h zaB#x%m(#}rXy3~Wc)_Ml_CqbXmBAsS{_>3|Jybpa?L~}BPnbeTQ(BoOd}T4x2fqRyA@ncH@Q|Y%hr`pvLf(}Z+ei6sb0TtA`@QSx#VKp3h&IDK zJGrvN1Uu|#J0$f>RZ{8|LQlH+Q>~AuW0|VD#fknyf5B3DrjNxgmVeV3_?3-XKw#S0 zNON(n#)U;b?m>~?IY@KyQ7GBAn~VX{RV;3jl8KY~cdk-=b`U#Vb3HOsOP!C~I$y%v z8=7I&qw@8R5)sHbpW70%Ug#lcaycy2MbA&ARFyAu#KGH_8Ys2Vq;}I7Z^26(y5U=I}`6~fs z1_Y$g8_}+7;dFal1M_q0ZEe!}o&1gmN$mNx9b+NtXZ_rDZAVCM*x z%!I%ucG*XAOqu&ngVgjQme_W(7PSPQjBu0dFOX-s|wK%PuN&xY65_&YZ#zd01N{ z+3^$bIv>u-;PfJ?+IN0)6>;z`pxA~hv#&!~ab!tZxPSGYUKVU9USz89reclz?E0TZ)t}10Np~4H zCaW*H(WRlAyxJL6k>e#V#edcXCnw*n-i{l0gebYRSZ_GR&i^tQt#giYDzQ%VXfUsx zA1m@9i3cWmx0t(9LXTJuy?@9WH+uPz_ch9{JZ8ou<22uf8g-l^om`-pFtdF=ZSp;? z4C2_Age}J{6SKI0=iyExPlux&UM5;tvGsc0pi_J}BcikVdEh~B+LDl}_JE|0fJnK| z#{IbX^|k|lnVepmcOJDG+S?TCu;9uDH6?0+v9M&G8PQ4K`a0H|Xf&b$`2;TyyKlZ3 zp5}k<#M)2WRE)eYDDo*D%aA(4w(FtG7e6|Y@y3Sng(gEupUC0t)0D|M&GedA4MkR& z8&?m%y3XVoujYQe7zr&dewxyk?@jQs7$E6SybJkAPF7Mq|HNT^+3D6M6}NAtFl7Fi zwDd5L^CRm9cx*ninr1G2sKB2SsGKwJ8QpyM0Bnd6^Z=byG45BJ1?bKAiZ>R8eEZJYdEU@IH zIT5drD@Mq^LP&j?RUi0VOjqUX#quAaVOOavU4V&M0wtMMA&H)~vOTN4WHE6ub4^&y>yp^igDW zasE;cmtiFd8o7f0!zlU-Z$zE4cz?DL)B9Vb8g7Q+#zD0bgicQUMQ;lQyxoMaSsO!= z*dTWqE7hP+cJfn%xCJp4W8BBVVYU#Gr}UGZRDA=znd^}^E(ES+sVw`3Y@H;gL<5)q z-fuwPnKfmbWwJt+b`|u0X$#DquvjV0{xS}NezVg9uD`wP6G9}0+EL;$)K7Nu?|%`9 zu52keY1A)B^IU3K!M!J~xp{$vd3sg6?&QW=E7$iLUPsC(JrP69j)=9)#l2*X89VaV Yk++*bH$FmPsTPZzy8wWX|LoJh0b{W(sQ>@~ From 745162fed1ec31dfd4caf290b37631b9b1f1f588 Mon Sep 17 00:00:00 2001 From: Jae Yun Kim Date: Wed, 2 Jul 2025 01:56:18 -0700 Subject: [PATCH 11/13] Changed color --- core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts b/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts index 3b8a59f1733..599e2f93c64 100644 --- a/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts +++ b/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts @@ -766,7 +766,7 @@ export class JointUIService { }, ".texera-operator-port-metrics": { text: "", - fill: "blue", + fill: "green", "font-size": "14px", visibility: "hidden", "ref-x": 0.5, From de3da1eca4201dc756532580d6475d677ad5adcb Mon Sep 17 00:00:00 2001 From: Jae Yun Kim Date: Thu, 3 Jul 2025 03:12:52 -0700 Subject: [PATCH 12/13] Fixed issues --- .../event/OperatorStatisticsUpdateEvent.scala | 2 -- .../workspace/service/joint-ui/joint-ui.service.ts | 13 +++++-------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/core/amber/src/main/scala/edu/uci/ics/texera/web/model/websocket/event/OperatorStatisticsUpdateEvent.scala b/core/amber/src/main/scala/edu/uci/ics/texera/web/model/websocket/event/OperatorStatisticsUpdateEvent.scala index 0b730d7ee5f..b33b6f93e15 100644 --- a/core/amber/src/main/scala/edu/uci/ics/texera/web/model/websocket/event/OperatorStatisticsUpdateEvent.scala +++ b/core/amber/src/main/scala/edu/uci/ics/texera/web/model/websocket/event/OperatorStatisticsUpdateEvent.scala @@ -19,8 +19,6 @@ package edu.uci.ics.texera.web.model.websocket.event -import edu.uci.ics.amber.engine.architecture.worker.statistics.TupleMetrics - case class OperatorAggregatedMetrics( operatorState: String, aggregatedInputRowCount: Long, diff --git a/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts b/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts index 599e2f93c64..ca31b078885 100644 --- a/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts +++ b/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts @@ -106,7 +106,6 @@ export const operatorViewResultIconClass = "texera-operator-view-result-icon"; export const operatorStateClass = "texera-operator-state"; export const operatorProcessedCountClass = "texera-operator-processed-count"; export const operatorOutputCountClass = "texera-operator-output-count"; -export const operatorAbbreviatedCountClass = "texera-operator-abbreviated-count"; export const operatorCoeditorEditingClass = "texera-operator-coeditor-editing"; export const operatorCoeditorChangedPropertyClass = "texera-operator-coeditor-changed-property"; @@ -133,7 +132,6 @@ class TexeraCustomJointElement extends joint.shapes.devs.Model { - @@ -291,7 +289,6 @@ export class JointUIService { jointPaper.getModelById(operatorID).attr({ [`.${operatorProcessedCountClass}`]: { text: "" }, [`.${operatorOutputCountClass}`]: { text: "" }, - [`.${operatorAbbreviatedCountClass}`]: { text: "" }, }); this.changeOperatorState(jointPaper, operatorID, OperatorState.Uninitialized); return; @@ -311,6 +308,7 @@ export class JointUIService { const outPorts = allPorts.filter(p => p.group === "out"); const inputMetrics = statistics.inputPortMetrics; + const outputMetrics = statistics.outputPortMetrics; inPorts.forEach(portDef => { const portId = portDef.id; @@ -339,7 +337,7 @@ export class JointUIService { const parts = portId.split("-"); const numericSuffix = parts.length > 1 ? parts[1] : portId; - const count: number = inputMetrics[numericSuffix] ?? 0; + const count: number = outputMetrics[numericSuffix] ?? 0; const rawAttrs = (portDef.attrs as any) || {}; const oldText: string = (rawAttrs[".port-label"] && rawAttrs[".port-label"].text) || ""; let originalName = oldText.includes(":") ? oldText.split(":", 1)[0].trim() : oldText; @@ -357,14 +355,12 @@ export class JointUIService { jointPaper.getModelById(operatorID).attr({ [`.${operatorProcessedCountClass}`]: isSink ? { text: processedText, "ref-y": -30 } : { text: processedText }, [`.${operatorOutputCountClass}`]: { text: outputText }, - [`.${operatorAbbreviatedCountClass}`]: { text: abbreviatedText }, }); this.changeOperatorState(jointPaper, operatorID, statistics.operatorState); } public foldOperatorDetails(jointPaper: joint.dia.Paper, operatorID: string): void { jointPaper.getModelById(operatorID).attr({ - [`.${operatorAbbreviatedCountClass}`]: { visibility: "visible" }, [`.${operatorProcessedCountClass}`]: { visibility: "hidden" }, [`.${operatorOutputCountClass}`]: { visibility: "hidden" }, [`.${operatorStateClass}`]: { visibility: "hidden" }, @@ -383,7 +379,6 @@ export class JointUIService { public unfoldOperatorDetails(jointPaper: joint.dia.Paper, operatorID: string): void { jointPaper.getModelById(operatorID).attr({ - [`.${operatorAbbreviatedCountClass}`]: { visibility: "hidden" }, [`.${operatorProcessedCountClass}`]: { visibility: "visible" }, [`.${operatorOutputCountClass}`]: { visibility: "visible" }, [`.${operatorStateClass}`]: { visibility: "visible" }, @@ -425,7 +420,6 @@ export class JointUIService { [`.${operatorStateClass}`]: { text: operatorState.toString() }, [`.${operatorStateClass}`]: { fill: fillColor }, "rect.body": { stroke: fillColor }, - [`.${operatorAbbreviatedCountClass}`]: { fill: fillColor }, [`.${operatorProcessedCountClass}`]: { fill: fillColor }, [`.${operatorOutputCountClass}`]: { fill: fillColor }, [`.${operatorPortMetricsClass}`]: { fill: fillColor }, @@ -665,6 +659,9 @@ export class JointUIService { event: "input-label:evt", dblclick: "input-label:dbclick", pointerdblclick: "input-label:pointerdblclick", + ref: ".port-body", + "ref-y": 0.5, + "y-alignment": "middle", }, }; } From fd9a463b7b5f06122d027ba60484aa56c66de78b Mon Sep 17 00:00:00 2001 From: Jae Yun Kim Date: Mon, 7 Jul 2025 22:51:19 -0700 Subject: [PATCH 13/13] Small change --- .../gui/src/app/workspace/service/joint-ui/joint-ui.service.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts b/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts index ca31b078885..e7a4c9dd824 100644 --- a/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts +++ b/core/gui/src/app/workspace/service/joint-ui/joint-ui.service.ts @@ -372,9 +372,6 @@ export class JointUIService { ".remove-output-port-button": { visibility: "hidden" }, }); const element = jointPaper.getModelById(operatorID) as joint.shapes.devs.Model; - if (!element) { - return; - } } public unfoldOperatorDetails(jointPaper: joint.dia.Paper, operatorID: string): void {