@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();
      }
    }
  }
  private void writeAttributes(
      XMLStreamWriter xmlWriter, AttributeColumn[] cols, String mode, String attClass)
      throws Exception {
    if (exportAttributes) {
      xmlWriter.writeStartElement(ATTRIBUTES);
      xmlWriter.writeAttribute(ATTRIBUTES_CLASS, attClass);
      xmlWriter.writeAttribute(ATTRIBUTES_MODE, mode);

      for (AttributeColumn col : cols) {
        if (!col.getOrigin().equals(AttributeOrigin.PROPERTY)
            || (exportDynamic
                && col.getOrigin().equals(AttributeOrigin.PROPERTY)
                && col.getIndex() == PropertiesColumn.EDGE_WEIGHT.getIndex())) {
          xmlWriter.writeStartElement(ATTRIBUTE);
          xmlWriter.writeAttribute(ATTRIBUTE_ID, col.getId());
          xmlWriter.writeAttribute(ATTRIBUTE_TITLE, col.getTitle());
          if (col.getType().equals(AttributeType.INT)) {
            xmlWriter.writeAttribute(ATTRIBUTE_TYPE, "integer");
          } else if (col.getType().isListType()) {
            if (col.getType().equals(AttributeType.LIST_INTEGER)) {
              xmlWriter.writeAttribute(ATTRIBUTE_TYPE, "listint");
            } else if (col.getType().equals(AttributeType.LIST_CHARACTER)) {
              xmlWriter.writeAttribute(ATTRIBUTE_TYPE, "listchar");
            } else {
              xmlWriter.writeAttribute(
                  ATTRIBUTE_TYPE, col.getType().getTypeString().toLowerCase().replace("_", ""));
            }
          } else if (col.getType().isDynamicType()) {
            AttributeType staticType = TypeConvertor.getStaticType(col.getType());
            if (staticType.equals(AttributeType.INT)) {
              xmlWriter.writeAttribute(ATTRIBUTE_TYPE, "integer");
            } else {
              xmlWriter.writeAttribute(ATTRIBUTE_TYPE, staticType.getTypeString().toLowerCase());
            }
          } else {
            xmlWriter.writeAttribute(ATTRIBUTE_TYPE, col.getType().getTypeString().toLowerCase());
          }
          if (col.getDefaultValue() != null) {
            xmlWriter.writeStartElement(ATTRIBUTE_DEFAULT);
            xmlWriter.writeCharacters(col.getDefaultValue().toString());
            xmlWriter.writeEndElement();
          }
          xmlWriter.writeEndElement();
        }
      }

      xmlWriter.writeEndElement();
    }
  }
 private void writeAttValues(
     XMLStreamWriter xmlWriter, AttributeRow row, TimeInterval visibleInterval) throws Exception {
   xmlWriter.writeStartElement(ATTVALUES);
   for (AttributeValue val : row.getValues()) {
     AttributeColumn col = val.getColumn();
     if (!col.getOrigin().equals(AttributeOrigin.PROPERTY)
         || (exportDynamic
             && col.getOrigin().equals(AttributeOrigin.PROPERTY)
             && col.getIndex() == PropertiesColumn.EDGE_WEIGHT.getIndex())) {
       AttributeType type = col.getType();
       if (type.isDynamicType()) {
         DynamicType dynamicValue = (DynamicType) val.getValue();
         if (dynamicValue != null && visibleInterval != null && exportDynamic) {
           List<Interval<?>> intervals =
               dynamicValue.getIntervals(visibleInterval.getLow(), visibleInterval.getHigh());
           for (Interval<?> interval : intervals) {
             Object value = interval.getValue();
             if (value != null) {
               xmlWriter.writeStartElement(ATTVALUE);
               xmlWriter.writeAttribute(ATTVALUE_FOR, col.getId());
               xmlWriter.writeAttribute(ATTVALUE_VALUE, value.toString());
               if (!Double.isInfinite(interval.getLow())) {
                 String intervalLow = formatTime(interval.getLow());
                 xmlWriter.writeAttribute(
                     interval.isLowExcluded() ? START_OPEN : START, intervalLow);
               }
               if (!Double.isInfinite(interval.getHigh())) {
                 String intervalHigh = formatTime(interval.getHigh());
                 xmlWriter.writeAttribute(
                     interval.isHighExcluded() ? END_OPEN : END, intervalHigh);
               }
               xmlWriter.writeEndElement();
             }
           }
         } else if (dynamicValue != null) {
           TimeInterval interval = visibleInterval;
           if (interval == null) {
             interval = new TimeInterval();
           }
           Object value =
               DynamicUtilities.getDynamicValue(
                   dynamicValue, interval.getLow(), interval.getHigh());
           if (value != null) {
             xmlWriter.writeStartElement(ATTVALUE);
             xmlWriter.writeAttribute(ATTVALUE_FOR, val.getColumn().getId());
             xmlWriter.writeAttribute(ATTVALUE_VALUE, value.toString());
             xmlWriter.writeEndElement();
           }
         }
       } else {
         if (val.getValue() != null) {
           xmlWriter.writeStartElement(ATTVALUE);
           xmlWriter.writeAttribute(ATTVALUE_FOR, col.getId());
           xmlWriter.writeAttribute(ATTVALUE_VALUE, val.getValue().toString());
           xmlWriter.writeEndElement();
         }
       }
     }
   }
   xmlWriter.writeEndElement();
 }