Ver Fonte

Complete overhaul of the plugin.

Juan Carlos Carvajal Bermúdez há 8 anos atrás
pai
commit
c0916ac6ed
2 ficheiros alterados com 314 adições e 230 exclusões
  1. 248 2
      src/ofxPlotter.cpp
  2. 66 228
      src/ofxPlotter.h

+ 248 - 2
src/ofxPlotter.cpp

@@ -1,10 +1,256 @@
 //
 //  ofxPlotter.cpp
 //
-//  Created by zebra on 06/05/16.
+//  Created by Juan Carlos Carvajal B.
+//  juan-carlos.info
+//
+//  Based on the plugin by zebra on 06/05/16.
 //
 //
 
 #include "ofxPlotter.h"
 
-int ofxPlotter::windowSize;
+
+ofxPlotter::dataCollection::dataCollection() :  plotColor ( ofColor(0) ) ,
+                                                autoRange ( True ),
+                                                drawOverlay ( True ),
+                                                drawInfo    ( True ),
+                                                plotLength ( 400 ),
+                                                maxValue ( 0 ),
+                                                minValue ( 0 ) {
+
+    records.clear();
+    singleValue tmpValue;
+    records.assign( plotLength, tmpValue );
+
+}
+
+void ofxPlotter::dataCollection::setPlotLength (int plotLength){
+    this->plotLength = plotLength;
+    records.clear();
+    singleValue tmpValue;
+    records.assign( plotLength, tmpValue );
+}
+
+
+ofxPlotter::ofxPlotter() {
+
+    ofAddListener(ofEvents().update, this, &::ofxPlotter::update);
+
+}
+
+void ofxPlotter::updateHistory() {
+
+    map<string, dataCollection>::iterator it;
+
+    for ( it = plotData.begin(); it != plotData.end(); it++) {
+
+        dataCollection *itDataCollection = &(it->second);
+
+        itDataCollection->records.push_back( itDataCollection->currentValue );
+
+        if ( int( itDataCollection->records.size() ) > itDataCollection->plotLength ){
+
+            itDataCollection->records.erase( itDataCollection->records.begin() );
+
+        }
+
+    }
+
+}
+
+
+void ofxPlotter::drawPlot(string plot){
+
+    drawPlot (plot, 0, 0, ofGetHeight(), ofGetWidth() ) ;
+
+}
+
+void ofxPlotter::drawPlot(string plot, int x, int y, int width, int height) {
+
+    vector<singleValue>* records =  &(plotData[plot].records);
+
+    float sum = 0;
+    float & max = plotData[plot].maxValue;
+    float & min = plotData[plot].minValue;
+
+    // Measuring the function scale
+    if ( plotData[plot].autoRange ) {
+
+        for ( unsigned long i = 0; i < records->size(); i++ ) {
+            float value = (*records)[i].getF();
+            sum += value;
+            if (value > max) max = value;
+            if (value < min) min = value;
+        }
+
+    }
+
+    float stepWidth = width / records->size();
+
+    ofPushMatrix();
+    ofPushStyle();
+        ofTranslate(x, y);
+
+        ofPoint p, p2;
+        for ( int j = 0; j < records->size(); j++) {
+
+            float mappedY = 1 - ofMap( (*records)[j].getF(), min, max, 0, 1);
+            float mappedX = ofMap(j, 0,records->size(),0, width );
+
+            p = ofPoint( mappedX , mappedY * float(height) );
+
+            ofSetColor( plotData[plot].plotColor );
+            ofSetLineWidth(2);
+            if (j != 0) ofDrawLine(p2, p);
+
+            p2 = p;
+
+        }
+
+        if ( plotData[plot].drawOverlay) {
+            drawOverlay(plot, x, y, width, height);
+        }
+
+        if ( plotData[plot].drawInfo) {
+            drawInfo(plot, x, y, width, height);
+        }
+
+        if ( plotData[plot].drawGuidelines) {
+            drawGuidelines(plot, x, y, width, height);
+        }
+    ofPopMatrix();
+    ofPopStyle();
+}
+
+/*
+ *
+ *  Draw all the plots contained in the map in a vertical layout
+ *
+ *
+*/
+
+
+void ofxPlotter::drawAllVertical() {
+
+    drawAllVertical(0, 0, ofGetHeight(), ofGetWidth() );
+
+}
+
+void ofxPlotter::drawAllVertical(float x, float y, float width, float height) {
+
+    map<string, dataCollection>::iterator it;
+
+    int plotDataSize = plotData.size();
+    int i = 0;
+
+    float dy = height / plotDataSize + 1;
+
+    for ( it = plotData.begin(); it != plotData.end(); it++) {
+
+        drawPlot(it->first, x, dy * i , width, dy);
+        i++;
+
+    }
+
+}
+
+/*
+ *
+ *  Draw all the plots contained in the map in a horizontal layout
+ *
+ *
+*/
+
+
+void ofxPlotter::drawAllHorizontal() {
+
+    drawAllHorizontal(0, 0, ofGetHeight(), ofGetWidth() );
+
+}
+
+void ofxPlotter::drawAllHorizontal(float x, float y, float width, float height) {
+
+    map<string, dataCollection>::iterator it;
+
+    int plotDataSize = plotData.size();
+    int i = 0;
+
+    float dx = width  / plotDataSize + 1;
+    // float dy = height / plotDataSize + 1;
+
+    for ( it = plotData.begin(); it != plotData.end(); it++) {
+
+        drawPlot(it->first, dx * i, y, dx, height);
+        i++;
+
+    }
+
+}
+
+/*
+ *
+ *  *** DRAW EXTRAS ***
+ *
+ *
+*/
+
+
+void ofxPlotter::drawOverlay(string plot, float x, float y, float width, float height) {
+
+    vector<singleValue>* records =  &(plotData[plot].records);
+
+    if (!ofRectangle(x, y, width, height).inside(ofGetMouseX(), ofGetMouseY())) return;
+
+    float mx = (ofGetMouseX()  - x);
+    float my = (ofGetMouseY()  - y);
+
+    //ofSetColor(128);
+
+    int position = int ( ofMap( mx, 0, width, 0,records->size() )  );
+    string tmpString = ofToString( (*records)[position].getF() );
+    ofDrawBitmapString( tmpString, mx, my);
+
+}
+
+void ofxPlotter::drawGuidelines(string plot, float x, float y, float width, float height) {
+
+    vector<float>* guidelines =  &(plotData[plot].guidelines);
+
+    if ( !guidelines->size() ) return;
+
+    float & max = plotData[plot].maxValue;
+    float & min = plotData[plot].minValue;
+
+    for (vector<float>::iterator it = guidelines->begin(); it != guidelines->end(); it++) {
+
+        float mappedY = ofMap( *it, min, max, 0, 1) * float(height);
+        ofDrawLine(0, mappedY, width, mappedY );
+
+    }
+
+}
+
+
+void ofxPlotter::drawInfo (string plot, float x, float y, float width, float height) {
+
+    dataCollection *iDataCollection = &(plotData[plot]);
+
+    ofSetColor(iDataCollection->plotColor);
+
+    // Plot name
+    // ofDrawRectangle(width - plot.length() * 8, yspace / 2 - 12, plot.length() * 8, 15);
+    ofDrawBitmapString( plot , width - plot.length() * 8, height / 2);
+
+    // Max value
+    string maxValue = ofToString ( iDataCollection->maxValue );
+    //ofDrawRectangle(0, 0, maxValue.length() * 8, 15);
+    ofDrawBitmapString( maxValue, 0, 12 );
+
+    // Min value
+    string minValue = ofToString ( iDataCollection->minValue );
+    //ofDrawRectangle(0, height - 12, minValue.length() * 8, 15);
+    ofDrawBitmapString(minValue, 0, height);
+
+}
+

+ 66 - 228
src/ofxPlotter.h

@@ -1,8 +1,10 @@
 //
-//  ofxPlotter.h
-//  Plotter example
+//  ofxPlotter.cpp
 //
-//  Created by zebra on 06/05/16.
+//  Created by Juan Carlos Carvajal B.
+//  juan-carlos.info
+//
+//  Based on the plugin by zebra on 06/05/16.
 //
 //
 
@@ -15,16 +17,18 @@
 
 #include "ofMain.h"
 
+using namespace std;
+
 
 class ofxPlotter {
     
-    class Value {
     public:
-        float inner_value;
-        float inner_value_filtered;
-        
-        Value() { }
-        
+
+    struct singleValue {
+    public:
+
+        singleValue() : inner_value (0) { }
+
         // Float righthand
         void operator<<(float righthand) {
             inner_value = righthand;
@@ -34,242 +38,76 @@ class ofxPlotter {
         void operator<<(int righthand) {
             inner_value = righthand;
         }
-        
-        
-        int getI() {
-            return inner_value;
-        }
 
-        float getF() {
-            return (float)inner_value;
+        void setCurrentValue(float righthand) {
+            inner_value = righthand;
         }
-        
-        float getFiltered(float filter_amount = 0.2) {
-            inner_value_filtered = inner_value_filtered * filter_amount + inner_value * filter_amount;
-            return inner_value_filtered;
+
+        void setCurrentValue(int righthand) {
+            inner_value = float(righthand);
         }
-        
-    };
 
-    
-    static int windowSize;
-    static float windowLength;
-    
-public:
-    ofxPlotter() {
-        windowSize = 300;
-        ofAddListener(ofEvents().update, this, &::ofxPlotter::update);
-    }
-    
-    void updateHistory() {
-        for (std::map<std::string, ofxPlotter::Value>::iterator i = values.begin(); i != values.end(); i++) {
-            history[i->first].push_back(i->second);
-            if (history[i->first].size() > windowSize) {
-                history[i->first].erase(history[i->first].begin());
-            }
-            if (accents[i->first].size() > windowSize) {
-                accents[i->first].erase(accents[i->first].begin());
-            }
-            accents[i->first].push_back(0);
+        // void setNullValue() { inner_value = NAN; }
+
+        float getF() {
+            return inner_value;
         }
-    }
-    
-    void addAccent(std::string index) {
-        accents[index][accents[index].size() - 1] = 5;
-    }
-    
-    void addGuideline(std::string index, float guideline) {
-        guidelines[index] = guideline;
-    }
-    
-    void update(ofEventArgs & args) {
-        updateHistory();
-    }
-    
-    Value& operator[](std::string righthand) {
-        return (Value&)values[righthand];
-        
-    }
-    
-    float getHistoryFor(std::string index, int step) {
-        return history[index][history[index].size() - 1 - step].getF();
-    }
-    
-    void drawOverlay(float x, float y, float width, float height) {
-        int graphCount = values.size();
-        if (!ofRectangle(x, y, width, height).inside(ofGetMouseX(), ofGetMouseY())) return;
-        float mx = (ofGetMouseX() - x) / width;
-        float my = (ofGetMouseY() - y) / height;
-        int yspace = (float)height / graphCount;
-        
-        int index = (my / (1 / (float)graphCount));
-        
-        ofSetColor(255);
+
+        float inner_value;
         
-        int counter = 0;
-        for (std::map<std::string, ofxPlotter::Value>::iterator i = values.begin(); i != values.end(); i++) {
-            if (index == counter) {
-                float position = (mx * history[i->first].size());
-                ofDrawBitmapStringHighlight(ofToString(history[i->first][position].getF()), x + mx * width, y + my * height);
-            }
-            counter++;
-        }
-    }
+    };
 
-	void drawCustomPlot(string plot, int x, int y,
-		int width, int height) {
-		std::vector<ofxPlotter::Value>* historyValues = &history[plot];
+    struct dataCollection{
+
+        dataCollection(); // : plotColor ( ofColor(0) ) , autoRange ( True ), drawOverlay ( False ), plotLength ( 300 )  {  }
+        ofColor             plotColor;
+        singleValue         currentValue;
+        vector<singleValue> records;
+        vector<float>       guidelines;
+        int    plotLength;
+        float  maxValue;
+        float  minValue;
+        bool   autoRange;
+        bool   drawOverlay;
+        bool   drawInfo;
+        bool   drawGuidelines;
+
+        void setCurrentValue (int   currentValue)   { this->currentValue.setCurrentValue(currentValue); }
+        void setCurrentValue (float currentValue)   { this->currentValue.setCurrentValue(currentValue); }
+        void setMinMaxValue  (float maxValue, float minValue )   { this->maxValue = maxValue; this->minValue = minValue; autoRange = false; }
+        void setPlotLength   (int   plotLength); //      { this->plotLength = plotLength; }
+        int getplotLength() { return plotLength; }
+        void setColor(ofColor plotColor) { this->plotColor = plotColor; }
+        void addGuideline(float guideline) { guidelines.push_back(guideline); }
 
-		// Measuring the function scale
-		float sum = 0;
-		float max = -999999999;
-		float min = 999999999;
-		for (int i = 0; i < historyValues->size(); i++) {
-			float value = (*historyValues).operator[](i).getF();
-			sum += value;
-			if (value > max) max = value;
-			if (value < min) min = value;
-		}
-		float median = sum / historyValues->size();
+    };
 
-		float multiplier = 1 / (max - min);
+    ofxPlotter();
+    ofxPlotter( int plotLength );
 
-		float stepWidth = width / historyValues->size();
-		ofPushMatrix();
-			ofTranslate(x, y);
+    void update(ofEventArgs & args) { updateHistory(); }
+    void updateHistory();
 
-			ofPoint p, p2;
-			for (int j = 0; j < (*historyValues).size(); j++) {
+    void drawAllVertical();
+    void drawAllVertical(float x, float y, float width, float height);
 
-				float mappedPoint = 1 - ofMap((*historyValues)[j].getF(), min, max, 0, 1);
+    void drawAllHorizontal();
+    void drawAllHorizontal(float x, float y, float width, float height);
 
-				p = ofPoint(j * stepWidth,
-					mappedPoint * (float)height);
-				ofSetLineWidth(2);
-				if (j != 0) ofLine(p2, p);
-				p2 = p;
+    void drawPlot(string plot);
+    void drawPlot(string plot, int x, int y, int width, int height);
 
-			}
-		ofPopMatrix();
-	}
-    
-    void draw(float x, float y, float width, float height, int verticalLines = 16) {
-        int graphCount = values.size();
-        int yspace = (float)height / graphCount;
-        int index = 0;
-        float colorspaceWidth = 255. / (float)graphCount;
-        for (std::map<std::string, ofxPlotter::Value>::iterator i = values.begin(); i != values.end(); i++) {
-            std::vector<ofxPlotter::Value>* historyValues = &history[i->first];
-            
-            ofColor plotColor = ofColor::fromHsb((index * colorspaceWidth), 255, 150, 255);
-            
-            // Measuring the function scale
-            float sum = 0;
-            float max = -999999999;
-            float min = 999999999;
-            for (int i = 0; i < historyValues->size(); i++) {
-                float value = (*historyValues).operator[](i).getF();
-                sum += value;
-                if (value > max) max = value;
-                if (value < min) min = value;
-            }
-            float median = sum / historyValues->size();
-            
-            float multiplier = 1 / (max - min);
-            
-            float stepWidth = width / historyValues->size();
-            ofPushMatrix();
-                ofTranslate(x, y + yspace * index);
-                
-                ofPoint p, p2;
-                for (int j = 0; j < (*historyValues).size(); j++) {
-                    
-                    float mappedPoint = 1 - ofMap((*historyValues)[j].getF(), min, max, 0, 1);
-                    
-                    p = ofPoint(j * stepWidth,
-                                mappedPoint * yspace);
-                    ofSetLineWidth(2);
-                    ofSetColor(plotColor);
-                    if (j != 0) ofLine(p2, p);
-                    p2 = p;
-                    
-                }
+    void drawOverlay(string plot, float x, float y, float width, float height);
+    void drawInfo(string plot, float x, float y, float width, float height);
+    void drawGuidelines(string plot, float x, float y, float width, float height);
 
-                auto guidelineIter = guidelines.find(i->first);
-                if (guidelineIter != guidelines.end()) {
-                    float mappedPoint = 1 - ofMap(guidelines[i->first], min, max, 0, 1);
-                    ofLine(x, y + yspace * mappedPoint, x + width, y + yspace * mappedPoint);
-                }
+    dataCollection& operator[](string name) {
+        return (dataCollection&)plotData[name];
 
-                int lastx = -200;
-                for (int j = 0; j < (*historyValues).size(); j++) {
-                    if (accents[i->first][j] != 0) {
-                        ofSetColor(255);
-                        ofSetLineWidth(2);
-                        ofLine(j * stepWidth, index * yspace,
-                               j * stepWidth, (index - 1) * yspace);
-                        ofCircle(j * stepWidth, index * yspace, 3);
-                        float mid = 0;
-                        if (j > 5) {
-                            for (int k = j - 5; k < j + 5; k++) {
-                                mid += (*historyValues)[k].getF();
-                            }
-                            mid /= 10;
-                        }
-                        if ((j * stepWidth - lastx) > 200) {
-                            ofDrawBitmapStringHighlight(ofToString(mid), j * stepWidth, index * yspace - 15);
-                            lastx = j * stepWidth;
-                        }
-                    }
-                }
-            
-                std::string overlayName = i->first;
-                std::string minValueStr = ofToString(min, 4);
-                std::string maxValueStr = ofToString(max, 4);
-            
-                // Plot name
-                ofSetColor(255, 240);
-                ofDrawRectangle(width - overlayName.length() * 8, yspace / 2 - 12, overlayName.length() * 8, 15);
-                ofSetColor(plotColor);
-                ofDrawBitmapString(overlayName, width - overlayName.length() * 8, yspace / 2);
-            
-                // Max value
-                ofSetColor(255, 240);
-                ofDrawRectangle(0, 0, maxValueStr.length() * 8, 15);
-                ofSetColor(plotColor);
-                ofDrawBitmapString(maxValueStr, 0, 12);
-            
-                // Min value
-                ofSetColor(255, 240);
-                ofDrawRectangle(0, yspace - 12, minValueStr.length() * 8, 15);
-                ofSetColor(plotColor);
-                ofDrawBitmapString(minValueStr, 0, yspace);
-            
-            ofPopMatrix();
-            
-            index++;
-        }
-        
-        if (drawMouseOverlay) drawOverlay(x, y, width, height);
     }
-    
-    std::map<std::string, ofxPlotter::Value> values;
-    std::map<std::string, std::vector<ofxPlotter::Value>> history;
-    std::map<std::string, std::vector<int>> accents;
-    std::map<std::string, float> guidelines;
-    
-    
-    // Parameters
-    
-    void setWindowSize(int size) {
-        windowSize = size;
-    }
-    
-    int getWindowSize() {
-        return windowSize;
-    }
-    
-    bool drawMouseOverlay = true;
+
+    map<string, dataCollection> plotData;
+
 };
 
 #endif /* ofxPlotter_h */