# Wiki source code of Updated Java Version Example with Connections

Last modified by Niklas Rentz on 2023/09/12 13:04
Export
Office Formats
Export as PDF Export as ODT Export as RTF
Other Formats

Select the pages to export:

select all/ none

Legend:
  Created Page
  Modified Extension Page
  Clean Extension Page

Export as HTML

Show last authors

author | version | line-number | content
--- | --- | --- | ---
|  | 1 | Here you'll find an updated version of the minimal examle:
|  | 2 |
|  | 3 | [[attach:de.cau.cs.kieler.klighd.example.mydata.zip]]
|  | 4 |
|  | 5 |
|  | 6 |
|  | 7 | Use the same procedure to get it to run as described on the [[parent page>>doc:KIELER.Discontinued Projects.KLighD old Minimal Example HowTo.Minimal Example (Java Model).WebHome]].
|  | 8 |
|  | 9 |
|  | 10 |
|  | 11 | The example runs with the following current (4.12.2014) version of KLighD: 0.6.0 ([[Pragmatics v. 2014-10>>url:http://rtsys.informatik.uni-kiel.de/%7Ekieler/updatesite/release_pragmatics_2014-10/||rel="nofollow" shape="rect" class="external-link"]])
|  | 12 |
|  | 13 | The visualized diagrams look like this:
|  | 14 |
|  | 15 | [[image:attach:klighd-updated1.jpg]][[image:attach:klighd-updated2.jpg]]
|  | 16 |
|  | 17 | Note that this diagram synthesis requests a specific layout algorithm for each case:
|  | 18 |
|  | 19 | 1. de.cau.cs.kieler.graphviz.dot for splines, and
|  | 20 | 1. de.cau.cs.kieler.klay.layered for NO splines).
|  | 21 |
|  | 22 | == The Files ==
|  | 23 |
|  | 24 | {{code title="MyData.java" language="java"}}
|  | 25 | public class MyData {
|  | 26 |
|  | 27 | public String name;
|  | 28 | public List<MyData> subData = new LinkedList<MyData>();
|  | 29 |
|  | 30 | public static MyData getTestData() {
|  | 31 | MyData d1 = new MyData();
|  | 32 | d1.name = "all data";
|  | 33 | MyData d2 = new MyData();
|  | 34 | d2.name = "outer data";
|  | 35 | MyData d3 = new MyData();
|  | 36 | d3.name = "inner 1";
|  | 37 | MyData d4 = new MyData();
|  | 38 | d4.name = "inner 2";
|  | 39 | MyData d5 = new MyData();
|  | 40 | d5.name = "inner 5";
|  | 41 | MyData d6 = new MyData();
|  | 42 | d6.name = "most inner 6";
|  | 43 | d1.subData.add(d2);
|  | 44 | d2.subData.add(d3);
|  | 45 | d2.subData.add(d4);
|  | 46 | d2.subData.add(d5);
|  | 47 | d4.subData.add(d6);
|  | 48 | return d1;
|  | 49 | }
|  | 50 |
|  | 51 | }
|  | 52 | {{/code}}
|  | 53 |
|  | 54 | {{code title="MyDataDiagrammSynthesisHandler.java" language="java"}}
|  | 55 | /*
|  | 56 | * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient
|  | 57 | *
|  | 58 | * http://www.informatik.uni-kiel.de/rtsys/kieler/
|  | 59 | *
|  | 60 | * Copyright 2013 by
|  | 61 | * + Christian-Albrechts-University of Kiel
|  | 62 | * + Department of Computer Science
|  | 63 | * + Real-Time and Embedded Systems Group
|  | 64 | *
|  | 65 | * This code is provided under the terms of the Eclipse Public License (EPL).
|  | 66 | * See the file epl-v10.html for the license text.
|  | 67 | */
|  | 68 | package de.cau.cs.kieler.klighd.example.mydata;
|  | 69 |
|  | 70 | import org.eclipse.core.commands.ExecutionEvent;
|  | 71 | import org.eclipse.core.commands.ExecutionException;
|  | 72 | import org.eclipse.ui.internal.handlers.WorkbenchWindowHandlerDelegate;
|  | 73 |
|  | 74 | import de.cau.cs.kieler.klighd.kivi.effects.KlighdUpdateDiagramEffect;
|  | 75 | import de.cau.cs.kieler.klighd.krendering.SimpleUpdateStrategy;
|  | 76 | import de.cau.cs.kieler.klighd.util.KlighdSynthesisProperties;
|  | 77 |
|  | 78 | /**
|  | 79 | * This is a small mininal example action that triggers a diagram synthesis of a
|  | 80 | * static data example. In this example the actions is connected to a tool bar
|  | 81 | * button and can be invoked by clicking on the button.
|  | 82 | *
|  | 83 | * UPDATED VERSION 4. DECEMBER 2014
|  | 84 | *
|  | 85 | * @author Christian Motika
|  | 86 | */
|  | 87 | public class MyDataDiagrammSynthesisHandler extends
|  | 88 | WorkbenchWindowHandlerDelegate { //IWorkbenchWindowActionDelegate {
|  | 89 |
|  | 90 |
|  | 91 | public Object execute(ExecutionEvent event) throws ExecutionException {
|  | 92 | // Get some static dummy test data
|  | 93 | MyData data = MyData.getTestData();
|  | 94 |
|  | 95 | // Prepare the diagram synthesis: Create a new klighdUpdateDiagramEffect
|  | 96 | KlighdUpdateDiagramEffect klighdEffect = new KlighdUpdateDiagramEffect(
|  | 97 | "de.cau.cs.kieler.klighd.example.mydata.MyDataDiagramSynthesis",
|  | 98 | "KLighD MyData Diagram", data);
|  | 99 |
|  | 100 | // FIXME: Note that the incremental update currently is under re-development
|  | 101 | // for Eclipse Kepler after large API changes to EMF Compare had been made.
|  | 102 | // At this time we cannot use the incremental update strategy (commented out).
|  | 103 | // As soon as it is fixed, uncomment the line below and delete the
|  | 104 | // SimpleUpdateStrategy line:
|  | 105 |
|  | 106 | // klighdEffect.setProperty(LightDiagramServices.REQUESTED_UPDATE_STRATEGY,
|  | 107 | // UpdateStrategy.ID);
|  | 108 |
|  | 109 | klighdEffect.setProperty(
|  | 110 | KlighdSynthesisProperties.REQUESTED_UPDATE_STRATEGY,
|  | 111 | SimpleUpdateStrategy.ID);
|  | 112 |
|  | 113 | // Do the diagram synthesis
|  | 114 | klighdEffect.execute();
|  | 115 | return null;
|  | 116 | }
|  | 117 |
|  | 118 | }
|  | 119 |
|  | 120 |
|  | 121 | {{/code}}
|  | 122 |
|  | 123 | {{code title="MyDataDiagramSynthesis.xtend"}}
|  | 124 | /*
|  | 125 | * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient
|  | 126 | *
|  | 127 | * http://www.informatik.uni-kiel.de/rtsys/kieler/
|  | 128 | *
|  | 129 | * Copyright 2013 by
|  | 130 | * + Christian-Albrechts-University of Kiel
|  | 131 | * + Department of Computer Science
|  | 132 | * + Real-Time and Embedded Systems Group
|  | 133 | *
|  | 134 | * This code is provided under the terms of the Eclipse Public License (EPL).
|  | 135 | * See the file epl-v10.html for the license text.
|  | 136 | */
|  | 137 | package de.cau.cs.kieler.klighd.example.mydata
|  | 138 |
|  | 139 | import com.google.common.collect.ImmutableList
|  | 140 | import de.cau.cs.kieler.core.kgraph.KNode
|  | 141 | import de.cau.cs.kieler.core.krendering.KColor
|  | 142 | import de.cau.cs.kieler.core.krendering.KPolyline
|  | 143 | import de.cau.cs.kieler.core.krendering.extensions.KColorExtensions
|  | 144 | import de.cau.cs.kieler.core.krendering.extensions.KContainerRenderingExtensions
|  | 145 | import de.cau.cs.kieler.core.krendering.extensions.KEdgeExtensions
|  | 146 | import de.cau.cs.kieler.core.krendering.extensions.KNodeExtensions
|  | 147 | import de.cau.cs.kieler.core.krendering.extensions.KPolylineExtensions
|  | 148 | import de.cau.cs.kieler.core.krendering.extensions.KRenderingExtensions
|  | 149 | import de.cau.cs.kieler.kiml.options.Direction
|  | 150 | import de.cau.cs.kieler.kiml.options.EdgeRouting
|  | 151 | import de.cau.cs.kieler.kiml.options.LayoutOptions
|  | 152 | import de.cau.cs.kieler.klighd.SynthesisOption
|  | 153 | import de.cau.cs.kieler.klighd.syntheses.AbstractDiagramSynthesis
|  | 154 | import javax.inject.Inject
|  | 155 |
|  | 156 | import static extension org.eclipse.emf.ecore.util.EcoreUtil.*
|  | 157 |
|  | 158 | //import static de.cau.cs.kieler.klighd.example.mydata.MyDataDiagramSynthesis.*
|  | 159 | /**
|  | 160 | * This is a small mininal example that creates a hierarchical KLighD diagram
|  | 161 | * out of very simple hierarchical data structure (MyData).
|  | 162 | *
|  | 163 | * @author Christian Motika
|  | 164 | */
|  | 165 | class MyDataDiagramSynthesis extends AbstractDiagramSynthesis<MyData> {
|  | 166 |
|  | 167 | @Inject extension KNodeExtensions
|  | 168 | @Inject extension KEdgeExtensions
|  | 169 |
|  | 170 | // @Inject extension KPortExtensions
|  | 171 | // @Inject extension KLabelExtensions
|  | 172 | @Inject extension KRenderingExtensions
|  | 173 | @Inject extension KContainerRenderingExtensions
|  | 174 | @Inject extension KPolylineExtensions
|  | 175 | @Inject extension KColorExtensions
|  | 176 |
|  | 177 | // Some self-defined colors
|  | 178 | private static val KColor BLUE1 = RENDERING_FACTORY.createKColor() =>
|  | 179 | [it.red = 248; it.green = 249; it.blue = 253];
|  | 180 | private static val KColor BLUE2 = RENDERING_FACTORY.createKColor() =>
|  | 181 | [it.red = 205; it.green = 220; it.blue = 243];
|  | 182 |
|  | 183 | // Additional transformation option to hide or show a shadow
|  | 184 | private static val SynthesisOption SHOW_SHADOW = SynthesisOption::createCheckOption("Shadow", true);
|  | 185 | private static SynthesisOption EDGE_STYLE = SynthesisOption::createCheckOption("Spline", false);
|  | 186 |
|  | 187 | // Add all transformation options (comma separated)
|  | 188 | override getDisplayedSynthesisOptions() {
|  | 189 | return ImmutableList::of(
|  | 190 | SHOW_SHADOW,
|  | 191 | EDGE_STYLE
|  | 192 | );
|  | 193 | }
|  | 194 |
|  | 195 | override KNode transform(MyData data) {
|  | 196 | val rootNode = data.createNode()
|  | 197 |
|  | 198 | if (EDGE_STYLE.booleanValue) {
|  | 199 | rootNode.setLayoutOption(LayoutOptions::SPACING, Float::valueOf("25.0"));
|  | 200 | rootNode.setLayoutOption(LayoutOptions::DIRECTION, Direction::DOWN);
|  | 201 | rootNode.addLayoutParam(LayoutOptions::EDGE_ROUTING, EdgeRouting::SPLINES);
|  | 202 | rootNode.addLayoutParam(LayoutOptions::ALGORITHM, "de.cau.cs.kieler.graphviz.dot");
|  | 203 | } else {
|  | 204 | rootNode.setLayoutOption(LayoutOptions::SPACING, Float::valueOf("15.0"));
|  | 205 | rootNode.setLayoutOption(LayoutOptions::DIRECTION, Direction::DOWN);
|  | 206 | rootNode.addLayoutParam(LayoutOptions::EDGE_ROUTING, EdgeRouting::ORTHOGONAL);
|  | 207 | rootNode.addLayoutParam(LayoutOptions::ALGORITHM, "de.cau.cs.kieler.klay.layered");
|  | 208 | }
|  | 209 |
|  | 210 | buildNodes(data, rootNode)
|  | 211 | buildConnections(data, rootNode)
|  | 212 |
|  | 213 | return rootNode;
|  | 214 | }
|  | 215 |
|  | 216 | def void buildNodes(MyData parentData, KNode rootNode) {
|  | 217 | val root = parentData.createNode()
|  | 218 | root.putToLookUpWith(parentData) => [
|  | 219 | // Optional Layout parameters can be set
|  | 220 | //it.addLayoutParam(LayoutOptions::ALGORITHM, "de.cau.cs.kieler.kiml.ogdf.planarization");
|  | 221 | //it.addLayoutParam(LayoutOptions::SPACING, 75f);
|  | 222 | //it.addLayoutParam(LayoutOptions::DIRECTION, Direction::UP);
|  | 223 | // A rounded rectangle is created for every MyData instance
|  | 224 | it.addRoundedRectangle(5, 5) => [
|  | 225 | // Set linewith, foreground color, and a fading background color
|  | 226 | it.lineWidth = 1;
|  | 227 | it.setForeground("darkGray".color)
|  | 228 | // We need a fresh copy of each color item, because it is contained by its element
|  | 229 | it.setBackgroundGradient(BLUE1.copy, BLUE2.copy, 90)
|  | 230 | // Here we see a how to use a boolean transformation/diagram option
|  | 231 | if (SHOW_SHADOW.booleanValue) {
|  | 232 | it.shadow = "black".color;
|  | 233 | }
|  | 234 | // Set a text
|  | 235 | it.addText(" " + parentData.name + " ") => [
|  | 236 | it.setFontSize(9)
|  | 237 | it.setForeground("black".color)
|  | 238 | ]
|  | 239 | // If this is a hierarchical MyData instance, then create horizontal splitter,
|  | 240 | // a child area, and add its children
|  | 241 | if (parentData.subData.length > 0) {
|  | 242 | it.setGridPlacement(1);
|  | 243 | it.addHorizontalSeperatorLine(1, 2).setForeground("darkGray".color)
|  | 244 | it.addChildArea().setGridPlacementData() => [
|  | 245 | from(LEFT, 3, 0, TOP, 3, 0).to(RIGHT, 3, 0, BOTTOM, 3, 0)
|  | 246 | minCellHeight = 5;
|  | 247 | minCellWidth = 5;
|  | 248 | ];
|  | 249 | for (subData : parentData.subData) {
|  | 250 |
|  | 251 | // To the recursive call to transform for all children
|  | 252 | val child = subData.transform
|  | 253 |
|  | 254 | // It is important to add all children to the root!
|  | 255 | root.children.add(child)
|  | 256 | }
|  | 257 | }
|  | 258 | ]
|  | 259 | ]
|  | 260 |
|  | 261 | }
|  | 262 |
|  | 263 | // Connect every first child to all childs (including itself!)
|  | 264 | def void buildConnections(MyData parentData, KNode rootNode) {
|  | 265 |
|  | 266 | // only if there is any child there
|  | 267 | if (parentData.subData.size > 0) {
|  | 268 | val firstChild = parentData.subData.get(0);
|  | 269 |
|  | 270 | for (child : parentData.subData) {
|  | 271 |
|  | 272 | // BE CAREFUL IF YOU CREATE A MAPPING LIKE THIS THERE WILL JUST BE CREATED ONE
|  | 273 | // EDGE PER "firstchild". That's why better use the child, because we iterate
|  | 274 | // over different child-objects (targets) but always habe the same firstChild-
|  | 275 | // -object.
|  | 276 | //val kEdge = firstChild.createEdge() // THIS IS MOST LIKELY WRONG
|  | 277 |
|  | 278 | val kEdge = child.createEdge()
|  | 279 | kEdge.source = firstChild.node;
|  | 280 | kEdge.target = child.node;
|  | 281 |
|  | 282 | System::out.println("Connect " + firstChild.name + " to " + child.name);
|  | 283 |
|  | 284 | if (!EDGE_STYLE.booleanValue) {
|  | 285 | kEdge.addPolyline(2)
|  | 286 | } else {
|  | 287 | kEdge.addSpline(2);
|  | 288 | }
|  | 289 |
|  | 290 | kEdge.KRendering as KPolyline => [
|  | 291 | it.addArrowDecorator()
|  | 292 | it.setLineWidth(2)
|  | 293 | ];
|  | 294 |
|  | 295 | child.buildConnections(rootNode);
|  | 296 | }
|  | 297 | }
|  | 298 |
|  | 299 | }
|  | 300 |
|  | 301 | }
|  | 302 |
|  | 303 |
|  | 304 | {{/code}}

# Quick Links

KIELER on GitHub
RTSYS Homepage

XWiki 14.4.7