JUNG - Get position of vertex and save using Graphml - jung

I'm trying to change a layout from CircleLayout to StaticLayout, keeping the positions of the Vertex, to do this im using the following code:
StaticLayout<VertexType, EdgeType> sLayout = new StaticLayout<VertexType, EdgeType>(graph,
new Transformer<VertexType, Point2D>() {
public Point2D transform(VertexType vertex) {
vertex.setX(layout.getX(vertex));
vertex.setY(layout.getY(vertex));
System.out.println(vertex.toString());
System.out.println(vertex.getX());
System.out.println(vertex.getY());
Point2D p = new Point2D.Double(vertex.getX(), vertex.getY());
return p;
}
}, dimension);
currentVV.setGraphLayout(sLayout);
Where currentVV is a VisualizationViewer and layout is a CircleLayout. setX(double) and setY(double) are methods from my custon Vertex, by default the vertex is initializated with x = 0.0 an y = 0.0.
In this stage I used teh println to check if all vertex get their positions correctly and it is working.
The next step is to save the graph using the GraphmlWritter:
GraphMLWriter<VertexType, EdgeType> graphWriter = new GraphMLWriter<VertexType, EdgeType>();
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(fileName)));
graphWriter.addEdgeData("label", null, "0", new Transformer<EdgeType, String>() {
#Override
public String transform(EdgeType v) {
return v.toString();
}
});
graphWriter.addVertexData("x", null, "0", new Transformer<VertexType, String>() {
public String transform(VertexType v) {
return Double.toString(v.getX());
}
});
graphWriter.addVertexData("y", null, "0", new Transformer<VertexType, String>() {
public String transform(VertexType v) {
return Double.toString(v.getY());
}
});
graphWriter.save(graph, out);
The problems is that while most of the vertexes are being saved sucessfully, some of the vertexes are being saved with the default values to X and Y (0.0), and I have no idea why. If I try to save the graph from directly from the CircleLayout getting the X and Y values from the layout with:
GraphMLWriter<VertexType, EdgeType> graphWriter = new GraphMLWriter<VertexType, EdgeType>();
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(fileName)));
graphWriter.addEdgeData("label", null, "0", new Transformer<EdgeType, String>() {
#Override
public String transform(EdgeType v) {
return v.toString();
}
});
graphWriter.addVertexData("x", null, "0", new Transformer<VertexType, String>() {
public String transform(VertexType v) {
return Double.toString(layout.getX(v));
}
});
graphWriter.addVertexData("y", null, "0", new Transformer<VertexType, String>() {
public String transform(VertexType v) {
return Double.toString(layout.getY(v));
}
});
While this solution helps I would prefer to save the X and Y values on the vertex as it will be used for future implementations.
Anyone knows where I'm missing the position info?
Thanks.

I'm not immediately sure where the bug in your code is.
First question: why are you trying to convert a CircleLayout to a StaticLayout? What does that buy you?
Assuming that this is actually what you need to do, you don't need to serialize it at all; you can initialize any AbstractLayout subclass with the positions of any other Layout instance, because a Layout is (among other things a Function<V, Point2D>, which means you can pass it to an AbstractLayout instance as an "initializer". Thus, for example:
CircleLayout<V, E> circleLayout = ...
...
StaticLayout<V, E> staticLayout = new StaticLayout(graph, circleLayout);

Related

Dart why my code not work with negative value

I try a small code but I have a strange behavior that I can't explain.
I want according to a value to return the "keyvalue" of a map which is based on the key.
My code works with positive value.
If the value is not in the array then it returns null.
It also works with negative values ​​only if the value is included in my array.
If I put a negative value lower than my array then it returns not null but zero which is false!
Keys in my map must be String.
My code that you can test on dartPad :
import 'dart:collection';
void main() {
int myVar = -360;
Map<String, dynamic> values = {
"-200" : 42,
"-100" : 21,
"0" : 0,
"100" : -22,
"150" : -30,
"200" : -43,
"300" : -64
};
Map<String, dynamic> filter(int myVar, Map<String, dynamic> values) {
SplayTreeMap<String, dynamic> newval = SplayTreeMap.of(values);
String convertString = myVar.toString();
if (values.containsKey(convertString)) {
return {convertString: values[convertString]};
}
String lowerKey;
String upperKey;
if(myVar > 0){
lowerKey = newval.lastKeyBefore(convertString);
upperKey = newval.firstKeyAfter(convertString);
}
else{
lowerKey = newval.firstKeyAfter(convertString);
upperKey = newval.lastKeyBefore(convertString);
}
print(lowerKey);
print(upperKey);
return {
if (lowerKey != null) lowerKey: values[lowerKey],
if (upperKey != null) upperKey: values[upperKey],
};
}
var result = filter(myVar, values);
print('============================');
print(result);
}
First I want to give a minor complain about the use of dynamic in the code. It is totally fine to use dynamic in cases where the type cannot be determined on runtime like JSON parsing. But in this case, all the types can be determined and the use of dynamic is not necessary. So I have fixed the code to remove the usage of dynamic and also removed unnecessary typing:
import 'dart:collection';
void main() {
const myVar = -360;
final values = {
"-200": 42,
"-100": 21,
"0": 0,
"100": -22,
"150": -30,
"200": -43,
"300": -64
};
Map<String, int> filter(int myVar, Map<String, int> values) {
final newVal = SplayTreeMap.of(values);
final convertString = myVar.toString();
if (values.containsKey(convertString)) {
return {convertString: values[convertString]};
}
String lowerKey;
String upperKey;
if (myVar > 0) {
lowerKey = newVal.lastKeyBefore(convertString);
upperKey = newVal.firstKeyAfter(convertString);
} else {
lowerKey = newVal.firstKeyAfter(convertString);
upperKey = newVal.lastKeyBefore(convertString);
}
print(lowerKey);
print(upperKey);
return {
if (lowerKey != null) lowerKey: values[lowerKey],
if (upperKey != null) upperKey: values[upperKey],
};
}
final result = filter(myVar, values);
print('============================');
print(result);
}
Your problem is that you are using SplayTreeMap to sort your keys in values but you have used Strings to represent your numbers. This is rather confusing since numbers is valid keys. But this also means that your sorting in your SplayTreeMap is alphabetical and not by number. This is properly the reason why your code does not work as expected.
You can either change the type of your keys to int or provide a compare method to your SplayTreeMap which changes how the sorting are done.
I have made the following example where I have changed the type of keys into int which makes your code work:
import 'dart:collection';
void main() {
const myVar = -360;
final values = {
-200: 42,
-100: 21,
0: 0,
100: -22,
150: -30,
200: -43,
300: -64
};
Map<int, int> filter(int myVar, Map<int, int> values) {
final newVal = SplayTreeMap.of(values);
if (values.containsKey(myVar)) {
return {myVar: values[myVar]};
}
int lowerKey;
int upperKey;
if (myVar > 0) {
lowerKey = newVal.lastKeyBefore(myVar);
upperKey = newVal.firstKeyAfter(myVar);
} else {
lowerKey = newVal.firstKeyAfter(myVar);
upperKey = newVal.lastKeyBefore(myVar);
}
print(lowerKey);
print(upperKey);
return {
if (lowerKey != null) lowerKey: values[lowerKey],
if (upperKey != null) upperKey: values[upperKey],
};
}
final result = filter(myVar, values);
print('============================');
print(result);
}
Output
-200
null
============================
{-200: 42}

key is not equal when map in future

I am using flutter webview plugin.
getCookies() will return a Future<Map<String, String>>.
the containsKey function is false even "id" exist in the Map.
I have no problem if the Map does not come from Future.
How can I access the value from Map?
flutterWebviewPlugin.getCookies().then((Map<String, String> _) {
if (_.containsKey("id")) {
print(${_["id"]});
}
});
print map by
flutterWebviewPlugin.getCookies().then((Map<String, String> _) {
print(_);
}
output of map values
{"locale: en, tcurrency: 6, id: 10702776, pbe: "}
I fix the cookie by this now
_flutterWebviewPlugin.getCookies().then((Map<String, String> cookies) {
Map<String, String> trimCookies = {};
for (String key in cookies.keys) {
trimCookies[key.replaceAll("\"", "").trim()] = cookies[key].replaceAll("\"", "");
}
}

While parsing input as JSON and persisting, only firsts JSON object is persisted

I am trying to read array of JSON posted to a topic that my pipeline is subscribed to and persist the same to BigQuery. The problem I face while doing so is that it persists only the first object, can someone please provide me insight on what I am doing wrong here.
/** A DoFn that converts a table row from JSON into a BigQuery table row. */
static class FormatAsTableRowFn extends DoFn<TableRow, TableRow> {
private static final long serialVersionUID = 0;
static TableSchema getSchema() {
return new TableSchema().setFields(new ArrayList<TableFieldSchema>() {
// Compose the list of TableFieldSchema from tableSchema.
{
add(new TableFieldSchema().setName("PillBoxID").setType("STRING").setMode("NULLABLE"));
add(new TableFieldSchema().setName("Period").setType("STRING").setMode("NULLABLE"));
add(new TableFieldSchema().setName("Time").setType("TIMESTAMP").setMode("NULLABLE"));
add(new TableFieldSchema().setName("IsTaken").setType("STRING").setMode("NULLABLE"));
}
});
}
#Override
public void processElement(ProcessContext c) {
TableRow jsonRow = c.element();
// Setup a date formatter to parse the date appropriately
SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
try {
TableRow bQueryRow = new TableRow()
.set("PillBoxID", (String) jsonRow.get("PillBoxID"))
.set("Period", (String) jsonRow.get("Period"))
.set("Time",ft.format(ft.parse((String) jsonRow.get("Time"))))
.set("IsTaken", (String) jsonRow.get("IsTaken"));
LOG.error("Inside try" + bQueryRow.getF());
c.output(bQueryRow);
} catch (ParseException pe) {
LOG.error("ParseException");
LOG.error(pe.getMessage());
}
}
}
and my pipleline code is as shown below,
bigQueryPipeLine
.apply(PubsubIO.Read.topic(options.getPubsubTopic()).withCoder(TableRowJsonCoder.of()))
.apply(ParDo.of(new FormatAsTableRowFn()))
.apply(BigQueryIO.Write.to(tableSpec)
.withSchema(FormatAsTableRowFn.getSchema()));
it is possible to process multiple records if you format the input JSON to include an array of items.
Example input:
{
"items":
[
{"PillBoxID":"ID5", "Period":"Morning", "Time":"2016-03-14T11:11:11", "IsTaken":"true"},
{"PillBoxID":"ID6", "Period":"Afternoon", "Time":"2016-03-14T15:11:11", "IsTaken":"false"}
]
}
The rough example processElement() code adds the 2 items to c.output() for later storage in BigQuery.
#Override
public void processElement(ProcessContext c) throws DatastoreException, IOException{
TableRow jsonRowObj = c.element();
LOG.info("Original input:" + c.element().toPrettyString());
ArrayList<Map> jsonRows = (ArrayList<Map>)jsonRowObj.get("items");
Iterator<Map> iterator = jsonRows.iterator();
while(iterator.hasNext()) {
Map jsonRow = (Map)iterator.next();
// Setup a date formatter to parse the date appropriately
SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
try {
LOG.info("child input JSON: "+jsonRow.toString());
TableRow bQueryRow = new TableRow()
.set("PillboxID", (String) jsonRow.get("PillBoxID"))
.set("Period", (String) jsonRow.get("Period"))
.set("Time",ft.format(ft.parse((String) jsonRow.get("Time"))))
.set("IsTaken", (boolean) Boolean.parseBoolean((String)jsonRow.get("IsTaken")));
c.output(bQueryRow);
} catch (ParseException pe) {
LOG.error("");
LOG.error("ParseException " +pe.getMessage());
}
}
}

Problems handling KeyboardEvents on DartFlash

I'm having trouble to handle KeyboardEvents on DartFlash.
I don't know what I'm doing wrong here. Could someone help me?
My intention is to just create a very simple walking character and every time I hit a key, it moves in the x and y, only to start understanding DartFlash API.
Here is the full source code:
class Character extends Sprite
{
TextureAtlas _atlas;
Bitmap _currentBitmap;
int _direction;
String _name;
Character(this._name, this._atlas)
{
this._direction=Direction.down;
this._currentBitmap=this.getBitmap("stand", this._direction);
addChild(this._currentBitmap);
}
String get name => this._name;
Bitmap getBitmap(String name, [int direction, int number])
{
if(direction == null)
{
return new Bitmap(this._atlas.getBitmapData(name));
} else if (number == null)
{
return new Bitmap(this._atlas.getBitmapData("${name}-${Direction.getDirectionName(direction)}"));
}
return new Bitmap(this._atlas.getBitmapData("${name}-${Direction.getDirectionName(direction)}-${number}"));
}
}
Character dk;
void keyboardListener(KeyboardEvent ke) {
print("Key code: ${ke.keyCode}");
dk.x+=1;
dk.y+=1;
}
void main()
{
Stage mainStage = new Stage("mainStage", html.document.query("#mainStage"));
RenderLoop renderLoop = new RenderLoop();
renderLoop.addStage(mainStage);
Resource resource=new Resource();
resource.addTextureAtlas("DarkKnight", "resources/DarkKnight.json", TextureAtlasFormat.JSONARRAY);
resource.load().then((res)
{
print(resource.toString());
dk=new Character("DarkKnight", resource.getTextureAtlas("DarkKnight"));
dk.x=10;
dk.y=10;
mainStage.addChild(dk);
dk.addEventListener(KeyboardEvent.KEY_DOWN, keyboardListener, false);
mainStage.focus=dk;
print("${mainStage.focus.name}");
});
}
There is an easy workaround. Just add an "tabindex" attribute to the canvas element and afterwards you will received KeyboardEvents. If the "tabindex" is not set, then the canvas does not receive keyboard events.
<canvas id="stage" width="800" height="600" tabindex="1"></canvas>
The canvas also needs the focus. You can get the focus by clicking on the canvas or problematically set the focus:
query('#stage').focus();

ASP.NET MVC JsonResult and JQuery flot

I'm trying to use the jquery flot graphing plugin with asp.net mvc. I'm trying to dynamically pull data from a JsonResult in order to populate the graph.
My problem is that I can't seem to get the data returned from the JsonResult in the correct format.
Here is my server side code:
public ActionResult JsonValues()
{
IList<IDictionary<string, int>> listofvalues = new List<IDictionary<string, int>>();
IDictionary<string, int> values1 = new Dictionary<string, int>();
values1.Add("2003", 10882);
values1.Add("2002", 10383);
values1.Add("2001", 10020);
values1.Add("2000", 9762);
values1.Add("1999", 9213);
values1.Add("1998", 8720);
IDictionary<string, int> values3 = new Dictionary<string, int>();
values3.Add("2003", 599);
values3.Add("2002", 510);
values3.Add("2001", 479);
values3.Add("2000", 457);
values3.Add("1999", 447);
values3.Add("1998", 414);
listofvalues.Add(values1);
listofvalues.Add(values3);
JsonResult result = new JsonResult { Data = listofvalues };
return result;
}
And here is my client side code:
$(function() {
$.getJSON("/path/to/JsonValues", function(data) {
var plotarea = $("#plot_area");
$.plot(plotarea, data);
});
});
Note, the following client side code works fine:
$(function() {
var points = [
[[2003, 10882],
[2002, 10383],
[2001, 10020],
[2000, 9762],
[1999, 9213],
[1998, 8720]],
[[2003, 599],
[2002, 510],
[2001, 479],
[2000, 457],
[1999, 447],
[1998, 414]]
];
var plotarea = $("#plot_area");
$.plot(plotarea, points);
});
Given that the above works correctly, it seems that it's just a matter of formatting the returned JsonResult correctly. How can I do this? Is the list of dictionaries the best type to be returning, or should I be using something else? Or is there a function in javascript that I should be using to format the data correctly?
Seems like a really simple thing, but I can't quite get it working.
Check your Json returned to the client, it will be Json objects with key value pairs, something like:
{{'2003':10882,'2002':10383},....}
Where as you require an array of Arrays.
[[[2003, 10882],[2002, 10383]],...]
You could always generate the Json string yourself and return the result
StringBuilder sb = new StringBuilder();
sb.append("[2003,10882],")
return Json("[" + sb.ToString() + "]");
Or you could try storing your values in Arrays which might generate the desired Json but I haven't tried that.
If you want to do it with C# arrays you could do the following:
var values = new object[] {
new object[] /* First series of value */
{
new int[,] { {2003,10882} },
new int[,] { {2002,10383} }
}
};
And then
return Json(values);
You need a JSON Array in the form:
[[1, 1], [2, 3], [5, 5]]
The flot category plugin expects data in the form:
[["category1", 12], ["category2", 3]]
This is not straightforward to create in C# (had to search for a long time :-))
The key is to create object Arrays (object [])
Untested Code follows:
IEnumerable<object[]> values1_array = from x in values1
select new object [] {x.Key, x.Value};
IEnumerable<object[]> values3_array = from x in values3
select new object [] {x.Key, x.Value};
//create one big object
var dataArray = new object[] {
new {data = values1_array, label="Values1"},
new {data = values3_array, label="Values3"},
};
//return Json data
return Json(dataArray) /* JsonRequestBehavior.AllowGet ?*/
Your JavaScript-Code should work:
$(function() {
$.getJSON("/path/to/JsonValues", function(data) {
var plotarea = $("#plot_area");
$.plot(plotarea, data);
});
});

Resources