Package org.timepedia.chronoscope.gviz.api.client

Source Code of org.timepedia.chronoscope.gviz.api.client.DataTableParser

package org.timepedia.chronoscope.gviz.api.client;

import com.google.gwt.core.client.JavaScriptException;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NodeList;
import com.google.gwt.dom.client.TableCellElement;
import com.google.gwt.dom.client.TableElement;
import com.google.gwt.dom.client.TableRowElement;
import com.google.gwt.dom.client.TableSectionElement;
import com.google.gwt.i18n.client.NumberFormat;

import org.timepedia.chronoscope.client.Dataset;
import org.timepedia.chronoscope.client.ComponentFactory;
import org.timepedia.chronoscope.client.Overlay;
import org.timepedia.chronoscope.client.browser.Chronoscope;
import org.timepedia.chronoscope.client.data.DatasetFactory;
import org.timepedia.chronoscope.client.data.DatasetRequest;
import org.timepedia.chronoscope.client.overlays.Marker;
import org.timepedia.chronoscope.client.overlays.OverlayClickListener;
import org.timepedia.chronoscope.client.util.DateParser;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;

/**
*
*/
public class DataTableParser {

  static class DataPair {

    public double domain[];

    public double range[];
  }

  public static Dataset[] parseDatasets(DataTable table,
      Map<Integer, Integer> dataset2Column) {

    int startRow = -1;
    for (int row = 0; row < table.getNumberOfRows(); row++) {
      if (!Double.isNaN(table.getValueDate(row, 0))) {
        startRow = row;
        break;
      }
    }

    int numCols = 0;
    for (int i = 1; i < table.getNumberOfColumns(); i++) {
      if (!Double.isNaN(table.getValueNumber(startRow, i))) {
        numCols++;
      }
    }

    DatasetFactory dsFactory = Chronoscope.get().getComponentFactory()
        .getDatasetFactory();

    Dataset[] ds = new Dataset[numCols];
    numCols = 0;
    for (int i = 1; i < table.getNumberOfColumns(); i++) {
      if (Double.isNaN(table.getValueNumber(startRow, i))) {
        continue;
      }
      String label = table.getColumnLabel(i);
      if (label == null || "".equals(label)) {
        label = "Series " + numCols;
      }
      label = label.trim();
      int ind = label.indexOf("(");
      int end = label.indexOf(")");

      String units = label;
      if (ind != -1 && end != -1 && end > ind) {
        units = label.substring(ind + 1, end).trim();
        label = label.substring(0, ind);
      }

      DataPair pair = table2datapair(table, startRow, i);
      sortAscendingDate(pair);

      DatasetRequest.Basic request = new DatasetRequest.Basic();
      request.setDomain(pair.domain);
      request.addRangeTupleSlice(pair.range);
      request.setIdentifier("col" + i);
      request.setRangeLabel(label);
      request.setAxisId(units);
      ds[numCols++] = dsFactory.create(request);

      if (dataset2Column != null) {
        dataset2Column.put(numCols - 1, i);
      }
    }

    return ds;
  }

  public static Marker[] parseMarkers(final JavaScriptObject eventSource,
      final DataTable table, Map<Integer, Integer> dataset2Column) {
    int startRow = -1;
    int curSeries = -1;
    ArrayList<Marker> markers = new ArrayList<Marker>();

    for (int row = 0; row < table.getNumberOfRows(); row++) {
      if (!Double.isNaN(table.getValueDate(row, 0))) {
        startRow = row;
        break;
      }
    }

    for (int i = 1; i < table.getNumberOfColumns(); i++) {

      if (!Double.isNaN(table.getValueNumber(startRow, i))) {
        curSeries++;
      } else {
        if ("markers".equalsIgnoreCase(table.getColumnLabel(i))) {
          for (int row = startRow; row < table.getNumberOfRows(); row++) {
            final Marker m = new Marker(table.getValueDate(row, 0),
                "" + (char) ('A' + markers.size()), curSeries);
            final String info = table.getValueString(row, i);
            final String info2 = info != null ? info.trim() : "";

            if (!"".equals(info2)) {
              m.addOverlayClickListener(new OverlayClickListener() {
                public void onOverlayClick(Overlay overlay, int i, int i1) {
                  m.openInfoWindow(info2);
                  GVizEventHelper
                      .trigger(eventSource, GVizEventHelper.SELECT_EVENT, null);
                }
              });
              markers.add(m);
            }
          }
        }
      }
    }
    return markers.toArray(new Marker[markers.size()]);
  }

  public static DataPair table2datapair(DataTable table, int startRow,
      int col) {
    DataPair pair = new DataPair();

    int rows = 0;
    for (int i = startRow; i < table.getNumberOfRows(); i++) {
      double val = table.getValueNumber(i, col);
      if (!Double.isNaN(val)) {
        rows++;
      }
    }

    int row = 0;
    pair.range = new double[rows];
    pair.domain = new double[rows];

    for (int i = startRow; i < table.getNumberOfRows(); i++) {
      double val = table.getValueNumber(i, col);
      if (!Double.isNaN(val)) {
        pair.range[row] = val;
        pair.domain[row] = table.getValueDate(i, 0);
        row++;
      }
    }

    return pair;
  }

  public static double[] table2domain(DataTable table, int startRow) {
    double d[] = new double[table.getNumberOfRows() - startRow];
    for (int i = startRow; i < table.getNumberOfRows(); i++) {
      d[i] = table.getValueDate(i, 0);
    }
    return d;
  }

  static DataTable parseMicroformatIntoDataTable(String id) {
    Element e = Document.get().getElementById(id);

    assertTrue("table".equalsIgnoreCase(e.getNodeName()),
        "Table Element with id " + id + " doesn't exist.");

    TableElement te = TableElement.as(e);
    TableSectionElement thead = te.getTHead();
    assertNotNull(thead, "Table must contain THEAD element");
    NodeList<TableRowElement> hrows = thead.getRows();
    assertTrue(hrows.getLength() == 1, "Table THEAD must contain 1 TR element");

    int numCols = 0;

    DataTable table = DataTable.create();

    if (hrows.getLength() == 1) {
      TableRowElement tr = hrows.getItem(0);
      NodeList<TableCellElement> hcols = tr.getCells();
      assertTrue(hcols.getLength() > 1,
          "THEAD TR contains less than 2 columns");
      for (int i = 0; i < hcols.getLength(); i++) {
        TableCellElement th = hcols.getItem(i);
        assertTrue("th".equalsIgnoreCase(th.getNodeName()),
            "Only TH elements should occur in THEAD TR");
        String title = th.getInnerText().trim();
        numCols++;
        if (i == 0) {
          table.addColumn("date", title);
        } else {
          if ("markers".equalsIgnoreCase(title)) {
            table.addColumn("string", title);
          } else {
            table.addColumn("number", title);
          }
        }
      }
    } else {
      throw new JavaScriptException("Table Element must ");
    }

    String dateFormat = "MM-dd-yy";
    NumberFormat numberFormats[] = new NumberFormat[numCols];

    NodeList<Element> colGroup = te.getElementsByTagName("colgroup");
    assertTrue(colGroup != null && colGroup.getLength() == 1,
        "Table must have exactly one COLGROUP element");

    NodeList<Element> cols = colGroup.getItem(0).getElementsByTagName("col");
    assertTrue(cols != null && cols.getLength() == numCols,
        "COLGROUP must have one COL element for each TH in THEAD");

    for (int i = 0; i < cols.getLength(); i++) {
      Element col = cols.getItem(i);
      String fmt = col.getAttribute("title");
      String className = col.getClassName();
      if (i == 0) {
        assertTrue(fmt != null && !"".equals(fmt),
            "COL for column 0 must have TITLE attribute containing date");
        assertTrue("cmf-dateformat".equals(className),
            "COL for column 0 must have CLASS of cmf-dateformat");
      }
      if (i == 0) {
        dateFormat = fmt;
      } else {
        if (fmt != null && !"".equals(fmt)) {
          assertTrue("cmf-numberformat".equals(className),
              "Number format COL elements must have class of cmf-numberformat with title containing format according to GWT NumberFormat syntax at http://google-web-toolkit.googlecode.com/svn/javadoc/1.4/com/google/gwt/i18n/client/NumberFormat.html");
          numberFormats[i] = NumberFormat.getFormat(fmt);
        } else if ("cmf-numberformat".equals(className)) {
          assertTrue(fmt != null && !"".equals(fmt),
              "COL has class cmf-numberformat but missing title attribute with format string with syntax http://google-web-toolkit.googlecode.com/svn/javadoc/1.4/com/google/gwt/i18n/client/NumberFormat.html");
          numberFormats[i] = NumberFormat.getFormat(fmt);
        }
      }
    }

    NodeList<TableSectionElement> tbodies = te.getTBodies();
    assertNotNull(tbodies, "Table must contain TBODY elements");
    assertTrue(tbodies.getLength() > 0, "Table must contain TBODY elements");
    int totalAdded = 0;
    for (int i = 0; i < tbodies.getLength(); i++) {
      TableSectionElement tbody = tbodies.getItem(i);
      NodeList<TableRowElement> drows = tbody.getRows();
      table.addRows(drows.getLength());
      for (int j = 0; j < drows.getLength(); j++) {
        TableRowElement row = drows.getItem(j);
        NodeList<TableCellElement> cells = row.getCells();
        assertTrue(cells.getLength() == numCols,
            "Number of TH header columns in THEAD must match number of TD columns in TBODY");

        for (int k = 0; k < cells.getLength(); k++) {
          TableCellElement cell = cells.getItem(k);
          if (k == 0) {
            table.setValueDate(totalAdded, k,
                DateParser.parse(dateFormat, cell.getInnerText().trim()));
          } else {
            if ("string".equals(table.getColumnType(k))) {
              table.setValue(totalAdded, k, cell.getInnerText().trim());
            } else {
              String cellText = cell.getInnerText().trim();
              try {
                double value = numberFormats[k] == null ? Double
                    .parseDouble(cellText) : numberFormats[k].parse(cellText);
                table.setValue(totalAdded, k, value);
              } catch (NumberFormatException e1) {
                // TODO: (ray) ? silently ignore parse errors
              }
            }
          }
        }
        totalAdded++;
      }
    }
    return table;
  }

  private static void assertNotNull(Object obj, String msg) {
    if (obj == null) {
      throw new JavaScriptException(msg);
    }
  }

  private static void assertTrue(boolean cont, String msg) {
    if (!cont) {
      throw new JavaScriptException(msg);
    }
  }

  public static class Pair implements Comparable<Pair> {

    public double x, y;

    public Pair(double x, double y) {
      this.x = x;
      this.y = y;
    }

    public int compareTo(Pair o) {
      return (int) (this.x - o.x);
    }
  }

  private static void sortAscendingDate(DataPair pair) {

    Pair[] p = new Pair[pair.domain.length];
    for (int i = 0; i < p.length; i++) {
      p[i] = new Pair(pair.domain[i], pair.range[i]);
    }
    Arrays.sort(p);
    for (int i = 0; i < p.length; i++) {
      pair.domain[i] = p[i].x;
      pair.range[i] = p[i].y;
    }
  }
}
TOP

Related Classes of org.timepedia.chronoscope.gviz.api.client.DataTableParser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.