@Override public void selectColumn(final AttributeColumn column) { if (model != null) { if (!(model.getChart() == null && column == null) || (model.getChart() != null && !model.getChart().getColumn().equals(column))) { if (column != null && !attributeModel.getGraphTable().hasColumn(column.getId())) { throw new IllegalArgumentException("Not a graph column"); } Thread thread = new Thread( new Runnable() { @Override public void run() { TimelineChart chart = null; Graph graph = Lookup.getDefault() .lookup(GraphController.class) .getModel() .getGraphVisible(); if (column != null) { DynamicType type = (DynamicType) graph.getAttributes().getValue(column.getIndex()); if (type != null) { List<Interval> intervals = type.getIntervals(model.getCustomMin(), model.getCustomMax()); Number[] xs = new Number[intervals.size() * 2]; Number[] ys = new Number[intervals.size() * 2]; int i = 0; for (Interval interval : intervals) { Number x = (Double) interval.getLow(); Number y = (Number) interval.getValue(); xs[i] = x; ys[i] = y; i++; xs[i] = (Double) interval.getHigh(); ys[i] = y; i++; } if (xs.length > 0) { chart = new TimelineChartImpl(column, xs, ys); } } } model.setChart(chart); fireTimelineModelEvent( new TimelineModelEvent(TimelineModelEvent.EventType.CHART, model, chart)); } }, "Timeline Chart"); thread.start(); } } }
@Override public void stopPlay() { if (model != null && model.isPlaying()) { model.setPlaying(false); fireTimelineModelEvent( new TimelineModelEvent(TimelineModelEvent.EventType.PLAY_STOP, model, null)); } if (playExecutor != null) { playExecutor.shutdown(); } }
@Override public void setInterval(double from, double to) { if (model != null) { if (model.getIntervalStart() != from || model.getIntervalEnd() != to) { if (from >= to) { throw new IllegalArgumentException("from should be less than to"); } if (from < model.getCustomMin() || to > model.getCustomMax()) { throw new IllegalArgumentException("From and to should be in the bounds"); } dynamicController.setVisibleInterval(from, to); } } }
@Override public void setEnabled(boolean enabled) { if (model != null) { if (enabled != model.isEnabled() && model.hasValidBounds()) { model.setEnabled(enabled); fireTimelineModelEvent( new TimelineModelEvent(TimelineModelEvent.EventType.ENABLED, model, enabled)); } if (!enabled) { // Disable filtering dynamicController.setVisibleInterval(new TimeInterval()); } } }
@Override public void setCustomBounds(double min, double max) { if (model != null) { if (model.getCustomMin() != min || model.getCustomMax() != max) { if (min >= max) { throw new IllegalArgumentException("min should be less than max"); } if (min < model.getMin() || max > model.getMax()) { throw new IllegalArgumentException("Min and max should be in the bounds"); } // Interval if (model.getIntervalStart() < min || model.getIntervalEnd() > max) { dynamicController.setVisibleInterval(min, max); } // Custom bounds double[] val = new double[] {min, max}; model.setCustomMin(min); model.setCustomMax(max); fireTimelineModelEvent( new TimelineModelEvent(TimelineModelEvent.EventType.CUSTOM_BOUNDS, model, val)); } } }
@Override public void setPlayMode(PlayMode playMode) { if (model != null) { model.setPlayMode(playMode); } }
@Override public void setPlayStep(double step) { if (model != null) { model.setPlayStep(step); } }
@Override public void setPlaySpeed(int delay) { if (model != null) { model.setPlayDelay(delay); } }
@Override public void startPlay() { if (model != null && !model.isPlaying()) { model.setPlaying(true); playExecutor = Executors.newScheduledThreadPool( 1, new ThreadFactory() { @Override public Thread newThread(Runnable r) { return new Thread(r, "Timeline animator"); } }); playExecutor.scheduleAtFixedRate( new Runnable() { @Override public void run() { double min = model.getCustomMin(); double max = model.getCustomMax(); double duration = max - min; double step = (duration * model.getPlayStep()) * 0.95; double from = model.getIntervalStart(); double to = model.getIntervalEnd(); boolean bothBounds = model.getPlayMode().equals(TimelineModel.PlayMode.TWO_BOUNDS); boolean someAction = false; if (bothBounds) { if (step > 0 && to < max) { from += step; to += step; someAction = true; } else if (step < 0 && from > min) { from += step; to += step; someAction = true; } } else { if (step > 0 && to < max) { to += step; someAction = true; } else if (step < 0 && from > min) { from += step; someAction = true; } } if (someAction) { from = Math.max(from, min); to = Math.min(to, max); setInterval(from, to); } else { stopPlay(); } } }, model.getPlayDelay(), model.getPlayDelay(), TimeUnit.MILLISECONDS); fireTimelineModelEvent( new TimelineModelEvent(TimelineModelEvent.EventType.PLAY_START, model, null)); } }
private boolean setMinMax(double min, double max) { if (model != null) { if (min > max) { throw new IllegalArgumentException("min should be less than max"); } else if (min == max) { // Avoid setting values at this point return false; } double previousBoundsMin = model.getCustomMin(); double previousBoundsMax = model.getCustomMax(); // Custom bounds if (model.getCustomMin() == model.getPreviousMin()) { model.setCustomMin(min); } else if (model.getCustomMin() < min) { model.setCustomMin(min); } if (model.getCustomMax() == model.getPreviousMax()) { model.setCustomMax(max); } else if (model.getCustomMax() > max) { model.setCustomMax(max); } model.setPreviousMin(min); model.setPreviousMax(max); if (model.hasValidBounds()) { fireTimelineModelEvent( new TimelineModelEvent( TimelineModelEvent.EventType.MIN_MAX, model, new double[] {min, max})); if (model.getCustomMax() != max || model.getCustomMin() != min) { fireTimelineModelEvent( new TimelineModelEvent( TimelineModelEvent.EventType.CUSTOM_BOUNDS, model, new double[] {min, max})); } } if ((Double.isInfinite(previousBoundsMax) || Double.isInfinite(previousBoundsMin)) && model.hasValidBounds()) { fireTimelineModelEvent( new TimelineModelEvent(TimelineModelEvent.EventType.VALID_BOUNDS, model, true)); } else if (!Double.isInfinite(previousBoundsMax) && !Double.isInfinite(previousBoundsMin) && !model.hasValidBounds()) { fireTimelineModelEvent( new TimelineModelEvent(TimelineModelEvent.EventType.VALID_BOUNDS, model, false)); } return true; } return false; }