New graph in place

Also:
- Data from Spacebrew publishers now utilised in bar graph
- Added raage slider to adjust graph width - it now starts just before
the HUD graphic hole and ends about 80% of screen length.
- Graph height now adjustable - these are the values
This commit is contained in:
James Alliban
2014-01-09 17:07:26 +00:00
parent e2523e0b72
commit 6d50b2efae
49 changed files with 456 additions and 94 deletions
+101 -21
View File
@@ -31,11 +31,11 @@ void DataManager::setup()
void DataManager::setupSpacebrew()
{
string host = "54.200.6.109"; // Spacebrew::SPACEBREW_CLOUD; // "localhost";
string name = "CRITTICAL INFRASTRUCTURE";
string description = "Description goes here. Not sure why.";
string name = "CRITICAL INFRASTRUCTURE";
string description = "Description goes here. Not sure why. Let me know if you see this and tell me if you need it";
spacebrew.addSubscribe(publisher0Name, Spacebrew::TYPE_RANGE);
spacebrew.addSubscribe(publisher1Name, Spacebrew::TYPE_RANGE);
spacebrew.addSubscribe(publisher0Name, Spacebrew::TYPE_STRING);
spacebrew.addSubscribe(publisher1Name, Spacebrew::TYPE_STRING);
spacebrew.connect( host, name, description );
// listen to spacebrew events
@@ -45,24 +45,39 @@ void DataManager::setupSpacebrew()
void DataManager::update()
{
if (isPublisher0DataReceived && isPublisher1DataReceived)
{
isPublisher0DataReceived = false;
isPublisher1DataReceived = false;
// send a DataReceived event
app->scene.barGraph.addNewData(newData);
}
if (isDataSimulated)
{
if (ofGetFrameNum() % (int)simulationSpeed == 0)
{
//newData[0] = (int)(ofNoise(newData.size() * 0.04, ofGetFrameNum() * 0.03, ofGetElapsedTimef() * 0.1) * 1000);
newData[0] = (int)(ofNoise(newData.size() * perlinXScale, ofGetElapsedTimef() * perlinYScale) * 1000);
newData[1] = (int)(ofNoise((newData.size() + 500) * perlinXScale, (ofGetElapsedTimef() + 1000) * perlinYScale) * 1000);
app->scene.barGraph.addNewData(newData);
DataObject dataObject0;
dataObject0.info = "Some text to describe the data\nSome more text\nOne more line";
dataObject0.value = ofNoise(newData.size() * perlinXScale, ofGetElapsedTimef() * perlinYScale);
dataObject0.min = 0;
dataObject0.max = 1;
//printf("dataObject0.value = %f \n", dataObject0.value);
newData[0] = dataObject0;
DataObject dataObject1;
dataObject1.info = "Some descriptive text\nSome more\nLittle bit more\nLast one";
dataObject1.value = ofNoise((newData.size() + 500) * perlinXScale, (ofGetElapsedTimef() + 1000) * perlinYScale);
dataObject1.min = 0;
dataObject1.max = 1;
newData[1] = dataObject1;
app->scene.activeGraph->addNewData(newData);
}
}
else
{
if (isPublisher0DataReceived && isPublisher1DataReceived)
{
isPublisher0DataReceived = false;
isPublisher1DataReceived = false;
app->scene.activeGraph->addNewData(newData);
}
}
}
@@ -81,16 +96,81 @@ void DataManager::draw()
void DataManager::onMessage( Spacebrew::Message & m )
{
printf("new message - %s\n", m.valueString().c_str());
// split the formatted string into a list of different data types
vector<string> data = explode(",", m.valueString());
//for(int i = 0; i < data.size(); i++)
// cout <<i << " ["<< data[i] <<"] " <<endl;
// make a new data object and add the different data sources to it
DataObject dataObject;
for (int i = 0; i < data.size(); i++)
{
if (data[i].substr(0, 5) == "info:")
{
printf("- - info = %s\n", data[i].substr(5, -1).c_str());
dataObject.info = data[i].substr(5, -1).c_str();
}
if (data[i].substr(0, 6) == "value:")
{
printf("- - value = %s\n", data[i].substr(6, -1).c_str());
dataObject.value = ofToFloat(data[i].substr(6, -1).c_str());
}
if (data[i].substr(0, 4) == "min:")
{
printf("- - min = %s\n", data[i].substr(4, -1).c_str());
dataObject.min = ofToFloat(data[i].substr(4, -1).c_str());
}
if (data[i].substr(0, 5) == " max:")
{
printf("- - max = %s\n", data[i].substr(5, -1).c_str());
dataObject.max = ofToFloat(data[i].substr(5, -1).c_str());
}
}
if (m.name == publisher0Name)
{
isPublisher0DataReceived = true;
//printf("frameNum: %i, publisher0Name: %i \n", ofGetFrameNum(), m.valueRange());
newData[0] = m.valueRange();
newData[0] = dataObject;
}
else if (m.name == publisher1Name)
{
isPublisher1DataReceived = true;
//printf("frameNum: %i, publisher1Name: %i \n", ofGetFrameNum(), m.valueRange());
newData[1] = m.valueRange();
newData[1] = dataObject;
}
}
vector<string> DataManager::explode(const string &delimiter, const string &str)
{
vector<string> arr;
int strleng = str.length();
int delleng = delimiter.length();
if (delleng==0)
return arr;//no change
int i=0;
int k=0;
while( i<strleng )
{
int j=0;
while (i+j<strleng && j<delleng && str[i+j]==delimiter[j])
j++;
if (j==delleng)//found delimiter
{
arr.push_back( str.substr(k, i-k) );
i+=delleng;
k=i;
}
else
{
i++;
}
}
arr.push_back( str.substr(k, i-k) );
return arr;
}
+10 -1
View File
@@ -9,6 +9,14 @@
class testApp;
struct DataObject
{
string info;
float value;
float min;
float max;
};
class DataManager
{
@@ -17,6 +25,7 @@ class DataManager
void setupSpacebrew();
void update();
void draw();
vector<string> explode( const string &delimiter, const string &str);
testApp* app;
@@ -28,7 +37,7 @@ class DataManager
string publisher0Name;
string publisher1Name;
vector<int> newData;
vector<DataObject> newData;
bool isPublisher0DataReceived;
bool isPublisher1DataReceived;
+65 -3
View File
@@ -8,6 +8,7 @@
#include "GUI.h"
#include "testApp.h"
#include "AbstractGraph.h"
void GUI::setup()
{
@@ -17,8 +18,9 @@ void GUI::setup()
dim = 8;
addKeyboardShortcutsGUI();
//addGraphAnimationGUI();
addGraphGlobalGUI();
addBarGraphDesignGUI();
addBodyGraphDesignGUI();
addGraphSimulationGUI();
addBackgroundGUI();
addHUDTextGUI();
@@ -49,15 +51,27 @@ void GUI::addKeyboardShortcutsGUI()
}
void GUI::addGraphAnimationGUI()
void GUI::addGraphGlobalGUI()
{
string title = "GRAPH ANIMATION";
string title = "GRAPH GLOBAL";
ofxUICanvas* gui = getNewGUI(title);
vector<string> graphNames;
graphNames.push_back("Bar graph");
graphNames.push_back("Solid Body graph");
graphNames.push_back("Line fade graph");
gui->addRadio("Graph Selection", graphNames, OFX_UI_ORIENTATION_VERTICAL, dim*2, dim*2);
gui->addSpacer(length, 1);
gui->addRangeSlider("Graph X begin/end (percent)", 0, 1, &AbstractGraph::minGraphPercent, &AbstractGraph::maxGraphPercent, length, dim);
ofAddListener(gui->newGUIEvent, this, &GUI::graphGlobalGUIEvent);
finaliseCanvas(gui, true);
}
void GUI::addBarGraphDesignGUI()
{
string title = "BAR GRAPH DESIGN";
@@ -65,6 +79,8 @@ void GUI::addBarGraphDesignGUI()
gui->addSlider("Graph Item X Gap", 5, 50, &app->scene.barGraph.graphItemXGap, length, dim);
gui->addSlider("BarWidth", 2, 50, &app->scene.barGraph.barWidth, length, dim);
gui->addSlider("Graph Height Max", 100, 1000, &app->scene.barGraph.graphHeightMax, length, dim);
gui->addSlider("Data0 red", 0, 255, &app->scene.barGraph.col0[0], length, dim);
gui->addSlider("Data0 green", 0, 255, &app->scene.barGraph.col0[1], length, dim);
@@ -79,6 +95,27 @@ void GUI::addBarGraphDesignGUI()
}
void GUI::addBodyGraphDesignGUI()
{
string title = "BODY GRAPH DESIGN";
ofxUICanvas* gui = getNewGUI(title);
gui->addSlider("Graph Item X Gap", 5, 50, &app->scene.bodyGraph.graphItemXGap, length, dim);
gui->addSlider("Line width", 1, 50, &app->scene.bodyGraph.lineWidth, length, dim);
gui->addSlider("Data0 red", 0, 255, &app->scene.bodyGraph.col0[0], length, dim);
gui->addSlider("Data0 green", 0, 255, &app->scene.bodyGraph.col0[1], length, dim);
gui->addSlider("Data0 blue", 0, 255, &app->scene.bodyGraph.col0[2], length, dim);
gui->addSlider("Data0 alpha", 0, 255, &app->scene.bodyGraph.col0[3], length, dim);
gui->addSlider("Data1 red", 0, 255, &app->scene.bodyGraph.col1[0], length, dim);
gui->addSlider("Data1 green", 0, 255, &app->scene.bodyGraph.col1[1], length, dim);
gui->addSlider("Data1 blue", 0, 255, &app->scene.bodyGraph.col1[2], length, dim);
gui->addSlider("Data1 alpha", 0, 255, &app->scene.bodyGraph.col1[3], length, dim);
finaliseCanvas(gui, true);
}
void GUI::addGraphSimulationGUI()
{
string title = "SIMULATION";
@@ -177,6 +214,31 @@ void GUI::draw()
void GUI::graphGlobalGUIEvent(ofxUIEventArgs &e)
{
string name = e.widget->getName();
ofxUIToggle *toggle = (ofxUIToggle *) e.widget;
if (name == "Bar graph")
{
//ofxUIToggle *toggle = (ofxUIToggle *) e.widget;
if (toggle->getValue()) app->scene.activeGraph = &app->scene.barGraph;
}
else if (name == "Solid Body graph")
{
printf("------------------- Solid Body graph\n");
if (toggle->getValue()) app->scene.activeGraph = &app->scene.bodyGraph;
}
else if (name == "Line fade graph")
{
printf("------------------- Line fade graph\n");
//app->scene.activeGraph = &app->scene.lineGraph;
}
}
void GUI::variousGUIEvent(ofxUIEventArgs &e)
{
string name = e.widget->getName();
+3 -1
View File
@@ -20,13 +20,15 @@ public:
virtual bool getVisible();
void addKeyboardShortcutsGUI();
void addGraphAnimationGUI();
void addGraphGlobalGUI();
void addBarGraphDesignGUI();
void addBodyGraphDesignGUI();
void addGraphSimulationGUI();
void addBackgroundGUI();
void addHUDTextGUI();
void addVariousGUI();
void graphGlobalGUIEvent(ofxUIEventArgs &e);
void variousGUIEvent(ofxUIEventArgs &e);
virtual void update();
+15 -11
View File
@@ -2,24 +2,27 @@
// TODO
// ====
// - Make graph system with 3 simple (for now) but different graphs that can be interchanged
// - Add image to background and create a mask
// - Use a shader to adjust image brightness/contrast and colour
// -
// - Add to config
// - - IP address
// - - Host name
// - - App name
//
//
//
// - Map graph min/max
// - Stop graph going beyond 80% of the screen
// - Add separate colour sliders for body graph
// - In body graph use one long line instead of loads of lines
// - Make 2nd graph - body
// - Make 3rd graph - separate fade
// - Add colour boxes to text - DON'T use graph colours - add sliders
// - Crosshairs in HUD
// - Add video camera feed
// - Create text parsing system
// - Tidy up the first graph
// - Create animation system
// - Make system to slow down data - The screen should show 15-20 minutes worth of data
// - Create a single config file to be loaded from online location. It will contain IP address and host name
//
//
//
//
// NOTES
// =====
// - Each publisher should have a unique number. There should be a config file kept in c:/ containing a unique ID
// - Check that the local data sources always have the same amount of data.
@@ -33,6 +36,7 @@ void testApp::setup()
ofEnableSmoothing();
ofSeedRandom(ofRandom(23243));
ofSetFullscreen(true);
ofSetVerticalSync(true);
dataManager.setup();
scene.setup();
+6 -9
View File
@@ -14,21 +14,18 @@ void Scene::setup()
bgImg.loadImage("images/tanks.jpg");
rgbShader.load("shaders/RGBShader");
barGraph.setup();
bodyGraph.setup();
//activeGraph = &barGraph;
text.loadFont("fonts/mplus-1c-regular.ttf", 8);
//text.setLineLength(ofGetWidth() - margin * 2);
xMargin = 500;
yMargin = 400;
lineLength = 200;
//text.loadFont("fonts/Roboto-Regular.ttf", 8);
text.loadFont("fonts/Roboto-Light.ttf", 8);
}
void Scene::update()
{
barGraph.update();
activeGraph->update();
text.setLineLength(lineLength);
text.setLineSpacing(lineSpacing);
@@ -40,7 +37,7 @@ void Scene::update()
void Scene::draw()
{
drawVideo();
barGraph.draw();
activeGraph->draw();
drawHUDBG();
drawHUDCopy();
}
+5 -1
View File
@@ -10,6 +10,7 @@
#include "ofMain.h"
#include "BarGraph.h"
#include "BodyGraph.h"
#include "ofxFTGL.h"
class testApp;
@@ -25,12 +26,15 @@ public:
void drawHUDCopy();
void drawTextBox(string copy, string align);
void keyPressed(int key);
BarGraph barGraph;
BodyGraph bodyGraph;
ofShader rgbShader;
ofImage bgImg;
ofxFTGLSimpleLayout text;
AbstractGraph* activeGraph;
// video image vars
@@ -8,6 +8,8 @@
#include "AbstractGraph.h"
float AbstractGraph::minGraphPercent;
float AbstractGraph::maxGraphPercent;
void AbstractGraph::setup()
{
@@ -27,14 +29,14 @@ void AbstractGraph::draw()
}
void AbstractGraph::addNewData(vector<int> newData)
void AbstractGraph::addNewData(vector<DataObject> newData)
{
publisher0Data.push_back(newData[0]);
publisher1Data.push_back(newData[1]);
maxData = ofGetWidth() / graphItemXGap;
maxData = (ofGetWidth() / graphItemXGap) * (AbstractGraph::maxGraphPercent - AbstractGraph::minGraphPercent);
if (publisher0Data.size() > maxData && publisher0Data.size() > maxData)
while (publisher0Data.size() > maxData && publisher0Data.size() > maxData)
{
publisher0Data.erase(publisher0Data.begin());
publisher1Data.erase(publisher1Data.begin());
@@ -9,22 +9,25 @@
#pragma once
#include "ofMain.h"
#include "DataManager.h"
class AbstractGraph
{
public:
void setup();
void update();
void draw();
virtual void addNewData(vector<int> newData);
virtual void update();
virtual void draw();
virtual void addNewData(vector<DataObject> newData);
vector<int> publisher0Data;
vector<int> publisher1Data;
vector<DataObject> publisher0Data;
vector<DataObject> publisher1Data;
int maxData; // calculated from graphWidth and graphItemXGap
static float minGraphPercent;
static float maxGraphPercent;
float graphItemXGap;
ofPoint startPnt;
int graphWidth;
int graphHeight;
float graphHeightMax;
};
+34 -20
View File
@@ -1,14 +1,5 @@
//
// gui->cpp
// emptyExample
//
// Created by James Alliban on 25/06/2013.
//
//
#include "BarGraph.h"
void BarGraph::setup()
{
AbstractGraph::setup();
@@ -26,18 +17,20 @@ void BarGraph::update()
void BarGraph::draw()
{
//printf("BarGraph::draw() - graphItemXGap = %f \n", graphItemXGap);
if (publisher0Data.size() > 1)
{
for (int i = 0; i < publisher0Data.size() - 1; i++)
{
if (i < publisher0Data.size() - 2)
{
ofPushStyle();
ofSetColor(0, 0, 0);
ofLine(i * graphItemXGap, publisher0Data[i], (i + 1) * graphItemXGap, publisher0Data[i + 1]);
ofSetColor(0, 0, 0);
ofLine(i * graphItemXGap, publisher1Data[i], (i + 1) * graphItemXGap, publisher1Data[i + 1]);
ofPopStyle();
//ofPushStyle();
//ofSetColor(0, 0, 0);
//ofLine(i * graphItemXGap, publisher0Data[i], (i + 1) * graphItemXGap, publisher0Data[i + 1]);
//ofSetColor(0, 0, 0);
//ofLine(i * graphItemXGap, publisher1Data[i], (i + 1) * graphItemXGap, publisher1Data[i + 1]);
//ofPopStyle();
}
}
@@ -50,16 +43,37 @@ void BarGraph::draw()
//ofCircle(i * graphItemXGap, publisher1Data[i], 5);
//ofPopStyle();
}
float xOffset = ofGetWidth() * AbstractGraph::minGraphPercent;
float outputMin = (ofGetHeight() * 0.5) - graphHeightMax;
float outputMax = (ofGetHeight() * 0.5) + graphHeightMax;
for (int i = 0; i < publisher0Data.size() - 1; i++)
{
ofPushStyle();
ofMesh bar;
bar.addVertex(ofVec3f(i * graphItemXGap - (barWidth * 0.5), publisher0Data[i], 0));
bar.addVertex(ofVec3f(i * graphItemXGap - (barWidth * 0.5) + barWidth, publisher0Data[i], 0));
bar.addVertex(ofVec3f(i * graphItemXGap - (barWidth * 0.5), publisher1Data[i], 0));
bar.addVertex(ofVec3f(i * graphItemXGap - (barWidth * 0.5) + barWidth, publisher1Data[i], 0));
float rectTLX = i * graphItemXGap - (barWidth * 0.5) + xOffset;
float rectTLY = ofMap(publisher0Data[i].value, publisher0Data[i].min, publisher0Data[i].max, outputMin, outputMax);
float rectTRX = i * graphItemXGap - (barWidth * 0.5) + barWidth + xOffset;
float rectTRY = ofMap(publisher0Data[i].value, publisher0Data[i].min, publisher0Data[i].max, outputMin, outputMax);
float rectBLX = i * graphItemXGap - (barWidth * 0.5) + xOffset;
float rectBLY = ofMap(publisher1Data[i].value, publisher1Data[i].min, publisher1Data[i].max, outputMin, outputMax);
float rectBRX = i * graphItemXGap - (barWidth * 0.5) + barWidth + xOffset;
float rectBRY = ofMap(publisher1Data[i].value, publisher1Data[i].min, publisher1Data[i].max, outputMin, outputMax);
//printf("val:%f, min:%f, max:%f - new val:%f \n", publisher0Data[i].value, publisher0Data[i].min, publisher0Data[i].max, rectTLY);
//printf("val:%f, min:%f, max:%f - new val:%f \n", publisher1Data[i].value, publisher1Data[i].min, publisher1Data[i].max, rectBLY);
bar.addVertex(ofVec3f(rectTLX, rectTLY, 0));
bar.addVertex(ofVec3f(rectTRX, rectTRY, 0));
bar.addVertex(ofVec3f(rectBLX, rectBLY, 0));
bar.addVertex(ofVec3f(rectBRX, rectBRY, 0));
bar.addIndex(0);
bar.addIndex(1);
bar.addIndex(3);
@@ -84,7 +98,7 @@ void BarGraph::draw()
void BarGraph::addNewData(vector<int> newData)
void BarGraph::addNewData(vector<DataObject> newData)
{
AbstractGraph::addNewData(newData);
}
+4 -11
View File
@@ -1,11 +1,3 @@
//
// BarGraph.h
// emptyExample
//
// Created by James Alliban on 25/06/2013.
//
//
#pragma once
#include "ofMain.h"
@@ -15,13 +7,14 @@ class BarGraph : public AbstractGraph
{
public:
void setup();
void update();
void draw();
virtual void addNewData(vector<int> newData);
virtual void update();
virtual void draw();
virtual void addNewData(vector<DataObject> newData);
float barWidth;
float col0[4];
float col1[4];
};
@@ -0,0 +1,73 @@
//
// Created by James Alliban on 08/01/2014.
//
//
#include "BodyGraph.h"
void BodyGraph::setup()
{
AbstractGraph::setup();
}
void BodyGraph::update()
{
// if (ofGetFrameNum() % 30 == 0)
// printf("publisher0Data.size():%i \n", publisher0Data.size());
}
void BodyGraph::draw()
{
if (publisher0Data.size() > 1)
{
//for (int i = 0; i < publisher0Data.size() - 1; i++)
//{
// ofPushStyle();
// ofSetColor(255, 0, 0);
// ofCircle(i * graphItemXGap, publisher0Data[i], 5);
// ofSetColor(0, 255, 0);
// ofCircle(i * graphItemXGap, publisher1Data[i], 5);
// ofPopStyle();
//}
ofMesh body;
body.setMode(OF_PRIMITIVE_TRIANGLE_STRIP);
for (int i = 0; i < publisher0Data.size() - 1; i++)
{
//body.addVertex(ofVec3f(i * graphItemXGap, publisher0Data[i], 0));
//body.addVertex(ofVec3f(i * graphItemXGap, publisher1Data[i], 0));
body.addColor(ofColor(col0[0],col0[1],col0[2], col0[3]));
body.addColor(ofColor(col1[0],col1[1],col1[2], col1[3]));
}
body.drawFaces();
for (int i = 0; i < publisher0Data.size() - 1; i++)
{
if (i < publisher0Data.size() - 2)
{
//ofPushStyle();
//ofSetLineWidth(lineWidth);
//ofSetColor(col0[0],col0[1],col0[2], 255);
//ofLine(i * graphItemXGap, publisher0Data[i], (i + 1) * graphItemXGap, publisher0Data[i + 1]);
//ofSetColor(col1[0],col1[1],col1[2], 255);
//ofLine(i * graphItemXGap, publisher1Data[i], (i + 1) * graphItemXGap, publisher1Data[i + 1]);
//ofPopStyle();
}
}
}
}
void BodyGraph::addNewData(vector<DataObject> newData)
{
AbstractGraph::addNewData(newData);
}
@@ -0,0 +1,20 @@
#pragma once
#include "ofMain.h"
#include "AbstractGraph.h"
class BodyGraph : public AbstractGraph
{
public:
void setup();
virtual void update();
virtual void draw();
virtual void addNewData(vector<DataObject> newData);
float barWidth;
float lineWidth;
float col0[4];
float col1[4];
};