Skip to content

Commit

Permalink
Merge pull request #34955 from phillip-kruger/dev-ui-graph-diagram
Browse files Browse the repository at this point in the history
Dev UI Arc Dependency graph diagram
  • Loading branch information
cescoffier authored Jul 25, 2023
2 parents 513a4aa + 69e05b7 commit 80fbc71
Show file tree
Hide file tree
Showing 9 changed files with 411 additions and 47 deletions.
2 changes: 1 addition & 1 deletion bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@
<dedupe-mixin.version>1.3.1</dedupe-mixin.version>
<vaadin-router.version>1.7.5</vaadin-router.version>
<lit-state.version>1.7.0</lit-state.version>
<echarts.version>5.4.2</echarts.version>
<echarts.version>5.4.3</echarts.version>
<wc-codemirror.version>2.1.0</wc-codemirror.version>
<es-module-shims.version>1.7.3</es-module-shims.version>
<path-to-regexp.version>2.4.0</path-to-regexp.version>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ public List<DevDecoratorInfo> getRemovedDecorators() {
return removedDecorators;
}

public Map<String, DependencyGraph> getDependencyGraphs() {
return dependencyGraphs;
}

public String getBeanDescription() {
return DevConsoleManager.getGlobal(ArcDevConsoleProcessor.BEAN_DESCRIPTION);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ public CardPageBuildItem pages(ArcBeanInfoBuildItem arcBeanInfoBuildItem, ArcCon
.staticLabel(String.valueOf(beans.size())));

pageBuildItem.addBuildTimeData(BEANS, toDevBeanWithInterceptorInfo(beans, beanInfos));

pageBuildItem.addBuildTimeData(BEAN_IDS_WITH_DEPENDENCY_GRAPHS, beanInfos.getDependencyGraphs().keySet());
pageBuildItem.addBuildTimeData(DEPENDENCY_GRAPHS, beanInfos.getDependencyGraphs());
}

List<DevObserverInfo> observers = beanInfos.getObservers();
Expand Down Expand Up @@ -167,6 +170,8 @@ private boolean isAdditionalBeanDefiningAnnotationOn(ClassInfo beanClass,
return false;
}

private static final String BEAN_IDS_WITH_DEPENDENCY_GRAPHS = "beanIdsWithDependencyGraphs";
private static final String DEPENDENCY_GRAPHS = "dependencyGraphs";
private static final String BEANS = "beans";
private static final String OBSERVERS = "observers";
private static final String INTERCEPTORS = "interceptors";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
import { LitElement, html, css} from 'lit';
import { dependencyGraphs } from 'build-time-data';
import 'echarts-force-graph';
import '@vaadin/button';
import '@vaadin/checkbox';
import '@vaadin/checkbox-group';

/**
* This component shows the Arc Bean Graph
*/
export class QwcArcBeanGraph extends LitElement {

static styles = css`
.top-bar {
display: flex;
align-items: baseline;
gap: 20px;
padding-left: 20px;
justify-content: space-between;
padding-right: 20px;
}
.top-bar h4 {
color: var(--lumo-contrast-60pct);
}
`;

static properties = {
beanId: {type: String},
beanDescription: {type: String},
_edgeLength: {type: Number, state: true},
_dependencyGraphs: {state: true},
_categories: {state: false},
_colors: {state: false},
_nodes: {state: true},
_links: {state: false},
_showSimpleDescription: {state: false}
};

constructor() {
super();
this.beanId = null;
this.beanDescription = null;
this._dependencyGraphs = dependencyGraphs;
this._categories = ['root' , 'direct dependencies', 'direct dependents', 'dependencies', 'declaring bean of a producer', 'potential dependency'];
this._categoriesEnum = ['root' , 'directDependency' , 'directDependent' , 'dependency' , 'producer' , 'lookup'];
this._colors = ['#ee6666', '#5470c6' , '#fac858' , '#91cc75' , '#73c0de' , '#ff00ff'];
this._edgeLength = 120;
this._nodes = null;
this._links = null;
this._showSimpleDescription = [];
}

connectedCallback() {
super.connectedCallback();
if(this.beanId){
this._createNodes();
}
}

_createNodes(){
let dependencyGraphsNodes = this._dependencyGraphs[this.beanId].nodes;
let dependencyGraphsLinks = this._dependencyGraphs[this.beanId].links;

this._links = []
this._nodes = []
for (var l = 0; l < dependencyGraphsLinks.length; l++) {
let link = new Object();
link.source = dependencyGraphsNodes.findIndex(item => item.id === dependencyGraphsLinks[l].source);
link.target = dependencyGraphsNodes.findIndex(item => item.id === dependencyGraphsLinks[l].target);
let catindex = this._categoriesEnum.indexOf(dependencyGraphsLinks[l].type);

this._addToNodes(dependencyGraphsNodes[link.source],catindex);
this._addToNodes(dependencyGraphsNodes[link.target],catindex);
this._links.push(link);
}

}

_addToNodes(dependencyGraphsNode, catindex){
let newNode = this._createNode(dependencyGraphsNode);
let index = this._nodes.findIndex(item => item.name === newNode.name);
if (index < 0 ) {
if(dependencyGraphsNode.id === this.beanId){
newNode.category = 0; // Root
}else {
newNode.category = catindex;
}
this._nodes.push(newNode);
}
}

_createNode(node){
let nodeObject = new Object();
if(this._showSimpleDescription.length>0){
nodeObject.name = node.simpleDescription;
}else{
nodeObject.name = node.description;
}

nodeObject.value = 1;
nodeObject.id = node.id;
nodeObject.description = node.description;
return nodeObject;
}

render() {
if(this.beanId){
return html`${this._renderTopBar()}
<echarts-force-graph width="400px" height="400px"
edgeLength=${this._edgeLength}
categories="${JSON.stringify(this._categories)}"
colors="${JSON.stringify(this._colors)}"
nodes="${JSON.stringify(this._nodes)}"
links="${JSON.stringify(this._links)}"
@echarts-click=${this._echartClicked}>
</echarts-force-graph>`;
}else{
return html`<span>No bean id provided</span>`;
}
}

_renderTopBar(){
return html`
<div class="top-bar">
<vaadin-button @click="${this._backAction}">
<vaadin-icon icon="font-awesome-solid:caret-left" slot="prefix"></vaadin-icon>
Back
</vaadin-button>
<h4>${this.beanDescription}</h4>
<div>
${this._renderCheckbox()}
<vaadin-button theme="icon" aria-label="Zoom in" @click=${this._zoomIn}>
<vaadin-icon icon="font-awesome-solid:magnifying-glass-plus"></vaadin-icon>
</vaadin-button>
<vaadin-button theme="icon" aria-label="Zoom out" @click=${this._zoomOut}>
<vaadin-icon icon="font-awesome-solid:magnifying-glass-minus"></vaadin-icon>
</vaadin-button>
</div>
</div>`;
}

_renderCheckbox(){
return html`<vaadin-checkbox-group
.value="${this._showSimpleDescription}"
@value-changed="${(event) => {
this._showSimpleDescription = event.detail.value;
this._createNodes();
}}">
<vaadin-checkbox value="0" label="Simple description"></vaadin-checkbox>
</vaadin-checkbox-group>`;
}

_backAction(){
const back = new CustomEvent("arc-beans-graph-back", {
detail: {},
bubbles: true,
cancelable: true,
composed: false,
});
this.dispatchEvent(back);
}

_zoomIn(){
if(this._edgeLength>10){
this._edgeLength = this._edgeLength - 10;
}else{
this._edgeLength = 10;
}
}

_zoomOut(){
this._edgeLength = this._edgeLength + 10;
}

_echartClicked(e){
this.beanId = e.detail.id;
this.beanDescription = e.detail.description;
this._createNodes();
}
}
customElements.define('qwc-arc-bean-graph', QwcArcBeanGraph);
Loading

0 comments on commit 80fbc71

Please sign in to comment.