「proce55ing-gr01」の編集履歴(バックアップ)一覧はこちら

proce55ing-gr01 - (2009/01/29 (木) 15:29:22) の最新版との変更点

追加された行は緑色になります。

削除された行は赤色になります。

*Processingでgraph 『ビジュアライジング・データ Processingによる情報視覚化手法』 #amazon(4873113784) を見ながらグラフを書いてみようと思います。 参考:pp.229-238 &bold(){使うもの:}Processing ---- ・はまりやすい?エラー "PFont"を"Pfont"と書いてるのに気付かなかった… 「cannnot find a class or type named "Pfont"」と出るのです。 ・あとは、これを書くだけです。↓ &bgcolor(#ff8800){※ Edgeクラスのrelax()に間違いがありましたので修正しました。} #highlight(c){{//*- This program is VisualisingData's p229-238 -*// int nodeCount; Node[] nodes = new Node[100]; HashMap nodeTable = new HashMap(); int edgeCount; Edge[] edges = new Edge[500]; static final color nodeColor = #F0C070; //node box background color static final color selectColor = #FF3030; //dragging color static final color fixedColor = #FF8080; //click->固定color static final color edgeColor = #000000; //line color PFont font; void setup(){ size(600, 600); loadData(); // font = loadFont("SansSerif.plain-12.vlw"); font = createFont("SansSerif", 10); textFont(font); smooth(); } void loadData(){ addEdge("joe", "food"); addEdge("joe", "dog"); addEdge("joe", "tea"); addEdge("joe", "cat"); addEdge("joe", "table"); addEdge("table", "plate"); addEdge("plate", "food"); addEdge("food", "mouse"); addEdge("food", "dog"); addEdge("mouse", "cat"); addEdge("table", "cup"); addEdge("cup", "tea"); addEdge("dog", "cat"); addEdge("cup", "spoon"); addEdge("plate", "fork"); addEdge("dog", "flea1"); addEdge("dog", "flea2"); addEdge("flea1", "flea2"); addEdge("plate", "knife"); } // 名前でノードを見つけ出す。見つからなかったノードは新規に追加 void addEdge(String fromLabel, String toLabel){ Node from = findNode(fromLabel); Node to = findNode(toLabel); Edge e = new Edge(from, to); if (edgeCount == edges.length){ edges = (Edge[]) expand(edges); } edges[edgeCount++] = e; } // ラベルからノードを見つける Node findNode(String label){ label = label.toLowerCase(); Node n = (Node) nodeTable.get(label); if (n == null){ return addNode(label); } return n; } // 名前での検索を可能にするためnodeTableへの追加も Node addNode(String label){ Node n = new Node(label); if (nodeCount == nodes.length){ nodes = (Node[]) expand(nodes); } nodeTable.put(label, n); nodes[nodeCount++] = n; return n; } void draw(){ background(255); for (int i = 0 ; i < edgeCount ; i++){ edges[i].relax(); } for (int i = 0 ; i < nodeCount ; i++){ nodes[i].relax(); } for (int i = 0 ; i < nodeCount ; i++){ nodes[i].update(); } for (int i = 0 ; i < edgeCount ; i++){ edges[i].draw(); } for (int i = 0 ; i < nodeCount ; i++){ nodes[i].draw(); } } //*- マウスでノード操作できるように -*// Node selection; void mousePressed(){ // これ以上に離れているノードはすべて無視 float closest = 20; for (int i = 0 ; i < nodeCount; i++){ Node n = nodes[i]; float d = dist(mouseX, mouseY, n.x, n.y); if (d < closest){ selection = n; closest = d; } } if (selection != null){ if (mouseButton == LEFT){ selection.fixed = true; } else if (mouseButton == RIGHT){ selection.fixed = false; } } } void mouseDragged(){ if (selection != null){ selection.x = mouseX; selection.y = mouseY; } } void mouseReleased(){ selection = null; } class Edge{ Node from; Node to; float len; Edge(Node from, Node to){ this.from = from; this.to = to; this.len = 50; } void relax(){ float vx = to.x - from.x; float vy = to.y - from.y; float d = mag(vx, vy); if (d > 0){ float f = (len - d) / (d * 3); float dx = f * vx; float dy = f * vy; to.dx += dx; to.dy += dy; from.dx -= dx; from.dy -= dy; } } void draw(){ stroke(edgeColor); strokeWeight(0.35); line(from.x, from.y, to.x, to.y); } } class Node{ float x, y; float dx, dy; boolean fixed; String label; Node(String label){ this.label = label; x = random(width); y = random(height); } void relax(){ float ddx = 0; float ddy = 0; for (int j = 0 ; j < nodeCount; j++){ Node n = nodes[j]; if (n != this){ float vx = x - n.x; float vy = y - n.y; float lensq = vx * vx + vy * vy; if (lensq == 0){ ddx += random(1); ddy += random(1); } else if (lensq < 100*100){ ddx += vx / lensq; ddy += vy / lensq; } } } float dlen = mag(ddx, ddy) /2; if (dlen > 0){ dx += ddx /dlen; dy += ddy /dlen; } } void update(){ if (!fixed){ x += constrain(dx, -5, 5); y += constrain(dy, -5, 5); x = constrain(x, 0, width); y = constrain(y, 0, height); } dx /= 2; dy /= 2; } void draw(){ if (selection == this){ fill(selectColor); } else if (fixed){ fill(fixedColor); } else { fill(nodeColor); } stroke(0); strokeWeight(0.5); rectMode(CORNER); float w = textWidth(label) + 10; float h = textAscent() + textDescent() + 4; rect(x - w/2, y - h/2, w, h); fill(0); textAlign(CENTER, CENTER); text(label, x, y); } } }} ・実行したら、こういうのが見えるはず。 #image(graph01.gif,center) ・これをマウスで適当に置きなおすとこうなります。 #image(graph02.gif,center) ・次は、どうしたらこれを自動できれいに配置できるか、とかやる予定。 ---- ---- today: &counter(today) yesterday: &counter(yesterday)
*Processingでgraph 01 『ビジュアライジング・データ Processingによる情報視覚化手法』 #amazon(4873113784) を見ながらグラフを書いてみようと思います。 参考:pp.229-238 &bold(){使うもの:}Processing ---- ・はまりやすい?エラー "PFont"を"Pfont"と書いてるのに気付かなかった… 「cannnot find a class or type named "Pfont"」と出るのです。 ・あとは、これを書くだけです。↓ &bgcolor(#ff8800){※ Edgeクラスのrelax()に間違いがありましたので修正しました。} #highlight(c){{//*- This program is VisualizingData's p229-238 -*// int nodeCount; Node[] nodes = new Node[100]; HashMap nodeTable = new HashMap(); int edgeCount; Edge[] edges = new Edge[500]; static final color nodeColor = #F0C070; //node box background color static final color selectColor = #FF3030; //dragging color static final color fixedColor = #FF8080; //click->固定color static final color edgeColor = #000000; //line color PFont font; void setup(){ size(600, 600); loadData(); font = createFont("SansSerif", 10); textFont(font); smooth(); } void loadData(){ addEdge("joe", "food"); addEdge("joe", "dog"); addEdge("joe", "tea"); addEdge("joe", "cat"); addEdge("joe", "table"); addEdge("table", "plate"); addEdge("plate", "food"); addEdge("food", "mouse"); addEdge("food", "dog"); addEdge("mouse", "cat"); addEdge("table", "cup"); addEdge("cup", "tea"); addEdge("dog", "cat"); addEdge("cup", "spoon"); addEdge("plate", "fork"); addEdge("dog", "flea1"); addEdge("dog", "flea2"); addEdge("flea1", "flea2"); addEdge("plate", "knife"); } // 名前でノードを見つけ出す。見つからなかったノードは新規に追加 void addEdge(String fromLabel, String toLabel){ Node from = findNode(fromLabel); Node to = findNode(toLabel); Edge e = new Edge(from, to); if (edgeCount == edges.length){ edges = (Edge[]) expand(edges); } edges[edgeCount++] = e; } // ラベルからノードを見つける Node findNode(String label){ label = label.toLowerCase(); Node n = (Node) nodeTable.get(label); if (n == null){ return addNode(label); } return n; } // 名前での検索を可能にするためnodeTableへの追加も Node addNode(String label){ Node n = new Node(label); if (nodeCount == nodes.length){ nodes = (Node[]) expand(nodes); } nodeTable.put(label, n); nodes[nodeCount++] = n; return n; } void draw(){ background(255); for (int i = 0 ; i < edgeCount ; i++){ edges[i].relax(); } for (int i = 0 ; i < nodeCount ; i++){ nodes[i].relax(); } for (int i = 0 ; i < nodeCount ; i++){ nodes[i].update(); } for (int i = 0 ; i < edgeCount ; i++){ edges[i].draw(); } for (int i = 0 ; i < nodeCount ; i++){ nodes[i].draw(); } } //*- マウスでノード操作できるように -*// Node selection; void mousePressed(){ // これ以上に離れているノードはすべて無視 float closest = 20; for (int i = 0 ; i < nodeCount; i++){ Node n = nodes[i]; float d = dist(mouseX, mouseY, n.x, n.y); if (d < closest){ selection = n; closest = d; } } if (selection != null){ if (mouseButton == LEFT){ selection.fixed = true; } else if (mouseButton == RIGHT){ selection.fixed = false; } } } void mouseDragged(){ if (selection != null){ selection.x = mouseX; selection.y = mouseY; } } void mouseReleased(){ selection = null; } class Edge{ Node from; Node to; float len; Edge(Node from, Node to){ this.from = from; this.to = to; this.len = 50; } void relax(){ float vx = to.x - from.x; float vy = to.y - from.y; float d = mag(vx, vy); if (d > 0){ float f = (len - d) / (d * 3); float dx = f * vx; float dy = f * vy; to.dx += dx; to.dy += dy; from.dx -= dx; from.dy -= dy; } } void draw(){ stroke(edgeColor); strokeWeight(0.35); line(from.x, from.y, to.x, to.y); } } class Node{ float x, y; float dx, dy; boolean fixed; String label; Node(String label){ this.label = label; x = random(width); y = random(height); } void relax(){ float ddx = 0; float ddy = 0; for (int j = 0 ; j < nodeCount; j++){ Node n = nodes[j]; if (n != this){ float vx = x - n.x; float vy = y - n.y; float lensq = vx * vx + vy * vy; if (lensq == 0){ ddx += random(1); ddy += random(1); } else if (lensq < 100*100){ ddx += vx / lensq; ddy += vy / lensq; } } } float dlen = mag(ddx, ddy) /2; if (dlen > 0){ dx += ddx /dlen; dy += ddy /dlen; } } void update(){ if (!fixed){ x += constrain(dx, -5, 5); y += constrain(dy, -5, 5); x = constrain(x, 0, width); y = constrain(y, 0, height); } dx /= 2; dy /= 2; } void draw(){ if (selection == this){ fill(selectColor); } else if (fixed){ fill(fixedColor); } else { fill(nodeColor); } stroke(0); strokeWeight(0.5); rectMode(CORNER); float w = textWidth(label) + 10; float h = textAscent() + textDescent() + 4; rect(x - w/2, y - h/2, w, h); fill(0); textAlign(CENTER, CENTER); text(label, x, y); } } }} ・実行したら、こういうのが見えるはず。真ん中に寄り集まってきます。 #image(graph01.gif,center) ・これをマウスで適当に置きなおすとこうなったり。 #image(graph02.gif,center) ・次は、大量のデータを配置してみる予定。 ---- ---- today: &counter(today) yesterday: &counter(yesterday)

表示オプション

横に並べて表示:
変化行の前後のみ表示: