Skip to content

Commit

Permalink
Feature/epic fixed folders (#1239)
Browse files Browse the repository at this point in the history
* Feature/fixed folders (#1199)

* Add example json representing folder structure in docs

* Update model with optional fixed and margin attributes

* Adds first steps to build the map, missing transformation of coordinates

* Refactor improve performance by counting nodes and blacklisted nodes at the same time

* Refactor improve performance by removing one loop

* Fix typo in y properties

* Add coordinate transformation, map is finally visible, but not scalable yet

* Add edges to example json

* Refactor use values in line

* Add size increases based on margin

* Refactor abstract methods and improved readability

* Fix broken tests after changing the method header

* Remove margin since it's not required anymore

* Add snapshot test for fixed folders

* Fix incoming and outgoing edge points are now set correctly

* Fix root folder name should be set based on the root-name of the map

* Presentation add example cc.json

* Presentation rename example cc.json

* Update rename fixed attributes

* Update snapshot since ids are no longer pre-decorated

* Refactor move static functions to helper file
Update jest.config to mock localStorage to test in IntelliJ

* Refactor convert class with static functions to exported objects with functions

* Refactor convert class with static functions to exported objects with functions

* Add no-else-return rule and fix errors

* Refactor use null propagation operator

* Update snapshots and remove unused snapshots

* Update visualization/app/codeCharta/util/treeMapGenerator.spec.ts

Co-authored-by: Ruben Bridgewater <ruben@bridgewater.de>

* Update visualization/app/codeCharta/util/fileHelper.ts

Co-authored-by: Ruben Bridgewater <ruben@bridgewater.de>

* Refactor rename isNodeToBeFlat to shouldNodeBeFlat

* Refactor use null coalescing to shorten code

* Refactor move shortcut return to the top to improve performance

* Update snapshot after renaming test

* Refactor rearrange function and add return statements to prevent obsolete calculations

* Refactor remove obsolete check in condition if attribute types are empty and added some more tests

* Refactor rename function

Co-authored-by: Ruben Bridgewater <ruben@bridgewater.de>

* Docs/fixed-folders (#1163)

* Add documentation on how to generate custom cc.jsons with the fixed attribute

* Fix list not formated correctly

* Update image with x and y coordinates and bounds

* Update remove margin from docs, since it's not required anymore
It is still recommended to apply a margin between folders, but the coordinates of the folders can be set to anything as long as these respect the rules.

* Update gh-pages/_posts/how-to/2020-08-17-fixate-folders-with-a-custom-cc-json.md

Co-authored-by: Ruben Bridgewater <ruben@bridgewater.de>

* Update gh-pages/_posts/how-to/2020-08-17-fixate-folders-with-a-custom-cc-json.md

* Update gh-pages/_posts/how-to/2020-08-17-fixate-folders-with-a-custom-cc-json.md

Co-authored-by: Ruben Bridgewater <ruben@bridgewater.de>

* Update renamed properties and rephrased explanation on how to set the coordinates

* Update gh-pages/_posts/how-to/2020-08-17-fixate-folders-with-a-custom-cc-json.md

Co-authored-by: Ruben Bridgewater <ruben@bridgewater.de>

* Update gh-pages/_posts/how-to/2020-08-17-fixate-folders-with-a-custom-cc-json.md

Co-authored-by: Ruben Bridgewater <ruben@bridgewater.de>

* Update docs

* Update gh-pages/_posts/how-to/2020-08-17-fixate-folders-with-a-custom-cc-json.md

Co-authored-by: Ruben Bridgewater <ruben@bridgewater.de>

* Update example image and it's corresponding cc.json

Co-authored-by: Ruben Bridgewater <ruben@bridgewater.de>

* Feature/fixed folders validation (#1213)

* Add example json representing folder structure in docs

* Update model with optional fixed and margin attributes

* Adds first steps to build the map, missing transformation of coordinates

* Refactor improve performance by counting nodes and blacklisted nodes at the same time

* Refactor improve performance by removing one loop

* Fix typo in y properties

* Add coordinate transformation, map is finally visible, but not scalable yet

* Add edges to example json

* Refactor use values in line

* Add size increases based on margin

* Refactor abstract methods and improved readability

* Fix broken tests after changing the method header

* Remove margin since it's not required anymore

* Add snapshot test for fixed folders

* Fix incoming and outgoing edge points are now set correctly

* Fix root folder name should be set based on the root-name of the map

* Add API.md to document the changes for the cc.json-api

* Update api-versions for tests and files

* Presentation add example cc.json

* Presentation rename example cc.json

* Add validation for fixed folders, not finalized

* Add finalized validation
Fix nodes empty error

* Update collect errors again instead of throwing them instantly

* Update e2e test to use the error messages enum instead of plain strings

* Fix missing whitespace in test of dialog message

* Update rename fixed attributes

* Update snapshot since ids are no longer pre-decorated

* Update tests with renamed fixed attributes

* Refactor move static functions to helper file
Update jest.config to mock localStorage to test in IntelliJ

* Refactor convert class with static functions to exported objects with functions

* Refactor convert class with static functions to exported objects with functions

* Add no-else-return rule and fix errors

* Refactor use null propagation operator

* Update snapshots and remove unused snapshots

* Add eslint rule no-lonely-if and autofix errors

* Update visualization/app/codeCharta/util/treeMapGenerator.spec.ts

Co-authored-by: Ruben Bridgewater <ruben@bridgewater.de>

* Update visualization/app/codeCharta/util/fileHelper.ts

Co-authored-by: Ruben Bridgewater <ruben@bridgewater.de>

* Refactor rename isNodeToBeFlat to shouldNodeBeFlat

* Refactor use null coalescing to shorten code

* Refactor move shortcut return to the top to improve performance

* Update snapshot after renaming test

* Refactor rearrange function and add return statements to prevent obsolete calculations

* Refactor remove obsolete check in condition if attribute types are empty and added some more tests

* Add e2e test to ensure lower api versions are working without errors or warnings

* Refactor replace custom type KeyValuePair with Record<string, number>

* Update jsonschema

* Refactor replace _.cloneDeep with the rfdc library

* Update snapshot with new api version

* Add fixedPosition attribute of folders resulting in errors during validation after their name for easier debugging

* Fix outOfBounds-Check not checking for negative width and height

* Add another test to ensure the new out of bounds function is working

* Add print found api version when a warning is thrown

* Update visualization/app/codeCharta/util/fileValidator.ts

Co-authored-by: Ruben Bridgewater <ruben@bridgewater.de>

* Update remove individual titles and use a generic title for errors and warnings

* Refactor check if both nodes have the fixedPosition attribute before starting calculating overlaps

* Refactor remove obsolete .values() call

* Add found duplicate node to error message
Refactor use a more intuitive implementation to find duplicate nodes
Fix duplicate file in example

* Update snapshot with new file names

* Fix broken e2e test with wrong warning message

* Refactor use root instead of whole file as parameter to validate fixed folders

* Refactor reorder functions

* Revert "Refactor replace custom type KeyValuePair with Record<string, number>"

This reverts commit 061ec81.

* Update json schema with KeyValuePair instead of Record again

* Move API.md from visualization to root of project

* Add throw an error if we encountered a fixed folder and the api version is smaller than 1.2

Co-authored-by: Ruben Bridgewater <ruben@bridgewater.de>

* Refactor rename file by replacing - with _ in the name

* Update CHANGELOG

* Update CHANGELOG, api version incremented

* Docs move api change to Changed section

* Update outdated property names

Co-authored-by: Ruben Bridgewater <ruben@bridgewater.de>
  • Loading branch information
NearW and BridgeAR authored Sep 11, 2020
1 parent 238a05c commit 25a9667
Show file tree
Hide file tree
Showing 51 changed files with 2,679 additions and 650 deletions.
32 changes: 32 additions & 0 deletions API.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# API-Changelog

## 1.1

- An additional optional property `edges` has been added to the `cc.json`
- Defines an array of edges between buildings
- Use SCMLogParser to generate edges

```ts
export interface Edge {
fromNodeName: string
toNodeName: string
attributes: KeyValuePair
}
```

## 1.2

- An additional optional property `fixedPosition` has been added to the `cc.json`
- Property can be set to direct children of the root-folder
- Define `left` and `top` as the top-left corner of the folder
- Define `width` and `height` for the length in x and y-direction
- Folders can't overlap and must be defined in range of `[0-100]`

```ts
export interface Fixed {
left: number
top: number
width: number
height: number
}
```
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,22 @@ and this project adheres to [Semantic Versioning](http://semver.org/)

### Added 🚀

- `fixedPosition` as a new property in the `cc.json` that allows to fixate folders in the map

### Changed

- `cc.json` version updated to `1.2`

### Removed 🗑

### Fixed 🐞

- Compressed `cc.jsons (.gz) not marked as accepted when selecting a file in the file chooser

### Chore 👨‍💻 👩‍💻
### Docs 🔎

- [How-To: Fixate Folders in the `cc.json`](https://maibornwolff.github.io//codecharta/how-to/fixate_folders_with_a_custom_cc_json/)
- CC-Json-API changes

## [1.56.0] - 2020-09-04

Expand Down
25 changes: 23 additions & 2 deletions analysis/tools/ValidationTool/src/main/resources/cc.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@
},
"type": "object"
},
"fixedPosition": {
"$ref": "#/definitions/FixedPosition"
},
"id": {
"type": "number"
},
Expand Down Expand Up @@ -165,6 +168,24 @@
"required": ["apiVersion", "nodes", "projectName"],
"type": "object"
},
"FixedPosition": {
"properties": {
"height": {
"type": "number"
},
"left": {
"type": "number"
},
"top": {
"type": "number"
},
"width": {
"type": "number"
}
},
"required": ["height", "left", "top", "width"],
"type": "object"
},
"KeyValuePair": {
"additionalProperties": {
"type": "number"
Expand Down Expand Up @@ -210,7 +231,7 @@
"type": "object"
}
],
"minItems": 1,
"minItems": 0,
"type": "array"
},
"nodes": {
Expand All @@ -234,7 +255,7 @@
"type": "object"
}
],
"minItems": 1,
"minItems": 0,
"type": "array"
}
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
---
categories:
- How-to
title: Fixate folders using a custom cc.json
---

# Introduction

The [Squarified-Tree-Map-Algorithm](https://www.win.tue.nl/~vanwijk/stm.pdf) generates a layout for the visualized map.
The layout varies depending on the area of each node. Adding a new file to a folder might increase the area of the parent folder,
so that the algorithm decides that the parent-folder needs to be relocated. Thus, folders may not be located at the same position anymore as before.
Another way to follow this problem is by changing the area-metric.

# Fixate folders

In order to prevent folders from changing locations, we introduced a new attribute to the `.cc.json` called `fixedPosition`.
This attribute is not auto-generated during the analysis and has to be defined manually by editing the `.cc.json`.

Setting this property is restricted to the top level folders and won't have any effect on sub-folders (folders in folders).

# API

```json
"fixedPosition": {
"left": 60,
"top:": 40,
"width": 35,
"height": 55
}
```

The property values must be numbers in the range between 0 and 100. They represent the size of the value in percent.

## Example

![Example]({{site.baseurl}}/assets/images/posts/how-to/fixate-folders/fixated-folder-example.jpg)

```json
{
"projectName": "example-project",
"apiVersion": "1.2",
"nodes": [
{
"name": "root",
"type": "Folder",
"attributes": {},
"children": [
{
"name": "folder_1_red",
"type": "Folder",
"attributes": {},
"children": [],
"fixedPosition": {
"left": 10,
"top": 10,
"width": 30,
"height": 20
}
},
{
"name": "folder_2_orange",
"type": "Folder",
"attributes": {},
"children": [],
"fixedPosition": {
"left": 50,
"top": 10,
"width": 40,
"height": 20
}
},
{
"name": "folder_3_blue",
"type": "Folder",
"attributes": {},
"children": [],
"fixedPosition": {
"left": 10,
"top": 40,
"width": 20,
"height": 50
}
},
{
"name": "folder_4_green",
"type": "Folder",
"attributes": {},
"children": [],
"fixedPosition": {
"left": 40,
"top": 40,
"width": 50,
"height": 20
}
},
{
"name": "folder_5_magenta",
"type": "Folder",
"attributes": {},
"children": [],
"fixedPosition": {
"left": 40,
"top": 70,
"width": 50,
"height": 20
}
}
]
}
]
}
```

A margin between folders is recommended. To apply one, set the coordinates for the folder in the top-left corner
to e.g., `left: 10` and `top: 10`. The margin between the border of the map and `folder_1` is therefore `10`. It may be chosen at will.
In order to define the coordinates of adjacent folders, apply any margin between `folder_1` and `folder_2`.
The example uses a margin of `10`, so that the coordinates of `folder_2` must be `left: 50` and `top: 10`.

## Restrictions

The following rules apply in order to build a valid custom `.cc.json`:

- The values of `left`, `top`, `width` and `height` must be in range of `[0, 100]
- The value `left + width` or `top + height` must be in a range of `[0, 100]`.
- Folders may not overlap.
- Leaving space between folders (for visibility reasons) is recommended.
- All children of the root folder require the `fixedPosition` attribute.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 17 additions & 8 deletions visualization/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,31 @@ module.exports = {
"error",
{
"selector": ["variable", "function"],
"format": ["camelCase", "UPPER_CASE"],
"format": ["camelCase", "UPPER_CASE", "PascalCase"],
"leadingUnderscore": "allow"
}
],
"@typescript-eslint/no-unused-vars": ["error"],
"object-shorthand": ["error", "always"],
"no-else-return": ["error"],
"no-lonely-if": ["error"],

// Do not apply inappropriate rules below
"@typescript-eslint/no-use-before-define": "off",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-use-before-define":
"off",
"@typescript-eslint/ban-ts-comment":
"off",

// TODO fix and remove rules below
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/ban-types": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/consistent-type-assertions": "off",
"@typescript-eslint/explicit-function-return-type":
"off",
"@typescript-eslint/explicit-module-boundary-types":
"off",
"@typescript-eslint/ban-types":
"off",
"@typescript-eslint/no-explicit-any":
"off",
"@typescript-eslint/consistent-type-assertions":
"off",
}
}
2 changes: 1 addition & 1 deletion visualization/app/codeCharta/assets/sample1.cc.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"projectName": "Sample Project with Edges",
"apiVersion": "1.1",
"apiVersion": "1.2",
"nodes": [
{
"name": "root",
Expand Down
2 changes: 1 addition & 1 deletion visualization/app/codeCharta/assets/sample2.cc.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"projectName": "Sample Project",
"apiVersion": "1.1",
"apiVersion": "1.2",
"nodes": [
{
"name": "root",
Expand Down
2 changes: 1 addition & 1 deletion visualization/app/codeCharta/assets/sample3.cc.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"projectName": "Sample Project",
"apiVersion": "1.1",
"apiVersion": "1.2",
"nodes": [
{
"name": "root",
Expand Down
7 changes: 4 additions & 3 deletions visualization/app/codeCharta/codeCharta.api.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ export enum ExportBlacklistType {
export enum APIVersions {
ZERO_POINT_ONE = "0.1",
ONE_POINT_ZERO = "1.0",
ONE_POINT_ONE = "1.1"
ONE_POINT_ONE = "1.1",
ONE_POINT_TWO = "1.2"
}

export interface ExportScenario {
Expand All @@ -32,6 +33,6 @@ export interface ExportScenario {
}

export interface OldAttributeTypes {
nodes?: [{ [key: string]: AttributeTypeValue }]
edges?: [{ [key: string]: AttributeTypeValue }]
nodes?: [{ [key: string]: AttributeTypeValue }?]
edges?: [{ [key: string]: AttributeTypeValue }?]
}
8 changes: 8 additions & 0 deletions visualization/app/codeCharta/codeCharta.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ export interface CodeMapNode {
deltas?: {
[key: string]: number
}
fixedPosition?: FixedPosition
}

export interface FixedPosition {
left: number
top: number
width: number
height: number
}

export enum NodeType {
Expand Down
11 changes: 4 additions & 7 deletions visualization/app/codeCharta/codeCharta.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { getCCFiles, isSingleState } from "./model/files/files.helper"
import { DialogService } from "./ui/dialog/dialog.service"
import { CCValidationResult, ERROR_MESSAGES } from "./util/fileValidator"
import { setNodeMetricData } from "./state/store/metricData/nodeMetricData/nodeMetricData.actions"
import packageJson from "../../package.json"
import { clone } from "./util/clone"

describe("codeChartaService", () => {
Expand Down Expand Up @@ -52,7 +53,7 @@ describe("codeChartaService", () => {

describe("loadFiles", () => {
const expected: CCFile = {
fileMeta: { apiVersion: "1.1", fileName, projectName: "Sample Map" },
fileMeta: { apiVersion: packageJson.codecharta.apiVersion, fileName, projectName: "Sample Map" },
map: {
attributes: {},
isExcluded: false,
Expand Down Expand Up @@ -169,8 +170,7 @@ describe("codeChartaService", () => {

it("should show error on invalid file", () => {
const expectedError: CCValidationResult = {
title: ERROR_MESSAGES.fileIsInvalid.title,
error: [ERROR_MESSAGES.fileIsInvalid.message],
error: [ERROR_MESSAGES.fileIsInvalid],
warning: []
}

Expand All @@ -182,8 +182,7 @@ describe("codeChartaService", () => {

it("should show error on a random string", () => {
const expectedError: CCValidationResult = {
title: ERROR_MESSAGES.apiVersionIsInvalid.title,
error: [ERROR_MESSAGES.apiVersionIsInvalid.message],
error: [ERROR_MESSAGES.apiVersionIsInvalid],
warning: []
}

Expand All @@ -195,7 +194,6 @@ describe("codeChartaService", () => {

it("should show error if a file is missing a required property", () => {
const expectedError: CCValidationResult = {
title: ERROR_MESSAGES.validationError.title,
error: ["Required error: should have required property 'projectName'"],
warning: []
}
Expand Down Expand Up @@ -224,7 +222,6 @@ describe("codeChartaService", () => {

it("should break the loop after the first invalid file was validated", () => {
const expectedError: CCValidationResult = {
title: ERROR_MESSAGES.validationError.title,
error: ["Required error: should have required property 'projectName'"],
warning: []
}
Expand Down
Loading

0 comments on commit 25a9667

Please sign in to comment.