void draw() {
    if (record) {
      // Note that #### will be replaced with the frame number. Fancy!
      parent.beginRecord(PConstants.PDF, "frame-####.pdf");
      parent.textMode(PConstants.SHAPE);
      parent.font = parent.createFont("Verdana", 18); // recreate as a
      // shape
      parent.textFont(parent.font);
    }
    parent.background(130, 130, 130);

    if (currentLarge == null) {
      // draw the actual timeline
      for (TwitterFilteringComponent a : timePoints) {
        a.draw();
        drawLinksTo(a);
        // moveToPosition(a);
      }

      drawTimeLine();
      fixOverlaps();
      // draw visualisations!
    } else {
      currentLarge.draw();
    }
    if (record) {
      parent.endRecord();
      parent.textMode(PConstants.MODEL);
      record = false;
    }
    // drawFrameRate(0,25);
    // controlP5.draw();
  }
  void controlEvent(ControlEvent theControlEvent) {

    for (TwitterFilteringComponent a : timePoints) {
      if (a.hasMouseOver()) {
        a.controlEvent(theControlEvent);
      }
    }
  }
 void mouseReleased() {
   if (currentDragging != null) {
     currentDragging.currentTransitionState = MovementState.SMALL;
     currentDragging = null;
     PApplet.println("Stopped dragging");
   }
   for (TwitterFilteringComponent a : timePoints) {
     if (a.hasMouseOver()) {
       a.mouseReleased();
     }
   }
 }
 void mouseDragged() {
   if (currentDragging != null) {
     // PApplet.println("Moving!");
     // currentDragging.x = parent.mouseX - draggingOffsetX;
     // currentDragging.y = parent.mouseY - draggingOffsetY;//
     currentDragging.moveImmediatelyTo(
         parent.mouseX - draggingOffsetX, parent.mouseY - draggingOffsetY);
     // PApplet.println("x y are " + currentDragging.x + " and "
     // + currentDragging.y);
   }
 }
 void moveToPosition(TwitterFilteringComponent t) {
   // moves component to a position above the middle of its range
   float maxX =
       PApplet.map(
           getHourOfYear(t.dateSelection.getEnd()),
           getHourOfYear(timelineStartDate),
           getHourOfYear(timelineEndDate),
           lineStart,
           lineStop);
   float minX =
       PApplet.map(
           getHourOfYear(t.dateSelection.getStart()),
           getHourOfYear(timelineStartDate),
           getHourOfYear(timelineEndDate),
           lineStart,
           lineStop);
   // if (t.x != int((maxX+minX)/2)-t.width/2) {
   t.moveTo((int) ((maxX + minX) / 2 - smallVizSize.x / 2), (int) (previousPos.y));
   // }
 }
  void mousePressed() {
    if (currentLarge != null) {
      if (parent.mouseEvent.getClickCount() == 2) {
        // shrink it back down!
        // generate thumbnail
        currentLarge.setSize((int) (smallVizSize.x), (int) (smallVizSize.y));
        moveToPosition(currentLarge);
        currentLarge
            .checkComponents(); // work out if we've double-clicked on the map, the cloud or the
                                // streamgraph!
        currentLarge.currentTransitionState = MovementState.SHRINKING;
        currentLarge = null;
      } else {
        currentLarge.mousePressed();
      }
    } else {
      for (TwitterFilteringComponent a : timePoints) {
        if (parent.mouseEvent.getClickCount() == 2 && a.hasMouseOver()) {
          PApplet.println("<double click> on " + a);
          previousPos = new PVector(a.x, a.y);
          a.moveTo(0, 0);
          a.setSize(width, height);
          currentLarge = a;
          a.currentTransitionState = MovementState.GROWING;
          break;
        } else if (a.hasMouseOver() && parent.keyPressed && parent.keyCode == PConstants.SHIFT) {
          // move middle to where the mouse is?
          PApplet.println("Dragging start" + a);
          currentDragging = a;
          draggingOffsetX = parent.mouseX - a.x;
          draggingOffsetY = parent.mouseY - a.y;
          currentDragging.currentTransitionState = MovementState.MOVING;
          // a.mousePressed();
        }

        if (parent.mouseButton == PConstants.RIGHT) {
          // aha! we're doing captioning!
          if (a.hasMouseOver() && !a.hasCaption()) {
            a.addCaption();
          } else if (a.hasCaption() && a.caption.mouseOver()) {
            PApplet.println("We want to edit the caption!");
            a.caption.createNote();
          }
        }
      }
    }
  }