Show last authors
1 These instructions should guide you if you'd like to try out using KLighD for visualizing your own models or data structures. A minimal example is shown where a Xtext model from a textual editor is visualized with KLighD.
2
3 == Step-By-Step Guide ==
4
5 In order to get this example working, please follow the instructions below:
6
7 1. Download Eclipse Kepler (Modeling Edition) and install KIELER Pragmatics 0.10.0 ([[according to these instructions>>doc:Minimal Example HowTo]])
8 1. Download the following files, unzip them and import them as existing projects into your Eclipse workspace using {{code language="none"}}File->Import...->General->Existing projects into Workspace{{/code}} (see [[help>>url:http://help.eclipse.org/kepler/index.jsp?topic=%2Forg.eclipse.platform.doc.user%2Ftasks%2Ftasks-importproject.htm&cp=0_3_10_0||shape="rect"]] for details):
9 [[attach:de.cau.cs.kieler.klighd.example.myxtextdata.zip]]
10 [[attach:de.cau.cs.kieler.klighd.example.myxtextdata.ui.zip]]
11 [[attach:de.cau.cs.kieler.klighd.example.myxtextdata.klighd.zip]]
12 1. You may now create a new run-configuration ([[according to these instructions>>doc:Minimal Example HowTo]]) and run everything as an Eclipse Application.
13 1. Once you create a new text file with the ending "*.myxtextdata" and enter some content (Ctrl+Space gives you content assist), you should see the synthesized diagram as follows:
14 [[image:attach:myxtextdata.png]]
15
16
17
18 == The Details ==
19
20 The following files are involved (found in the **src** folder of the imported project in your Eclipse workspace):
21
22 1. **MyXtextData.xtext **(de.cau.cs.kieler.klighd.example.myxtextdata) : It contains a very simple Xtext grammar for the textual language
23 1. **ShowDiagramCombination.java** (de.cau.cs.kieler.klighd.example.myxtextdata.klighd) : This is a KIELER combination for triggering the automatic diagram synthesis when editing the model in the textual editor.
24 1. **MyXtextDataDiagramSynthesis.xtend** (de.cau.cs.kieler.klighd.example.myxtextdata.klighd) : This is the most essential part, it is the transformation from your data/model to the view model (the diagram). You can use this as a bare bone example and extend it as you like. Note that it already uses several KLighD extension libraries that are included. These libraries can be inspected also if you are searching for further features that you want to use, they contain the most common features already.
25
26 == The Files ==
27
28 {{code title="MyXtextData.xtext" language="java"}}
29 grammar de.cau.cs.kieler.klighd.example.myxtextdata.MyXtextData with org.eclipse.xtext.common.Terminals
30
31 generate myXtextData "http://www.cau.de/cs/kieler/klighd/example/myxtextdata/MyXtextData"
32
33 Model:
34 name=ID (':' '{'
35 subData+=Model*
36 '}')?;
37
38 {{/code}}
39
40 {{code title="ShowDiagramCombination.java" language="java"}}
41 package de.cau.cs.kieler.klighd.example.myxtextdata.klighd;
42 import de.cau.cs.kieler.core.kivi.AbstractCombination;
43 import de.cau.cs.kieler.core.kivi.triggers.PartTrigger;
44 import de.cau.cs.kieler.core.kivi.triggers.SelectionTrigger;
45 import de.cau.cs.kieler.klighd.xtext.UpdateXtextModelKLighDCombination;
46 //import de.cau.cs.kieler.klighd.incremental.UpdateStrategy
47 public class ShowDiagramCombination extends UpdateXtextModelKLighDCombination {
48 /**
49 * The 'execute()' method, see doc of {@link AbstractCombination}.
50 */
51 public void execute(PartTrigger.PartState es, SelectionTrigger.SelectionState selectionState) {
52
53 // do not react on partStates as well as on selectionStates in case
54 // a view part has been deactivated recently, as an potentially out-dated selection
55 // is currently about to be processed
56 // most certainly a "part activated" event will follow and subsequently a further
57 // selection event if the selection of the newly active part is changed, too!
58 if (this.latestState() == es || es.getEventType() == PartTrigger.EventType.VIEW_DEACTIVATED) {
59 return;
60 }
61
62 }
63
64 }
65 {{/code}}
66
67 {{code title="MyXtextDataDiagramSynthesis.xtend"}}
68 class MyXtextDataDiagramSynthesis extends AbstractDiagramSynthesis<Model> {
69 @Inject extension KNodeExtensions
70 @Inject extension KEdgeExtensions
71 @Inject extension KPortExtensions
72 @Inject extension KLabelExtensions
73 @Inject extension KRenderingExtensions
74 @Inject extension KContainerRenderingExtensions
75 @Inject extension KPolylineExtensions
76 @Inject extension KColorExtensions
77 // Some self-defined colors
78 private static val KColor BLUE1 = RENDERING_FACTORY.createKColor() =>
79 [it.red = 248; it.green = 249; it.blue = 253];
80 private static val KColor BLUE2 = RENDERING_FACTORY.createKColor() =>
81 [it.red = 205; it.green = 220; it.blue = 243];
82 // Additional transformation option to hide or show a shadow
83 private static val SynthesisOption SHOW_SHADOW = SynthesisOption::createCheckOption("Shadow", true);
84 // Add all transformation options (comma separated)
85 override getDisplayedSynthesisOptions() {
86 return ImmutableList::of(
87 SHOW_SHADOW
88 );
89 }
90 override KNode transform(Model model) {
91 val root = model.createNode()
92 root.putToLookUpWith(model) => [
93 // Optional Layout parameters can be set
94 //it.addLayoutParam(LayoutOptions::ALGORITHM, "de.cau.cs.kieler.kiml.ogdf.planarization");
95 //it.addLayoutParam(LayoutOptions::SPACING, 75f);
96 //it.addLayoutParam(LayoutOptions::DIRECTION, Direction::UP);
97 // A rounded rectangle is created for every MyData instance
98 it.addRoundedRectangle(5, 5) => [
99 // Set linewith, foreground color, and a fading background color
100 it.lineWidth = 1;
101 it.setForeground("darkGray".color)
102 // We need a fresh copy of each color item, because it is contained by its element
103 it.setBackgroundGradient(BLUE1.copy, BLUE2.copy, 90)
104 // Here we see a how to use a boolean transformation/diagram option
105 if (SHOW_SHADOW.booleanValue) {
106 it.shadow = "black".color;
107 }
108 // Set a text
109 it.addText(" " + model.name + " ") => [
110 it.setFontSize(9)
111 it.setForeground("black".color)
112 ]
113 // If this is a hierarchical MyData instance, then create horizontal splitter,
114 // a child area, and add its children
115 if (model.subData.length > 0) {
116 it.setGridPlacement(1);
117 it.addHorizontalSeperatorLine(1, 2).setForeground("darkGray".color)
118 it.addChildArea().setGridPlacementData() => [
119 from(LEFT, 3, 0, TOP, 3, 0).to(RIGHT, 3, 0, BOTTOM, 3, 0)
120 minCellHeight = 5;
121 minCellWidth = 5;
122 ];
123 for (subData : model.subData) {
124 // To the recursive call to transform for all children
125 val child = subData.transform
126 // It is important to add all children to the root!
127 root.children.add(child)
128 }
129 }
130 ]
131 ]
132 return root;
133 }
134 }
135 {{/code}}