codecharta-visualization 1.117.0 → 1.119.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.
- package/README.md +13 -1
- package/app/codeCharta/services/loadInitialFile/urlExtractor.ts +2 -2
- package/app/codeCharta/state/selectors/accumulatedData/metricData/edgeMetricData.calculator.ts +5 -1
- package/app/codeCharta/state/selectors/primaryMetrics/primaryMetrics.selector.ts +7 -15
- package/app/codeCharta/state/store/dynamicSettings/colorRange/resetColorRange.effect.spec.ts +9 -0
- package/app/codeCharta/state/store/dynamicSettings/colorRange/resetColorRange.effect.ts +9 -0
- package/app/codeCharta/ui/attributeSideBar/attributeSideBar.component.scss +27 -0
- package/app/codeCharta/ui/attributeSideBar/attributeSideBar.component.spec.ts +18 -15
- package/app/codeCharta/ui/attributeSideBar/attributeSideBar.module.ts +10 -2
- package/app/codeCharta/ui/attributeSideBar/attributeSideBarHeaderSection/nodePath/nodePath.component.spec.ts +2 -2
- package/app/codeCharta/ui/attributeSideBar/attributeSideBarPrimaryMetrics/attributeSideBarPrimaryMetric/attributeSideBarPrimaryMetric.component.html +7 -1
- package/app/codeCharta/ui/attributeSideBar/attributeSideBarPrimaryMetrics/attributeSideBarPrimaryMetric/attributeSideBarPrimaryMetric.component.ts +1 -0
- package/app/codeCharta/ui/attributeSideBar/attributeSideBarPrimaryMetrics/attributeSideBarPrimaryMetrics.component.html +20 -6
- package/app/codeCharta/ui/attributeSideBar/attributeSideBarPrimaryMetrics/attributeSideBarPrimaryMetrics.component.ts +7 -4
- package/app/codeCharta/ui/attributeSideBar/attributeSideBarSecondaryMetrics/attributeSideBarSecondaryMetrics.component.html +17 -3
- package/app/codeCharta/ui/attributeSideBar/attributeSideBarSecondaryMetrics/attributeSideBarSecondaryMetrics.component.ts +8 -5
- package/app/codeCharta/ui/attributeSideBar/attributeSideBarSecondaryMetrics/secondaryMetrics.selector.spec.ts +4 -23
- package/app/codeCharta/ui/attributeSideBar/attributeSideBarSecondaryMetrics/secondaryMetrics.selector.ts +4 -16
- package/app/codeCharta/ui/attributeSideBar/metricDeltaSelected/metricDeltaSelected.component.spec.ts +1 -1
- package/app/codeCharta/ui/attributeSideBar/util/edge.ts +0 -2
- package/app/codeCharta/ui/attributeSideBar/util/metric.ts +0 -2
- package/app/codeCharta/ui/codeMap/arrow/codeMap.arrow.service.ts +2 -5
- package/app/codeCharta/ui/customConfigs/customConfigs.module.ts +4 -3
- package/app/codeCharta/ui/customConfigs/uploadCustomConfigButton/uploadCustomConfigButton.component.ts +1 -1
- package/app/codeCharta/ui/fileExtensionBar/fileExtensionBar.component.spec.ts +3 -1
- package/app/codeCharta/ui/filePanel/filePanel.module.ts +2 -2
- package/app/codeCharta/ui/legendPanel/legendBlock/legendBlock.component.html +24 -20
- package/app/codeCharta/ui/legendPanel/legendBlock/legendBlock.component.ts +10 -3
- package/app/codeCharta/ui/legendPanel/legendPanel.component.html +7 -13
- package/app/codeCharta/ui/legendPanel/legendPanel.component.scss +16 -18
- package/app/codeCharta/ui/legendPanel/legendPanel.component.spec.ts +34 -12
- package/app/codeCharta/ui/legendPanel/legendPanel.component.ts +8 -8
- package/app/codeCharta/ui/legendPanel/legendPanel.module.ts +3 -2
- package/app/codeCharta/ui/metricChooser/metricChooser.component.html +7 -2
- package/app/codeCharta/ui/metricChooser/metricChooser.component.scss +8 -0
- package/app/codeCharta/ui/metricChooser/metricChooser.component.spec.ts +39 -11
- package/app/codeCharta/ui/metricChooser/metricChooser.component.ts +2 -2
- package/app/codeCharta/ui/metricChooser/metricChooser.module.ts +3 -2
- package/app/codeCharta/ui/ribbonBar/areaMetricChooser/areaMetricChooser.component.html +1 -0
- package/app/codeCharta/ui/ribbonBar/areaMetricChooser/areaMetricChooser.component.spec.ts +17 -6
- package/app/codeCharta/ui/ribbonBar/colorMetricChooser/colorMetricChooser.component.html +1 -0
- package/app/codeCharta/ui/ribbonBar/colorMetricChooser/colorMetricChooser.component.spec.ts +19 -6
- package/app/codeCharta/ui/ribbonBar/edgeMetricChooser/edgeMetricChooser.component.html +1 -0
- package/app/codeCharta/ui/ribbonBar/edgeMetricChooser/edgeMetricChooser.component.spec.ts +15 -5
- package/app/codeCharta/ui/ribbonBar/heightMetricChooser/heightMetricChooser.component.html +1 -0
- package/app/codeCharta/ui/ribbonBar/heightMetricChooser/heightMetricChooser.component.spec.ts +21 -8
- package/app/codeCharta/ui/ribbonBar/heightMetricChooser/heightMetricChooser.module.ts +1 -1
- package/app/codeCharta/ui/ribbonBar/ribbonBar.module.ts +1 -1
- package/app/codeCharta/util/algorithm/streetLayout/horizontalStreet.ts +2 -2
- package/app/codeCharta/util/algorithm/streetLayout/verticalStreet.ts +2 -2
- package/app/codeCharta/util/dataMocks.ts +18 -1
- package/app/codeCharta/util/gameObjectsParser/gameObjectsImporter.ts +1 -1
- package/app/codeCharta/util/pipes/AttributeDescriptorTooltipPipeModule.ts +8 -0
- package/app/codeCharta/util/pipes/RemoveExtensionPipeModule.ts +8 -0
- package/app/codeCharta/util/pipes/TruncateTextPipeModule.ts +8 -0
- package/app/codeCharta/util/pipes/attributeDescriptorTooltip.pipe.spec.ts +61 -0
- package/app/codeCharta/util/pipes/attributeDescriptorTooltip.pipe.ts +19 -0
- package/dist/webpack/index.html +1 -1
- package/dist/webpack/main.0e368e65a1bdf78b.js +1 -0
- package/package.json +3 -3
- package/app/codeCharta/ui/attributeSideBar/util/metricDescriptors.ts +0 -30
- package/app/codeCharta/ui/legendPanel/selectors/legendAreaMetric.selector.ts +0 -10
- package/app/codeCharta/ui/legendPanel/selectors/legendColorMetric.selector.ts +0 -10
- package/app/codeCharta/ui/legendPanel/selectors/legendEdgeMetric.selector.spec.ts +0 -76
- package/app/codeCharta/ui/legendPanel/selectors/legendEdgeMetric.selector.ts +0 -25
- package/app/codeCharta/ui/legendPanel/selectors/legendHeightMetric.selector.ts +0 -10
- package/app/codeCharta/util/simplePipes/SimplePipesModule.ts +0 -9
- package/app/codeCharta/util/simplePipes/metricDescriptorTitle.pipe.spec.ts +0 -62
- package/app/codeCharta/util/simplePipes/metricDescriptorTitle.pipe.ts +0 -18
- package/dist/webpack/main.276ed7d686dd2d87.js +0 -1
- /package/app/codeCharta/ui/ribbonBar/colorMetricChooser/{heightMetricChooser.module.ts → colorMetricChooser.module.ts} +0 -0
- /package/app/codeCharta/ui/ribbonBar/heightMetricChooser/{areaMetricChooser.component.ts → heightMetricChooser.component.ts} +0 -0
- /package/app/codeCharta/util/{simplePipes → pipes}/removeExtension.pipe.spec.ts +0 -0
- /package/app/codeCharta/util/{simplePipes → pipes}/removeExtension.pipe.ts +0 -0
- /package/app/codeCharta/util/{truncateText.pipe.ts → pipes/truncateText.pipe.ts} +0 -0
- /package/app/codeCharta/util/{truncateText.spec.ts → pipes/truncateText.spec.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# CodeCharta Visualization
|
|
2
2
|
|
|
3
|
-
[](https://sonarcloud.io/project/overview?id=maibornwolff-gmbh_codecharta_visualization)
|
|
4
4
|
|
|
5
5
|
> CodeCharta by [MaibornWolff](https://www.maibornwolff.de)
|
|
6
6
|
|
|
@@ -19,6 +19,8 @@ You can start with **Codecharta Visualization** on multiple ways:
|
|
|
19
19
|
- Installation as a [npm package](#npm-package) (Recommended)
|
|
20
20
|
- Run an operating system specific [standalone](#run-a-standalone)
|
|
21
21
|
- Build it yourself from the github [repository](#build-it-yourself)
|
|
22
|
+
- Use [docker-compose](https://maibornwolff.github.io/codecharta/docs/docker-containers/) to run this with other needed tools like a Sonar instance or analyzing tools of codecharta-analysis.
|
|
23
|
+
- Use our [Dockerfile](#run-in-docker-container) to run the visualization in a container
|
|
22
24
|
- Try out the [online version](https://maibornwolff.github.io/codecharta/visualization/app/index.html?file=codecharta.cc.json&file=codecharta_analysis.cc.json)
|
|
23
25
|
|
|
24
26
|
> Be aware, that if you are on Apple Silicon, you need to do additional config for npm installation
|
|
@@ -140,6 +142,16 @@ $ npm run e2e:auto
|
|
|
140
142
|
|
|
141
143
|
> To follow/watch the steps the e2e test is performing, deactivate headless mode in `jest-puppeteer.config.js` (and maybe set the `slowMo` parameter)
|
|
142
144
|
|
|
145
|
+
## Run in Docker container
|
|
146
|
+
|
|
147
|
+
You can use this via docker compose or as a standalone container. This section will deal with how to use the visualization as a standalone container. For information on how to use this with docker compose, please check out [Docker Getting Started](https://maibornwolff.github.io/codecharta/docs/docker-containers/)
|
|
148
|
+
We assume that you already installed docker, if not, you have to do that before!
|
|
149
|
+
|
|
150
|
+
To containerize the visualization, please follow the below listed steps.
|
|
151
|
+
|
|
152
|
+
- Start the docker container: `docker run -d -p 9000:80 codecharta/codecharta-visualization`. This detaches the container and exposes port 80 on the container and port 9000 on the host.
|
|
153
|
+
- Open `localhost:9000` in your browser and you can already use the visualization, upload `cc.json` files and play around!
|
|
154
|
+
|
|
143
155
|
# JSON structure
|
|
144
156
|
|
|
145
157
|
[Example Data](/visualization/app/codeCharta/assets/sample1.cc.json)
|
|
@@ -9,7 +9,7 @@ export class UrlExtractor {
|
|
|
9
9
|
constructor(private httpClient: HttpClient) {}
|
|
10
10
|
|
|
11
11
|
getParameterByName(name: string) {
|
|
12
|
-
const sanitizedName = name.
|
|
12
|
+
const sanitizedName = name.replaceAll(/[[\]]/g, "\\$&")
|
|
13
13
|
const regex = new RegExp(`[?&]${sanitizedName}(=([^&#]*)|&|#|$)`),
|
|
14
14
|
results = regex.exec(window.location.href)
|
|
15
15
|
|
|
@@ -19,7 +19,7 @@ export class UrlExtractor {
|
|
|
19
19
|
if (!results[2]) {
|
|
20
20
|
return ""
|
|
21
21
|
}
|
|
22
|
-
return decodeURIComponent(results[2].
|
|
22
|
+
return decodeURIComponent(results[2].replaceAll("+", " "))
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
async getFileDataFromQueryParam() {
|
package/app/codeCharta/state/selectors/accumulatedData/metricData/edgeMetricData.calculator.ts
CHANGED
|
@@ -84,7 +84,11 @@ function getMetricDataFromMap(nodeEdgeMetricsMap: NodeEdgeMetricsMap) {
|
|
|
84
84
|
minimumMetricValue = combinedValue
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
|
-
metricData.push({
|
|
87
|
+
metricData.push({
|
|
88
|
+
name: edgeMetric,
|
|
89
|
+
maxValue: maximumMetricValue,
|
|
90
|
+
minValue: minimumMetricValue
|
|
91
|
+
})
|
|
88
92
|
}
|
|
89
93
|
|
|
90
94
|
return metricData
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import { selectedNodeSelector } from "../selectedNode.selector"
|
|
2
2
|
import { Metric } from "../../../ui/attributeSideBar/util/metric"
|
|
3
3
|
import { primaryMetricNamesSelector } from "./primaryMetricNames.selector"
|
|
4
|
-
import { getMetricDescriptors } from "../../../ui/attributeSideBar/util/metricDescriptors"
|
|
5
|
-
import { attributeDescriptorsSelector } from "../../store/fileSettings/attributeDescriptors/attributeDescriptors.selector"
|
|
6
4
|
import { Edge } from "app/codeCharta/ui/attributeSideBar/util/edge"
|
|
7
5
|
import { CodeMapNode } from "app/codeCharta/codeCharta.model"
|
|
8
|
-
import { AttributeDescriptors } from "../../../codeCharta.model"
|
|
9
6
|
import { createSelector } from "@ngrx/store"
|
|
10
7
|
|
|
11
8
|
export type PrimaryMetrics = {
|
|
@@ -18,8 +15,7 @@ export type PrimaryMetrics = {
|
|
|
18
15
|
export const primaryMetricsSelector = createSelector(
|
|
19
16
|
selectedNodeSelector,
|
|
20
17
|
primaryMetricNamesSelector,
|
|
21
|
-
|
|
22
|
-
(selectedNode, primaryMetricNames, attributeDescriptors) => {
|
|
18
|
+
(selectedNode, primaryMetricNames) => {
|
|
23
19
|
if (!selectedNode) {
|
|
24
20
|
return
|
|
25
21
|
}
|
|
@@ -27,32 +23,28 @@ export const primaryMetricsSelector = createSelector(
|
|
|
27
23
|
return {
|
|
28
24
|
area: {
|
|
29
25
|
name: primaryMetricNames.areaMetric,
|
|
30
|
-
value: selectedNode.attributes[primaryMetricNames.areaMetric]
|
|
31
|
-
descriptors: getMetricDescriptors(primaryMetricNames.areaMetric, attributeDescriptors)
|
|
26
|
+
value: selectedNode.attributes[primaryMetricNames.areaMetric]
|
|
32
27
|
},
|
|
33
28
|
height: {
|
|
34
29
|
name: primaryMetricNames.heightMetric,
|
|
35
|
-
value: selectedNode.attributes[primaryMetricNames.heightMetric]
|
|
36
|
-
descriptors: getMetricDescriptors(primaryMetricNames.heightMetric, attributeDescriptors)
|
|
30
|
+
value: selectedNode.attributes[primaryMetricNames.heightMetric]
|
|
37
31
|
},
|
|
38
32
|
color: {
|
|
39
33
|
name: primaryMetricNames.colorMetric,
|
|
40
|
-
value: selectedNode.attributes[primaryMetricNames.colorMetric]
|
|
41
|
-
descriptors: getMetricDescriptors(primaryMetricNames.colorMetric, attributeDescriptors)
|
|
34
|
+
value: selectedNode.attributes[primaryMetricNames.colorMetric]
|
|
42
35
|
},
|
|
43
|
-
edge: getEdge(primaryMetricNames.edgeMetric, selectedNode
|
|
36
|
+
edge: getEdge(primaryMetricNames.edgeMetric, selectedNode)
|
|
44
37
|
}
|
|
45
38
|
}
|
|
46
39
|
)
|
|
47
40
|
|
|
48
|
-
function getEdge(key: string, selectedNode: CodeMapNode
|
|
41
|
+
function getEdge(key: string, selectedNode: CodeMapNode): Edge {
|
|
49
42
|
if (key === undefined || key === null) {
|
|
50
43
|
return null
|
|
51
44
|
}
|
|
52
45
|
return {
|
|
53
46
|
name: key,
|
|
54
47
|
incoming: selectedNode.edgeAttributes[key]?.incoming,
|
|
55
|
-
outgoing: selectedNode.edgeAttributes[key]?.outgoing
|
|
56
|
-
descriptors: getMetricDescriptors(key, attributeDescriptors)
|
|
48
|
+
outgoing: selectedNode.edgeAttributes[key]?.outgoing
|
|
57
49
|
}
|
|
58
50
|
}
|
package/app/codeCharta/state/store/dynamicSettings/colorRange/resetColorRange.effect.spec.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { BehaviorSubject } from "rxjs"
|
|
|
8
8
|
import { Action } from "@ngrx/store"
|
|
9
9
|
import { setStandard } from "../../files/files.actions"
|
|
10
10
|
import { getLastAction } from "../../../../util/testUtils/store.utils"
|
|
11
|
+
import { setColorMetric } from "../colorMetric/colorMetric.actions"
|
|
11
12
|
|
|
12
13
|
describe("ResetColorRangeEffect", () => {
|
|
13
14
|
let actions$: BehaviorSubject<Action>
|
|
@@ -48,4 +49,12 @@ describe("ResetColorRangeEffect", () => {
|
|
|
48
49
|
store.refreshState()
|
|
49
50
|
expect(await getLastAction(store)).not.toEqual({ value: { from: 53, to: 86 }, type: "SET_COLOR_RANGE" })
|
|
50
51
|
})
|
|
52
|
+
|
|
53
|
+
it("should fire when colorMetric selection changed", async () => {
|
|
54
|
+
const store = TestBed.inject(MockStore)
|
|
55
|
+
store.overrideSelector(selectedColorMetricDataSelector, { minValue: 20, maxValue: 120 })
|
|
56
|
+
store.refreshState()
|
|
57
|
+
actions$.next(setColorMetric({ value: "anotherMetric" }))
|
|
58
|
+
expect(await getLastAction(store)).toEqual({ value: { from: 53, to: 86 }, type: "SET_COLOR_RANGE" })
|
|
59
|
+
})
|
|
51
60
|
})
|
|
@@ -7,6 +7,7 @@ import { calculateInitialColorRange } from "./calculateInitialColorRange"
|
|
|
7
7
|
import { setColorRange } from "./colorRange.actions"
|
|
8
8
|
import { fileActions } from "../../files/files.actions"
|
|
9
9
|
import { CcState } from "../../../../codeCharta.model"
|
|
10
|
+
import { setColorMetric } from "../colorMetric/colorMetric.actions"
|
|
10
11
|
|
|
11
12
|
@Injectable()
|
|
12
13
|
export class ResetColorRangeEffect {
|
|
@@ -19,4 +20,12 @@ export class ResetColorRangeEffect {
|
|
|
19
20
|
map(selectedColorMetricData => setColorRange({ value: calculateInitialColorRange(selectedColorMetricData) }))
|
|
20
21
|
)
|
|
21
22
|
)
|
|
23
|
+
|
|
24
|
+
resetColorRangeOnColorMetricChange$ = createEffect(() =>
|
|
25
|
+
this.actions$.pipe(
|
|
26
|
+
ofType(setColorMetric),
|
|
27
|
+
switchMap(() => this.store.select(selectedColorMetricDataSelector).pipe(take(1))),
|
|
28
|
+
map(selectedColorMetricData => setColorRange({ value: calculateInitialColorRange(selectedColorMetricData) }))
|
|
29
|
+
)
|
|
30
|
+
)
|
|
22
31
|
}
|
|
@@ -133,5 +133,32 @@ cc-attribute-side-bar {
|
|
|
133
133
|
margin-top: 5px;
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
|
+
|
|
137
|
+
cc-attribute-side-bar-primary-metrics,
|
|
138
|
+
cc-attribute-side-bar-secondary-metrics {
|
|
139
|
+
.metric-box,
|
|
140
|
+
.metrics-wrapper {
|
|
141
|
+
i.fa.fa-external-link {
|
|
142
|
+
font-size: 10px;
|
|
143
|
+
min-width: 10px;
|
|
144
|
+
text-align: center;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
a:link,
|
|
148
|
+
a:visited {
|
|
149
|
+
text-decoration: none;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
a:hover {
|
|
153
|
+
color: blue;
|
|
154
|
+
text-decoration: solid;
|
|
155
|
+
text-decoration-line: underline;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
a:active {
|
|
159
|
+
color: red;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
136
163
|
}
|
|
137
164
|
}
|
|
@@ -18,6 +18,7 @@ import { primaryMetricsSelector } from "../../state/selectors/primaryMetrics/pri
|
|
|
18
18
|
import { attributeTypesSelector } from "../../state/store/fileSettings/attributeTypes/attributeTypes.selector"
|
|
19
19
|
import { defaultAttributeTypes } from "../../state/store/fileSettings/attributeTypes/attributeTypes.reducer"
|
|
20
20
|
import { showAttributeTypeSelectorSelector } from "./util/showAttributeTypeSelector.selector"
|
|
21
|
+
import { metricTitles } from "../../util/metric/metricTitles"
|
|
21
22
|
|
|
22
23
|
let selectedMetricNames
|
|
23
24
|
|
|
@@ -110,31 +111,29 @@ describe("AttributeSideBarComponent", () => {
|
|
|
110
111
|
it("should contain primary/secondary metrics with title/tooltip attribute/metric descriptor information", async () => {
|
|
111
112
|
selectedMetricNames.areaMetric = "a"
|
|
112
113
|
selectedMetricNames.heightMetric = "b"
|
|
113
|
-
selectedMetricNames.colorMetric = "
|
|
114
|
+
selectedMetricNames.colorMetric = "mcc"
|
|
114
115
|
selectedMetricNames.edgeMetric = "someEdge"
|
|
115
116
|
|
|
116
117
|
const { container, detectChanges } = await render(AttributeSideBarComponent, { excludeComponentDeclaration: true })
|
|
117
118
|
|
|
118
119
|
const store = TestBed.inject(MockStore)
|
|
119
120
|
store.overrideSelector(primaryMetricsSelector, {
|
|
120
|
-
area: { name: "a", value: 3
|
|
121
|
-
height: { name: "b", value: 1
|
|
121
|
+
area: { name: "a", value: 3 },
|
|
122
|
+
height: { name: "b", value: 1 },
|
|
122
123
|
color: {
|
|
123
|
-
name: "
|
|
124
|
-
value: 10
|
|
125
|
-
descriptors: { key: "someColor", description: "", hintHighValue: "", hintLowValue: "", link: "", title: "" }
|
|
124
|
+
name: "mcc",
|
|
125
|
+
value: 10
|
|
126
126
|
},
|
|
127
127
|
edge: {
|
|
128
|
-
name: "
|
|
128
|
+
name: "someEdge",
|
|
129
129
|
incoming: 20,
|
|
130
|
-
outgoing: 60
|
|
131
|
-
descriptors: { key: "someEdge", description: "", hintHighValue: "", hintLowValue: "", link: "", title: "" }
|
|
130
|
+
outgoing: 60
|
|
132
131
|
}
|
|
133
132
|
})
|
|
134
133
|
|
|
135
134
|
const selectedNode = klona(TEST_NODE_FOLDER)
|
|
136
135
|
selectedNode["children"] = [{}]
|
|
137
|
-
selectedNode["attributes"] = { a: 3, b: 1,
|
|
136
|
+
selectedNode["attributes"] = { a: 3, b: 1, mcc: 4, rloc: 222, someColor: 10, d: 100 }
|
|
138
137
|
selectedNode["edgeAttributes"] = { someEdge: { incoming: 20, outgoing: 60 } }
|
|
139
138
|
mockSelectedNode(selectedNode as unknown as CodeMapNode, detectChanges)
|
|
140
139
|
|
|
@@ -142,11 +141,15 @@ describe("AttributeSideBarComponent", () => {
|
|
|
142
141
|
const attributeTypeSelectorWithinSecondaryMetrics = container.querySelectorAll("cc-attribute-side-bar-secondary-metrics tr")
|
|
143
142
|
expect(attributeTypeSelectorWithinPrimaryMetrics[0].getAttribute("title")).toBe("a_testTitle (a):\na_testDescription")
|
|
144
143
|
expect(attributeTypeSelectorWithinPrimaryMetrics[1].getAttribute("title")).toBe("b_testTitle (b)")
|
|
145
|
-
expect(attributeTypeSelectorWithinPrimaryMetrics[
|
|
146
|
-
expect(attributeTypeSelectorWithinPrimaryMetrics[
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
expect(attributeTypeSelectorWithinSecondaryMetrics.
|
|
144
|
+
expect(attributeTypeSelectorWithinPrimaryMetrics[1].querySelector("a").getAttribute("href")).toBe("https://test.link")
|
|
145
|
+
expect(attributeTypeSelectorWithinPrimaryMetrics[2].getAttribute("title")).toBe(metricTitles.get("mcc"))
|
|
146
|
+
expect(attributeTypeSelectorWithinPrimaryMetrics[3].getAttribute("title")).toBe("")
|
|
147
|
+
|
|
148
|
+
expect(attributeTypeSelectorWithinSecondaryMetrics[1].querySelector("a").getAttribute("href")).toBe("https://test2.link")
|
|
149
|
+
expect(attributeTypeSelectorWithinSecondaryMetrics[1].getAttribute("title")).toBe("d")
|
|
150
|
+
expect(attributeTypeSelectorWithinSecondaryMetrics[2].getAttribute("title")).toBe(metricTitles.get("rloc"))
|
|
151
|
+
expect(attributeTypeSelectorWithinSecondaryMetrics[3].getAttribute("title")).toBe("") // someColor
|
|
152
|
+
expect(attributeTypeSelectorWithinSecondaryMetrics.length).toBe(4) // header + three entries
|
|
150
153
|
})
|
|
151
154
|
})
|
|
152
155
|
|
|
@@ -10,10 +10,18 @@ import { AttributeSideBarPrimaryMetricComponent } from "./attributeSideBarPrimar
|
|
|
10
10
|
import { AttributeSideBarHeaderSectionComponent } from "./attributeSideBarHeaderSection/attributeSideBarHeaderSection.component"
|
|
11
11
|
import { NodePathComponent } from "./attributeSideBarHeaderSection/nodePath/nodePath.component"
|
|
12
12
|
import { MaterialModule } from "../../../material/material.module"
|
|
13
|
-
import {
|
|
13
|
+
import { RemoveExtensionPipeModule } from "../../util/pipes/RemoveExtensionPipeModule"
|
|
14
|
+
import { AttributeDescriptorTooltipPipeModule } from "../../util/pipes/AttributeDescriptorTooltipPipeModule"
|
|
14
15
|
|
|
15
16
|
@NgModule({
|
|
16
|
-
imports: [
|
|
17
|
+
imports: [
|
|
18
|
+
CommonModule,
|
|
19
|
+
MaterialModule,
|
|
20
|
+
AttributeTypeSelectorModule,
|
|
21
|
+
MetricDeltaSelectedModule,
|
|
22
|
+
RemoveExtensionPipeModule,
|
|
23
|
+
AttributeDescriptorTooltipPipeModule
|
|
24
|
+
],
|
|
17
25
|
declarations: [
|
|
18
26
|
AttributeSideBarComponent,
|
|
19
27
|
AttributeSideBarHeaderSectionComponent,
|
|
@@ -54,7 +54,7 @@ describe("nodePathComponent", () => {
|
|
|
54
54
|
store.refreshState()
|
|
55
55
|
detectChanges()
|
|
56
56
|
|
|
57
|
-
expect(container.textContent.
|
|
57
|
+
expect(container.textContent.replaceAll(/\s+/g, " ")).toContain("some/folder ( 2 files )")
|
|
58
58
|
})
|
|
59
59
|
|
|
60
60
|
it("should display node path,amount of files, added and removed files, when a folder is selected and delta mode is enabled", async () => {
|
|
@@ -75,7 +75,7 @@ describe("nodePathComponent", () => {
|
|
|
75
75
|
store.refreshState()
|
|
76
76
|
detectChanges()
|
|
77
77
|
|
|
78
|
-
expect(container.textContent.
|
|
78
|
+
expect(container.textContent.replaceAll(/\s+/g, " ")).toContain("some/folder ( 2 files | Δ1 | Δ-2 | Δ3)")
|
|
79
79
|
})
|
|
80
80
|
|
|
81
81
|
it("should display amount of files with correct english grammar, when an empty folder is selected and delta mode is enabled", async () => {
|
|
@@ -10,5 +10,11 @@
|
|
|
10
10
|
<span class="primary-metric-value">{{ metric.value | number: "1.0-0" }}</span>
|
|
11
11
|
</div>
|
|
12
12
|
<cc-metric-delta-selected [metricName]="metric.name"></cc-metric-delta-selected>
|
|
13
|
-
<
|
|
13
|
+
<a class="metric-name" [href]="link" target="_blank" *ngIf="metricLink as link; else primaryMetricNoLink">
|
|
14
|
+
{{ metric.name }}
|
|
15
|
+
<i class="fa fa-external-link"></i>
|
|
16
|
+
</a>
|
|
17
|
+
<ng-template #primaryMetricNoLink
|
|
18
|
+
><span class="metric-name">{{ metric.name }}</span></ng-template
|
|
19
|
+
>
|
|
14
20
|
</div>
|
|
@@ -14,6 +14,7 @@ import { showAttributeTypeSelectorSelector } from "../../util/showAttributeTypeS
|
|
|
14
14
|
export class AttributeSideBarPrimaryMetricComponent {
|
|
15
15
|
@Input() iconName: string
|
|
16
16
|
@Input() metric: Metric
|
|
17
|
+
@Input() metricLink: string
|
|
17
18
|
showAttributeTypeSelector$: Observable<boolean>
|
|
18
19
|
|
|
19
20
|
constructor(store: Store<CcState>) {
|
|
@@ -1,30 +1,33 @@
|
|
|
1
|
-
<div class="metric-box">
|
|
1
|
+
<div class="metric-box" *ngIf="attributeDescriptors$ | async as attributeDescriptors">
|
|
2
2
|
<table *ngIf="primaryMetrics$ | async; let primaryMetrics" class="primary-metrics" aria-hidden="true">
|
|
3
3
|
<th scope="col">Primary Metrics</th>
|
|
4
4
|
|
|
5
5
|
<tr>
|
|
6
|
-
<td [title]="primaryMetrics.area.
|
|
6
|
+
<td [title]="attributeDescriptors[primaryMetrics.area.name] | attributeDescriptorTooltip: primaryMetrics.area.name">
|
|
7
7
|
<cc-attribute-side-bar-primary-metric
|
|
8
8
|
[iconName]="'fa fa-arrows-alt'"
|
|
9
9
|
[metric]="primaryMetrics.area"
|
|
10
|
+
[metricLink]="attributeDescriptors[primaryMetrics.area.name]?.link"
|
|
10
11
|
></cc-attribute-side-bar-primary-metric>
|
|
11
12
|
</td>
|
|
12
|
-
<td [title]="primaryMetrics.height.
|
|
13
|
+
<td [title]="attributeDescriptors[primaryMetrics.height.name] | attributeDescriptorTooltip: primaryMetrics.height.name">
|
|
13
14
|
<cc-attribute-side-bar-primary-metric
|
|
14
15
|
[iconName]="'fa fa-arrows-v'"
|
|
15
16
|
[metric]="primaryMetrics.height"
|
|
17
|
+
[metricLink]="attributeDescriptors[primaryMetrics.height.name]?.link"
|
|
16
18
|
></cc-attribute-side-bar-primary-metric>
|
|
17
19
|
</td>
|
|
18
20
|
</tr>
|
|
19
21
|
<tr>
|
|
20
|
-
<td [title]="primaryMetrics.color.
|
|
22
|
+
<td [title]="attributeDescriptors[primaryMetrics.color.name] | attributeDescriptorTooltip: primaryMetrics.color.name">
|
|
21
23
|
<cc-attribute-side-bar-primary-metric
|
|
22
24
|
[iconName]="'fa fa-paint-brush'"
|
|
23
25
|
[metric]="primaryMetrics.color"
|
|
26
|
+
[metricLink]="attributeDescriptors[primaryMetrics.color.name]?.link"
|
|
24
27
|
></cc-attribute-side-bar-primary-metric>
|
|
25
28
|
</td>
|
|
26
29
|
<ng-container *ngIf="primaryMetrics.edge as edge; else sidebarPrimaryMetricsEdgeElse">
|
|
27
|
-
<td [title]="edge.
|
|
30
|
+
<td [title]="attributeDescriptors[edge.name] | attributeDescriptorTooltip: edge.name">
|
|
28
31
|
<div class="primary-metric-box">
|
|
29
32
|
<div class="primary-metric-row">
|
|
30
33
|
<i class="fa fa-exchange"></i>
|
|
@@ -40,7 +43,18 @@
|
|
|
40
43
|
{{ edge.outgoing | number: "1.0-0" }}
|
|
41
44
|
</span>
|
|
42
45
|
</div>
|
|
43
|
-
<
|
|
46
|
+
<a
|
|
47
|
+
class="metric-name"
|
|
48
|
+
[href]="link"
|
|
49
|
+
target="_blank"
|
|
50
|
+
*ngIf="attributeDescriptors[edge.name]?.link as link; else primaryMetricNoLink"
|
|
51
|
+
>
|
|
52
|
+
{{ edge.name }} (in/out)
|
|
53
|
+
<i class="fa fa-external-link"></i>
|
|
54
|
+
</a>
|
|
55
|
+
<ng-template #primaryMetricNoLink
|
|
56
|
+
><span class="metric-name">{{ edge.name }} (in/out)</span></ng-template
|
|
57
|
+
>
|
|
44
58
|
</div>
|
|
45
59
|
</td>
|
|
46
60
|
</ng-container>
|
|
@@ -4,7 +4,8 @@ import { Observable } from "rxjs"
|
|
|
4
4
|
import { showAttributeTypeSelectorSelector } from "../util/showAttributeTypeSelector.selector"
|
|
5
5
|
import { PrimaryMetrics, primaryMetricsSelector } from "../../../state/selectors/primaryMetrics/primaryMetrics.selector"
|
|
6
6
|
import { Store } from "@ngrx/store"
|
|
7
|
-
import { CcState } from "../../../codeCharta.model"
|
|
7
|
+
import { AttributeDescriptors, CcState } from "../../../codeCharta.model"
|
|
8
|
+
import { attributeDescriptorsSelector } from "../../../state/store/fileSettings/attributeDescriptors/attributeDescriptors.selector"
|
|
8
9
|
|
|
9
10
|
@Component({
|
|
10
11
|
selector: "cc-attribute-side-bar-primary-metrics",
|
|
@@ -14,9 +15,11 @@ import { CcState } from "../../../codeCharta.model"
|
|
|
14
15
|
export class AttributeSideBarPrimaryMetricsComponent {
|
|
15
16
|
primaryMetrics$: Observable<PrimaryMetrics>
|
|
16
17
|
showAttributeTypeSelector$: Observable<boolean>
|
|
18
|
+
attributeDescriptors$: Observable<AttributeDescriptors>
|
|
17
19
|
|
|
18
|
-
constructor(store: Store<CcState>) {
|
|
19
|
-
this.primaryMetrics$ = store.select(primaryMetricsSelector)
|
|
20
|
-
this.showAttributeTypeSelector$ = store.select(showAttributeTypeSelectorSelector)
|
|
20
|
+
constructor(private store: Store<CcState>) {
|
|
21
|
+
this.primaryMetrics$ = this.store.select(primaryMetricsSelector)
|
|
22
|
+
this.showAttributeTypeSelector$ = this.store.select(showAttributeTypeSelectorSelector)
|
|
23
|
+
this.attributeDescriptors$ = this.store.select(attributeDescriptorsSelector)
|
|
21
24
|
}
|
|
22
25
|
}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
<div class="secondary-metrics-wrapper">
|
|
2
2
|
<div class="metrics-wrapper">
|
|
3
|
-
<div class="metric-box scrollable-content">
|
|
3
|
+
<div class="metric-box scrollable-content" *ngIf="attributeDescriptors$ | async as attributeDescriptors">
|
|
4
4
|
<table class="secondary-metrics" aria-hidden="true">
|
|
5
5
|
<tr>
|
|
6
6
|
<th scope="col" colspan="2">Secondary Metrics</th>
|
|
7
7
|
</tr>
|
|
8
|
-
<tr
|
|
8
|
+
<tr
|
|
9
|
+
*ngFor="let secondaryMetric of secondaryMetrics$ | async"
|
|
10
|
+
[title]="attributeDescriptors[secondaryMetric.name] | attributeDescriptorTooltip: secondaryMetric.name"
|
|
11
|
+
>
|
|
9
12
|
<td class="secondary-metric-box">
|
|
10
13
|
<div class="secondary-metric-row">
|
|
11
14
|
<cc-attribute-type-selector
|
|
@@ -22,7 +25,18 @@
|
|
|
22
25
|
<cc-metric-delta-selected [metricName]="secondaryMetric.name"></cc-metric-delta-selected>
|
|
23
26
|
</td>
|
|
24
27
|
<td>
|
|
25
|
-
<
|
|
28
|
+
<a
|
|
29
|
+
class="metric-name"
|
|
30
|
+
[href]="link"
|
|
31
|
+
target="_blank"
|
|
32
|
+
*ngIf="attributeDescriptors[secondaryMetric.name]?.link as link; else secondaryMetricNoLink"
|
|
33
|
+
>
|
|
34
|
+
{{ secondaryMetric.name }}
|
|
35
|
+
<i class="fa fa-external-link"></i>
|
|
36
|
+
</a>
|
|
37
|
+
<ng-template #secondaryMetricNoLink
|
|
38
|
+
><span class="metric-name">{{ secondaryMetric.name }}</span>
|
|
39
|
+
</ng-template>
|
|
26
40
|
</td>
|
|
27
41
|
</tr>
|
|
28
42
|
</table>
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { Component, ViewEncapsulation } from "@angular/core"
|
|
2
2
|
import { Store } from "@ngrx/store"
|
|
3
3
|
import { Observable } from "rxjs"
|
|
4
|
-
import { CcState } from "../../../codeCharta.model"
|
|
4
|
+
import { AttributeDescriptors, CcState } from "../../../codeCharta.model"
|
|
5
5
|
|
|
6
6
|
import { Metric } from "../util/metric"
|
|
7
7
|
import { showAttributeTypeSelectorSelector } from "../util/showAttributeTypeSelector.selector"
|
|
8
8
|
import { showDeltaValueSelector } from "../util/showDeltaValueSelector"
|
|
9
9
|
import { secondaryMetricsSelector } from "./secondaryMetrics.selector"
|
|
10
|
+
import { attributeDescriptorsSelector } from "../../../state/store/fileSettings/attributeDescriptors/attributeDescriptors.selector"
|
|
10
11
|
|
|
11
12
|
@Component({
|
|
12
13
|
selector: "cc-attribute-side-bar-secondary-metrics",
|
|
@@ -17,10 +18,12 @@ export class AttributeSideBarSecondaryMetricsComponent {
|
|
|
17
18
|
secondaryMetrics$: Observable<Metric[]>
|
|
18
19
|
showAttributeTypeSelector$: Observable<boolean>
|
|
19
20
|
showDeltaValue$: Observable<boolean>
|
|
21
|
+
attributeDescriptors$: Observable<AttributeDescriptors>
|
|
20
22
|
|
|
21
|
-
constructor(store: Store<CcState>) {
|
|
22
|
-
this.secondaryMetrics$ = store.select(secondaryMetricsSelector)
|
|
23
|
-
this.showAttributeTypeSelector$ = store.select(showAttributeTypeSelectorSelector)
|
|
24
|
-
this.showDeltaValue$ = store.select(showDeltaValueSelector)
|
|
23
|
+
constructor(private store: Store<CcState>) {
|
|
24
|
+
this.secondaryMetrics$ = this.store.select(secondaryMetricsSelector)
|
|
25
|
+
this.showAttributeTypeSelector$ = this.store.select(showAttributeTypeSelectorSelector)
|
|
26
|
+
this.showDeltaValue$ = this.store.select(showDeltaValueSelector)
|
|
27
|
+
this.attributeDescriptors$ = this.store.select(attributeDescriptorsSelector)
|
|
25
28
|
}
|
|
26
29
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { DIFFERENT_NODE } from "../../../util/dataMocks"
|
|
2
2
|
import { _calculateSecondaryMetrics } from "./secondaryMetrics.selector"
|
|
3
|
-
import { AttributeDescriptors } from "../../../codeCharta.model"
|
|
4
3
|
|
|
5
4
|
const primaryMetricNames = {
|
|
6
5
|
areaMetric: "a",
|
|
@@ -9,38 +8,20 @@ const primaryMetricNames = {
|
|
|
9
8
|
edgeMetric: "None"
|
|
10
9
|
}
|
|
11
10
|
|
|
12
|
-
const attributeDescriptors: AttributeDescriptors = {}
|
|
13
|
-
|
|
14
11
|
describe("secondaryMetricsSelector", () => {
|
|
15
12
|
it("should return an empty list if there is no selectedNode", () => {
|
|
16
|
-
expect(_calculateSecondaryMetrics(primaryMetricNames
|
|
13
|
+
expect(_calculateSecondaryMetrics(primaryMetricNames)).toEqual([])
|
|
17
14
|
})
|
|
18
15
|
|
|
19
16
|
it("should return a by name sorted list of metrics without primary metrics", () => {
|
|
20
|
-
expect(_calculateSecondaryMetrics(primaryMetricNames,
|
|
17
|
+
expect(_calculateSecondaryMetrics(primaryMetricNames, DIFFERENT_NODE)).toEqual([
|
|
21
18
|
{
|
|
22
19
|
name: "b",
|
|
23
|
-
value: 15
|
|
24
|
-
descriptors: {
|
|
25
|
-
description: undefined,
|
|
26
|
-
hintHighValue: undefined,
|
|
27
|
-
hintLowValue: undefined,
|
|
28
|
-
key: "b",
|
|
29
|
-
link: undefined,
|
|
30
|
-
title: undefined
|
|
31
|
-
}
|
|
20
|
+
value: 15
|
|
32
21
|
},
|
|
33
22
|
{
|
|
34
23
|
name: "mcc",
|
|
35
|
-
value: 14
|
|
36
|
-
descriptors: {
|
|
37
|
-
description: undefined,
|
|
38
|
-
hintHighValue: undefined,
|
|
39
|
-
hintLowValue: undefined,
|
|
40
|
-
key: "mcc",
|
|
41
|
-
link: undefined,
|
|
42
|
-
title: "Cyclomatic Complexity"
|
|
43
|
-
}
|
|
24
|
+
value: 14
|
|
44
25
|
}
|
|
45
26
|
])
|
|
46
27
|
})
|
|
@@ -1,16 +1,10 @@
|
|
|
1
|
-
import { CodeMapNode, PrimaryMetrics
|
|
1
|
+
import { CodeMapNode, PrimaryMetrics } from "../../../codeCharta.model"
|
|
2
2
|
import { primaryMetricNamesSelector } from "../../../state/selectors/primaryMetrics/primaryMetricNames.selector"
|
|
3
3
|
import { selectedNodeSelector } from "../../../state/selectors/selectedNode.selector"
|
|
4
4
|
import { Metric } from "../util/metric"
|
|
5
|
-
import { attributeDescriptorsSelector } from "../../../state/store/fileSettings/attributeDescriptors/attributeDescriptors.selector"
|
|
6
|
-
import { getMetricDescriptors } from "../util/metricDescriptors"
|
|
7
5
|
import { createSelector } from "@ngrx/store"
|
|
8
6
|
|
|
9
|
-
export const _calculateSecondaryMetrics = (
|
|
10
|
-
primaryMetrics: PrimaryMetrics,
|
|
11
|
-
attributeDescriptors: AttributeDescriptors,
|
|
12
|
-
node?: Pick<CodeMapNode, "attributes">
|
|
13
|
-
) => {
|
|
7
|
+
export const _calculateSecondaryMetrics = (primaryMetrics: PrimaryMetrics, node?: Pick<CodeMapNode, "attributes">) => {
|
|
14
8
|
if (!node) {
|
|
15
9
|
return [] as Metric[]
|
|
16
10
|
}
|
|
@@ -22,14 +16,8 @@ export const _calculateSecondaryMetrics = (
|
|
|
22
16
|
|
|
23
17
|
return secondaryMetricNames.map(secondaryMetricName => ({
|
|
24
18
|
name: secondaryMetricName,
|
|
25
|
-
value: node.attributes[secondaryMetricName]
|
|
26
|
-
descriptors: getMetricDescriptors(secondaryMetricName, attributeDescriptors)
|
|
19
|
+
value: node.attributes[secondaryMetricName]
|
|
27
20
|
}))
|
|
28
21
|
}
|
|
29
22
|
|
|
30
|
-
export const secondaryMetricsSelector = createSelector(
|
|
31
|
-
primaryMetricNamesSelector,
|
|
32
|
-
attributeDescriptorsSelector,
|
|
33
|
-
selectedNodeSelector,
|
|
34
|
-
_calculateSecondaryMetrics
|
|
35
|
-
)
|
|
23
|
+
export const secondaryMetricsSelector = createSelector(primaryMetricNamesSelector, selectedNodeSelector, _calculateSecondaryMetrics)
|
package/app/codeCharta/ui/attributeSideBar/metricDeltaSelected/metricDeltaSelected.component.spec.ts
CHANGED
|
@@ -12,7 +12,7 @@ import { mapColorsSelector } from "../../../state/store/appSettings/mapColors/ma
|
|
|
12
12
|
describe("MetricDeltaSelectedComponent", () => {
|
|
13
13
|
const areColorsEqual = (hex: string, styleColor: string) => {
|
|
14
14
|
const formattedHex = ColorConverter.convertHexToRgba(hex).replace(/,1\)$/, ")").replace("a", "")
|
|
15
|
-
const formattedStyleColor = styleColor.
|
|
15
|
+
const formattedStyleColor = styleColor.replaceAll(" ", "")
|
|
16
16
|
return formattedHex === formattedStyleColor
|
|
17
17
|
}
|
|
18
18
|
|
|
@@ -256,12 +256,9 @@ export class CodeMapArrowService implements OnDestroy {
|
|
|
256
256
|
}
|
|
257
257
|
|
|
258
258
|
private buildArrow(points: Vector3[], ARROW_COLOR = 0, headLength = 10, headWidth = 10) {
|
|
259
|
-
const direction = points
|
|
260
|
-
.clone()
|
|
261
|
-
.sub(points[points.length - 2].clone())
|
|
262
|
-
.normalize()
|
|
259
|
+
const direction = points.at(-1).clone().sub(points.at(-2).clone()).normalize()
|
|
263
260
|
|
|
264
|
-
const origin = points
|
|
261
|
+
const origin = points.at(-1).clone()
|
|
265
262
|
if (direction.y < 0) {
|
|
266
263
|
origin.y += headLength + 1
|
|
267
264
|
}
|