ProcessingでDynamic Graph@93日目
Processingでグラフを作ってみた.とりあえず本当に現状のものをコピペしたので,きれいなスクリプトではありませんし,バグも残ってます.ま,参考までに.
なお,プログラミング制作にあたり参考にした書籍は日記の最後に紹介してます.
ま,今日もプレゼンがあったが,受けた質問に(しどろもどろだが)答えることが出来たのは自分に取っては一番の収穫かも.
あと,本当にどうでもいいことだが,ノルディックウォーキングを始めた.見かけによらず腕をものすごく使うので,かなり全身運動になる.驚きだ.
[java]
//N=400
//omit invisible nodes and edges caliculations.
//
PFont font;
//-----------------
int nodeCount;
Node[] nodes = new Node[100];
HashMap nodeTable = new HashMap();
int edgeCount;
Edge[] edges = new Edge[500];
static final color nodeColor =#FFFFFF;//#F0C070;
static final color selectColor =#FF3030;
static final color fixedColor =#FF8080;
static final color edgeColor =#FFFFFF;
float maxConnection=0;
int checkGenerationNum = 3; //selection of generation from root
int rootNode=1;
int orglen = 80;
//color between = lerpColor (#296F34, #61E2F0, percent, HSB);
//----------------------
void setup(){
size(600,600);
loadData();
font = createFont("SansSerif", 14);
textFont(font);
smooth();
}
void loadData(){
for (int i = 0; i< 200; i++){
if(random(3) > 1.5){
addEdge("word" + str(i), "word"+str(i+1));
}else{
addEdge("word"+str(int(i)), "word"+str(int(random(100))));
}
}
addEdge ("word100", "climate");
addEdge ("fruits", "food");
addEdge ("apple", "fruits");
addEdge ("orange", "fruits");
addEdge ("CO2", "temparatre");
addEdge ("melon", "fruits");
addEdge ("climate", "weather");
addEdge ("climate", "tsunami");
addEdge ("tsunami", "sea");
addEdge ("sea", "temparature");
addEdge ("hot", "temparature");
addEdge ("fruits", "climate");
addEdge ("greennhouse", "temparature");
}
//-----------------------
void addEdge(String fromLabel, String toLabel){
Node from = findNode(fromLabel); //return n
Node to = findNode(toLabel); //retune n
from.increment();
to.increment();
if (from.count > to.count){
if (maxConnection < from.count){
maxConnection = from.count;
}
}else{
if (maxConnection < to.count){
maxConnection = to.count;
}
}
Edge e = new Edge(from, to); //create new edge "e"
if(edgeCount == edges.length){ //edgegount = int //edges is Array
edges = (Edge[]) expand(edges);
}
edges[edgeCount++] = e; //add edgesList
}
//-------------------
Node findNode(String label){ //return n
label = label.toLowerCase(); // make all strings into small letteres
Node n = (Node) nodeTable.get(label);// ??
if(n == null){
return addNode(label); // retun n
}
return n; //return Node
}
//------------------
Node addNode(String label){
Node n = new Node(label);
if (nodeCount == nodes.length){
nodes = (Node[]) expand(nodes);
}
nodeTable.put(label, n); //add infromation to hashtable
nodes[nodeCount++] = n; //add nodes Array
return n;
}
//-------------------------
// drawa in every frames
//-------------------------
void draw(){
background(0);
//draw some nodes and edges....
//(1)edge-relax
//(2)node-relax
//(3)node update
//(4)edge draw
//(5)node draw
for(int i=0; i< edgeCount; i++){
if(edges[i].showFlag == true) {
edges[i].relax();
}
}
for(int i=0; i< nodeCount; i++){
if(nodes[i].showFlag == true) {
nodes[i].relax();
}
}
for(int i=0; i< nodeCount; i++){
if(nodes[i].showFlag == true) {
nodes[i].update();
}
}
for(int i=0; i< edgeCount; i++){
if(edges[i].showFlag == true) {
edges[i].draw();
}
}
for(int i=0; i< nodeCount; i++){
if(nodes[i].showFlag == true) {
nodes[i].draw();
}
}
text(maxConnection, 30, 10);
}
//-----------------------------
class Node {
float x,y;
float dx, dy;
boolean fixed;
String label;
int count;
boolean showFlag=false;
int generation;
//constructor
Node (String label){
this.label = label;
x = random(width);
y = random(height);
if(label =="climate"){
showFlag = true;
fixed = true;
}
generation = 0;
}
void increment(){
count++;
}
void relax(){ //node
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(){
fill (nodeColor);
if (selection == this){
fill(selectColor);
ellipse(x,y,20,20);
}else if (fixed){
float nodeSize = (this.count / maxConnection ) * 30 + 10;
// float nodeAlpha =(this.count / maxConnection ) *200 +30;
fill(nodeColor); //,nodeAlpha);
stroke(0);
strokeWeight(0.5);
ellipse(x,y,nodeSize,nodeSize);
fill(fixedColor);
rectMode(CORNER);
float w = textWidth(label) + 10;
float h= textAscent() + textDescent() + 4;
textAlign(CENTER,CENTER);
rect (x - w/2, y-h/2, w,h);
fill(0,0,0);
text(label, x,y);
}else{
float nodeSize = (this.count / maxConnection ) * 30 + 10;
//float nodeAlpha =(this.count / maxConnection ) *200 +30;
fill(nodeColor); ////,nodeAlpha);
stroke(0);
strokeWeight(0.5);
ellipse(x,y,nodeSize,nodeSize);
float w = textWidth(label) + 10;
textAlign(CENTER,CENTER);
fill(0,102,153);
text(label +"_g:"+ generation, x+nodeSize+w/2,y);
}
}
}
//-----------------------------
class Edge{
Node from;
Node to;
float len;
int count;
boolean showFlag=false;
boolean fromShowFlag = false;
boolean toShowFlag = false;
Edge(Node from, Node to){
this.from = from;
this.to = to;
this.len = orglen;
from.increment();
to.increment();
}
void increment(){
count++;
}
void relax(){ //edge 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);
}
}
//---------------
Node selection;
void mousePressed(){
float closest = 20;
for (int i =0; i<nodeCount; i++){
Node n =nodes[i]; //find node number
n.fixed = false;
float d = dist(mouseX, mouseY, n.x, n.y);
if(d < closest){
selection = n;
println("selection = "+ n);
closest = d;
}
}
if (selection != null){
if (mouseButton == LEFT){
//set the flag of other nodes
//"selection"is node object
// ALL RESET
for ( int i=0; i< edgeCount; i++){
edges[i].showFlag = false;
edges[i].len = 0;
}
for ( int j=0; j< nodeCount; j++){
nodes[j].showFlag = false;
nodes[j].x = width/2;
nodes[j].y = height/2;
nodes[j].generation = 0;
}
selection.fixed = true;
selection.x = width /2;
selection.y = height / 2;
//
//check Generation
checkGeneration(selection,checkGenerationNum);
}else if (mouseButton == RIGHT){
selection.fixed = false;
}
}else{
println("elese");
for (int m=0; m<nodeCount; m++){
nodes[m].showFlag = true;
}
for (int j=0; j<edgeCount; j++){
edges[j].showFlag = true;
edges[j].len = orglen*0.5;
}
}
}
//-----------------------
void checkGeneration(Node target, int level){
if(level >= 1){
println ("level=" + level);
level -= 1;
//check for all edges
for (int j=0; j<edgeCount; j++)
{
//println("edgeCount=" + edgeCount);
//check from
if (edges[j].from == target){
edges[j].fromShowFlag = true;
checkGeneration(edges[j].to, level);
target.showFlag = true;
target.generation++;
}
if (edges[j].to == target){
edges[j].toShowFlag = true;
checkGeneration(edges[j].from, level);
target.showFlag = true;
target.generation++;
}
}
}else{
println("lastcheck");
for(int m=0; m < edgeCount; m++){
if(edges[m].fromShowFlag == true && edges[m].toShowFlag == true){
edges[m].showFlag = true;
edges[m].len = orglen;
}
}
}
}
void mouseDragged(){
// if (selection != null){
// selection.x = mouseX;
// selection.y = mouseY;
// }
}
void mouseReleased(){
selection = null;
}
[/java]
ビジュアライジング・データ ―Processingによる情報視覚化手法
posted with amazlet at 09.12.03
Ben Fry
オライリージャパン
売り上げランキング: 9511
オライリージャパン
売り上げランキング: 9511

