Package ar

Source Code of ar.SimpleApp

package ar;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

import ar.aggregates.AggregateUtils;
import ar.app.display.AggregatingDisplay;
import ar.app.display.TransferDisplay;
import ar.app.util.ZoomPanHandler;
import ar.glyphsets.WrappedCollection;
import ar.glyphsets.implicitgeometry.Indexed;
import ar.renderers.ParallelRenderer;
import ar.rules.Numbers;
import ar.selectors.TouchesPixel;
import ar.util.DelimitedReader;
import ar.util.Util;

public class SimpleApp {
  public static void main(String[] args) throws Exception {
    //------------------------ Setup Operations -------------------
    //Get a dataset loaded into a data structure.  This is not technically
    //Abstract Rendering, but it is necessary to get anything other than
    //a white box out of this demo
    ArrayList<Indexed> items = new ArrayList<>();
    DelimitedReader reader = new DelimitedReader(new File("../data/circlepoints.csv"), 1, ",");
    System.out.print("Loading example data...");
    while (reader.hasNext()) {
      String[] parts = reader.next();
      if (parts == null) {continue;}
      Double[] vals = new Double[parts.length];
      for (int i=0; i<parts.length; i++) {vals[i] = Double.parseDouble(parts[i]);}
      items.add(new Indexed.ArrayWrapper(vals));
    }
    System.out.println(items.size() + " items");
    //----------------------- End of setup operations -------------
   
   
    //Load the existing dataset into an abstract rendering glyphset.
    //We use the Wrapper glyphset because no copying is required.
    //However, in exchange we need to supply the "shaper" and the "valuer" instances.
    //These instances are defined above and depend on what exactly is
    //held in the collection being wrapped.
    Glyphset<Rectangle2D, Double> dataset = WrappedCollection.wrap(items, new Indexed.ToRect(.05,2,3), new Indexed.ToValue<Indexed,Double>(4));
   


    //The Renderer class defines a strategy for iterating through the abstract
    //canvas space and through the glyphset.  The two big options are to divide
    //the canvas into regions or divide the glyphset into subsets.
    //The ParalleGlyph renderer is the highest performance BUT requires
    // the glyphset to be partitionable and requires an "Aggregate Reduction" function
    // to combine results from different glyph subsets.
    Renderer r = new ParallelRenderer();

    //The Aggregator is used to combine values from multiple glyphs into a value for a single
    //aggregate bin.  The 'Count' aggregator simply counts how many glyphs fell into the bin.
    Aggregator<Object,Integer> aggregator = new Numbers.Count<Object>();
   

    //The transfer function is used to convert one set of aggregates into another.
    //In the end, an image is a set of aggreagates where the value in each bin is a color.
    Transfer<Number, Color> transfer = new  Numbers.Interpolate<>(new Color(255,0,0,25), new Color(255,0,0,255));


    //Selector associates the glyphs individual bins. 
    //The geometry type matters (and thus is a type-parameter) because it determines which test to use
    Selector<Rectangle2D> selector = TouchesPixel.make(dataset);

   
    //Drive the rendering "by-hand"  (ie, not using any of the swing tools)
    //We must first define a display surface's size, shape and zoom characteristics
    //At the end, a simple buffered image is produced.
    int width = 800;
    int height = 800;
    AffineTransform vt = Util.zoomFit(dataset.bounds(), width, height);
    Aggregates<Integer> aggregates = r.aggregate(dataset, selector, aggregator, vt, width, height);
    Transfer.Specialized<Number,Color> specializedTransfer = transfer.specialize(aggregates);
    Aggregates<Color> colors = r.transfer(aggregates, specializedTransfer);
   
    //Make a final image (if the aggregates are colors)
    @SuppressWarnings("unused"//Unused because its just a demo of how to do it
    BufferedImage image = AggregateUtils.asImage(colors, width, height, Color.white);
   
    //A simple display panel can be found in SimpleDisplay.
    //It takes aggregates and a transfer function to make colors.
    //This display includes zoom/pan capabilities (though they must enabled separately).
    //(Most of this is swing boilerplate).
    JFrame frame = new JFrame("Transfer Display");
    frame.setLayout(new BorderLayout());
    frame.setSize(width,height);
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    TransferDisplay td = new TransferDisplay(aggregates, transfer);
    ZoomPanHandler.installOn(td);
    frame.add(td, BorderLayout.CENTER);
    frame.setVisible(true);
    frame.revalidate();
    frame.validate();
   
    //Full Display is more fully-featured than ARDisplay. It will run the whole render loop
    //and includes zoom/pan listeners.  It is harder to use though, because it takes control
    //over the process in a more robust but somewhat opaque way.
    //Since ARPanel drives the whole rendering process, it takes the dataset, rendering strategy
    //and related definitions in as parameters
    JFrame frame2 = new JFrame("Aggregating Display");
    frame2.setLocation(100, 0);
    frame2.setLayout(new BorderLayout());
    frame2.setSize(width,height);
    frame2.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    final AggregatingDisplay panel = new AggregatingDisplay(aggregator, transfer, dataset, r);
    frame2.add(panel, BorderLayout.CENTER);
    frame2.setVisible(true);
    frame2.revalidate();
    frame2.validate();
    SwingUtilities.invokeAndWait(new Runnable() {public void run() {panel.zoomFit();}});
  }
}
TOP

Related Classes of ar.SimpleApp

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.