/** * Subscribe - Private Interface * * <p>Patch provided by petereddy on GitHub * * @param String channel name. * @param Callback function callback. * @param String timetoken. */ private void _subscribe(String channel, Callback callback, String timetoken) { while (true) { try { // Build URL List<String> url = java.util.Arrays.asList("subscribe", this.SUBSCRIBE_KEY, channel, "0", timetoken); // Wait for Message JSONArray response = _request(url); JSONArray messages = response.optJSONArray(0); // Update TimeToken if (response.optString(1).length() > 0) timetoken = response.optString(1); // Run user Callback and Reconnect if user permits. If // there's a timeout then messages.length() == 0. for (int i = 0; messages.length() > i; i++) { JSONObject message = messages.optJSONObject(i); if (!callback.execute(message) || cancel) return; } } catch (Exception e) { try { Thread.sleep(1000); } catch (InterruptedException ie) { return; } } } }
/** Main threading method. Runs layout or sleeps. */ public void run() { System.out.println(Thread.currentThread().getName() + " layout starting up"); while (active) { if (stable) { // graph is stable, sleep and try again later. // System.out.println(Thread.currentThread().getName() + " done, sleeping."); try { idleing = true; Thread.sleep(THREAD_SLEEP_TIME); } catch (InterruptedException ex) { // just stop sleeping early... // System.out.println( Thread.currentThread().getName() + " waking up."); } idleing = false; } else { // System.out.println(Thread.currentThread().getName() + " doing layout..."); doLayout(); } } System.out.println(Thread.currentThread().getName() + "layout stopping."); }
/** * Layout core logic. * * <p>This iterates over all the nodes and determines their velocities based on a force directed * layout approach, performs collision detection/avoidance and then ultimately their new positions * as they move. */ private void doLayout() { double maxVelocity = 100; double numOfIterations = 0; double step = 100; double skip = step; int counter = 1; boolean dividerChanged = false; // active = true; while (maxVelocity > 1 && active && (numOfIterations < MAX_NUM_OF_ITERATIONS)) { counter++; maxVelocity = 0; numOfIterations++; Iterator<Node> outer = controller.getNodeIterator(); startTime = System.currentTimeMillis(); double systemMovement = 0; double kineticEnergy = 0; /* Iterate over all nodes and calculate velocity */ while (outer.hasNext()) { Node current = outer.next(); current.resetVelocity(); current.resetAcceleration(); /* * If current node is not pinned or selected, * perform force directed layout calculations here. */ if (!((current == controller.getGraphSelected()) || current.isPinned())) { calculateNodeAttractiveForce(current); calculateNodeRepulsiveForces(current); // applyNodeFriction(current); // if (IS_COOLING) { // calculateNodeCooling(current, numOfIterations); // } // calculate velocities current.setVX(current.getVX() + current.accelx * TIMESTEP * DAMPING); current.setVY(current.getVY() + current.accely * TIMESTEP * DAMPING); double speedSquared = current.getVX() * current.getVX() + current.getVY() * current.getVY(); kineticEnergy += 0.5 * current.weight * speedSquared; // cap the velocity if (current.getVX() >= 0) { current.setVX(Math.min(current.getVX(), MAX_DIST_PER_MOVE)); } else { current.setVX(Math.max(current.getVX(), -MAX_DIST_PER_MOVE)); } if (current.getVY() >= 0) { current.setVY(Math.min(current.getVY(), MAX_DIST_PER_MOVE)); } else { current.setVY(Math.max(current.getVY(), -MAX_DIST_PER_MOVE)); } // System.out.println("vy "+ current.getVY() + ", vx " + current.getVX()); } } /* Iterate over all nodes move them after all the velocities are set */ outer = controller.getNodeIterator(); while (outer.hasNext()) { Node current = outer.next(); int xStart = current.getX(); int yStart = current.getY(); /* update node position */ int xEnd = current.getX() + (int) current.getVX(); int yEnd = current.getY() + (int) current.getVY(); int dX = Math.abs(xStart - xEnd); int dY = Math.abs(yStart - yEnd); // systemMovement += dX; // systemMovement += dY; // if(dX + dY > 6) { controller.moveNode(current, xEnd, yEnd); // } // controller.moveNode(current, Math.min(current.getX() + (int) // current.getVX(),MAX_DIST_PER_MOVE), Math.min(current.getY() + (int) current.getVY(), // MAX_DIST_PER_MOVE)); /* compute maxVelocity for layout iteration */ maxVelocity = Math.max( maxVelocity, Math.sqrt(Math.pow(current.getVX(), 2) + Math.pow(current.getVY(), 2))); } if (kineticEnergy < ENERGY_THRESHOLD) { numOfIterations = MAX_NUM_OF_ITERATIONS; } /* Make animation slower */ try { Thread.sleep(sleepInterval); } catch (InterruptedException ex) { } /* Calculate how long the iteration took */ stopTime = System.currentTimeMillis(); long duration = stopTime - startTime; if ((duration > MAX_ITERATION_TIME) && (sleepInterval > 5)) { sleepInterval -= 5; } else if (duration < MIN_ITERATION_TIME) { sleepInterval += 5; } if (numOfIterations > skip) { skip += step; System.out.print('.'); } } /* We've reached a stable layout, hold on for now */ stable = true; // System.out.println("ran in " + numOfIterations + " iterations."); }