@@ -8,15 +8,19 @@ import com.squareup.invert.common.DependencyGraph
8
8
import com.squareup.invert.common.InvertReportPage
9
9
import com.squareup.invert.common.ModuleOwnerAndCodeReference
10
10
import com.squareup.invert.common.ReportDataRepo
11
+ import com.squareup.invert.common.charts.ChartJsLineChartComposable
12
+ import com.squareup.invert.common.charts.ChartsJs
11
13
import com.squareup.invert.common.charts.PlotlyTreeMapComposable
12
14
import com.squareup.invert.common.navigation.NavPage
13
15
import com.squareup.invert.common.navigation.NavRouteRepo
14
16
import com.squareup.invert.common.navigation.routes.BaseNavRoute
15
17
import com.squareup.invert.common.pages.CodeReferencesNavRoute.Companion.parser
18
+ import com.squareup.invert.common.utils.FormattingUtils.formatEpochToDate
16
19
import com.squareup.invert.models.ExtraKey
17
20
import com.squareup.invert.models.ModulePath
18
21
import com.squareup.invert.models.OwnerName
19
22
import com.squareup.invert.models.StatDataType
23
+ import com.squareup.invert.models.StatKey
20
24
import com.squareup.invert.models.js.StatTotalAndMetadata
21
25
import org.jetbrains.compose.web.dom.A
22
26
import org.jetbrains.compose.web.dom.H3
@@ -39,6 +43,7 @@ data class CodeReferencesNavRoute(
39
43
val owner : String? = null ,
40
44
val module : String? = null ,
41
45
val treemap : Boolean? = null ,
46
+ val chart : Boolean? = null ,
42
47
) : BaseNavRoute(CodeReferencesReportPage .navPage) {
43
48
44
49
override fun toSearchParams (): Map <String , String > = toParamsWithOnlyPageId(this )
@@ -55,11 +60,15 @@ data class CodeReferencesNavRoute(
55
60
treemap?.let {
56
61
params[TREEMAP_PARAM ] = treemap.toString()
57
62
}
63
+ chart?.let {
64
+ params[CHART_PARAM ] = chart.toString()
65
+ }
58
66
}
59
67
60
68
companion object {
61
69
62
70
private const val STATKEY_PARAM = " statkey"
71
+ private const val CHART_PARAM = " chart"
63
72
private const val OWNER_PARAM = " owner"
64
73
private const val MODULE_PARAM = " module"
65
74
private const val TREEMAP_PARAM = " treemap"
@@ -87,11 +96,19 @@ data class CodeReferencesNavRoute(
87
96
null
88
97
}
89
98
}
99
+ val chart = params[CHART_PARAM ]?.trim()?.let {
100
+ if (it.isNotBlank()) {
101
+ it.toBoolean()
102
+ } else {
103
+ null
104
+ }
105
+ }
90
106
return CodeReferencesNavRoute (
91
107
statKey = statKey,
92
108
owner = owner,
93
109
module = module,
94
110
treemap = treemap,
111
+ chart = chart,
95
112
)
96
113
}
97
114
}
@@ -119,15 +136,18 @@ fun CodeReferencesComposable(
119
136
navRouteRepo : NavRouteRepo = DependencyGraph .navRouteRepo,
120
137
) {
121
138
val allModulesOrig by reportDataRepo.allModules.collectAsState(null )
139
+ val historicalDataOrig by reportDataRepo.historicalData.collectAsState(null )
122
140
val allOwnerNames by reportDataRepo.allOwnerNames.collectAsState(null )
123
141
val moduleToOwnerMapFlowValue: Map <ModulePath , OwnerName >? by reportDataRepo.moduleToOwnerMap.collectAsState(null )
124
142
125
143
val statInfosOrig by reportDataRepo.statInfos.collectAsState(null )
126
- if (statInfosOrig == null || allOwnerNames == null ) {
144
+ if (statInfosOrig == null || allOwnerNames == null || historicalDataOrig == null ) {
127
145
BootstrapLoadingMessageWithSpinner (" Loading Stats" )
128
146
return
129
147
}
130
148
149
+ val historicalData = historicalDataOrig!!
150
+
131
151
val metadata by reportDataRepo.reportMetadata.collectAsState(null )
132
152
BootstrapRow {
133
153
BootstrapColumn (8 ) {
@@ -142,7 +162,6 @@ fun CodeReferencesComposable(
142
162
}
143
163
}
144
164
BootstrapColumn (4 ) {
145
-
146
165
codeReferencesNavRoute.statKey?.let { statKey ->
147
166
P {
148
167
Ul {
@@ -155,6 +174,29 @@ fun CodeReferencesComposable(
155
174
Text (" View Grouped by Module" )
156
175
}
157
176
}
177
+ if (historicalData.size > 1 ) {
178
+ Li {
179
+ A (" #" , {
180
+ onClick {
181
+ navRouteRepo.updateNavRoute(
182
+ codeReferencesNavRoute.copy(
183
+ chart = if (codeReferencesNavRoute.chart != null ) {
184
+ ! codeReferencesNavRoute.chart
185
+ } else {
186
+ true
187
+ }
188
+ )
189
+ )
190
+ }
191
+ }) {
192
+ if (codeReferencesNavRoute.chart == true ) {
193
+ Text (" Hide Chart" )
194
+ } else {
195
+ Text (" Show Chart" )
196
+ }
197
+ }
198
+ }
199
+ }
158
200
Li {
159
201
A (" #" , {
160
202
onClick {
@@ -283,6 +325,39 @@ fun CodeReferencesComposable(
283
325
}
284
326
}
285
327
328
+ if (codeReferencesNavRoute.chart == true ) {
329
+ BootstrapRow {
330
+ BootstrapColumn {
331
+ val datasets = mutableListOf<ChartsJs .ChartJsDataset >()
332
+ val currentHistoricalData = historicalData.last()
333
+ val remainingStatKeys: List <StatKey > = listOf (statKey)
334
+ remainingStatKeys.forEach { remainingStatKey ->
335
+ val values: List <Int > = historicalData.map { historicalDataPoint ->
336
+ historicalDataPoint.statTotalsAndMetadata.statTotals[remainingStatKey]?.total ? : 0
337
+ }
338
+ val remainingStat = currentHistoricalData.statTotalsAndMetadata.statTotals[remainingStatKey]!! .metadata
339
+ datasets.add(
340
+ ChartsJs .ChartJsDataset (
341
+ label = remainingStat.description,
342
+ data = values
343
+ )
344
+ )
345
+ }
346
+
347
+ val chartJsData = ChartsJs .ChartJsData (
348
+ labels = historicalData.map { formatEpochToDate(it.reportMetadata.latestCommitTime) },
349
+ datasets = datasets,
350
+ )
351
+
352
+ ChartJsLineChartComposable (
353
+ data = chartJsData,
354
+ onClick = { label, value ->
355
+
356
+ })
357
+ }
358
+ }
359
+ }
360
+
286
361
val codeReferencesByOwner = allCodeReferencesForStat.groupBy { it.owner }
287
362
val totalCodeReferenceCount = allCodeReferencesForStat.size
288
363
BootstrapRow {
0 commit comments