11package org.digma.intellij.plugin.ui.list.insights
22
3+ import com.intellij.openapi.fileEditor.impl.HTMLEditorProvider
34import com.intellij.openapi.project.Project
4- import org.digma.intellij.plugin.model.rest.insights.*
5- import org.digma.intellij.plugin.ui.common.CopyableLabelHtmlWithForegroundColor
6- import org.digma.intellij.plugin.ui.common.Laf
7- import org.digma.intellij.plugin.ui.common.asHtml
8- import org.digma.intellij.plugin.ui.common.spanBold
9- import javax.swing.Box
10- import javax.swing.JLabel
11- import javax.swing.JPanel
12-
13- fun spanScalingListViewItemsPanel (project : Project , insight : SpanScalingInsight ): JPanel {
5+ import com.intellij.ui.components.ActionLink
6+ import com.intellij.ui.components.JBLabel
7+ import com.intellij.util.ui.JBUI.Borders.empty
8+ import com.intellij.util.ui.JBUI.Borders.emptyBottom
9+ import org.apache.commons.lang3.StringUtils
10+ import org.digma.intellij.plugin.analytics.AnalyticsService
11+ import org.digma.intellij.plugin.document.CodeObjectsUtil
12+ import org.digma.intellij.plugin.model.rest.insights.RootCauseSpan
13+ import org.digma.intellij.plugin.model.rest.insights.SpanScalingInsight
14+ import org.digma.intellij.plugin.ui.common.*
15+ import org.digma.intellij.plugin.ui.list.ListItemActionButton
16+ import org.digma.intellij.plugin.ui.list.openWorkspaceFileForSpan
17+ import org.digma.intellij.plugin.ui.model.TraceSample
18+ import java.awt.BorderLayout
19+ import javax.swing.*
20+
21+ fun spanScalingListViewItemsPanel (project : Project , insight : SpanScalingInsight , moreData : HashMap <String , Any >): JPanel {
1422 val scalingPanel = createDefaultBoxLayoutYAxisPanel()
1523 scalingPanel.add(getScalingDescriptionPanel(insight))
1624 scalingPanel.add(getScalingCalculationsPanel(insight))
25+ scalingPanel.border = emptyBottom(2 )
26+
27+ if (insight.rootCauseSpans.isNotEmpty()) {
28+ scalingPanel.add(getRootCauseSpansPanel(project,moreData,insight))
29+ }
30+
31+ val buttonToGraph = buildButtonToPercentilesGraph(project, insight.spanName,insight.spanInstrumentationLibrary)
1732
1833 return createInsightPanel(
1934 project = project,
@@ -22,11 +37,68 @@ fun spanScalingListViewItemsPanel(project: Project, insight: SpanScalingInsight)
2237 description = " " ,
2338 iconsList = listOf (Laf .Icons .Insight .SCALE ),
2439 bodyPanel = scalingPanel,
25- buttons = null ,
40+ buttons = listOf (buttonToGraph) ,
2641 paginationComponent = null
2742 )
2843}
2944
45+ fun getRootCauseSpansPanel (project : Project , moreData : HashMap <String , Any >, insight : SpanScalingInsight ): JPanel {
46+
47+ val rootCauseSpansPanel = createDefaultBoxLayoutYAxisPanel()
48+
49+ val causedByLabel = JLabel (" Caused By:" )
50+ causedByLabel.horizontalAlignment = SwingConstants .LEFT
51+ val causedByPanel = JPanel (BorderLayout ())
52+ causedByPanel.border = empty()
53+ causedByPanel.isOpaque = false
54+ causedByPanel.add(causedByLabel,BorderLayout .WEST )
55+ rootCauseSpansPanel.add(causedByPanel)
56+
57+ insight.rootCauseSpans.let { spans ->
58+ repeat(spans.size) {index ->
59+ rootCauseSpansPanel.add(getRootCauseSpanPanel(project,moreData,spans[index]))
60+ }
61+ }
62+
63+ return rootCauseSpansPanel
64+ }
65+
66+ fun getRootCauseSpanPanel (project : Project , moreData : HashMap <String , Any >, rootCauseSpan : RootCauseSpan ): JPanel {
67+
68+ val rootCausePanel = JPanel (BorderLayout ())
69+ rootCausePanel.border = empty()
70+ rootCausePanel.isOpaque = false
71+
72+ val normalizedDisplayName = StringUtils .normalizeSpace(rootCauseSpan.displayName)
73+ val spanId = CodeObjectsUtil .createSpanId(rootCauseSpan.instrumentationLibrary, rootCauseSpan.name)
74+
75+ if (moreData.contains(spanId)) {
76+ val link = ActionLink (normalizedDisplayName) {
77+ openWorkspaceFileForSpan(project, moreData, spanId)
78+ }
79+ link.toolTipText = asHtml(spanId)
80+ rootCausePanel.add(link,BorderLayout .CENTER )
81+ }else {
82+ val displayNameLabel = JBLabel (normalizedDisplayName, SwingConstants .TRAILING )
83+ displayNameLabel.toolTipText = asHtml(spanId)
84+ displayNameLabel.horizontalAlignment = SwingConstants .LEFT
85+ rootCausePanel.add(displayNameLabel,BorderLayout .CENTER )
86+ }
87+
88+ val spanName = rootCauseSpan.name
89+ val sampleTraceId = rootCauseSpan.sampleTraceId
90+ val traceSample = TraceSample (spanName, sampleTraceId)
91+ val buttonToJaeger = buildButtonToJaeger(project, " Trace" , spanName, listOf (traceSample))
92+ if (buttonToJaeger != null ) {
93+ rootCausePanel.add(buttonToJaeger, BorderLayout .EAST )
94+ }
95+
96+ return rootCausePanel
97+ }
98+
99+
100+
101+
30102private fun getScalingDescriptionPanel (insight : SpanScalingInsight ): CopyableLabelHtmlWithForegroundColor {
31103 val description = " Significant performance degradation at ${insight.turningPointConcurrency} executions/second"
32104 return CopyableLabelHtmlWithForegroundColor (description, Laf .Colors .GRAY )
@@ -43,4 +115,16 @@ private fun getScalingCalculationsPanel(insight: SpanScalingInsight): JPanel {
43115 scalingBodyPanel.add(Box .createHorizontalGlue())
44116 scalingBodyPanel.add(durationLabel)
45117 return scalingBodyPanel
118+ }
119+
120+
121+ private fun buildButtonToPercentilesGraph (project : Project , spanName : String ,instLibrary : String ): JButton {
122+ val analyticsService = AnalyticsService .getInstance(project)
123+ val button = ListItemActionButton (" Histogram" )
124+ button.addActionListener {
125+ val htmlContent = analyticsService.getHtmlGraphForSpanPercentiles(instLibrary, spanName, Laf .Colors .PLUGIN_BACKGROUND .getHex())
126+ HTMLEditorProvider .openEditor(project, " Percentiles Graph of Span $spanName " , htmlContent)
127+ }
128+
129+ return button
46130}
0 commit comments