codecharta-visualization 1.89.0 → 1.90.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/app/app.module.ts +16 -2
  2. package/app/codeCharta/assets/gameObjectsFile.json +75 -0
  3. package/app/codeCharta/codeCharta.model.ts +1 -10
  4. package/app/codeCharta/services/idToBuilding/idToBuilding.service.ts +17 -0
  5. package/app/codeCharta/state/effects/nodeContextMenu/highlightButtons/highlightButtons.component.spec.ts +14 -23
  6. package/app/codeCharta/state/effects/nodeContextMenu/highlightButtons/highlightButtons.component.ts +7 -5
  7. package/app/codeCharta/state/effects/nodeContextMenu/nodeContextMenuCard/nodeContextMenuCard.component.spec.ts +3 -1
  8. package/app/codeCharta/state/effects/nodeContextMenu/rightClickedCodeMapNode.selector.ts +1 -1
  9. package/app/codeCharta/state/effects/trackEventUsageData/trackEventUsageData.effect.spec.ts +56 -0
  10. package/app/codeCharta/state/effects/trackEventUsageData/trackEventUsageData.effect.ts +49 -0
  11. package/app/codeCharta/state/effects/unfocusNodesOnLoadingMap.effect.ts +2 -1
  12. package/app/codeCharta/state/injector.service.ts +0 -4
  13. package/app/codeCharta/state/selectors/accumulatedData/idToNode.selector.spec.ts +15 -0
  14. package/app/codeCharta/state/selectors/accumulatedData/idToNode.selector.ts +16 -0
  15. package/app/codeCharta/state/selectors/selectedNode.selector.ts +5 -2
  16. package/app/codeCharta/state/state.module.ts +0 -4
  17. package/app/codeCharta/state/store/appSettings/isLoadingMap/isLoadingMap.reducer.ts +1 -5
  18. package/app/codeCharta/state/store/state.actions.ts +0 -2
  19. package/app/codeCharta/state/store/state.reducer.ts +0 -2
  20. package/app/codeCharta/state/store/state.splitter.ts +0 -10
  21. package/app/codeCharta/state/store.service.ts +0 -16
  22. package/app/codeCharta/ui/attributeSideBar/attributeSideBar.component.spec.ts +5 -1
  23. package/app/codeCharta/ui/attributeSideBar/attributeSideBar.component.ts +2 -2
  24. package/app/codeCharta/ui/attributeSideBar/attributeSideBarHeaderSection/attributeSideBarHeaderSection.component.html +0 -1
  25. package/app/codeCharta/ui/attributeSideBar/attributeSideBarHeaderSection/attributeSideBarHeaderSection.component.spec.ts +3 -45
  26. package/app/codeCharta/ui/attributeSideBar/attributeSideBarHeaderSection/attributeSideBarHeaderSection.component.ts +2 -8
  27. package/app/codeCharta/ui/attributeSideBar/attributeSideBarHeaderSection/nodePath/nodePath.component.html +1 -1
  28. package/app/codeCharta/ui/attributeSideBar/attributeSideBarHeaderSection/nodePath/nodePath.component.spec.ts +3 -2
  29. package/app/codeCharta/ui/attributeSideBar/attributeSideBarHeaderSection/nodePath/nodePath.component.ts +2 -2
  30. package/app/codeCharta/ui/attributeSideBar/attributeSideBarSecondaryMetrics/secondaryMetrics.selector.ts +2 -2
  31. package/app/codeCharta/ui/attributeSideBar/metricDeltaSelected/metricDeltaSelected.component.spec.ts +26 -23
  32. package/app/codeCharta/ui/attributeSideBar/metricDeltaSelected/metricDeltaSelected.component.ts +2 -2
  33. package/app/codeCharta/ui/attributeSideBar/util/showAttributeTypeSelector.selector.spec.ts +2 -2
  34. package/app/codeCharta/ui/attributeSideBar/util/showAttributeTypeSelector.selector.ts +2 -2
  35. package/app/codeCharta/ui/codeMap/codeMap.mouseEvent.service.spec.ts +28 -45
  36. package/app/codeCharta/ui/codeMap/codeMap.mouseEvent.service.ts +7 -11
  37. package/app/codeCharta/ui/codeMap/codeMap.preRender.service.ts +4 -46
  38. package/app/codeCharta/ui/codeMap/threeViewer/threeSceneService.spec.ts +26 -19
  39. package/app/codeCharta/ui/codeMap/threeViewer/threeSceneService.ts +13 -25
  40. package/app/codeCharta/ui/codeMap/threeViewer/threeViewer.module.ts +3 -0
  41. package/app/codeCharta/ui/dialog/dialog.globalSettings.component.ts +3 -5
  42. package/app/codeCharta/ui/dialog/dialog.globalSettings.e2e.ts +1 -1
  43. package/app/codeCharta/ui/fileChooser/fileChooser.component.spec.ts +1 -0
  44. package/app/codeCharta/ui/fileChooser/fileChooser.component.ts +6 -1
  45. package/app/codeCharta/ui/fileChooser/fileChooser.e2e.ts +5 -0
  46. package/app/codeCharta/ui/filePanel/filePanel.component.html +1 -0
  47. package/app/codeCharta/ui/filePanel/filePanel.component.spec.ts +7 -0
  48. package/app/codeCharta/ui/filePanel/filePanel.component.ts +1 -2
  49. package/app/codeCharta/ui/filePanel/filePanel.module.ts +2 -0
  50. package/app/codeCharta/ui/filePanel/filePanelFileSelector/filePanelFileSelector.component.html +7 -1
  51. package/app/codeCharta/ui/filePanel/filePanelFileSelector/filePanelFileSelector.component.scss +6 -0
  52. package/app/codeCharta/ui/filePanel/filePanelFileSelector/filePanelFileSelector.component.ts +2 -1
  53. package/app/codeCharta/ui/filePanel/filePanelFileSelector/removeFileButton/removeFileButton.component.html +3 -0
  54. package/app/codeCharta/ui/filePanel/filePanelFileSelector/removeFileButton/removeFileButton.component.scss +9 -0
  55. package/app/codeCharta/ui/filePanel/filePanelFileSelector/removeFileButton/removeFileButton.component.ts +11 -0
  56. package/app/codeCharta/ui/rangeSlider/rangeSlider.component.ts +9 -33
  57. package/app/codeCharta/util/__snapshots__/usageDataTracker.spec.ts.snap +1 -16
  58. package/app/codeCharta/util/codeMapHelper.ts +3 -2
  59. package/app/codeCharta/util/customConfigHelper.ts +4 -16
  60. package/app/codeCharta/util/dataMocks.ts +0 -8
  61. package/app/codeCharta/util/envDetector.ts +0 -4
  62. package/app/codeCharta/util/gameObjectsParser/__snapshots__/gameObjectsImporter.spec.ts.snap +121 -0
  63. package/app/codeCharta/util/gameObjectsParser/gameObjectsImporter.spec.ts +11 -0
  64. package/app/codeCharta/util/gameObjectsParser/gameObjectsImporter.ts +170 -0
  65. package/app/codeCharta/util/gameObjectsParser/gameObjectsMocks.ts +75 -0
  66. package/app/codeCharta/util/gameObjectsParser/gameObjectsSchema.json +271 -0
  67. package/app/codeCharta/util/gameObjectsParser/gameObjectsValidator.spec.ts +18 -0
  68. package/app/codeCharta/util/gameObjectsParser/gameObjectsValidator.ts +7 -0
  69. package/app/codeCharta/util/nodeDecorator.ts +1 -0
  70. package/app/codeCharta/util/usageDataTracker.spec.ts +36 -76
  71. package/app/codeCharta/util/usageDataTracker.ts +20 -31
  72. package/conf/webpack.config.js +7 -7
  73. package/dist/webpack/bundle.js +871 -1260
  74. package/dist/webpack/bundle.js.map +1 -1
  75. package/package.json +10 -11
  76. package/app/codeCharta/state/selectors/selectedBuilding.selector.ts +0 -8
  77. package/app/codeCharta/state/store/lookUp/idToBuilding/idToBuilding.actions.ts +0 -22
  78. package/app/codeCharta/state/store/lookUp/idToBuilding/idToBuilding.reducer.spec.ts +0 -33
  79. package/app/codeCharta/state/store/lookUp/idToBuilding/idToBuilding.reducer.ts +0 -14
  80. package/app/codeCharta/state/store/lookUp/idToBuilding/idToBuilding.selector.ts +0 -3
  81. package/app/codeCharta/state/store/lookUp/idToBuilding/idToBuilding.service.spec.ts +0 -40
  82. package/app/codeCharta/state/store/lookUp/idToBuilding/idToBuilding.service.ts +0 -23
  83. package/app/codeCharta/state/store/lookUp/idToBuilding/idToBuilding.splitter.ts +0 -6
  84. package/app/codeCharta/state/store/lookUp/idToNode/idToNode.actions.ts +0 -22
  85. package/app/codeCharta/state/store/lookUp/idToNode/idToNode.reducer.spec.ts +0 -39
  86. package/app/codeCharta/state/store/lookUp/idToNode/idToNode.reducer.ts +0 -11
  87. package/app/codeCharta/state/store/lookUp/idToNode/idToNode.selector.ts +0 -4
  88. package/app/codeCharta/state/store/lookUp/idToNode/idToNode.service.spec.ts +0 -57
  89. package/app/codeCharta/state/store/lookUp/idToNode/idToNode.service.ts +0 -23
  90. package/app/codeCharta/state/store/lookUp/idToNode/idToNode.splitter.ts +0 -6
  91. package/app/codeCharta/state/store/lookUp/lookUp.actions.ts +0 -27
  92. package/app/codeCharta/state/store/lookUp/lookUp.reducer.ts +0 -10
  93. package/app/codeCharta/state/store/lookUp/lookUp.selector.ts +0 -3
  94. package/app/codeCharta/state/store/lookUp/lookUp.splitter.ts +0 -19
  95. package/app/codeCharta/ui/removeFileButton/removeFileButton.component.html +0 -5
  96. package/app/codeCharta/ui/removeFileButton/removeFileButton.component.scss +0 -41
  97. package/app/codeCharta/ui/removeFileButton/removeFileButton.component.ts +0 -18
  98. package/app/codeCharta/ui/removeFileButton/removeFileButton.module.ts +0 -7
  99. package/app/codeCharta/util/codeChartaFileStorage.spec.ts +0 -73
  100. package/app/codeCharta/util/codeChartaStorage.ts +0 -62
  101. package/app/codeCharta/util/lazyLoader.spec.ts +0 -33
  102. package/app/codeCharta/util/lazyLoader.ts +0 -50
  103. package/dist/webpack/vendors-node_modules_open_index_js.bundle.js +0 -1036
  104. package/dist/webpack/vendors-node_modules_open_index_js.bundle.js.map +0 -1
@@ -3,7 +3,7 @@
3
3
  import { CodeMapNode, FileMeta } from "../../codeCharta.model"
4
4
  import { IRootScopeService } from "angular"
5
5
  import { CodeMapRenderService } from "./codeMap.render.service"
6
- import { StoreExtendedSubscriber, StoreService, StoreSubscriber } from "../../state/store.service"
6
+ import { StoreService, StoreSubscriber } from "../../state/store.service"
7
7
  import { ScalingService, ScalingSubscriber } from "../../state/store/appSettings/scaling/scaling.service"
8
8
  import debounce from "lodash.debounce"
9
9
  import { ScalingActions } from "../../state/store/appSettings/scaling/scaling.actions"
@@ -20,14 +20,7 @@ import { PresentationModeActions } from "../../state/store/appSettings/isPresent
20
20
  import { MetricDataService, MetricDataSubscriber } from "../../state/store/metricData/metricData.service"
21
21
  import { ExperimentalFeaturesEnabledActions } from "../../state/store/appSettings/enableExperimentalFeatures/experimentalFeaturesEnabled.actions"
22
22
  import { LayoutAlgorithmService, LayoutAlgorithmSubscriber } from "../../state/store/appSettings/layoutAlgorithm/layoutAlgorithm.service"
23
- import { trackEventUsageData, trackMapMetaData } from "../../util/usageDataTracker"
24
- import { AreaMetricActions } from "../../state/store/dynamicSettings/areaMetric/areaMetric.actions"
25
- import { HeightMetricActions } from "../../state/store/dynamicSettings/heightMetric/heightMetric.actions"
26
- import { ColorMetricActions } from "../../state/store/dynamicSettings/colorMetric/colorMetric.actions"
27
- import { ColorRangeActions } from "../../state/store/dynamicSettings/colorRange/colorRange.actions"
28
- import { BlacklistActions } from "../../state/store/fileSettings/blacklist/blacklist.actions"
29
- import { FocusedNodePathActions } from "../../state/store/dynamicSettings/focusedNodePath/focusedNodePath.actions"
30
- import { ColorRangeFromSubscriber, ColorRangeToSubscriber, RangeSliderController } from "../rangeSlider/rangeSlider.component"
23
+ import { trackMapMetaData } from "../../util/usageDataTracker"
31
24
  import { HoveredBuildingPathActions } from "../../state/store/appStatus/hoveredBuildingPath/hoveredBuildingPath.actions"
32
25
  import { accumulatedDataSelector } from "../../state/selectors/accumulatedData/accumulatedData.selector"
33
26
  import { areAllNecessaryRenderDataAvailableSelector } from "../../state/selectors/allNecessaryRenderDataAvailable/areAllNecessaryRenderDataAvailable.selector"
@@ -37,16 +30,7 @@ export interface CodeMapPreRenderServiceSubscriber {
37
30
  onRenderMapChanged(map: CodeMapNode)
38
31
  }
39
32
 
40
- export class CodeMapPreRenderService
41
- implements
42
- StoreSubscriber,
43
- StoreExtendedSubscriber,
44
- MetricDataSubscriber,
45
- ScalingSubscriber,
46
- LayoutAlgorithmSubscriber,
47
- ColorRangeFromSubscriber,
48
- ColorRangeToSubscriber
49
- {
33
+ export class CodeMapPreRenderService implements StoreSubscriber, MetricDataSubscriber, ScalingSubscriber, LayoutAlgorithmSubscriber {
50
34
  private static RENDER_MAP_CHANGED_EVENT = "render-map-changed"
51
35
 
52
36
  private unifiedMap: CodeMapNode
@@ -64,18 +48,15 @@ export class CodeMapPreRenderService
64
48
  "ngInject"
65
49
  MetricDataService.subscribe(this.$rootScope, this)
66
50
  StoreService.subscribe(this.$rootScope, this)
67
- StoreService.subscribeDetailedData(this.$rootScope, this)
68
51
  ScalingService.subscribe(this.$rootScope, this)
69
52
  LayoutAlgorithmService.subscribe(this.$rootScope, this)
70
- RangeSliderController.subscribeToColorRangeFromUpdated(this.$rootScope, this)
71
- RangeSliderController.subscribeToColorRangeToUpdated(this.$rootScope, this)
72
53
 
73
54
  this.debounceRendering = debounce(() => {
74
55
  this.renderAndNotify()
75
56
  }, this.DEBOUNCE_TIME)
76
57
 
77
58
  this.debounceTracking = debounce(() => {
78
- trackMapMetaData(this.storeService.getState())
59
+ trackMapMetaData(this.storeService.getState().files)
79
60
  }, 1000)
80
61
  }
81
62
 
@@ -111,29 +92,6 @@ export class CodeMapPreRenderService
111
92
  }
112
93
  }
113
94
 
114
- onStoreChangedExtended(actionType: string, payload?: any) {
115
- if (
116
- this.allNecessaryRenderDataAvailable() &&
117
- (isActionOfType(actionType, AreaMetricActions) ||
118
- isActionOfType(actionType, HeightMetricActions) ||
119
- isActionOfType(actionType, ColorMetricActions) ||
120
- isActionOfType(actionType, ColorRangeActions) ||
121
- isActionOfType(actionType, BlacklistActions) ||
122
- isActionOfType(actionType, FocusedNodePathActions))
123
- ) {
124
- // Track event usage data only on certain events
125
- trackEventUsageData(actionType, this.storeService.getState(), payload)
126
- }
127
- }
128
-
129
- onColorRangeFromUpdated(colorMetric: string, fromValue: number) {
130
- trackEventUsageData(RangeSliderController.COLOR_RANGE_FROM_UPDATED, this.storeService.getState(), { colorMetric, fromValue })
131
- }
132
-
133
- onColorRangeToUpdated(colorMetric: string, toValue: number) {
134
- trackEventUsageData(RangeSliderController.COLOR_RANGE_TO_UPDATED, this.storeService.getState(), { colorMetric, toValue })
135
- }
136
-
137
95
  onLayoutAlgorithmChanged() {
138
96
  this.debounceRendering()
139
97
  }
@@ -17,17 +17,24 @@ import { StoreService } from "../../../state/store.service"
17
17
  import { CodeMapMesh } from "../rendering/codeMapMesh"
18
18
  import { klona } from "klona"
19
19
  import { CodeMapNode, LayoutAlgorithm } from "../../../codeCharta.model"
20
- import { setIdToBuilding } from "../../../state/store/lookUp/idToBuilding/idToBuilding.actions"
21
- import { setIdToNode } from "../../../state/store/lookUp/idToNode/idToNode.actions"
22
20
  import { setScaling } from "../../../state/store/appSettings/scaling/scaling.actions"
23
21
  import { Box3, BufferGeometry, Group, Material, Matrix4, Object3D, Raycaster, Vector3 } from "three"
24
22
  import { setLayoutAlgorithm } from "../../../state/store/appSettings/layoutAlgorithm/layoutAlgorithm.actions"
25
23
  import { FloorLabelDrawer } from "./floorLabels/floorLabelDrawer"
24
+ import { idToNodeSelector } from "../../../state/selectors/accumulatedData/idToNode.selector"
25
+ import { mocked } from "ts-jest/utils"
26
+ import { IdToBuildingService } from "../../../services/idToBuilding/idToBuilding.service"
27
+
28
+ jest.mock("../../../state/selectors/accumulatedData/idToNode.selector", () => ({
29
+ idToNodeSelector: jest.fn()
30
+ }))
31
+ const mockedIdToNodeSelector = mocked(idToNodeSelector)
26
32
 
27
33
  describe("ThreeSceneService", () => {
28
34
  let threeSceneService: ThreeSceneService
29
35
  let $rootScope: IRootScopeService
30
36
  let storeService: StoreService
37
+ let idToBuildingService: IdToBuildingService
31
38
 
32
39
  let codeMapBuilding: CodeMapBuilding
33
40
 
@@ -42,12 +49,13 @@ describe("ThreeSceneService", () => {
42
49
  $rootScope = getService<IRootScopeService>("$rootScope")
43
50
  storeService = getService<StoreService>("storeService")
44
51
  threeSceneService = getService<ThreeSceneService>("threeSceneService")
52
+ idToBuildingService = getService<IdToBuildingService>("idToBuilding")
45
53
 
46
54
  codeMapBuilding = klona(CODE_MAP_BUILDING)
47
55
  }
48
56
 
49
57
  function rebuildService() {
50
- threeSceneService = new ThreeSceneService($rootScope, storeService)
58
+ threeSceneService = new ThreeSceneService($rootScope, storeService, idToBuildingService)
51
59
  }
52
60
 
53
61
  beforeEach(() => {
@@ -104,14 +112,13 @@ describe("ThreeSceneService", () => {
104
112
 
105
113
  describe("addNodeAndChildrenToConstantHighlight", () => {
106
114
  beforeEach(() => {
107
- const idToBuilding = new Map<number, CodeMapBuilding>()
108
- idToBuilding.set(CODE_MAP_BUILDING.id, CODE_MAP_BUILDING)
109
- idToBuilding.set(CODE_MAP_BUILDING_TS_NODE.id, CODE_MAP_BUILDING_TS_NODE)
110
- storeService.dispatch(setIdToBuilding(idToBuilding))
111
- const idToNode = new Map<number, CodeMapNode>()
112
- idToNode.set(VALID_NODES_WITH_ID.id, VALID_NODES_WITH_ID)
113
- idToNode.set(VALID_FILE_NODE_WITH_ID.id, VALID_FILE_NODE_WITH_ID)
114
- storeService.dispatch(setIdToNode(idToNode))
115
+ mockedIdToNodeSelector.mockImplementation(() => {
116
+ const idToNode = new Map<number, CodeMapNode>()
117
+ idToNode.set(VALID_NODES_WITH_ID.id, VALID_NODES_WITH_ID)
118
+ idToNode.set(VALID_FILE_NODE_WITH_ID.id, VALID_FILE_NODE_WITH_ID)
119
+ return idToNode
120
+ })
121
+ idToBuildingService.setIdToBuilding([CODE_MAP_BUILDING, CODE_MAP_BUILDING_TS_NODE])
115
122
  threeSceneService["constantHighlight"] = new Map()
116
123
  })
117
124
 
@@ -137,15 +144,15 @@ describe("ThreeSceneService", () => {
137
144
 
138
145
  describe("removeNodeAndChildrenFromConstantHighlight", () => {
139
146
  beforeEach(() => {
140
- const idToBuilding = new Map<number, CodeMapBuilding>()
141
- idToBuilding.set(CODE_MAP_BUILDING.id, CODE_MAP_BUILDING)
142
- idToBuilding.set(CODE_MAP_BUILDING_TS_NODE.id, CODE_MAP_BUILDING_TS_NODE)
143
- storeService.dispatch(setIdToBuilding(idToBuilding))
144
- const idToNode = new Map<number, CodeMapNode>()
145
- idToNode.set(VALID_NODES_WITH_ID.id, VALID_NODES_WITH_ID)
146
- idToNode.set(VALID_FILE_NODE_WITH_ID.id, VALID_FILE_NODE_WITH_ID)
147
- storeService.dispatch(setIdToNode(idToNode))
147
+ mockedIdToNodeSelector.mockImplementation(() => {
148
+ const idToNode = new Map<number, CodeMapNode>()
149
+ idToNode.set(VALID_NODES_WITH_ID.id, VALID_NODES_WITH_ID)
150
+ idToNode.set(VALID_FILE_NODE_WITH_ID.id, VALID_FILE_NODE_WITH_ID)
151
+ return idToNode
152
+ })
153
+ idToBuildingService.setIdToBuilding([CODE_MAP_BUILDING, CODE_MAP_BUILDING_TS_NODE])
148
154
  })
155
+
149
156
  it("should remove the building from constant Highlight ", () => {
150
157
  const result = new Map<number, CodeMapBuilding>()
151
158
  result.set(CODE_MAP_BUILDING.id, CODE_MAP_BUILDING)
@@ -10,6 +10,8 @@ import { ColorConverter } from "../../../util/color/colorConverter"
10
10
  import { MapColorsService, MapColorsSubscriber } from "../../../state/store/appSettings/mapColors/mapColors.service"
11
11
  import { FloorLabelDrawer } from "./floorLabels/floorLabelDrawer"
12
12
  import { setSelectedBuildingId } from "../../../state/store/appStatus/selectedBuildingId/selectedBuildingId.actions"
13
+ import { idToNodeSelector } from "../../../state/selectors/accumulatedData/idToNode.selector"
14
+ import { IdToBuildingService } from "../../../services/idToBuilding/idToBuilding.service"
13
15
 
14
16
  export interface BuildingSelectedEventSubscriber {
15
17
  onBuildingSelected(selectedBuilding?: CodeMapBuilding)
@@ -19,14 +21,9 @@ export interface BuildingDeselectedEventSubscriber {
19
21
  onBuildingDeselected()
20
22
  }
21
23
 
22
- export interface CodeMapMeshChangedSubscriber {
23
- onCodeMapMeshChanged(mapMesh: CodeMapMesh)
24
- }
25
-
26
24
  export class ThreeSceneService implements CodeMapPreRenderServiceSubscriber, MapColorsSubscriber {
27
25
  private static readonly BUILDING_SELECTED_EVENT = "building-selected"
28
26
  private static readonly BUILDING_DESELECTED_EVENT = "building-deselected"
29
- private static readonly CODE_MAP_MESH_CHANGED_EVENT = "code-map-mesh-changed"
30
27
 
31
28
  scene: Scene
32
29
  labels: Group
@@ -53,7 +50,7 @@ export class ThreeSceneService implements CodeMapPreRenderServiceSubscriber, Map
53
50
  private highlightedLine = null
54
51
  private mapLabelColors = this.storeService.getState().appSettings.mapColors.labelColorAndAlpha
55
52
 
56
- constructor(private $rootScope: IRootScopeService, private storeService: StoreService) {
53
+ constructor(private $rootScope: IRootScopeService, private storeService: StoreService, private idToBuilding: IdToBuildingService) {
57
54
  "ngInject"
58
55
  MapColorsService.subscribe(this.$rootScope, this)
59
56
  CodeMapPreRenderService.subscribe(this.$rootScope, this)
@@ -341,22 +338,22 @@ export class ThreeSceneService implements CodeMapPreRenderServiceSubscriber, Map
341
338
  return maxDistance
342
339
  }
343
340
 
344
- addNodeAndChildrenToConstantHighlight(codeMapNode: CodeMapNode) {
345
- const { lookUp } = this.storeService.getState()
346
- const codeMapBuilding = lookUp.idToNode.get(codeMapNode.id)
341
+ addNodeAndChildrenToConstantHighlight(codeMapNode: Pick<CodeMapNode, "id">) {
342
+ const idToNode = idToNodeSelector(this.storeService.getState())
343
+ const codeMapBuilding = idToNode.get(codeMapNode.id)
347
344
  for (const { data } of hierarchy(codeMapBuilding)) {
348
- const building = lookUp.idToBuilding.get(data.id)
345
+ const building = this.idToBuilding.get(data.id)
349
346
  if (building) {
350
347
  this.constantHighlight.set(building.id, building)
351
348
  }
352
349
  }
353
350
  }
354
351
 
355
- removeNodeAndChildrenFromConstantHighlight(codeMapNode: CodeMapNode) {
356
- const { lookUp } = this.storeService.getState()
357
- const codeMapBuilding = lookUp.idToNode.get(codeMapNode.id)
352
+ removeNodeAndChildrenFromConstantHighlight(codeMapNode: Pick<CodeMapNode, "id">) {
353
+ const idToNode = idToNodeSelector(this.storeService.getState())
354
+ const codeMapBuilding = idToNode.get(codeMapNode.id)
358
355
  for (const { data } of hierarchy(codeMapBuilding)) {
359
- const building = lookUp.idToBuilding.get(data.id)
356
+ const building = this.idToBuilding.get(data.id)
360
357
  if (building) {
361
358
  this.constantHighlight.delete(building.id)
362
359
  }
@@ -412,7 +409,8 @@ export class ThreeSceneService implements CodeMapPreRenderServiceSubscriber, Map
412
409
  this.mapGeometry.position.z = -mapSize
413
410
 
414
411
  this.mapGeometry.add(this.mapMesh.getThreeMesh())
415
- this.notifyMapMeshChanged()
412
+
413
+ this.idToBuilding.setIdToBuilding(this.mapMesh.getMeshDescription().buildings)
416
414
  }
417
415
 
418
416
  getMapMesh() {
@@ -443,10 +441,6 @@ export class ThreeSceneService implements CodeMapPreRenderServiceSubscriber, Map
443
441
  }
444
442
  }
445
443
 
446
- private notifyMapMeshChanged() {
447
- this.$rootScope.$broadcast(ThreeSceneService.CODE_MAP_MESH_CHANGED_EVENT, this.mapMesh)
448
- }
449
-
450
444
  dispose() {
451
445
  this.mapMesh?.dispose()
452
446
  }
@@ -462,10 +456,4 @@ export class ThreeSceneService implements CodeMapPreRenderServiceSubscriber, Map
462
456
  subscriber.onBuildingSelected(selectedBuilding)
463
457
  })
464
458
  }
465
-
466
- static subscribeToCodeMapMeshChangedEvent($rootScope: IRootScopeService, subscriber: CodeMapMeshChangedSubscriber) {
467
- $rootScope.$on(this.CODE_MAP_MESH_CHANGED_EVENT, (_event, mapMesh: CodeMapMesh) => {
468
- subscriber.onCodeMapMeshChanged(mapMesh)
469
- })
470
- }
471
459
  }
@@ -9,6 +9,8 @@ import "../../../state/state.module"
9
9
  import camelCase from "lodash.camelcase"
10
10
 
11
11
  import angular from "angular"
12
+ import { downgradeInjectable } from "@angular/upgrade/static"
13
+ import { IdToBuildingService } from "../../../services/idToBuilding/idToBuilding.service"
12
14
 
13
15
  angular
14
16
  .module("app.codeCharta.ui.codeMap.threeViewer", ["app.codeCharta.state"])
@@ -19,3 +21,4 @@ angular
19
21
  .service(camelCase(ThreeOrbitControlsService.name), ThreeOrbitControlsService)
20
22
  .service(camelCase(ThreeCameraService.name), ThreeCameraService)
21
23
  .service(camelCase(ThreeStatsService.name), ThreeStatsService)
24
+ .factory("idToBuilding", downgradeInjectable(IdToBuildingService))
@@ -28,15 +28,14 @@ import { setMaxTreeMapFiles } from "../../state/store/appSettings/maxTreeMapFile
28
28
  import { GlobalSettingsHelper } from "../../util/globalSettingsHelper"
29
29
  import { SharpnessModeService, SharpnessModeSubscriber } from "../../state/store/appSettings/sharpnessMode/sharpnessMode.service"
30
30
  import { setSharpnessMode } from "../../state/store/appSettings/sharpnessMode/sharpnessMode.actions"
31
- import { CodeChartaStorage } from "../../util/codeChartaStorage"
32
31
  import { FileDownloader } from "../../util/fileDownloader"
33
32
  import { getVisibleFileStates, isSingleState } from "../../model/files/files.helper"
34
- import { isStandalone } from "../../util/envDetector"
35
33
  import { setScreenshotToClipboardEnabled } from "../../state/store/appSettings/enableClipboard/screenshotToClipboardEnabled.actions"
36
34
  import {
37
35
  ScreenshotToClipboardEnabledService,
38
36
  ScreenshotToClipboardEnabledSubscriber
39
37
  } from "../../state/store/appSettings/enableClipboard/screenshotToClipboardEnabled.service"
38
+ import { TRACKING_DATA_LOCAL_STORAGE_ELEMENT } from "../../util/usageDataTracker"
40
39
 
41
40
  export class DialogGlobalSettingsController
42
41
  implements
@@ -166,19 +165,18 @@ export class DialogGlobalSettingsController
166
165
 
167
166
  mapTrackingDataAvailable() {
168
167
  const files = this.storeService.getState().files
169
- return isStandalone() && isSingleState(files) && getVisibleFileStates(files)
168
+ return isSingleState(files) && getVisibleFileStates(files)
170
169
  }
171
170
 
172
171
  downloadTrackingData() {
173
172
  //TODO: this should be removed as soon as we send the data to a server
174
- const fileStorage = new CodeChartaStorage()
175
173
 
176
174
  // Make sure that only file within usageData can be read
177
175
  const fileChecksum = this.storeService.getState().files[0].file.fileMeta.fileChecksum.replace(/\//g, "")
178
176
 
179
177
  let trackedMapMetaData = ""
180
178
  try {
181
- trackedMapMetaData = fileStorage.getItem(`usageData/${fileChecksum}-meta`)
179
+ trackedMapMetaData = localStorage.getItem(`${TRACKING_DATA_LOCAL_STORAGE_ELEMENT}/${fileChecksum}-meta`)
182
180
  } catch {
183
181
  // ignore, it no events item exists
184
182
  }
@@ -54,7 +54,7 @@ describe("DialogGlobalSettings", () => {
54
54
 
55
55
  const layout = await globalSettingsPageObject.getDisplayQuality()
56
56
 
57
- expect(layout).toEqual(SharpnessMode.PixelRatioNoAA)
57
+ expect(layout).toContain(SharpnessMode.PixelRatioNoAA)
58
58
  })
59
59
  })
60
60
  })
@@ -46,6 +46,7 @@ describe("fileChooserController", () => {
46
46
  loadFiles: jest.fn().mockReturnValue({ catch: jest.fn() })
47
47
  })()
48
48
  }
49
+
49
50
  describe("setNewData", () => {
50
51
  it("should call loadFiles with read files", () => {
51
52
  const file: NameDataPair = {
@@ -8,6 +8,8 @@ import { ExportCCFile } from "../../codeCharta.api.model"
8
8
  import zlib from "zlib"
9
9
  import { CUSTOM_CONFIG_FILE_EXTENSION, CustomConfigHelper } from "../../util/customConfigHelper"
10
10
  import { getCCFileAndDecorateFileChecksum } from "../../util/fileHelper"
11
+ import { parseGameObjectsFile } from "../../util/gameObjectsParser/gameObjectsImporter"
12
+ import { validateGameObjects } from "../../util/gameObjectsParser/gameObjectsValidator"
11
13
 
12
14
  export class FileChooserController {
13
15
  private files: NameDataPair[] = []
@@ -38,7 +40,10 @@ export class FileChooserController {
38
40
  }
39
41
 
40
42
  reader.onload = event => {
41
- content = (isCompressed ? zlib.unzipSync(Buffer.from(<string>event.target.result)) : event.target.result).toString()
43
+ const result = event.target.result.toString()
44
+ content = isCompressed ? zlib.unzipSync(Buffer.from(<string>event.target.result)).toString() : result
45
+ if (result.includes("gameObjectPositions") && validateGameObjects(result))
46
+ content = JSON.stringify(parseGameObjectsFile(result))
42
47
  }
43
48
 
44
49
  reader.onloadend = () => {
@@ -16,6 +16,11 @@ describe("FileChooser", () => {
16
16
 
17
17
  await goto()
18
18
  })
19
+ it("should load a valid gameObjects file", async () => {
20
+ await fileChooser.openFiles(["./app/codeCharta/assets/gameObjectsFile.json"])
21
+
22
+ expect(await filePanel.getSelectedName()).toEqual("gameObjectsFile.json")
23
+ })
19
24
 
20
25
  it("should load another cc.json", async () => {
21
26
  await fileChooser.openFiles(["./app/codeCharta/assets/sample3.cc.json"])
@@ -13,6 +13,7 @@
13
13
  [handle-select-zero-partial-files]="$ctrl.selectZeroPartialFiles"
14
14
  [handle-invert-selected-partial-files]="$ctrl.invertPartialFileSelection"
15
15
  [handle-on-selection-closed]="$ctrl.onPartialSelectionClosed"
16
+ [handle-on-remove-file]="$ctrl.onRemoveFile"
16
17
  [files]="$ctrl._viewModel.files"
17
18
  ></cc-file-panel-file-selector>
18
19
 
@@ -311,6 +311,13 @@ describe("filePanelController", () => {
311
311
  ]
312
312
  })
313
313
 
314
+ it("should delete file", () => {
315
+ filePanelController.onRemoveFile("fileA", new Event("mouseEvent"))
316
+
317
+ const remainingFiles = storeService.getState().files
318
+ expect(remainingFiles.length).toEqual(3)
319
+ })
320
+
314
321
  it("should not change selection when partially selected files still exist", () => {
315
322
  storeService.dispatch(setMultiple([TEST_DELTA_MAP_B, TEST_DELTA_MAP_C]))
316
323
 
@@ -56,7 +56,7 @@ export class FilePanelController implements FilesSelectionSubscriber, MapColorsS
56
56
  this._viewModel.pictogramLowerColor = mapColors.negativeDelta
57
57
  }
58
58
 
59
- onRemoveFile(filename, $event): void {
59
+ onRemoveFile = (filename: string, $event): void => {
60
60
  this.storeService.dispatch(removeFile(filename))
61
61
  this.storeService.dispatch(removeRecentFile(filename))
62
62
 
@@ -69,7 +69,6 @@ export class FilePanelController implements FilesSelectionSubscriber, MapColorsS
69
69
 
70
70
  private partialStateFileRemove(files: FileState[]) {
71
71
  const selectedFiles = files.filter(x => x.selectedAs === FileSelectionState.Partial).map(fileState => getFileNameOf(fileState))
72
-
73
72
  if (selectedFiles.length > 0) {
74
73
  this.onPartialFilesChange(selectedFiles)
75
74
  } else {
@@ -9,6 +9,7 @@ import { downgradeComponent } from "@angular/upgrade/static"
9
9
  import { FilePanelFileSelectorComponent } from "./filePanelFileSelector/filePanelFileSelector.component"
10
10
  import { FilePanelStateButtonsComponent } from "./filePanelStateButtons/filePanelStateButtons.component"
11
11
  import { FilePanelDeltaSelectorComponent } from "./filePanelDeltaSelector/filePanelDeltaSelector.component"
12
+ import { RemoveFileButtonComponent } from "./filePanelFileSelector/removeFileButton/removeFileButton.component"
12
13
 
13
14
  angular
14
15
  .module("app.codeCharta.ui.filePanel", ["app.codeCharta.state"])
@@ -16,3 +17,4 @@ angular
16
17
  .directive("ccFilePanelFileSelector", downgradeComponent({ component: FilePanelFileSelectorComponent }))
17
18
  .directive("ccFilePanelStateButtons", downgradeComponent({ component: FilePanelStateButtonsComponent }))
18
19
  .directive("ccFilePanelDeltaSelector", downgradeComponent({ component: FilePanelDeltaSelectorComponent }))
20
+ .directive("ccRemoveFileButton", downgradeComponent({ component: RemoveFileButtonComponent }))
@@ -12,7 +12,13 @@
12
12
  <button mat-button (click)="handleSelectZeroPartialFiles()">None</button>
13
13
  <button mat-button (click)="handleInvertSelectedPartialFiles()">Invert</button>
14
14
  </div>
15
- <mat-option *ngFor="let file of files" [value]="file.file.fileMeta.fileName">
15
+ <mat-option class="filenames" *ngFor="let file of files" [value]="file.file.fileMeta.fileName">
16
16
  {{ file.file.fileMeta.fileName }}
17
+
18
+ <cc-remove-file-button
19
+ *ngIf="files.length > 1"
20
+ [filename]="file.file.fileMeta.fileName"
21
+ [onRemoveFile]="handleOnRemoveFile"
22
+ ></cc-remove-file-button>
17
23
  </mat-option>
18
24
  </mat-select>
@@ -0,0 +1,6 @@
1
+ .filenames {
2
+ .mat-option-text {
3
+ display: flex;
4
+ justify-content: space-between;
5
+ }
6
+ }
@@ -1,6 +1,6 @@
1
+ import "./filePanelFileSelector.component.scss"
1
2
  import { Component, Input } from "@angular/core"
2
3
  import { FileState } from "../../../model/files/files"
3
-
4
4
  @Component({
5
5
  selector: "cc-file-panel-file-selector",
6
6
  template: require("./filePanelFileSelector.component.html")
@@ -13,4 +13,5 @@ export class FilePanelFileSelectorComponent {
13
13
  @Input() handleSelectZeroPartialFiles: () => void
14
14
  @Input() handleInvertSelectedPartialFiles: () => void
15
15
  @Input() handleOnSelectionClosed: () => void
16
+ @Input() handleOnRemoveFile: (filename: string, event) => void
16
17
  }
@@ -0,0 +1,3 @@
1
+ <button mat-button (click)="onRemoveFile(filename, $event)" title="Remove map">
2
+ <i class="fa fa-trash delete-symbol"></i>
3
+ </button>
@@ -0,0 +1,9 @@
1
+ cc-remove-file-button {
2
+ .mat-button {
3
+ border-radius: 50%;
4
+ margin: 0;
5
+ min-width: 0;
6
+ line-height: 0;
7
+ padding: 8px 10px;
8
+ }
9
+ }
@@ -0,0 +1,11 @@
1
+ import "./removeFileButton.component.scss"
2
+ import { Component, Input } from "@angular/core"
3
+
4
+ @Component({
5
+ selector: "cc-remove-file-button",
6
+ template: require("./removeFileButton.component.html")
7
+ })
8
+ export class RemoveFileButtonComponent {
9
+ @Input() filename: string
10
+ @Input() onRemoveFile: (filename: string, event) => void
11
+ }
@@ -11,14 +11,7 @@ import { isDeltaState } from "../../model/files/files.helper"
11
11
  import { BlacklistService, BlacklistSubscriber } from "../../state/store/fileSettings/blacklist/blacklist.service"
12
12
  import { NodeMetricDataService } from "../../state/store/metricData/nodeMetricData/nodeMetricData.service"
13
13
  import { MapColorsService, MapColorsSubscriber } from "../../state/store/appSettings/mapColors/mapColors.service"
14
-
15
- export interface ColorRangeFromSubscriber {
16
- onColorRangeFromUpdated(colorMetric: string, fromValue: number)
17
- }
18
-
19
- export interface ColorRangeToSubscriber {
20
- onColorRangeToUpdated(colorMetric: string, toValue: number)
21
- }
14
+ import { trackEventUsageData } from "../../util/usageDataTracker"
22
15
 
23
16
  export class RangeSliderController
24
17
  implements ColorMetricSubscriber, ColorRangeSubscriber, FilesSelectionSubscriber, BlacklistSubscriber, MapColorsSubscriber
@@ -30,9 +23,6 @@ export class RangeSliderController
30
23
  private MAX_DIGITS = 6
31
24
  private FULL_WIDTH_SLIDER = 235
32
25
 
33
- static COLOR_RANGE_FROM_UPDATED = "color-range-from-updated"
34
- static COLOR_RANGE_TO_UPDATED = "color-range-to-updated"
35
-
36
26
  private _viewModel: {
37
27
  colorRangeFrom: number
38
28
  colorRangeTo: number
@@ -145,32 +135,18 @@ export class RangeSliderController
145
135
 
146
136
  private applySliderUpdateDone(modelValue, highValue, pointerType) {
147
137
  if (pointerType === "min") {
148
- this.broadcastColorRangeFromUpdated(this.storeService.getState().dynamicSettings.colorMetric, modelValue)
138
+ trackEventUsageData("color-range-from-updated", this.storeService.getState().files, {
139
+ colorMetric: this.storeService.getState().dynamicSettings.colorMetric,
140
+ fromValue: modelValue
141
+ })
149
142
  } else if (pointerType === "max") {
150
- this.broadcastColorRangeToUpdated(this.storeService.getState().dynamicSettings.colorMetric, highValue)
143
+ trackEventUsageData("color-range-to-updated", this.storeService.getState().files, {
144
+ colorMetric: this.storeService.getState().dynamicSettings.colorMetric,
145
+ toValue: highValue
146
+ })
151
147
  }
152
148
  }
153
149
 
154
- private broadcastColorRangeFromUpdated(colorMetric: string, fromValue: number) {
155
- this.$rootScope.$broadcast(RangeSliderController.COLOR_RANGE_FROM_UPDATED, { colorMetric, fromValue })
156
- }
157
-
158
- private broadcastColorRangeToUpdated(colorMetric: string, toValue: number) {
159
- this.$rootScope.$broadcast(RangeSliderController.COLOR_RANGE_TO_UPDATED, { colorMetric, toValue })
160
- }
161
-
162
- static subscribeToColorRangeFromUpdated($rootScope: IRootScopeService, subscriber: ColorRangeFromSubscriber) {
163
- $rootScope.$on(RangeSliderController.COLOR_RANGE_FROM_UPDATED, (_event, data) => {
164
- subscriber.onColorRangeFromUpdated(data.colorMetric, data.fromValue)
165
- })
166
- }
167
-
168
- static subscribeToColorRangeToUpdated($rootScope: IRootScopeService, subscriber: ColorRangeToSubscriber) {
169
- $rootScope.$on(RangeSliderController.COLOR_RANGE_TO_UPDATED, (_event, data) => {
170
- subscriber.onColorRangeToUpdated(data.colorMetric, data.toValue)
171
- })
172
- }
173
-
174
150
  private updateInputFieldWidth() {
175
151
  const fromLength = this._viewModel.colorRangeFrom.toFixed(0).length + 1
176
152
  const toLength = this._viewModel.colorRangeTo.toFixed(0).length + 1
@@ -1,25 +1,10 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
- exports[`UsageDataTracker trackEventUsageData should track node interaction blacklist event 1`] = `
4
- "some-already-tracked-events-from-file-storage
5
- {\\"mapId\\":\\"invalid-md5-sample-checksum\\",\\"eventType\\":\\"node_interaction\\",\\"eventTime\\":1612428357566,\\"payload\\":{\\"eventName\\":\\"ADD_BLACKLIST_ITEM\\",\\"id\\":\\"098f6bcd4621d373cade4e832627b4f6\\",\\"type\\":\\"exclude\\",\\"attributes\\":{}}}"
6
- `;
7
-
8
- exports[`UsageDataTracker trackEventUsageData should track node interaction focus event 1`] = `
9
- "some-already-tracked-events-from-file-storage
10
- {\\"mapId\\":\\"invalid-md5-sample-checksum\\",\\"eventType\\":\\"node_interaction\\",\\"eventTime\\":1612428357566,\\"payload\\":{\\"eventName\\":\\"FOCUS_NODE\\",\\"id\\":\\"9d1e46ce2260c90b8b7600a11ca08972\\"}}"
11
- `;
12
-
13
- exports[`UsageDataTracker trackEventUsageData should track setting changed event 1`] = `
3
+ exports[`UsageDataTracker trackEventUsageData should track an event 1`] = `
14
4
  "some-already-tracked-events-from-file-storage
15
5
  {\\"mapId\\":\\"invalid-md5-sample-checksum\\",\\"eventType\\":\\"setting_changed\\",\\"eventTime\\":1612428357566,\\"payload\\":{\\"eventName\\":\\"SET_HEIGHT_METRIC\\",\\"newValue\\":\\"newHeightMetricValue\\"}}"
16
6
  `;
17
7
 
18
- exports[`UsageDataTracker trackEventUsageData should track setting changed event for resetting the blacklist 1`] = `
19
- "some-already-tracked-events-from-file-storage
20
- {\\"mapId\\":\\"invalid-md5-sample-checksum\\",\\"eventType\\":\\"setting_changed\\",\\"eventTime\\":1612428357566,\\"payload\\":{\\"eventName\\":\\"SET_BLACKLIST\\",\\"newValue\\":[]}}"
21
- `;
22
-
23
8
  exports[`UsageDataTracker trackMetaUsageData should not consider files with divergent metrics for statistic calculation 1`] = `"{\\"mapId\\":\\"invalid-md5-sample-checksum\\",\\"codeChartaApiVersion\\":\\"1.1\\",\\"creationTime\\":1612369999999,\\"exportedFileSizeInBytes\\":999,\\"statisticsPerLanguage\\":{\\"ts\\":{\\"metrics\\":{\\"rloc\\":{\\"avg\\":33.333333333333336,\\"max\\":70,\\"median\\":30,\\"min\\":0,\\"numberOfFiles\\":3,\\"totalSum\\":100,\\"firstQuantile\\":0,\\"thirdQuantile\\":70,\\"variance\\":822.2222222222223,\\"standardDeviation\\":28.674417556808756,\\"variationCoefficient\\":0.8602325267042626,\\"outliers\\":[],\\"metricValues\\":[0,30,70]}},\\"numberOfFiles\\":3,\\"maxFilePathDepth\\":4,\\"avgFilePathDepth\\":3.6666666666666665},\\"java\\":{\\"metrics\\":{\\"rloc\\":{\\"avg\\":55,\\"max\\":100,\\"median\\":50,\\"min\\":20,\\"numberOfFiles\\":4,\\"totalSum\\":220,\\"firstQuantile\\":25,\\"thirdQuantile\\":85,\\"variance\\":1025,\\"standardDeviation\\":32.01562118716424,\\"variationCoefficient\\":0.5821022034029862,\\"outliers\\":[],\\"metricValues\\":[100,30,70,20]},\\"functions\\":{\\"avg\\":280,\\"max\\":1000,\\"median\\":55,\\"min\\":10,\\"numberOfFiles\\":4,\\"totalSum\\":1120,\\"firstQuantile\\":10,\\"thirdQuantile\\":550,\\"variance\\":174150,\\"standardDeviation\\":417.31283229730667,\\"variationCoefficient\\":1.490402972490381,\\"outliers\\":[],\\"metricValues\\":[10,100,1000,10]},\\"mcc\\":{\\"avg\\":28.25,\\"max\\":100,\\"median\\":6,\\"min\\":1,\\"numberOfFiles\\":4,\\"totalSum\\":113,\\"firstQuantile\\":1.5,\\"thirdQuantile\\":55,\\"variance\\":1728.1875,\\"standardDeviation\\":41.57147459496716,\\"variationCoefficient\\":1.4715566228306958,\\"outliers\\":[],\\"metricValues\\":[1,100,10,2]}},\\"numberOfFiles\\":4,\\"maxFilePathDepth\\":4,\\"avgFilePathDepth\\":3.75}}}"`;
24
9
 
25
10
  exports[`UsageDataTracker trackMetaUsageData should track files with multiple programming languages properly 1`] = `"{\\"mapId\\":\\"invalid-md5-sample-checksum\\",\\"codeChartaApiVersion\\":\\"1.1\\",\\"creationTime\\":1612369999999,\\"exportedFileSizeInBytes\\":999,\\"statisticsPerLanguage\\":{\\"ts\\":{\\"metrics\\":{\\"rloc\\":{\\"avg\\":66.66666666666667,\\"max\\":100,\\"median\\":70,\\"min\\":30,\\"numberOfFiles\\":3,\\"totalSum\\":200,\\"firstQuantile\\":30,\\"thirdQuantile\\":100,\\"variance\\":822.2222222222223,\\"standardDeviation\\":28.674417556808756,\\"variationCoefficient\\":0.4301162633521313,\\"outliers\\":[],\\"metricValues\\":[100,30,70]},\\"functions\\":{\\"avg\\":370,\\"max\\":1000,\\"median\\":100,\\"min\\":10,\\"numberOfFiles\\":3,\\"totalSum\\":1110,\\"firstQuantile\\":10,\\"thirdQuantile\\":1000,\\"variance\\":199800,\\"standardDeviation\\":446.9899327725402,\\"variationCoefficient\\":1.2080808993852439,\\"outliers\\":[],\\"metricValues\\":[10,100,1000]},\\"mcc\\":{\\"avg\\":37,\\"max\\":100,\\"median\\":10,\\"min\\":1,\\"numberOfFiles\\":3,\\"totalSum\\":111,\\"firstQuantile\\":1,\\"thirdQuantile\\":100,\\"variance\\":1998,\\"standardDeviation\\":44.69899327725402,\\"variationCoefficient\\":1.2080808993852437,\\"outliers\\":[],\\"metricValues\\":[1,100,10]}},\\"numberOfFiles\\":3,\\"maxFilePathDepth\\":4,\\"avgFilePathDepth\\":3.6666666666666665},\\"java\\":{\\"metrics\\":{\\"rloc\\":{\\"avg\\":55,\\"max\\":100,\\"median\\":50,\\"min\\":20,\\"numberOfFiles\\":4,\\"totalSum\\":220,\\"firstQuantile\\":25,\\"thirdQuantile\\":85,\\"variance\\":1025,\\"standardDeviation\\":32.01562118716424,\\"variationCoefficient\\":0.5821022034029862,\\"outliers\\":[],\\"metricValues\\":[100,30,70,20]},\\"functions\\":{\\"avg\\":280,\\"max\\":1000,\\"median\\":55,\\"min\\":10,\\"numberOfFiles\\":4,\\"totalSum\\":1120,\\"firstQuantile\\":10,\\"thirdQuantile\\":550,\\"variance\\":174150,\\"standardDeviation\\":417.31283229730667,\\"variationCoefficient\\":1.490402972490381,\\"outliers\\":[],\\"metricValues\\":[10,100,1000,10]},\\"mcc\\":{\\"avg\\":28.25,\\"max\\":100,\\"median\\":6,\\"min\\":1,\\"numberOfFiles\\":4,\\"totalSum\\":113,\\"firstQuantile\\":1.5,\\"thirdQuantile\\":55,\\"variance\\":1728.1875,\\"standardDeviation\\":41.57147459496716,\\"variationCoefficient\\":1.4715566228306958,\\"outliers\\":[],\\"metricValues\\":[1,100,10,2]}},\\"numberOfFiles\\":4,\\"maxFilePathDepth\\":4,\\"avgFilePathDepth\\":3.75}}}"`;
@@ -1,4 +1,4 @@
1
- import { hierarchy, HierarchyNode } from "d3-hierarchy"
1
+ import { hierarchy } from "d3-hierarchy"
2
2
  import { BlacklistItem, BlacklistType, CodeMapNode, MarkedPackage } from "../codeCharta.model"
3
3
  import ignore from "ignore"
4
4
  import { FileState } from "../model/files/files"
@@ -105,7 +105,8 @@ export function isBlacklisted(node: CodeMapNode) {
105
105
  return node.isExcluded || node.isFlattened
106
106
  }
107
107
 
108
- export function isLeaf(node: CodeMapNode | HierarchyNode<unknown>) {
108
+ export type MaybeLeaf = { children?: unknown[] }
109
+ export function isLeaf(node: MaybeLeaf) {
109
110
  return node.children === undefined || node.children.length === 0
110
111
  }
111
112