Commit 689fc597 authored by James Frink's avatar James Frink
Browse files

Update rapidmix bitalino example

parent c9e3bfb8
//
// BarChart.hpp
// RapidVisualizerOSC
//
// Created by James on 09/11/2017.
//
//
#ifndef BarChart_hpp
#define BarChart_hpp
#include <stdio.h>
#include "RealTimeGraph.hpp"
class BarChart : public RealTimeGraph
{
public:
BarChart ( GraphState* state ) : RealTimeGraph (state)
{
//
}
~BarChart ( void )
{
//
}
void updateRep ( void )
{
//
}
void drawSubGraph ( std::string subLabel, DataContainer<std::vector<double>>& data, ofRectangle subLabelRect )
{
double
minIn = 0,
minOut = 0,
maxOut = -subLabelRect.height,
startPosY = subLabelRect.height,
barSize = subLabelRect.width/data.labelData.size(),
separation = barSize/16,
halfSeparation = separation/2;
bool drawZeroSep = false;
if (data.minValue < 0)
{ // Add negative part
startPosY = subLabelRect.height/2;
minIn = -data.maxValue;
minOut = subLabelRect.height/2;
maxOut /= 2;
drawZeroSep = true;
}
for (uint32_t i = 0; i < data.labelData.size(); ++i)
{
double output = mapVals(data.labelData[i], minIn, data.maxValue, minOut, maxOut );
ofSetColor (graphColor);
ofFill();
ofDrawRectangle(subLabelRect.x + barSize * i + halfSeparation, subLabelRect.y + startPosY, barSize - separation, output );
}
if (drawZeroSep)
{
ofSetLineWidth(1.25);
ofSetColor (175,150,150);
ofDrawLine(subLabelRect.x, subLabelRect.y + startPosY,
subLabelRect.x + subLabelRect.width, subLabelRect.y + startPosY);
}
}
void update ( void )
{
//
}
};
#endif /* BarChart_hpp */
//
// Graph.hpp
// RapidVisualizerOSC
//
// Created by James on 09/11/2017.
//
//
#ifndef Graph_h
#define Graph_h
#include <string>
#include <vector>
#include <list>
#include "ofMain.h"
#include "ofxGui.h"
// TODO: add namespace, move funcs and struct to other header(s)
enum class TextAlignment {
LEFT,
CENTER,
RIGHT
};
static inline void drawTextLabel ( std::string label, ofVec2f position, ofColor labelBackgroundColor, ofColor stringColor, TextAlignment alignment, bool drawAbove )
{
uint32_t strLenPix = label.length()*8;
switch (alignment) {
case TextAlignment::LEFT:
// No exception
break;
case TextAlignment::CENTER:
position.x -= strLenPix / 2;
break;
case TextAlignment::RIGHT:
position.x -= strLenPix;
break;
default:
break;
}
ofSetColor (labelBackgroundColor);
ofRectangle bmpStringRect(position.x - 2,
position.y + ((drawAbove) ? -4 : 12) + 2,
strLenPix + 4, -12);
ofDrawRectangle(bmpStringRect);
ofSetColor (stringColor);
ofDrawBitmapString(label, position.x, position.y + ((drawAbove) ? -4 : 12));
}
static inline double mapVals ( double x, double in_min, double in_max, double out_min, double out_max )
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
template <typename T>
struct DataContainer {
T labelData;
double minValue = 0.0;
double maxValue = 1.0;
uint32_t iteratorPos = 0;
//ofColor graphColor;
void updateMinMax ( void )
{
auto mm = std::minmax_element(labelData.begin(), labelData.end());
double min = labelData[std::distance(labelData.begin(), mm.first)];
double max = labelData[std::distance(labelData.begin(), mm.second)];
if (min < minValue)
minValue = min;
if (max > maxValue)
maxValue = max;
if (fabs(min) > maxValue)
maxValue = fabs(min);
}
};
class Graph {
public:
enum graphLayout {
GRAPHS_STACKED,
GRAPHS_VERTICAL
};
struct GraphState {
std::string label;
graphLayout layout = graphLayout::GRAPHS_STACKED;
bool hasHistory = false;
ofRectangle positionAndSize;
uint32_t historySize;
};
Graph ( GraphState* state )
: state(state)
{
graphColor = ofColor(24, 219, 92);
textColor = ofColor(255, 157, 117);
}
virtual ~Graph ( void )
{
}
virtual void updateRep ( void ) = 0; // update representation
virtual void addData ( std::string subLabel, std::vector<double>& data ) = 0;
virtual void reset ( void ) = 0;
virtual void update ( void ) = 0;
virtual void draw ( void ) = 0;
virtual uint32_t getNumSubGraphs ( void ) const = 0;
protected:
GraphState *state = nullptr;
ofColor graphColor;
ofColor textColor;
};
#endif /* Graph_h */
//
// HistoryGraph.hpp
// RapidVisualizerOSC
//
// Created by James on 09/11/2017.
//
//
#ifndef HistoryGraph_h
#define HistoryGraph_h
#include "Graph.hpp"
#include <list>
class HistoryGraph : public Graph
{
public:
HistoryGraph ( GraphState* state )
: Graph(state)
{
}
~HistoryGraph ( void )
{
}
virtual void updateRep ( void ) = 0; // update representation
virtual void drawSubGraph ( std::string subLabel, DataContainer<std::list<double>>& data, ofRectangle subLabelrect ) = 0;
virtual void update ( void ) = 0;
void addData ( std::string subLabel, std::vector<double>& data )
{
if (data.size() < state->historySize)
{
//FIXME: can be sped up by using the result of this search instead of accessing by[] again
if ( subLabelData.find(subLabel) == subLabelData.end() ) {
// not found
DataContainer<std::list<double>> container;
container.labelData.resize(state->historySize);
std::fill(container.labelData.begin(), container.labelData.end(), 0.0);
subLabelData[subLabel] = container;
}
DataContainer<std::list<double>>& dataRef = subLabelData[subLabel];
list<double>& referencedList = dataRef.labelData;
while (referencedList.size() + data.size() >= state->historySize)
{
referencedList.pop_front();
}
for (int32_t i = data.size()-1; i >= 0; --i)
{
double val = data[i];
if (val < dataRef.minValue)
dataRef.minValue = val;
if (val > dataRef.maxValue)
dataRef.maxValue = val;
if (fabs(val) > dataRef.maxValue)
dataRef.maxValue = fabs(val);
referencedList.push_back(val);
}
}
}
void reset ( void )
{
subLabelData.clear();
}
void draw ( void )
{
uint32_t numElements = subLabelData.size();
uint16_t heightBetweenSubLabels = state->positionAndSize.height/numElements;
uint16_t subLabelY = 0;
ofSetColor (textColor);
ofDrawLine(state->positionAndSize.x, state->positionAndSize.y + heightBetweenSubLabels - 1.5,
state->positionAndSize.x + state->positionAndSize.width, state->positionAndSize.y + heightBetweenSubLabels - 1.5);
std::map<std::string, DataContainer<std::list<double>>>::iterator it;
for(it = subLabelData.begin(); it != subLabelData.end(); ++it)
{
std::string subLabel = it->first;
DataContainer<std::list<double>>& data = it->second;
drawSubGraph (subLabel, data, ofRectangle(state->positionAndSize.x,
state->positionAndSize.y + subLabelY + 3,
state->positionAndSize.width,
heightBetweenSubLabels - 6));
// Draw label and background
drawTextLabel(subLabel, ofVec2f(state->positionAndSize.x + state->positionAndSize.width,
state->positionAndSize.y + subLabelY),
ofColor(100, 100, 100), ofColor(textColor), TextAlignment::RIGHT, false);
// Draw max value
drawTextLabel(ofToString(data.maxValue),
ofVec2f(state->positionAndSize.x + state->positionAndSize.width/2,
state->positionAndSize.y + subLabelY),
ofColor(50, 50, 50), ofColor(255, 255, 255), TextAlignment::CENTER, false);
// Increment Y position
subLabelY += heightBetweenSubLabels;
// Draw min value
// Show actual min value?
drawTextLabel(ofToString((data.minValue < 0) ? -data.maxValue : 0),
ofVec2f(state->positionAndSize.x + state->positionAndSize.width/2,
state->positionAndSize.y + subLabelY),
ofColor(50, 50, 50), ofColor(255, 255, 255), TextAlignment::CENTER, true);
// Draw Line at bottom of graph
//ofSetLineWidth(2.0);
//ofSetColor (180,180,180);
/*ofDrawLine(state->positionAndSize.x, state->positionAndSize.y + subLabelY + 3,
state->positionAndSize.x + state->positionAndSize.width, state->positionAndSize.y + subLabelY + 3);*/
}
}
uint32_t getNumSubGraphs ( void ) const
{
return subLabelData.size();
}
protected:
std::map <std::string, DataContainer<std::list<double>>> subLabelData;
};
#endif /* HistoryGraph_h */
//
// LineGraph.hpp
// RapidVisualizerOSC
//
// Created by James on 09/11/2017.
//
//
#ifndef LineGraph_h
#define LineGraph_h
#include <stdio.h>
#include "RealTimeGraph.hpp"
class LineGraph : public RealTimeGraph
{
public:
LineGraph ( GraphState* state ) : RealTimeGraph (state)
{
//
}
~LineGraph ( void )
{
//
}
void updateRep ( void )
{
//
}
void drawSubGraph ( std::string subLabel, DataContainer<std::vector<double>>& data, ofRectangle subLabelRect )
{
double
minIn = 0,
minOut = 0,
maxOut = -subLabelRect.height,
startPosY = subLabelRect.height,
pointDistance = subLabelRect.width/data.labelData.size(),
separation = pointDistance/2;
//halfSeparation = separation/2;
bool drawZeroSep = false;
if (data.minValue < 0)
{ // Add negative part
startPosY = subLabelRect.height/2;
minIn = -data.maxValue;
minOut = subLabelRect.height/2;
maxOut /= 2;
drawZeroSep = true;
}
ofBeginShape();
ofFill();
ofVertex(subLabelRect.x, subLabelRect.y + startPosY);
double output = mapVals(data.labelData[0], minIn, data.maxValue, minOut, maxOut );
ofVertex(subLabelRect.x, subLabelRect.y + startPosY + output);
for (uint32_t i = 0; i < data.labelData.size(); ++i)
{
output = mapVals(data.labelData[i], minIn, data.maxValue, minOut, maxOut );
ofSetColor (graphColor);
ofVertex(subLabelRect.x + pointDistance * i + separation, subLabelRect.y + startPosY + output);
//ofDrawRectangle(subLabelRect.x + barSize * i + halfSeparation, subLabelRect.y + startPosY, barSize - separation, output );
}
output = mapVals(data.labelData[data.labelData.size()-1], minIn, data.maxValue, minOut, maxOut );
ofVertex(subLabelRect.x + subLabelRect.width, subLabelRect.y + startPosY + output);
ofVertex(subLabelRect.x + subLabelRect.width, subLabelRect.y + startPosY);
ofEndShape();
if (drawZeroSep)
{
ofSetLineWidth(1.25);
ofSetColor (175,150,150);
ofDrawLine(subLabelRect.x, subLabelRect.y + startPosY,
subLabelRect.x + subLabelRect.width, subLabelRect.y + startPosY);
}
}
void update ( void )
{
//
}
};
#endif /* LineGraph_h */
//
// LineGraphHistory.hpp
// RapidVisualizerOSC
//
// Created by James on 10/11/2017.
//
//
#ifndef LineGraphHistory_h
#define LineGraphHistory_h
#include <stdio.h>
#include "HistoryGraph.hpp"
class LineGraphHistory : public HistoryGraph
{
public:
LineGraphHistory ( GraphState* state ) : HistoryGraph (state)
{
//
}
~LineGraphHistory ( void )
{
//
}
void updateRep ( void )
{
//
}
void drawSubGraph ( std::string subLabel, DataContainer<std::list<double>>& data, ofRectangle subLabelRect )
{
double
minIn = 0,
minOut = 0,
maxOut = -subLabelRect.height,
startPosY = subLabelRect.height,
pointDistance = subLabelRect.width/data.labelData.size(),
separation = pointDistance/2;
//halfSeparation = separation/2;
bool drawZeroSep = false;
if (data.minValue < 0)
{ // Add negative part
startPosY = subLabelRect.height/2;
minIn = -data.maxValue;
minOut = subLabelRect.height/2;
maxOut /= 2;
drawZeroSep = true;
}
ofBeginShape();
ofFill();
ofVertex(subLabelRect.x, subLabelRect.y + startPosY);
double output = mapVals(data.labelData.front(), minIn, data.maxValue, minOut, maxOut );
ofVertex(subLabelRect.x, subLabelRect.y + startPosY + output);
uint32_t i = 0;
for (double d : data.labelData)
{
output = mapVals(d, minIn, data.maxValue, minOut, maxOut );
ofSetColor (graphColor);
ofVertex(subLabelRect.x + pointDistance * i + separation, subLabelRect.y + startPosY + output);
//ofDrawRectangle(subLabelRect.x + barSize * i + halfSeparation, subLabelRect.y + startPosY, barSize - separation, output );
++i;
}
output = mapVals(data.labelData.back(), minIn, data.maxValue, minOut, maxOut );
ofVertex(subLabelRect.x + subLabelRect.width, subLabelRect.y + startPosY + output);
ofVertex(subLabelRect.x + subLabelRect.width, subLabelRect.y + startPosY);
ofEndShape();
if (drawZeroSep)
{
ofSetLineWidth(1.25);
ofSetColor (175,150,150);
ofDrawLine(subLabelRect.x, subLabelRect.y + startPosY,
subLabelRect.x + subLabelRect.width, subLabelRect.y + startPosY);
}
}
void update ( void )
{
//
}
};
#endif /* LineGraphHistory_h */
//
// RapidVisualization.cpp
// RapidVisualizerOSC
//
// Created by James on 13/11/2017.
//
//
#include <stdio.h>
#include "RapidVisualization.hpp"
RapidVisualization::RapidVisualization ( void )
{
}
RapidVisualization::~RapidVisualization ( void )
{
std::map<std::string, RapidVisualizer*>::iterator it;
for(it = visualizers.begin(); it != visualizers.end(); ++it)
{
if (it->second)
delete it->second;
}
}
void RapidVisualization::setup ( ofRectangle posAndSize, uint32_t defaultHistorySize )
{
this->posAndSize = posAndSize;
this->defaultHistorySize = defaultHistorySize;
}
std::pair<std::string, std::string> RapidVisualization::getRoute(std::string& address)
{
std::pair<std::string, std::string> ret;
size_t delimPos = address.substr(1).find("/");
if (delimPos != std::string::npos)
{
delimPos += 1;
ret.first = address.substr(0, delimPos);
ret.second = address.substr(delimPos);
}
else
{
ret.first = address.substr(0, address.length());
ret.second = "/";
}
return ret;
}
void RapidVisualization::addData ( std::string address, std::vector<double>& data )
{
std::pair<std::string, std::string> route = getRoute(address);
if ( visualizers.find(route.first) == visualizers.end() ) {
RapidVisualizer* ptr = visualizers[route.first] = new RapidVisualizer(); // Add new graph
ptr->setup(route.first, RapidVisualizer::LINE_GRAPH_WITH_HISTORY, defaultHistorySize, Graph::GRAPHS_STACKED, false, ofRectangle(0,0,100,100));
}
RapidVisualizer* rapidVizPtr = visualizers[route.first];
rapidVizPtr->addData(address, data);
updateRep();
}
void RapidVisualization::addData ( std::string graphName, std::string subGraphName, std::vector<double>& data )
{
if ( visualizers.find(graphName) == visualizers.end() ) {
RapidVisualizer* ptr = visualizers[graphName] = new RapidVisualizer(); // Add new graph
ptr->setup(graphName, RapidVisualizer::LINE_GRAPH_WITH_HISTORY, defaultHistorySize, Graph::GRAPHS_STACKED, false, ofRectangle(0,0,100,100));
}
RapidVisualizer* rapidVizPtr = visualizers[graphName];
rapidVizPtr->addData(subGraphName, data);
updateRep();
}
void RapidVisualization::reset ( void )
{
std::map<std::string, RapidVisualizer*>::iterator it;
for(it = visualizers.begin(); it != visualizers.end(); ++it)
{
if (it->second)
delete it->second;
}