1
- import { useCallback , useLayoutEffect , useMemo , useRef , useState } from 'react' ;
1
+ import { useLayoutEffect , useRef , useState } from 'react' ;
2
2
import type { Theme } from '@emotion/react' ;
3
3
import { useTheme } from '@emotion/react' ;
4
4
import styled from '@emotion/styled' ;
5
- import type { TooltipComponentFormatterCallbackParams } from 'echarts' ;
6
- import type { CallbackDataParams } from 'echarts/types/dist/shared' ;
7
5
8
6
import BaseChart from 'sentry/components/charts/baseChart' ;
9
7
import { space } from 'sentry/styles/space' ;
@@ -31,75 +29,6 @@ export function Charts({rankedAttributes}: Props) {
31
29
) ;
32
30
}
33
31
34
- type CohortData = SuspectAttributesResult [ 'rankedAttributes' ] [ number ] [ 'cohort1' ] ;
35
-
36
- function cohortsToSeriesData (
37
- cohort1 : CohortData ,
38
- cohort2 : CohortData
39
- ) : {
40
- [ BASELINE_SERIES_NAME ] : Array < { label : string ; value : string } > ;
41
- [ SELECTED_SERIES_NAME ] : Array < { label : string ; value : string } > ;
42
- } {
43
- const cohort1Map = new Map ( cohort1 . map ( ( { label, value} ) => [ label , value ] ) ) ;
44
- const cohort2Map = new Map ( cohort2 . map ( ( { label, value} ) => [ label , value ] ) ) ;
45
-
46
- const uniqueLabels = new Set ( [
47
- ...cohort1 . map ( c => c . label ) ,
48
- ...cohort2 . map ( c => c . label ) ,
49
- ] ) ;
50
-
51
- // From the unique labels, we create two series data objects, one for the selected cohort and one for the baseline cohort.
52
- // If a label isn't present in either of the cohorts, we assign a value of 0, to that label in the respective series.
53
- const seriesData = Array . from ( uniqueLabels ) . map ( label => {
54
- const selectedVal = cohort1Map . get ( label ) ?? '0' ;
55
- const baselineVal = cohort2Map . get ( label ) ?? '0' ;
56
-
57
- // We sort by descending value of the selected cohort
58
- const sortVal = Number ( selectedVal ) ;
59
-
60
- return {
61
- label,
62
- selectedValue : selectedVal ,
63
- baselineValue : baselineVal ,
64
- sortValue : sortVal ,
65
- } ;
66
- } ) ;
67
-
68
- seriesData . sort ( ( a , b ) => b . sortValue - a . sortValue ) ;
69
-
70
- const selectedSeriesData = seriesData . map ( ( { label, selectedValue} ) => ( {
71
- label,
72
- value : selectedValue ,
73
- } ) ) ;
74
-
75
- const baselineSeriesData = seriesData . map ( ( { label, baselineValue} ) => ( {
76
- label,
77
- value : baselineValue ,
78
- } ) ) ;
79
-
80
- return {
81
- [ SELECTED_SERIES_NAME ] : selectedSeriesData ,
82
- [ BASELINE_SERIES_NAME ] : baselineSeriesData ,
83
- } ;
84
- }
85
-
86
- // TODO Abdullah Khan: This is a temporary function to get the totals of the cohorts. Will be removed
87
- // once the backend returns the totals.
88
- function cohortTotals (
89
- cohort1 : CohortData ,
90
- cohort2 : CohortData
91
- ) : {
92
- [ BASELINE_SERIES_NAME ] : number ;
93
- [ SELECTED_SERIES_NAME ] : number ;
94
- } {
95
- const cohort1Total = cohort1 . reduce ( ( acc , curr ) => acc + Number ( curr . value ) , 0 ) ;
96
- const cohort2Total = cohort2 . reduce ( ( acc , curr ) => acc + Number ( curr . value ) , 0 ) ;
97
- return {
98
- [ SELECTED_SERIES_NAME ] : cohort1Total ,
99
- [ BASELINE_SERIES_NAME ] : cohort2Total ,
100
- } ;
101
- }
102
-
103
32
function Chart ( {
104
33
attribute,
105
34
theme,
@@ -113,68 +42,6 @@ function Chart({
113
42
const cohort1Color = theme . chart . getColorPalette ( 0 ) ?. [ 0 ] ;
114
43
const cohort2Color = '#dddddd' ;
115
44
116
- const seriesData = useMemo (
117
- ( ) => cohortsToSeriesData ( attribute . cohort1 , attribute . cohort2 ) ,
118
- [ attribute . cohort1 , attribute . cohort2 ]
119
- ) ;
120
-
121
- const seriesTotals = useMemo (
122
- ( ) => cohortTotals ( attribute . cohort1 , attribute . cohort2 ) ,
123
- [ attribute . cohort1 , attribute . cohort2 ]
124
- ) ;
125
-
126
- const valueFormatter = useCallback (
127
- ( _value : number , label ?: string , seriesParams ?: CallbackDataParams ) => {
128
- const data = Number ( seriesParams ?. data ) ;
129
- const total = seriesTotals [ label as keyof typeof seriesTotals ] ;
130
- const percentage = ( data / total ) * 100 ;
131
- return `${ percentage . toFixed ( 1 ) } %` ;
132
- } ,
133
- [ seriesTotals ]
134
- ) ;
135
-
136
- const formatAxisLabel = useCallback (
137
- (
138
- _value : number ,
139
- _isTimestamp : boolean ,
140
- _utc : boolean ,
141
- _showTimeInTooltip : boolean ,
142
- _addSecondsToTimeFormat : boolean ,
143
- _bucketSize : number | undefined ,
144
- seriesParamsOrParam : TooltipComponentFormatterCallbackParams
145
- ) => {
146
- if ( ! Array . isArray ( seriesParamsOrParam ) ) {
147
- throw new Error ( 'seriesParamsOrParam is not an array in formatAxisLabel' ) ;
148
- }
149
-
150
- const selectedParam = seriesParamsOrParam [ 0 ] ;
151
- const baselineParam = seriesParamsOrParam [ 1 ] ;
152
-
153
- if ( ! selectedParam || ! baselineParam ) {
154
- throw new Error ( 'selectedParam or baselineParam is not defined' ) ;
155
- }
156
-
157
- const selectedTotal =
158
- seriesTotals [ selectedParam ?. seriesName as keyof typeof seriesTotals ] ;
159
- const selectedData = Number ( selectedParam ?. data ) ;
160
- const selectedPercentage = ( selectedData / selectedTotal ) * 100 ;
161
-
162
- const baselineTotal =
163
- seriesTotals [ baselineParam ?. seriesName as keyof typeof seriesTotals ] ;
164
- const baselineData = Number ( baselineParam ?. data ) ;
165
- const baselinePercentage = ( baselineData / baselineTotal ) * 100 ;
166
-
167
- const isDifferent = selectedPercentage . toFixed ( 1 ) !== baselinePercentage . toFixed ( 1 ) ;
168
-
169
- const status = isDifferent
170
- ? { adjective : 'different' , message : 'This is suspicious.' }
171
- : { adjective : 'similar' , message : 'Nothing unusual here.' } ;
172
-
173
- return `<div style="max-width: 200px; white-space: normal; word-wrap: break-word; line-height: 1.2;">${ selectedParam ?. name } <span style="color: ${ theme . textColor } ;">is <strong>${ status . adjective } </strong> ${ isDifferent ? 'between' : 'across' } selected and baseline data. ${ status . message } </span></div>` ;
174
- } ,
175
- [ seriesTotals , theme . textColor ]
176
- ) ;
177
-
178
45
useLayoutEffect ( ( ) => {
179
46
const chartContainer = chartRef . current ?. getEchartsInstance ( ) . getDom ( ) ;
180
47
if ( ! chartContainer ) return ;
@@ -202,9 +69,8 @@ function Chart({
202
69
autoHeightResize
203
70
isGroupedByDate = { false }
204
71
tooltip = { {
205
- renderMode : 'html' ,
206
- valueFormatter,
207
- formatAxisLabel,
72
+ trigger : 'axis' ,
73
+ confine : true ,
208
74
} }
209
75
grid = { {
210
76
left : 2 ,
@@ -214,7 +80,7 @@ function Chart({
214
80
xAxis = { {
215
81
show : true ,
216
82
type : 'category' ,
217
- data : seriesData [ SELECTED_SERIES_NAME ] . map ( cohort => cohort . label ) ,
83
+ data : attribute . cohort1 . map ( cohort => cohort . label ) ,
218
84
truncate : 14 ,
219
85
axisLabel : hideLabels
220
86
? { show : false }
@@ -237,7 +103,7 @@ function Chart({
237
103
series = { [
238
104
{
239
105
type : 'bar' ,
240
- data : seriesData [ SELECTED_SERIES_NAME ] . map ( cohort => cohort . value ) ,
106
+ data : attribute . cohort1 . map ( cohort => cohort . value ) ,
241
107
name : SELECTED_SERIES_NAME ,
242
108
itemStyle : {
243
109
color : cohort1Color ,
@@ -247,7 +113,7 @@ function Chart({
247
113
} ,
248
114
{
249
115
type : 'bar' ,
250
- data : seriesData [ BASELINE_SERIES_NAME ] . map ( cohort => cohort . value ) ,
116
+ data : attribute . cohort2 . map ( cohort => cohort . value ) ,
251
117
name : BASELINE_SERIES_NAME ,
252
118
itemStyle : {
253
119
color : cohort2Color ,
0 commit comments