Skip to content

Commit

Permalink
adding original code
Browse files Browse the repository at this point in the history
  • Loading branch information
Lee Byron committed Mar 31, 2010
0 parents commit 2cdf0ff
Show file tree
Hide file tree
Showing 34 changed files with 1,003 additions and 0 deletions.
Binary file added .DS_Store
Binary file not shown.
24 changes: 24 additions & 0 deletions BasicLateOnsetSort.java
@@ -0,0 +1,24 @@
import java.util.*;

/**
* BasicLateOnsetSort
* Sorts by onset, but does not partition to the outsides of the graph in
* order to illustrate short-sighted errors found during design process.
*
* @author Lee Byron
* @author Martin Wattenberg
*/
public class BasicLateOnsetSort extends LayerSort {

public String getName() {
return "Late Onset Sorting, Top to Bottom";
}

public Layer[] sort(Layer[] layers) {
// first sort by onset
Arrays.sort(layers, new OnsetComparator(true));

return layers;
}

}
58 changes: 58 additions & 0 deletions BelievableDataSource.java
@@ -0,0 +1,58 @@
import java.util.*;

/**
* BelievableDataSource
* Create test data for layout engine.
*
* @author Lee Byron
* @author Martin Wattenberg
*/
public class BelievableDataSource implements DataSource {

public Random rnd;

public BelievableDataSource() {
// seeded, so we can reproduce results
this(2);
}

public BelievableDataSource(int seed) {
rnd = new Random(seed);
}

public Layer[] make(int numLayers, int sizeArrayLength) {
Layer[] layers = new Layer[numLayers];

for (int i = 0; i < numLayers; i++) {
String name = "Layer #" + i;
float[] size = new float[sizeArrayLength];
size = makeRandomArray(sizeArrayLength);
layers[i] = new Layer(name, size);
}

return layers;
}

protected float[] makeRandomArray(int n) {
float[] x = new float[n];

// add a handful of random bumps
for (int i=0; i<5; i++) {
addRandomBump(x);
}

return x;
}

protected void addRandomBump(float[] x) {
float height = 1 / rnd.nextFloat();
float cx = (float)(2 * rnd.nextFloat() - 0.5);
float r = rnd.nextFloat() / 10;

for (int i = 0; i < x.length; i++) {
float a = (i / (float)x.length - cx) / r;
x[i] += height * Math.exp(-a * a);
}
}

}
23 changes: 23 additions & 0 deletions COPYRIGHT
@@ -0,0 +1,23 @@
Copyright (c) 2008, Lee Byron, Martin Wattenberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* The names of the contributors may NOT be used to endorse or promote products
derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL LEE BYRON BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14 changes: 14 additions & 0 deletions ColorPicker.java
@@ -0,0 +1,14 @@
/**
* ColorPicker
* Interface for new coloring algorithms.
*
* @author Lee Byron
* @author Martin Wattenberg
*/
public interface ColorPicker {

public void colorize(Layer[] layers);

public String getName();

}
12 changes: 12 additions & 0 deletions DataSource.java
@@ -0,0 +1,12 @@
/**
* DataSource
* Interface for creating a data source
*
* @author Lee Byron
* @author Martin Wattenberg
*/
public interface DataSource {

public Layer[] make(int numLayers, int sizeArrayLength);

}
25 changes: 25 additions & 0 deletions InverseVolatilitySort.java
@@ -0,0 +1,25 @@
import java.util.*;

/**
* InverseVolatilitySort
* Sorts an array of layers by their volatility, placing the most volatile
* layers along the insides of the graph, illustrating how disruptive this
* volatility can be to a stacked graph.
*
* @author Lee Byron
* @author Martin Wattenberg
*/
public class InverseVolatilitySort extends LayerSort {

public String getName() {
return "Inverse Volatility Sorting, Evenly Weighted";
}

public Layer[] sort(Layer[] layers) {
// first sort by volatility
Arrays.sort(layers, new VolatilityComparator(false));

return orderToOutside(layers);
}

}
53 changes: 53 additions & 0 deletions LastFMColorPicker.java
@@ -0,0 +1,53 @@
import processing.core.*;

/**
* LastFMColorPicker
* Loads in an image and uses it as a two-dimensional gradient
* Supply two [0,1) numbers and get the color of the gradient at that point
*
* @author Lee Byron
* @author Martin Wattenberg
*/
public class LastFMColorPicker implements ColorPicker {

public PImage source;

public LastFMColorPicker(PApplet parent, String src) {
source = parent.loadImage(src);
}

public String getName() {
return "Listening History Color Scheme";
}

public void colorize(Layer[] layers) {
// find the largest layer to use as a normalizer
float maxSum = 0;
for (int i=0; i<layers.length; i++) {
maxSum = (float) Math.max(maxSum, layers[i].sum);
}

// find the color for each layer
for (int i = 0; i < layers.length; i++) {
float normalizedOnset = (float)layers[i].onset / layers[i].size.length;
float normalizedSum = layers[i].sum / maxSum;
float shapedSum = (float)(1.0 - Math.sqrt(normalizedSum));

layers[i].rgb = get(normalizedOnset, shapedSum);
}
}

protected int get(float g1, float g2) {
// get pixel coordinate based on provided parameters
int x = PApplet.floor(g1 * source.width);
int y = PApplet.floor(g2 * source.height);

// ensure that the pixel is within bounds.
x = PApplet.constrain(x, 0, source.width - 1);
y = PApplet.constrain(y, 0, source.height - 1);

// return the color at the requested pixel
return source.pixels[x + y * source.width];
}

}
61 changes: 61 additions & 0 deletions LateOnsetDataSource.java
@@ -0,0 +1,61 @@
import java.util.*;

/**
* LateOnsetData
* Creates false data which resembles late onset time-series.
* Such as band popularity or movie box-office income.
*
* @author Lee Byron
* @author Martin Wattenberg
*/
public class LateOnsetDataSource implements DataSource {

public Random rnd;

public LateOnsetDataSource() {
// seeded, so we can reproduce results
this(2);
}

public LateOnsetDataSource(int seed) {
rnd = new Random(seed);
}

public Layer[] make(int numLayers, int sizeArrayLength) {
Layer[] layers = new Layer[numLayers];

for (int i = 0; i < numLayers; i++) {
String name = "Layer #" + i;
int onset = (int)(sizeArrayLength * (rnd.nextFloat() * 1.25 - 0.25));
int duration = (int)(rnd.nextFloat() * 0.75 * sizeArrayLength);
float[] size = new float[sizeArrayLength];
size = makeRandomArray(sizeArrayLength, onset, duration);
layers[i] = new Layer(name, size);
}

return layers;
}

protected float[] makeRandomArray(int n, int onset, int duration) {
float[] x = new float[n];

// add a single random bump
addRandomBump(x, onset, duration);

return x;
}

protected void addRandomBump(float[] x, int onset, int duration) {
float height = rnd.nextFloat();
int start = Math.max(0, onset);
int end = Math.min(x.length, onset + duration);
int len = end - onset;

for (int i = start; i < x.length && i < onset + duration; i++) {
float xx = (float)(i - onset) / duration;
float yy = (float)(xx * Math.exp(-10 * xx));
x[i] += height * yy;
}
}

}
26 changes: 26 additions & 0 deletions LateOnsetSort.java
@@ -0,0 +1,26 @@
import java.util.*;

/**
* LateOnsetSort
* Sorts by onset, and orders to the outsides of the graph.
*
* This is the sort technique preferred when using late-onset data, which the
* Streamgraph technique is best suited to represent
*
* @author Lee Byron
* @author Martin Wattenberg
*/
public class LateOnsetSort extends LayerSort {

public String getName() {
return "Late Onset Sorting, Evenly Weighted";
}

public Layer[] sort(Layer[] layers) {
// first sort by onset
Arrays.sort(layers, new OnsetComparator(true));

return orderToOutside(layers);
}

}
63 changes: 63 additions & 0 deletions Layer.java
@@ -0,0 +1,63 @@
/**
* Layer
* Represents a layer in a layered graph, maintaining properties which
* define it's position, size, color and mathemetical characteristics
*
* @author Lee Byron
* @author Martin Wattenberg
*/
public class Layer {

public String name;
public float[] size;
public float[] yBottom;
public float[] yTop;
public int rgb;
public int onset;
public int end;
public float sum;
public float volatility;

public Layer(String name, float[] size) {

// check for reasonable data
for (int i = 0; i < size.length; i++) {
if (size[i] < 0) {
throw new IllegalArgumentException("No negative sizes allowed.");
}
}

this.name = name;
this.size = size;
yBottom = new float[size.length];
yTop = new float[size.length];
sum = 0;
volatility = 0;
onset = -1;

for (int i = 0; i < size.length; i++) {

// sum is the summation of all points
sum += size[i];

// onset is the first non-zero point
// end is the last non-zero point
if (size[i] > 0) {
if (onset == -1) {
onset = i;
} else {
end = i;
}
}

// volatility is the maximum change between any two consecutive points
if (i > 0) {
volatility = Math.max(
volatility,
Math.abs(size[i] - size[i-1])
);
}
}
}

}

0 comments on commit 2cdf0ff

Please sign in to comment.