Skip to content

Commit

Permalink
Added parameters for visualization
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristophDoll committed Dec 8, 2023
1 parent d820f77 commit e082a89
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2509,7 +2509,8 @@ public Response getCoverVisualization(@PathParam("graphId") String graphIdStr,
@DefaultValue("TRUE") @QueryParam("doLabelNodes") String doLabelNodesStr,
@DefaultValue("FALSE") @QueryParam("doLabelEdges") String doLabelEdgesStr,
@DefaultValue("20") @QueryParam("minNodeSize") String minNodeSizeStr,
@DefaultValue("45") @QueryParam("maxNodeSize") String maxNodeSizeStr) {
@DefaultValue("45") @QueryParam("maxNodeSize") String maxNodeSizeStr,
@DefaultValue("10") @QueryParam("maxColorCount") String maxColorCountStr) {
try {

String username = getUserName();
Expand All @@ -2534,6 +2535,16 @@ public Response getCoverVisualization(@PathParam("graphId") String graphIdStr,
requestHandler.log(Level.WARNING, "user: " + username, e);
return requestHandler.writeError(Error.PARAMETER_INVALID, "Max node size is not valid.");
}
int maxColorCount;
try {
maxColorCount = Integer.parseInt(maxColorCountStr);
if (maxColorCount < 1) {
throw new IllegalArgumentException();
}
} catch (Exception e) {
requestHandler.log(Level.WARNING, "user: " + username, e);
return requestHandler.writeError(Error.PARAMETER_INVALID, "Max color count is not valid.");
}
VisualOutputFormat format;
GraphLayoutType layout;
boolean doLabelNodes;
Expand Down Expand Up @@ -2579,7 +2590,7 @@ public Response getCoverVisualization(@PathParam("graphId") String graphIdStr,
"Cover does not exist: cover id " + coverIdStr + ", graph id " + graphIdStr);
}

layoutHandler.doLayout(cover, layout, doLabelNodes, doLabelEdges, minNodeSize, maxNodeSize, painting);
layoutHandler.doLayout(cover, layout, doLabelNodes, doLabelEdges, minNodeSize, maxNodeSize, painting, maxColorCount);
database.updateCover(cover);
generalLogger.getLogger().log(Level.INFO, "user " + username + ": get visualization of cover " + coverIdStr + " in " +visualOutputFormatStr + " format." );
return requestHandler.writeCover(cover, format);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ public void writeGraph(CustomGraph graph) throws AdapterException {
//Label
tmp.put("label", n.getLabel("label").toString());

//Multicolor Nodes
if (n.getAttribute("ui.belonging-color") != null) {
tmp.put("multicolor", n.getAttribute("ui.belonging-color"));
}

JSONObject jsonNode = (JSONObject) JSONValue.parse(JSONValue.toJSONString(tmp));

nodes.add(jsonNode);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@
import i5.las2peer.services.ocd.viewer.utils.CentralityVisualizationType;

import java.awt.Color;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.bouncycastle.pqc.math.linearalgebra.Matrix;
import org.graphstream.graph.Node;
import org.graphstream.graph.Edge;

Expand Down Expand Up @@ -117,15 +119,15 @@ private void setLayoutDefaults(CustomGraph graph, double minNodeSize, double max
* @throws InterruptedException If the executing thread was interrupted.
*/
public void doLayout(Cover cover, GraphLayoutType layoutType, boolean doLabelNodes, boolean doLabelEdges,
double minNodeSize, double maxNodeSize, CoverPaintingType paintingType) throws InstantiationException, IllegalAccessException, InterruptedException {
double minNodeSize, double maxNodeSize, CoverPaintingType paintingType, int maxNodeColors) throws InstantiationException, IllegalAccessException, InterruptedException {
CustomGraph graph = cover.getGraph();
setCoverLayoutDefaults(graph, minNodeSize, maxNodeSize);
labelGraph(graph, doLabelNodes, doLabelEdges);
GraphLayouter layouter = graphLayouterFactory.getInstance(layoutType);
layouter.doLayout(graph);
CoverPainter painter = coverPainterFactory.getInstance(paintingType);
painter.doPaint(cover);
paintNodes(cover);
paintNodes(cover, maxNodeColors);
setViewDefaults(graph);

}
Expand Down Expand Up @@ -284,12 +286,13 @@ private void labelGraph(CustomGraph graph, boolean doLabelNodes, boolean doLabel
* membership degrees / belonging factors.
* @param cover The cover.
*/
private void paintNodes(Cover cover) {
private void paintNodes(Cover cover, int maxNodeColors) {
CustomGraph graph = cover.getGraph();
Iterator<Node> nodesIt = graph.iterator();
float[] curColorCompArray = new float[4];
float[] colorCompArray;
Node node;
maxNodeColors--;
while(nodesIt.hasNext()) {
colorCompArray = new float[4];
node = nodesIt.next();
Expand All @@ -306,6 +309,40 @@ private void paintNodes(Cover cover) {
node.setAttribute("ui.style",node.getAttribute("ui.style") + "fill-color: rgba(" + color.getRed() + "," + color.getGreen() + "," + color.getBlue() + "," + color.getAlpha() + ");");
//TODO: Ideally we shouldn't need a separate ui.fill-color attribute and should be able to use the value from ui.style
node.setAttribute("ui.fill-color", new float[]{color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()/255}); // set directly accessible color attribute for node

if (maxNodeColors > 0) {
final Node n = node;
HashMap<String, Double> belongingColors = new HashMap<>();
communityIndices.sort((i1, i2) -> cover.getBelongingFactor(n, i2) < cover.getBelongingFactor(n, i1) ? -1 : 1);
if (maxNodeColors < communityIndices.size()) {
double sum = 0;
for (int i = 0; i < maxNodeColors; i++) {
Color c = cover.getCommunityColor(communityIndices.get(i));
String hexColor = String.format("#%02x%02x%02x%02x", c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
belongingColors.put(hexColor, cover.getBelongingFactor(node, communityIndices.get(i)));
sum += cover.getBelongingFactor(node, communityIndices.get(i));
}
sum = 1-sum;
colorCompArray = new float[4];
for (int i = maxNodeColors; i < communityIndices.size(); i++) {
Color comColor = cover.getCommunityColor(communityIndices.get(i));
comColor.getRGBComponents(curColorCompArray);
for (int j = 0; j < 4; j++) {
colorCompArray[j] += curColorCompArray[j] * (cover.getBelongingFactor(node, communityIndices.get(i)) / sum);
}
}
Color c = new Color(colorCompArray[0], colorCompArray[1], colorCompArray[2], colorCompArray[3]);
String hexColor = String.format("#%02x%02x%02x%02x", c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
belongingColors.put(hexColor, sum);
} else {
for (int index : communityIndices) {
Color c = cover.getCommunityColor(index);
String hexColor = String.format("#%02x%02x%02x%02x", c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
belongingColors.put(hexColor, cover.getBelongingFactor(node, index));
}
}
node.setAttribute("ui.belonging-color", belongingColors);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public class PredefinedColorsCoverPainterTest {
public void testOnSawmill() throws AdapterException, IOException, InstantiationException, IllegalAccessException, InterruptedException {
Cover cover = ViewerTestGraphFactory.getSlpaSawmillCover();
LayoutHandler handler = new LayoutHandler();
handler.doLayout(cover, GraphLayoutType.ORGANIC, true, false, 20, 45, CoverPaintingType.PREDEFINED_COLORS);
handler.doLayout(cover, GraphLayoutType.ORGANIC, true, false, 20, 45, CoverPaintingType.PREDEFINED_COLORS, 10);
SvgVisualOutputAdapter adapter = new SvgVisualOutputAdapter();
adapter.setWriter(new FileWriter(ViewerTestConstants.slpaSawmillSvgOutputPath));
adapter.writeGraph(cover.getGraph());
Expand All @@ -29,7 +29,7 @@ public void testOnSawmill() throws AdapterException, IOException, InstantiationE
public void testOnDolphins() throws AdapterException, IOException, InstantiationException, IllegalAccessException, InterruptedException {
Cover cover = ViewerTestGraphFactory.getSlpaDolphinsCover();
LayoutHandler handler = new LayoutHandler();
handler.doLayout(cover, GraphLayoutType.ORGANIC, true, false, 20, 45, CoverPaintingType.PREDEFINED_COLORS);
handler.doLayout(cover, GraphLayoutType.ORGANIC, true, false, 20, 45, CoverPaintingType.PREDEFINED_COLORS, 10);
SvgVisualOutputAdapter adapter = new SvgVisualOutputAdapter();
adapter.setWriter(new FileWriter(ViewerTestConstants.slpaDolphinsSvgOutputPath));
adapter.writeGraph(cover.getGraph());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public class RandomColorPainterTest {
public void testOnSawmill() throws AdapterException, IOException, InstantiationException, IllegalAccessException, InterruptedException {
Cover cover = ViewerTestGraphFactory.getSlpaSawmillCover();
LayoutHandler handler = new LayoutHandler();
handler.doLayout(cover, GraphLayoutType.ORGANIC, true, false, 20, 45, CoverPaintingType.RANDOM_COLORS);
handler.doLayout(cover, GraphLayoutType.ORGANIC, true, false, 20, 45, CoverPaintingType.RANDOM_COLORS, 10);
SvgVisualOutputAdapter adapter = new SvgVisualOutputAdapter();
adapter.setWriter(new FileWriter(ViewerTestConstants.slpaSawmillSvgOutputPath));
adapter.writeGraph(cover.getGraph());
Expand All @@ -29,7 +29,7 @@ public void testOnSawmill() throws AdapterException, IOException, InstantiationE
public void testOnDolphins() throws AdapterException, IOException, InstantiationException, IllegalAccessException, InterruptedException {
Cover cover = ViewerTestGraphFactory.getSlpaDolphinsCover();
LayoutHandler handler = new LayoutHandler();
handler.doLayout(cover, GraphLayoutType.ORGANIC, true, false, 20, 45, CoverPaintingType.RANDOM_COLORS);
handler.doLayout(cover, GraphLayoutType.ORGANIC, true, false, 20, 45, CoverPaintingType.RANDOM_COLORS, 10);
SvgVisualOutputAdapter adapter = new SvgVisualOutputAdapter();
adapter.setWriter(new FileWriter(ViewerTestConstants.slpaDolphinsSvgOutputPath));
adapter.writeGraph(cover.getGraph());
Expand Down

0 comments on commit e082a89

Please sign in to comment.