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による情報視覚化手法
Ben Fry
オライリージャパン
売り上げランキング: 9511

Follow me!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA