-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add abstract radial and grid demos to the examples/demos folder
- Loading branch information
Phil Gough
committed
Aug 23, 2017
1 parent
e4cef6a
commit 2eb2331
Showing
4 changed files
with
263 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
import hivis.common.*; | ||
import hivis.data.*; | ||
import hivis.data.reader.*; | ||
import hivis.data.view.*; | ||
|
||
// This skecth animates an abstract data visualisation | ||
|
||
// The source data | ||
DataTable data; | ||
|
||
// some DataSeries to store the data | ||
DataSeries heightSeries; | ||
DataSeries weightSeries; | ||
DataSeries waistSeries; | ||
DataSeries BMISeries; | ||
String[] smokerSeries; | ||
|
||
|
||
// size of the grid | ||
int rectSize = 25; | ||
|
||
|
||
void setup() { | ||
size(1000, 700); | ||
// setup the visual | ||
colorMode(HSB, 360, 255, 255, 255); | ||
noStroke(); | ||
background(0); | ||
|
||
// Load the data | ||
fileSelected(sketchFile("NCHS_dataset.xlsx")); | ||
} | ||
|
||
void fileSelected(File selection) { | ||
|
||
// Get data from spread sheet. The SpreadSheetReader will automatically update the DataTable it provides. | ||
println("loading data"); | ||
data = HV.loadSpreadSheet(HV.loadSSConfig().sourceFile(selection)); | ||
|
||
println("\nLoaded data:\n" + data); | ||
// add the data to our data structures | ||
heightSeries = data.get("height"); | ||
weightSeries = data.get("weight"); | ||
waistSeries = data.get("waist"); | ||
BMISeries = data.get("bmi"); | ||
smokerSeries = data.get("smoker").asStringArray(); | ||
} | ||
|
||
|
||
|
||
|
||
void draw() { | ||
// a counter to remember which row of data we are looking at | ||
int row = 0; | ||
// draw a grid | ||
for (int x = 0; x < width; x+= rectSize) { | ||
for (int y = 0; y < height; y+= rectSize) { | ||
// use pushMatrix to draw at the origin, but translate the coordinates to our x and y position | ||
pushMatrix(); | ||
translate(x, y); | ||
|
||
// slowly change the colour of our background rectangles | ||
fill(frameCount/12.5%360, 100, 100, 20); | ||
// draw the background rectangles | ||
rect(0, 0, rectSize-1, rectSize-1); | ||
|
||
// grab the data from our DataSeries | ||
// (the weight is too high to use below, so scale it) | ||
float we = weightSeries.getFloat(row) / 50; | ||
float wa = waistSeries.getFloat(row); | ||
float hi = heightSeries.getFloat(row); | ||
|
||
// we will draw dot, make it white | ||
fill(360, 0, 255, 200); | ||
|
||
|
||
// is the person a smoker? slow down their dot a little | ||
float smok = 1.5; | ||
if (smokerSeries[row].equals("no")) { | ||
smok = 1.2; | ||
} | ||
// we could do the next part in one step, but it's broken down here... | ||
|
||
// the dot starts at the centre of our rectangle | ||
float cx = rectSize/2.0; | ||
float cy = rectSize/2.0; | ||
|
||
// we will use sin() and cos() to make our dot move, | ||
// but since sin() and cos() is from 0 to 1 | ||
// we need an offset to scale them by, | ||
// and scale it by their waist size, bigger waist = bigger movement | ||
float offset = rectSize/4 * wa; | ||
|
||
// x will be affected by height of the person | ||
cx += sin(pow(radians(frameCount*smok), hi)) * offset; | ||
// y will be affected by their weight | ||
cy += cos(pow(radians(frameCount*smok), we)) * offset; | ||
// draw the dot | ||
ellipse(cx, cy, 1, 1); | ||
// make sure to run popMatrix() after we finish drawing this box | ||
popMatrix(); | ||
// move to the next row | ||
row ++; | ||
// if we get to the of our data, we will just move to the next one | ||
row %= data.length(); | ||
} | ||
} | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
import hivis.common.*; | ||
import hivis.data.*; | ||
import hivis.data.reader.*; | ||
import hivis.data.view.*; | ||
|
||
// This skecth animates an abstract data visualisation | ||
|
||
// The source data | ||
DataTable data; | ||
|
||
|
||
// This is a flag to indicate that data is being (re)loaded and so the plot should not be drawn yet. | ||
boolean noDataLoaded = true; | ||
|
||
DataSeries heightSeries; | ||
DataSeries weightSeries; | ||
DataSeries waistSeries; | ||
DataSeries BMISeries; | ||
String[] smokerSeries; | ||
|
||
int alpha = 15; | ||
int[] randomRows; | ||
int numRows = 10; | ||
void setup() { | ||
size(1000, 700); | ||
colorMode(HSB, 360, 255, 255, 255); | ||
// make the background slightly off-white | ||
background(350); | ||
noFill(); | ||
strokeWeight(3); | ||
|
||
// load the data | ||
fileSelected(sketchFile("NCHS_dataset.xlsx")); | ||
} | ||
|
||
void fileSelected(File selection) { | ||
// Get data from spread sheet. The SpreadSheetReader will automatically update the DataTable it provides. | ||
println("loading data"); | ||
data = HV.loadSpreadSheet(HV.loadSSConfig().sourceFile(selection)); | ||
|
||
println("\nLoaded data:\n" + data); | ||
// populate our data series | ||
heightSeries = data.get("height"); | ||
weightSeries = data.get("weight"); | ||
waistSeries = data.get("waist"); | ||
BMISeries = data.get("bmi"); | ||
smokerSeries = data.get("smoker").asStringArray(); | ||
noDataLoaded = false; | ||
|
||
// start by selecting some random rows to draw | ||
randomRows = new int[numRows]; | ||
for (int i = 0; i < numRows; i++) { | ||
randomRows[i] = int(random(data.length())); | ||
} | ||
|
||
} | ||
|
||
|
||
|
||
|
||
void draw() { | ||
// blur and fade the background | ||
fill(360, alpha); | ||
noStroke(); | ||
rect(0, 0, width, height); | ||
filter(BLUR, .7); | ||
|
||
// update the rows from the data frame that we are visualising every 30 frames | ||
if (frameCount % 30 == 0) { | ||
println("updating rows"); | ||
updateRows(); | ||
} | ||
// draw the rows we have selected as a lines from the centre | ||
for (int i = 0; i < randomRows.length; i++) { | ||
int row = randomRows[i]; | ||
// starting point for lines | ||
float cx = width/2.0; | ||
float cy = height/2.0; | ||
// angle for this data point | ||
float r = row * 360/data.length(); | ||
randomSeed(row); | ||
// direction to draw the line | ||
float dx = sin(radians(r + random(-3.1, 3.1) * frameCount%90)) * 20; | ||
float dy = cos(radians(r)) * 20; | ||
// store the previous position of the line | ||
float px = 0; | ||
float py = 0; | ||
// select the colour for this line | ||
stroke(getColour(row, 50, 400)); | ||
|
||
// get the data from this row | ||
float we = weightSeries.getFloat(row); | ||
float wa = waistSeries.getFloat(row); | ||
float hi = heightSeries.getFloat(row); | ||
|
||
// create a counter for our while loop | ||
float count = 0; | ||
while (onScreen(cx, cy)) { | ||
// increase the count, to be used in the noise function | ||
count += (row % 9)/10 + .1; | ||
noise(px/10); | ||
// update the previous position | ||
px = cx; | ||
py = cy; | ||
// update the new position | ||
noiseSeed(int(we * count * 10)); | ||
cx += dx + noise(frameCount + count)/8 * we; | ||
noiseSeed(int(wa * hi * count * 5)); | ||
cy += dy + noise(frameCount + count)/8 * we; | ||
// draw circles if they are smoker | ||
if (isSmoker(row)) { | ||
ellipse(cx, cy, wa*10, hi*5); | ||
} | ||
// draw lines if not a smoker | ||
else { | ||
line(cx, cy, px, py); | ||
} | ||
} | ||
} | ||
} | ||
|
||
// returns true if the positions given are within the boundary of the screen | ||
boolean onScreen(float x, float y) { | ||
if (0 < x && x < width) { | ||
if (0 < y && y < height) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
// returns a colour based on the data for BMI | ||
color getColour(int r, int hue, int hueRange) { | ||
float min = BMISeries.min().getFloat(); | ||
float max = BMISeries.max().getFloat(); | ||
float bmi = (BMISeries.getFloat(r) - min)/max * hueRange + hue; | ||
color c = color(bmi, 200, 220, alpha * 2); | ||
return c; | ||
} | ||
|
||
// return whether the person smokes or not | ||
boolean isSmoker(int r) { | ||
if (smokerSeries[r].equals("no")) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
// update the data being drawn | ||
void updateRows() { | ||
for (int i = 0; i < randomRows.length-1; i++) { | ||
randomRows[i] = randomRows[i+1]; | ||
} | ||
randomRows[randomRows.length-1] = int(random(data.length())); | ||
} |