├── .appveyor.yml ├── .gitignore ├── .project ├── .travis.yml ├── README.md ├── addon_config.mk ├── docs └── Doxyfile.txt ├── example-10000Points ├── Makefile ├── addons.make └── src │ ├── main.cpp │ ├── ofApp.cpp │ └── ofApp.h ├── example-colorHistograms ├── Makefile ├── addons.make ├── bin │ └── data │ │ └── picture.jpg └── src │ ├── main.cpp │ ├── ofApp.cpp │ └── ofApp.h ├── example-defaultPlot ├── Makefile ├── addons.make └── src │ ├── main.cpp │ ├── ofApp.cpp │ └── ofApp.h ├── example-exponentialTrend ├── Makefile ├── addons.make └── src │ ├── main.cpp │ ├── ofApp.cpp │ └── ofApp.h ├── example-exportToPdf ├── Makefile ├── addons.make └── src │ ├── main.cpp │ ├── ofApp.cpp │ └── ofApp.h ├── example-lifeExpectancy ├── Makefile ├── addons.make ├── bin │ └── data │ │ └── data.csv └── src │ ├── main.cpp │ ├── ofApp.cpp │ └── ofApp.h ├── example-movingPoints ├── Makefile ├── addons.make └── src │ ├── main.cpp │ ├── ofApp.cpp │ └── ofApp.h ├── example-multiplePanels ├── Makefile ├── addons.make └── src │ ├── main.cpp │ ├── ofApp.cpp │ └── ofApp.h ├── example-multiplePlots ├── Makefile ├── addons.make ├── bin │ └── data │ │ ├── beermug.png │ │ └── beermug.svg └── src │ ├── main.cpp │ ├── ofApp.cpp │ └── ofApp.h ├── example-oktoberfest ├── Makefile ├── addons.make ├── bin │ └── data │ │ └── OktoberfestVSGermanElections.csv └── src │ ├── main.cpp │ ├── ofApp.cpp │ └── ofApp.h ├── example-twoVerticalAxes ├── Makefile ├── addons.make └── src │ ├── main.cpp │ ├── ofApp.cpp │ └── ofApp.h ├── license.md ├── ofxaddons_thumbnail.png └── src ├── ofxGAxis.cpp ├── ofxGAxis.h ├── ofxGAxisLabel.cpp ├── ofxGAxisLabel.h ├── ofxGConstants.h ├── ofxGHistogram.cpp ├── ofxGHistogram.h ├── ofxGLayer.cpp ├── ofxGLayer.h ├── ofxGPlot.cpp ├── ofxGPlot.h ├── ofxGPoint.cpp ├── ofxGPoint.h ├── ofxGTitle.cpp ├── ofxGTitle.h └── ofxGrafica.h /.appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 1.0.{build} 2 | os: Visual Studio 2015 RC 3 | 4 | environment: 5 | global: 6 | APPVEYOR_OS_NAME: windows 7 | matrix: 8 | #MSYS2 Building 9 | - platform: x86 10 | BUILDER: MSYS2 11 | 12 | #VisualStudio Building 13 | - platform: x86 14 | BUILDER : VS 15 | BITS: 32 16 | - platform: x64 17 | BUILDER : VS 18 | BITS: 64 19 | 20 | configuration: Debug 21 | shallow_clone: true 22 | clone_depth: 10 23 | init: 24 | - set MSYS2_PATH=c:\msys64 25 | - set CHERE_INVOKING=1 26 | - if "%BUILDER%_%PLATFORM%"=="MSYS2_x86" set MSYSTEM=MINGW32 27 | - if "%BUILDER%_%PLATFORM%"=="MSYS2_x64" set MSYSTEM=MINGW64 28 | - if "%BUILDER%"=="VS" set PATH=C:\Program Files (x86)\MSBuild\14.0\Bin;%PATH% 29 | 30 | install: 31 | - cd .. 32 | - git clone --depth=1 --branch=master https://github.com/openframeworks/openFrameworks 33 | - call openFrameworks\scripts\ci\addons\install.cmd 34 | 35 | build_script: 36 | - cd %OF_PATH% 37 | - scripts\ci\addons\build.cmd 38 | 39 | 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ######################### 2 | # general patterns 3 | ######################### 4 | 5 | docs/html 6 | docs/tagfile.xml 7 | 8 | */bin/* 9 | !*/bin/data/ 10 | */bin/data/*.pdf 11 | 12 | # for bin folder in root 13 | /bin/* 14 | !/bin/data/ 15 | 16 | [Bb]uild/ 17 | [Oo]bj/ 18 | *.o 19 | [Dd]ebug*/ 20 | [Rr]elease*/ 21 | *.mode* 22 | *.app/ 23 | *.pyc 24 | .svn/ 25 | 26 | ######################### 27 | # IDE 28 | ######################### 29 | 30 | # XCode 31 | *.pbxuser 32 | *.perspective 33 | *.perspectivev3 34 | *.mode1v3 35 | *.mode2v3 36 | #XCode 4 37 | xcuserdata 38 | *.xcworkspace 39 | 40 | # Code::Blocks 41 | *.depend 42 | *.layout 43 | *.cbTemp 44 | 45 | # Visual Studio 46 | *.sdf 47 | *.opensdf 48 | *.suo 49 | *.pdb 50 | *.ilk 51 | *.aps 52 | ipch/ 53 | 54 | # Eclipse 55 | .metadata 56 | local.properties 57 | .externalToolBuilders 58 | .settings 59 | .cproject 60 | 61 | # Codelite 62 | *.session 63 | *.tags 64 | *.workspace.* 65 | 66 | ######################### 67 | # operating system 68 | ######################### 69 | 70 | # Linux 71 | *~ 72 | # KDE 73 | .directory 74 | .AppleDouble 75 | 76 | # OSX 77 | .DS_Store 78 | *.swp 79 | *~.nib 80 | # Thumbnails 81 | ._* 82 | 83 | # Windows 84 | # Windows image file caches 85 | Thumbs.db 86 | # Folder config file 87 | Desktop.ini 88 | 89 | #Android 90 | .csettings 91 | 92 | ######################### 93 | # packages 94 | ######################### 95 | 96 | # it's better to unpack these files and commit the raw source 97 | # git has its own built in compression methods 98 | *.7z 99 | *.dmg 100 | *.gz 101 | *.iso 102 | *.jar 103 | *.rar 104 | *.tar 105 | *.zip 106 | 107 | # Logs and databases 108 | *.log 109 | *.sql 110 | *.sqlite 111 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | ofxGrafica 4 | 5 | 6 | openFrameworks 7 | 8 | 9 | 10 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 11 | clean,full,incremental, 12 | 13 | 14 | 15 | 16 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 17 | full,incremental, 18 | 19 | 20 | 21 | 22 | 23 | org.eclipse.cdt.core.cnature 24 | org.eclipse.cdt.core.ccnature 25 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 26 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 27 | 28 | 29 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # This file allows testing your addon using travis CI servers to use it you'll need to 2 | # create an account in travis.org and enable your addon there. 3 | # 4 | # By default it will test linux 64bit and osx against the master and stable OF branches. 5 | # Other platforms can be enabled by uncommenting the corresponding sections. 6 | # 7 | # If any extra install is needed to use the addon it can be included in the corresponding 8 | # install script in: 9 | # 10 | # scripts/ci/$TARGET/install.sh 11 | # 12 | 13 | 14 | language: c++ 15 | compiler: gcc 16 | sudo: true 17 | matrix: 18 | include: 19 | # fully specify builds, include can't dynamically expand matrix entries 20 | # relative order of sudo and env is important so that addons: is recognized 21 | 22 | # Linux 64bit, OF master 23 | - os: linux 24 | dist: trusty 25 | sudo: required 26 | env: TARGET="linux64" OF_BRANCH="master" 27 | addons: 28 | apt: 29 | sources: 30 | - ubuntu-toolchain-r-test 31 | packages: 32 | - gcc-4.9 33 | - g++-4.9 34 | - gdb 35 | 36 | # Linux 64bit, OF stable: Not supported yet 37 | # - os: linux 38 | # dist: trusty 39 | # sudo: required 40 | # env: TARGET="linux64" OF_BRANCH="stable" 41 | # addons: 42 | # apt: 43 | # sources: 44 | # - ubuntu-toolchain-r-test 45 | # packages: 46 | # - gcc-4.9 47 | # - g++-4.9 48 | # - gdb 49 | 50 | # OSX, OF master 51 | - os: osx 52 | osx_image: xcode8 53 | compiler: clang 54 | env: TARGET="osx" OF_BRANCH="master" 55 | 56 | # OSX, OF stable: Not supported yet 57 | # - os: osx 58 | # osx_image: xcode8 59 | # compiler: clang 60 | # env: TARGET="osx" OF_BRANCH="stable" 61 | 62 | # Linux ARM6, OF master: Uncomment following lines to enable 63 | # - os: linux 64 | # sudo: required 65 | # dist: trusty 66 | # env: TARGET="linuxarmv6l" OF_BRANCH="master" 67 | 68 | 69 | # Linux ARM6, OF stable: Not supported yet 70 | # - os: linux 71 | # sudo: required 72 | # dist: trusty 73 | # env: TARGET="linuxarmv6l" OF_BRANCH="stable" 74 | 75 | # Linux ARM7, OF master: Uncomment following lines to enable 76 | # - os: linux 77 | # sudo: false 78 | # env: TARGET="linuxarmv7l" OF_BRANCH="master" 79 | # cache: 80 | # directories: 81 | # - ~/rpi2_toolchain 82 | # - ~/firmware-master 83 | # - ~/archlinux 84 | 85 | # Linux ARM7, OF stable: Not supported yet 86 | # - os: linux 87 | # sudo: false 88 | # env: TARGET="linuxarmv7l" OF_BRANCH="stable" 89 | # cache: 90 | # directories: 91 | # - ~/rpi2_toolchain 92 | # - ~/firmware-master 93 | # - ~/archlinux 94 | 95 | 96 | # Emscripten, OF master: Uncomment following lines to enable 97 | # - os: linux 98 | # sudo: false 99 | # env: TARGET="emscripten" OF_BRANCH="master" 100 | # addons: 101 | # apt: 102 | # sources: 103 | # - ubuntu-toolchain-r-test 104 | # packages: 105 | # - libstdc++6 106 | 107 | 108 | # Emscripten, OF stable: Not supported yet 109 | # - os: linux 110 | # sudo: false 111 | # env: TARGET="emscripten" OF_BRANCH="stable" 112 | # addons: 113 | # apt: 114 | # sources: 115 | # - ubuntu-toolchain-r-test 116 | # packages: 117 | # - libstdc++6 118 | 119 | 120 | # iOS, OF master: Not supported yet 121 | # - os: osx 122 | # osx_image: xcode8 123 | # compiler: clang 124 | # env: TARGET="ios" OF_BRANCH="master" 125 | 126 | 127 | # iOS, OF stable: Not supported yet 128 | # - os: osx 129 | # osx_image: xcode8 130 | # compiler: clang 131 | # env: TARGET="ios" OF_BRANCH="stable" 132 | 133 | 134 | # tvOS, OF master: Not supported yet 135 | # - os: osx 136 | # osx_image: xcode8 137 | # compiler: clang 138 | # env: TARGET="tvos" OF_BRANCH="master" 139 | 140 | 141 | # tvOS, OF stable: Not supported yet 142 | # - os: osx 143 | # osx_image: xcode8 144 | # compiler: clang 145 | # env: TARGET="tvos" OF_BRANCH="stable" 146 | 147 | 148 | # Android armv7, OF master: Uncomment following lines to enable 149 | # - os: linux 150 | # sudo: false 151 | # env: TARGET="android" OPT="armv7" OF_BRANCH="master" 152 | # cache: 153 | # directories: 154 | # - ~/android-ndk-r12b 155 | 156 | 157 | # Android armv7, OF stable: Not supported yet 158 | # - os: linux 159 | # sudo: false 160 | # env: TARGET="android" OPT="armv7" OF_BRANCH="stable" 161 | # cache: 162 | # directories: 163 | # - ~/android-ndk-r12b 164 | 165 | 166 | # Android x86, OF master: Uncomment following lines to enable 167 | # - os: linux 168 | # sudo: false 169 | # env: TARGET="android" OPT="x86" OF_BRANCH="master" 170 | # cache: 171 | # directories: 172 | # - ~/android-ndk-r12b 173 | 174 | 175 | # Android x86, OF stable: Not supported yet 176 | # - os: linux 177 | # sudo: false 178 | # env: TARGET="android" OPT="x86" OF_BRANCH="stable" 179 | # cache: 180 | # directories: 181 | # - ~/android-ndk-r12b 182 | 183 | 184 | # Exclude the default build that would otherwise be generated 185 | # see https://github.com/travis-ci/travis-ci/issues/1228 186 | exclude: 187 | - compiler: gcc 188 | 189 | install: 190 | - cd ~ 191 | - git clone --depth=1 --branch=$OF_BRANCH https://github.com/openframeworks/openFrameworks 192 | - cd openFrameworks 193 | - scripts/ci/addons/install.sh 194 | 195 | script: 196 | - scripts/ci/addons/build.sh 197 | 198 | git: 199 | depth: 10 200 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ofxGrafica 2 | ===================================== 3 | 4 | Introduction 5 | ------------ 6 | 7 | ofxGrafica is a simple and configurable plotting library for [openFrameworks](http://openframeworks.cc). It's the C++ version of the [grafica](https://jagracar.com/grafica.php) Processing library. With it you can easily create 2D plots that will enjoy the full interactive capabilities of openFrameworks. 8 | 9 | ## Main features 10 | 11 | * Make fancy scatter and linear plots that update in real time. 12 | * Display histograms in the vertical and horizontal directions. 13 | * Add several layers with different properties to the same plot. 14 | * It works both with linear and logarithmic scales. 15 | * Automatic axis tick determination. 16 | * Interactive zooming and panning. Make your data move! 17 | * Add labels to your points and display them with one click. 18 | * You can use images to represent your points. 19 | * Highly customizable. Defaults are nice, but you can tweak almost everything. 20 | * openFrameworks coding style. If you are used to work with OF, ofxGrafica will be very easy. 21 | * It comes with a good set of [examples](https://jagracar.com/grafica.php). 22 | * It's open source. ofxGrafica is under the MIT License. You can find the complete source code [here](https://github.com/jagracar/ofxGrafica/tree/master/src). 23 | 24 | Installation 25 | ------------ 26 | 27 | Simply copy the ofxGrafica folder into the `openFrameworks/addons/` folder. 28 | 29 | Compatibility 30 | ------------ 31 | 32 | Tested with openFrameworks v0.10.1 linux64. 33 | -------------------------------------------------------------------------------- /addon_config.mk: -------------------------------------------------------------------------------- 1 | # All variables and this file are optional, if they are not present the PG and the 2 | # makefiles will try to parse the correct values from the file system. 3 | # 4 | # Variables that specify exclusions can use % as a wildcard to specify that anything in 5 | # that position will match. A partial path can also be specified to, for example, exclude 6 | # a whole folder from the parsed paths from the file system 7 | # 8 | # Variables can be specified using = or += 9 | # = will clear the contents of that variable both specified from the file or the ones parsed 10 | # from the file system 11 | # += will add the values to the previous ones in the file or the ones parsed from the file 12 | # system 13 | # 14 | # The PG can be used to detect errors in this file, just create a new project with this addon 15 | # and the PG will write to the console the kind of error and in which line it is 16 | 17 | meta: 18 | ADDON_NAME = ofxGrafica 19 | ADDON_DESCRIPTION = A simple and configurable plotting library for openFrameworks 20 | ADDON_AUTHOR = @jagracar 21 | ADDON_TAGS = "plot" "scatter" "histogram" "graphics" 22 | ADDON_URL = http://github.com/jagracar/ofxGrafica 23 | 24 | common: 25 | # dependencies with other addons, a list of them separated by spaces 26 | # or use += in several lines 27 | # ADDON_DEPENDENCIES = 28 | 29 | # include search paths, this will be usually parsed from the file system 30 | # but if the addon or addon libraries need special search paths they can be 31 | # specified here separated by spaces or one per line using += 32 | # ADDON_INCLUDES = 33 | 34 | # any special flag that should be passed to the compiler when using this 35 | # addon 36 | # ADDON_CFLAGS = 37 | 38 | # any special flag that should be passed to the linker when using this 39 | # addon, also used for system libraries with -lname 40 | # ADDON_LDFLAGS = 41 | 42 | # linux only, any library that should be included in the project using 43 | # pkg-config 44 | # ADDON_PKG_CONFIG_LIBRARIES = 45 | 46 | # osx/iOS only, any framework that should be included in the project 47 | # ADDON_FRAMEWORKS = 48 | 49 | # source files, these will be usually parsed from the file system looking 50 | # in the src folders in libs and the root of the addon. if your addon needs 51 | # to include files in different places or a different set of files per platform 52 | # they can be specified here 53 | # ADDON_SOURCES = 54 | 55 | # some addons need resources to be copied to the bin/data folder of the project 56 | # specify here any files that need to be copied, you can use wildcards like * and ? 57 | # ADDON_DATA = 58 | 59 | # when parsing the file system looking for libraries exclude this for all or 60 | # a specific platform 61 | # ADDON_LIBS_EXCLUDE = 62 | 63 | linux64: 64 | # binary libraries, these will be usually parsed from the file system but some 65 | # libraries need to passed to the linker in a specific order/ 66 | # 67 | # For example in the ofxOpenCV addon we do something like this: 68 | # 69 | # ADDON_LIBS = 70 | # ADDON_LIBS += libs/opencv/lib/linuxarmv6l/libopencv_legacy.a 71 | # ADDON_LIBS += libs/opencv/lib/linuxarmv6l/libopencv_calib3d.a 72 | # ... 73 | linux: 74 | win_cb: 75 | linuxarmv6l: 76 | linuxarmv7l: 77 | android/armeabi: 78 | android/armeabi-v7a: 79 | -------------------------------------------------------------------------------- /example-10000Points/Makefile: -------------------------------------------------------------------------------- 1 | # Attempt to load a config.make file. 2 | # If none is found, project defaults in config.project.make will be used. 3 | ifneq ($(wildcard config.make),) 4 | include config.make 5 | endif 6 | 7 | # make sure the the OF_ROOT location is defined 8 | ifndef OF_ROOT 9 | OF_ROOT=$(realpath ../../..) 10 | endif 11 | 12 | # call the project makefile! 13 | include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk 14 | -------------------------------------------------------------------------------- /example-10000Points/addons.make: -------------------------------------------------------------------------------- 1 | #This file is currently only for linux users! 2 | #Add your addon and all other necessary ones here (without '#') 3 | #put every addon in one line, for example 4 | ofxGrafica 5 | -------------------------------------------------------------------------------- /example-10000Points/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | 3 | int main() { 4 | // this kicks off the running of my app 5 | // can be OF_WINDOW or OF_FULLSCREEN 6 | // pass in width and height too: 7 | ofSetupOpenGL(1000, 600, OF_WINDOW); 8 | 9 | ofRunApp(new ofApp()); 10 | } 11 | -------------------------------------------------------------------------------- /example-10000Points/src/ofApp.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | #include "ofxGrafica.h" 3 | 4 | //-------------------------------------------------------------- 5 | void ofApp::setup() { 6 | ofSetBackgroundColor(255); 7 | 8 | // Initialize the global variables 9 | pointColor = ofColor(255, 0, 0, 155); 10 | drawLines = true; 11 | circleResolution = 22; 12 | 13 | // Set the circle resolution 14 | ofSetCircleResolution(circleResolution); 15 | 16 | // Set the plot position and dimentions 17 | plot.setPos(0, 0); 18 | plot.setOuterDim(ofGetWidth(), ofGetHeight()); 19 | 20 | // Set the title text relative position and alignment 21 | plot.getTitle().setRelativePos(0.4); 22 | plot.getTitle().setTextAlignment(GRAFICA_LEFT_ALIGN); 23 | 24 | // Set the axis labels 25 | plot.getXAxis().setAxisLabelText("x axis"); 26 | plot.getYAxis().setAxisLabelText("y axis"); 27 | 28 | // Prepare the points for the plot 29 | int nPoints = 10000; 30 | vector points; 31 | 32 | for (int i = 0; i < nPoints; ++i) { 33 | points.emplace_back(ofRandom(100), ofRandom(100)); 34 | } 35 | 36 | // Add the points 37 | plot.setPoints(points); 38 | 39 | // Activate panning and zooming 40 | plot.activatePanning(); 41 | plot.activateZooming(1.1, OF_MOUSE_BUTTON_LEFT, OF_MOUSE_BUTTON_LEFT); 42 | } 43 | 44 | //-------------------------------------------------------------- 45 | void ofApp::update() { 46 | plot.getTitle().setText("Frame rate: " + to_string(ofGetFrameRate())); 47 | } 48 | 49 | //-------------------------------------------------------------- 50 | void ofApp::draw() { 51 | plot.beginDraw(); 52 | plot.drawBox(); 53 | plot.drawXAxis(); 54 | plot.drawYAxis(); 55 | plot.drawTitle(); 56 | 57 | if (drawLines) { 58 | plot.drawLines(); 59 | } 60 | 61 | plot.drawPoints(pointColor); // this is 3 times faster than drawPoints() 62 | plot.drawLabels(); 63 | plot.endDraw(); 64 | } 65 | 66 | //-------------------------------------------------------------- 67 | void ofApp::keyPressed(int key) { 68 | if (key == 'l') { 69 | drawLines = !drawLines; 70 | } else if (key == '+') { 71 | circleResolution = ofClamp(++circleResolution, 3, 50); 72 | ofSetCircleResolution(circleResolution); 73 | } else if (key == '-') { 74 | circleResolution = ofClamp(--circleResolution, 3, 50); 75 | ofSetCircleResolution(circleResolution); 76 | } 77 | } 78 | 79 | //-------------------------------------------------------------- 80 | void ofApp::keyReleased(int key) { 81 | 82 | } 83 | 84 | //-------------------------------------------------------------- 85 | void ofApp::mouseMoved(int x, int y) { 86 | 87 | } 88 | 89 | //-------------------------------------------------------------- 90 | void ofApp::mouseDragged(int x, int y, int button) { 91 | 92 | } 93 | 94 | //-------------------------------------------------------------- 95 | void ofApp::mousePressed(int x, int y, int button) { 96 | 97 | } 98 | 99 | //-------------------------------------------------------------- 100 | void ofApp::mouseReleased(int x, int y, int button) { 101 | 102 | } 103 | 104 | //-------------------------------------------------------------- 105 | void ofApp::windowResized(int w, int h) { 106 | 107 | } 108 | 109 | //-------------------------------------------------------------- 110 | void ofApp::gotMessage(ofMessage msg) { 111 | 112 | } 113 | 114 | //-------------------------------------------------------------- 115 | void ofApp::dragEvent(ofDragInfo dragInfo) { 116 | 117 | } 118 | -------------------------------------------------------------------------------- /example-10000Points/src/ofApp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ofxGrafica.h" 5 | 6 | class ofApp: public ofBaseApp { 7 | public: 8 | void setup(); 9 | void update(); 10 | void draw(); 11 | 12 | void keyPressed(int key); 13 | void keyReleased(int key); 14 | void mouseMoved(int x, int y); 15 | void mouseDragged(int x, int y, int button); 16 | void mousePressed(int x, int y, int button); 17 | void mouseReleased(int x, int y, int button); 18 | void windowResized(int w, int h); 19 | void dragEvent(ofDragInfo dragInfo); 20 | void gotMessage(ofMessage msg); 21 | 22 | ofColor pointColor; 23 | bool drawLines; 24 | int circleResolution; 25 | ofxGPlot plot; 26 | }; 27 | -------------------------------------------------------------------------------- /example-colorHistograms/Makefile: -------------------------------------------------------------------------------- 1 | # Attempt to load a config.make file. 2 | # If none is found, project defaults in config.project.make will be used. 3 | ifneq ($(wildcard config.make),) 4 | include config.make 5 | endif 6 | 7 | # make sure the the OF_ROOT location is defined 8 | ifndef OF_ROOT 9 | OF_ROOT=$(realpath ../../..) 10 | endif 11 | 12 | # call the project makefile! 13 | include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk 14 | -------------------------------------------------------------------------------- /example-colorHistograms/addons.make: -------------------------------------------------------------------------------- 1 | #This file is currently only for linux users! 2 | #Add your addon and all other necessary ones here (without '#') 3 | #put every addon in one line, for example 4 | ofxGrafica 5 | -------------------------------------------------------------------------------- /example-colorHistograms/bin/data/picture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jagracar/ofxGrafica/dea9e974f2f181bba59d2de5adceb936d4e7c8c7/example-colorHistograms/bin/data/picture.jpg -------------------------------------------------------------------------------- /example-colorHistograms/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | 3 | int main() { 4 | // this kicks off the running of my app 5 | // can be OF_WINDOW or OF_FULLSCREEN 6 | // pass in width and height too: 7 | ofSetupOpenGL(850, 800, OF_WINDOW); 8 | 9 | ofRunApp(new ofApp()); 10 | } 11 | -------------------------------------------------------------------------------- /example-colorHistograms/src/ofApp.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | #include "ofxGrafica.h" 3 | 4 | //-------------------------------------------------------------- 5 | void ofApp::setup() { 6 | ofSetBackgroundColor(255); 7 | 8 | // Load the image and set the image position 9 | img.load("picture.jpg"); 10 | imgPos = glm::vec2(410, 100); 11 | 12 | // Set the rectangle position and size 13 | rect.set(imgPos, 20, 20); 14 | 15 | // Calculate the color histograms 16 | calculateHistograms(); 17 | 18 | // Setup for the first plot 19 | plot1.setPos(0, 0); 20 | plot1.setDim(300, 200); 21 | plot1.setXLim(0, 255); 22 | plot1.setTitleText("Color histograms"); 23 | plot1.getYAxis().getAxisLabel().setText("N"); 24 | plot1.getYAxis().getAxisLabel().setRotate(false); 25 | plot1.setPoints(redHistPoints); 26 | plot1.startHistograms(GRAFICA_VERTICAL_HISTOGRAM); 27 | plot1.getHistogram().setBgColors( { ofColor(255, 0, 0, 100) }); 28 | plot1.getHistogram().setLineColors( { ofColor(0, 0) }); 29 | plot1.getHistogram().setSeparations( { 0 }); 30 | plot1.activateZooming(1.2, OF_MOUSE_BUTTON_LEFT, OF_MOUSE_BUTTON_LEFT); 31 | plot1.activateReset(); 32 | 33 | // Setup for the second plot 34 | plot2.setPos(0, 245); 35 | plot2.setDim(300, 200); 36 | plot2.setXLim(0, 255); 37 | plot2.getYAxis().getAxisLabel().setText("N"); 38 | plot2.getYAxis().getAxisLabel().setRotate(false); 39 | plot2.setPoints(greenHistPoints); 40 | plot2.startHistograms(GRAFICA_VERTICAL_HISTOGRAM); 41 | plot2.getHistogram().setBgColors( { ofColor(0, 255, 0, 100) }); 42 | plot2.getHistogram().setLineColors( { ofColor(0, 0) }); 43 | plot2.getHistogram().setSeparations( { 0 }); 44 | plot2.activateZooming(1.2, OF_MOUSE_BUTTON_LEFT, OF_MOUSE_BUTTON_LEFT); 45 | plot2.activateReset(); 46 | 47 | // Setup for the third plot 48 | plot3.setPos(0, 490); 49 | plot3.setDim(300, 200); 50 | plot3.setXLim(0, 255); 51 | plot3.getXAxis().getAxisLabel().setText("color value"); 52 | plot3.getYAxis().getAxisLabel().setText("N"); 53 | plot3.getYAxis().getAxisLabel().setRotate(false); 54 | plot3.setPoints(blueHistPoints); 55 | plot3.startHistograms(GRAFICA_VERTICAL_HISTOGRAM); 56 | plot3.getHistogram().setBgColors( { ofColor(0, 0, 255, 100) }); 57 | plot3.getHistogram().setLineColors( { ofColor(0, 0) }); 58 | plot3.getHistogram().setSeparations( { 0 }); 59 | plot3.activateZooming(1.2, OF_MOUSE_BUTTON_LEFT, OF_MOUSE_BUTTON_LEFT); 60 | plot3.activateReset(); 61 | } 62 | 63 | //-------------------------------------------------------------- 64 | void ofApp::calculateHistograms() { 65 | // Calculate the color histograms 66 | int delta = 2; 67 | int nBins = 255 / delta; 68 | vector redHist(nBins, 0); 69 | vector greenHist(nBins, 0); 70 | vector blueHist(nBins, 0); 71 | int xStart = ofClamp(rect.getX() - imgPos.x, 0, img.getWidth()); 72 | int yStart = ofClamp(rect.getY() - imgPos.y, 0, img.getHeight()); 73 | int xEnd = ofClamp(rect.getX() + rect.getWidth() - imgPos.x, 0, img.getWidth()); 74 | int yEnd = ofClamp(rect.getY() + rect.getHeight() - imgPos.y, 0, img.getHeight()); 75 | int counter = 0; 76 | 77 | for (int x = xStart; x < xEnd; ++x) { 78 | for (int y = yStart; y < yEnd; ++y) { 79 | ofColor c = img.getColor(x, y); 80 | ++redHist[c.r / delta]; 81 | ++greenHist[c.g / delta]; 82 | ++blueHist[c.b / delta]; 83 | ++counter; 84 | } 85 | } 86 | 87 | // Calculate the plot points 88 | redHistPoints.clear(); 89 | greenHistPoints.clear(); 90 | blueHistPoints.clear(); 91 | 92 | for (int i = 0; i < nBins; ++i) { 93 | redHistPoints.emplace_back((i + 0.5) * delta, redHist[i] / counter); 94 | greenHistPoints.emplace_back((i + 0.5) * delta, greenHist[i] / counter); 95 | blueHistPoints.emplace_back((i + 0.5) * delta, blueHist[i] / counter); 96 | } 97 | } 98 | 99 | //-------------------------------------------------------------- 100 | void ofApp::update() { 101 | 102 | } 103 | 104 | //-------------------------------------------------------------- 105 | void ofApp::draw() { 106 | // Draw the first plot 107 | plot1.beginDraw(); 108 | plot1.drawBox(); 109 | plot1.drawTitle(); 110 | plot1.drawXAxis(); 111 | plot1.drawYAxis(); 112 | plot1.drawGridLines(GRAFICA_VERTICAL_DIRECTION); 113 | plot1.drawHistograms(); 114 | plot1.endDraw(); 115 | 116 | // Draw the second plot 117 | plot2.beginDraw(); 118 | plot2.drawBox(); 119 | plot2.drawXAxis(); 120 | plot2.drawYAxis(); 121 | plot2.drawGridLines(GRAFICA_VERTICAL_DIRECTION); 122 | plot2.drawHistograms(); 123 | plot2.endDraw(); 124 | 125 | // Draw the third plot 126 | plot3.beginDraw(); 127 | plot3.drawBox(); 128 | plot3.drawXAxis(); 129 | plot3.drawYAxis(); 130 | plot3.drawGridLines(GRAFICA_VERTICAL_DIRECTION); 131 | plot3.drawHistograms(); 132 | plot3.endDraw(); 133 | 134 | // Draw the image 135 | img.draw(imgPos); 136 | 137 | // Draw the square 138 | ofPushStyle(); 139 | ofNoFill(); 140 | ofSetColor(0, 255, 0); 141 | ofDrawRectangle(rect); 142 | ofPopStyle(); 143 | } 144 | 145 | //-------------------------------------------------------------- 146 | void ofApp::keyPressed(int key) { 147 | 148 | } 149 | 150 | //-------------------------------------------------------------- 151 | void ofApp::keyReleased(int key) { 152 | 153 | } 154 | 155 | //-------------------------------------------------------------- 156 | void ofApp::mouseMoved(int x, int y) { 157 | 158 | } 159 | 160 | //-------------------------------------------------------------- 161 | void ofApp::mouseDragged(int x, int y, int button) { 162 | // Center the rectangle on the mouse position 163 | rect.setX(x - rect.getWidth() / 2); 164 | rect.setY(y - rect.getHeight() / 2); 165 | 166 | // Calculate the color histograms 167 | calculateHistograms(); 168 | 169 | // Update the plots 170 | plot1.setPoints(redHistPoints); 171 | plot2.setPoints(greenHistPoints); 172 | plot3.setPoints(blueHistPoints); 173 | } 174 | 175 | //-------------------------------------------------------------- 176 | void ofApp::mousePressed(int x, int y, int button) { 177 | 178 | } 179 | 180 | //-------------------------------------------------------------- 181 | void ofApp::mouseReleased(int x, int y, int button) { 182 | 183 | } 184 | 185 | //-------------------------------------------------------------- 186 | void ofApp::windowResized(int w, int h) { 187 | 188 | } 189 | 190 | //-------------------------------------------------------------- 191 | void ofApp::gotMessage(ofMessage msg) { 192 | 193 | } 194 | 195 | //-------------------------------------------------------------- 196 | void ofApp::dragEvent(ofDragInfo dragInfo) { 197 | 198 | } 199 | -------------------------------------------------------------------------------- /example-colorHistograms/src/ofApp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ofxGrafica.h" 5 | 6 | class ofApp: public ofBaseApp { 7 | public: 8 | void setup(); 9 | void update(); 10 | void draw(); 11 | 12 | void keyPressed(int key); 13 | void keyReleased(int key); 14 | void mouseMoved(int x, int y); 15 | void mouseDragged(int x, int y, int button); 16 | void mousePressed(int x, int y, int button); 17 | void mouseReleased(int x, int y, int button); 18 | void windowResized(int w, int h); 19 | void dragEvent(ofDragInfo dragInfo); 20 | void gotMessage(ofMessage msg); 21 | 22 | ofxGPlot plot1, plot2, plot3; 23 | vector redHistPoints, greenHistPoints, blueHistPoints; 24 | ofImage img; 25 | ofPoint imgPos; 26 | ofRectangle rect; 27 | void calculateHistograms(); 28 | }; 29 | -------------------------------------------------------------------------------- /example-defaultPlot/Makefile: -------------------------------------------------------------------------------- 1 | # Attempt to load a config.make file. 2 | # If none is found, project defaults in config.project.make will be used. 3 | ifneq ($(wildcard config.make),) 4 | include config.make 5 | endif 6 | 7 | # make sure the the OF_ROOT location is defined 8 | ifndef OF_ROOT 9 | OF_ROOT=$(realpath ../../..) 10 | endif 11 | 12 | # call the project makefile! 13 | include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk 14 | -------------------------------------------------------------------------------- /example-defaultPlot/addons.make: -------------------------------------------------------------------------------- 1 | #This file is currently only for linux users! 2 | #Add your addon and all other necessary ones here (without '#') 3 | #put every addon in one line, for example 4 | ofxGrafica 5 | -------------------------------------------------------------------------------- /example-defaultPlot/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | 3 | int main() { 4 | // this kicks off the running of my app 5 | // can be OF_WINDOW or OF_FULLSCREEN 6 | // pass in width and height too: 7 | ofSetupOpenGL(500, 350, OF_WINDOW); 8 | 9 | ofRunApp(new ofApp()); 10 | } 11 | -------------------------------------------------------------------------------- /example-defaultPlot/src/ofApp.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | #include "ofxGrafica.h" 3 | 4 | //-------------------------------------------------------------- 5 | void ofApp::setup() { 6 | ofSetBackgroundColor(150); 7 | 8 | // Prepare the points for the plot 9 | int nPoints = 100; 10 | vector points; 11 | 12 | for (int i = 0; i < nPoints; ++i) { 13 | points.emplace_back(i, 10 * ofNoise(0.1 * i)); 14 | } 15 | 16 | // Set the plot position on the screen 17 | plot.setPos(25, 25); 18 | 19 | // Set the plot title and the axis labels 20 | plot.setTitleText("A very simple example"); 21 | plot.getXAxis().setAxisLabelText("x axis"); 22 | plot.getYAxis().setAxisLabelText("y axis"); 23 | 24 | // Add the points 25 | plot.setPoints(points); 26 | } 27 | 28 | //-------------------------------------------------------------- 29 | void ofApp::update() { 30 | 31 | } 32 | 33 | //-------------------------------------------------------------- 34 | void ofApp::draw() { 35 | plot.defaultDraw(); 36 | } 37 | 38 | //-------------------------------------------------------------- 39 | void ofApp::keyPressed(int key) { 40 | 41 | } 42 | 43 | //-------------------------------------------------------------- 44 | void ofApp::keyReleased(int key) { 45 | 46 | } 47 | 48 | //-------------------------------------------------------------- 49 | void ofApp::mouseMoved(int x, int y) { 50 | 51 | } 52 | 53 | //-------------------------------------------------------------- 54 | void ofApp::mouseDragged(int x, int y, int button) { 55 | 56 | } 57 | 58 | //-------------------------------------------------------------- 59 | void ofApp::mousePressed(int x, int y, int button) { 60 | 61 | } 62 | 63 | //-------------------------------------------------------------- 64 | void ofApp::mouseReleased(int x, int y, int button) { 65 | 66 | } 67 | 68 | //-------------------------------------------------------------- 69 | void ofApp::windowResized(int w, int h) { 70 | 71 | } 72 | 73 | //-------------------------------------------------------------- 74 | void ofApp::gotMessage(ofMessage msg) { 75 | 76 | } 77 | 78 | //-------------------------------------------------------------- 79 | void ofApp::dragEvent(ofDragInfo dragInfo) { 80 | 81 | } 82 | -------------------------------------------------------------------------------- /example-defaultPlot/src/ofApp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ofxGrafica.h" 5 | 6 | class ofApp: public ofBaseApp { 7 | public: 8 | void setup(); 9 | void update(); 10 | void draw(); 11 | 12 | void keyPressed(int key); 13 | void keyReleased(int key); 14 | void mouseMoved(int x, int y); 15 | void mouseDragged(int x, int y, int button); 16 | void mousePressed(int x, int y, int button); 17 | void mouseReleased(int x, int y, int button); 18 | void windowResized(int w, int h); 19 | void dragEvent(ofDragInfo dragInfo); 20 | void gotMessage(ofMessage msg); 21 | 22 | ofxGPlot plot; 23 | }; 24 | -------------------------------------------------------------------------------- /example-exponentialTrend/Makefile: -------------------------------------------------------------------------------- 1 | # Attempt to load a config.make file. 2 | # If none is found, project defaults in config.project.make will be used. 3 | ifneq ($(wildcard config.make),) 4 | include config.make 5 | endif 6 | 7 | # make sure the the OF_ROOT location is defined 8 | ifndef OF_ROOT 9 | OF_ROOT=$(realpath ../../..) 10 | endif 11 | 12 | # call the project makefile! 13 | include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk 14 | -------------------------------------------------------------------------------- /example-exponentialTrend/addons.make: -------------------------------------------------------------------------------- 1 | #This file is currently only for linux users! 2 | #Add your addon and all other necessary ones here (without '#') 3 | #put every addon in one line, for example 4 | ofxGrafica 5 | -------------------------------------------------------------------------------- /example-exponentialTrend/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | 3 | int main() { 4 | // this kicks off the running of my app 5 | // can be OF_WINDOW or OF_FULLSCREEN 6 | // pass in width and height too: 7 | ofSetupOpenGL(450, 450, OF_WINDOW); 8 | 9 | ofRunApp(new ofApp()); 10 | } 11 | -------------------------------------------------------------------------------- /example-exponentialTrend/src/ofApp.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | #include "ofxGrafica.h" 3 | #include 4 | 5 | //-------------------------------------------------------------- 6 | void ofApp::setup() { 7 | ofSetBackgroundColor(150); 8 | 9 | // Prepare the points for the plot 10 | int nPoints = 1000; 11 | vector points; 12 | default_random_engine generator; 13 | normal_distribution distribution(0.0, 2.0); 14 | 15 | for (int i = 0; i < nPoints; ++i) { 16 | float x = 10 + ofRandom(200); 17 | float y = 10 * exp(0.015 * x); 18 | float xErr = distribution(generator); 19 | float yErr = distribution(generator); 20 | points.emplace_back(x + xErr, y + yErr); 21 | } 22 | 23 | // Set the plot position and dimension 24 | plot.setPos(25, 25); 25 | plot.setDim(300, 300); 26 | 27 | // Set the plot title and the axis labels 28 | plot.setTitleText("Exponential law"); 29 | plot.getXAxis().setAxisLabelText("x"); 30 | 31 | if (logScale) { 32 | plot.setLogScale("y"); 33 | plot.getYAxis().setAxisLabelText("log y"); 34 | } else { 35 | plot.setLogScale(""); 36 | plot.getYAxis().setAxisLabelText("y"); 37 | } 38 | 39 | // Add the points to the plot 40 | plot.setPoints(points); 41 | plot.setPointColor(ofColor(100, 100, 255, 50)); 42 | } 43 | 44 | //-------------------------------------------------------------- 45 | void ofApp::update() { 46 | 47 | } 48 | 49 | //-------------------------------------------------------------- 50 | void ofApp::draw() { 51 | plot.beginDraw(); 52 | plot.drawBackground(); 53 | plot.drawBox(); 54 | plot.drawXAxis(); 55 | plot.drawYAxis(); 56 | plot.drawTopAxis(); 57 | plot.drawRightAxis(); 58 | plot.drawTitle(); 59 | plot.drawPoints(); 60 | plot.endDraw(); 61 | } 62 | 63 | //-------------------------------------------------------------- 64 | void ofApp::keyPressed(int key) { 65 | 66 | } 67 | 68 | //-------------------------------------------------------------- 69 | void ofApp::keyReleased(int key) { 70 | 71 | } 72 | 73 | //-------------------------------------------------------------- 74 | void ofApp::mouseMoved(int x, int y) { 75 | 76 | } 77 | 78 | //-------------------------------------------------------------- 79 | void ofApp::mouseDragged(int x, int y, int button) { 80 | 81 | } 82 | 83 | //-------------------------------------------------------------- 84 | void ofApp::mousePressed(int x, int y, int button) { 85 | 86 | } 87 | 88 | //-------------------------------------------------------------- 89 | void ofApp::mouseReleased(int x, int y, int button) { 90 | // Change the log scale 91 | logScale = !logScale; 92 | 93 | if (logScale) { 94 | plot.setLogScale("y"); 95 | plot.getYAxis().setAxisLabelText("log y"); 96 | } else { 97 | plot.setLogScale(""); 98 | plot.getYAxis().setAxisLabelText("y"); 99 | } 100 | } 101 | 102 | //-------------------------------------------------------------- 103 | void ofApp::windowResized(int w, int h) { 104 | 105 | } 106 | 107 | //-------------------------------------------------------------- 108 | void ofApp::gotMessage(ofMessage msg) { 109 | 110 | } 111 | 112 | //-------------------------------------------------------------- 113 | void ofApp::dragEvent(ofDragInfo dragInfo) { 114 | 115 | } 116 | -------------------------------------------------------------------------------- /example-exponentialTrend/src/ofApp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ofxGrafica.h" 5 | 6 | class ofApp: public ofBaseApp { 7 | public: 8 | void setup(); 9 | void update(); 10 | void draw(); 11 | 12 | void keyPressed(int key); 13 | void keyReleased(int key); 14 | void mouseMoved(int x, int y); 15 | void mouseDragged(int x, int y, int button); 16 | void mousePressed(int x, int y, int button); 17 | void mouseReleased(int x, int y, int button); 18 | void windowResized(int w, int h); 19 | void dragEvent(ofDragInfo dragInfo); 20 | void gotMessage(ofMessage msg); 21 | 22 | ofxGPlot plot; 23 | bool logScale; 24 | }; 25 | -------------------------------------------------------------------------------- /example-exportToPdf/Makefile: -------------------------------------------------------------------------------- 1 | # Attempt to load a config.make file. 2 | # If none is found, project defaults in config.project.make will be used. 3 | ifneq ($(wildcard config.make),) 4 | include config.make 5 | endif 6 | 7 | # make sure the the OF_ROOT location is defined 8 | ifndef OF_ROOT 9 | OF_ROOT=$(realpath ../../..) 10 | endif 11 | 12 | # call the project makefile! 13 | include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk 14 | -------------------------------------------------------------------------------- /example-exportToPdf/addons.make: -------------------------------------------------------------------------------- 1 | #This file is currently only for linux users! 2 | #Add your addon and all other necessary ones here (without '#') 3 | #put every addon in one line, for example 4 | ofxGrafica 5 | -------------------------------------------------------------------------------- /example-exportToPdf/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | 3 | int main() { 4 | // this kicks off the running of my app 5 | // can be OF_WINDOW or OF_FULLSCREEN 6 | // pass in width and height too: 7 | ofSetupOpenGL(500, 350, OF_WINDOW); 8 | 9 | ofRunApp(new ofApp()); 10 | } 11 | -------------------------------------------------------------------------------- /example-exportToPdf/src/ofApp.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | #include "ofxGrafica.h" 3 | 4 | //-------------------------------------------------------------- 5 | void ofApp::setup() { 6 | ofSetBackgroundColor(150); 7 | 8 | // Prepare the points for the plot 9 | int nPoints = 100; 10 | vector points; 11 | 12 | for (int i = 0; i < nPoints; ++i) { 13 | points.emplace_back(i, 10 * ofNoise(0.1 * i)); 14 | } 15 | 16 | // Set the plot position on the screen 17 | plot.setPos(25, 25); 18 | 19 | // Set the plot title and the axis labels 20 | plot.setTitleText("A very simple example"); 21 | plot.getXAxis().setAxisLabelText("x axis"); 22 | plot.getYAxis().setAxisLabelText("y axis"); 23 | 24 | // Add the points 25 | plot.setPoints(points); 26 | 27 | // This is needed to be able to save the fonts in the pdf 28 | plot.setFontsMakeContours(true); 29 | } 30 | 31 | //-------------------------------------------------------------- 32 | void ofApp::update() { 33 | 34 | } 35 | 36 | //-------------------------------------------------------------- 37 | void ofApp::draw() { 38 | // Save the plot as a pdf 39 | ofBeginSaveScreenAsPDF("screenshot-" + ofGetTimestampString() + ".pdf", false); 40 | plot.defaultDraw(); 41 | ofEndSaveScreenAsPDF(); 42 | 43 | // Exit the app 44 | ofExit(); 45 | } 46 | 47 | //-------------------------------------------------------------- 48 | void ofApp::keyPressed(int key) { 49 | 50 | } 51 | 52 | //-------------------------------------------------------------- 53 | void ofApp::keyReleased(int key) { 54 | 55 | } 56 | 57 | //-------------------------------------------------------------- 58 | void ofApp::mouseMoved(int x, int y) { 59 | 60 | } 61 | 62 | //-------------------------------------------------------------- 63 | void ofApp::mouseDragged(int x, int y, int button) { 64 | 65 | } 66 | 67 | //-------------------------------------------------------------- 68 | void ofApp::mousePressed(int x, int y, int button) { 69 | 70 | } 71 | 72 | //-------------------------------------------------------------- 73 | void ofApp::mouseReleased(int x, int y, int button) { 74 | 75 | } 76 | 77 | //-------------------------------------------------------------- 78 | void ofApp::windowResized(int w, int h) { 79 | 80 | } 81 | 82 | //-------------------------------------------------------------- 83 | void ofApp::gotMessage(ofMessage msg) { 84 | 85 | } 86 | 87 | //-------------------------------------------------------------- 88 | void ofApp::dragEvent(ofDragInfo dragInfo) { 89 | 90 | } 91 | -------------------------------------------------------------------------------- /example-exportToPdf/src/ofApp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ofxGrafica.h" 5 | 6 | class ofApp: public ofBaseApp { 7 | public: 8 | void setup(); 9 | void update(); 10 | void draw(); 11 | 12 | void keyPressed(int key); 13 | void keyReleased(int key); 14 | void mouseMoved(int x, int y); 15 | void mouseDragged(int x, int y, int button); 16 | void mousePressed(int x, int y, int button); 17 | void mouseReleased(int x, int y, int button); 18 | void windowResized(int w, int h); 19 | void dragEvent(ofDragInfo dragInfo); 20 | void gotMessage(ofMessage msg); 21 | 22 | ofxGPlot plot; 23 | }; 24 | -------------------------------------------------------------------------------- /example-lifeExpectancy/Makefile: -------------------------------------------------------------------------------- 1 | # Attempt to load a config.make file. 2 | # If none is found, project defaults in config.project.make will be used. 3 | ifneq ($(wildcard config.make),) 4 | include config.make 5 | endif 6 | 7 | # make sure the the OF_ROOT location is defined 8 | ifndef OF_ROOT 9 | OF_ROOT=$(realpath ../../..) 10 | endif 11 | 12 | # call the project makefile! 13 | include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk 14 | -------------------------------------------------------------------------------- /example-lifeExpectancy/addons.make: -------------------------------------------------------------------------------- 1 | #This file is currently only for linux users! 2 | #Add your addon and all other necessary ones here (without '#') 3 | #put every addon in one line, for example 4 | ofxGrafica 5 | -------------------------------------------------------------------------------- /example-lifeExpectancy/bin/data/data.csv: -------------------------------------------------------------------------------- 1 | country,income,health,population,,,,, 2 | Central African Republic,599,53.8,4900274,,,,, 3 | Somalia,624,58.7,10787104,,,,, 4 | Burundi,777,60.4,11178921,,,,, 5 | Malawi,799,60.22,17215232,,,,, 6 | "Congo Dem. Rep.",809,58.3,77266814,,,,, 7 | Niger,943,62.2,19899120,,,,, 8 | Liberia,958,63.9,4503438,,,,, 9 | Eritrea,1129,62.9,5227791,,,,, 10 | Mozambique,1176,56.4,27977863,,,,, 11 | Guinea,1225,60.8,12608590,,,,, 12 | Guinea-Bissau,1386,53.4,1844325,,,,, 13 | North Korea,1390,71.4,25155317,,,,, 14 | Madagascar,1400,64.7,24235390,,,,, 15 | Togo,1433,64.23,7304578,,,,, 16 | Comoros,1472,64.1,788474,,,,, 17 | Ethiopia,1520,63.6,99390750,,,,, 18 | Rwanda,1549,66.53,11609666,,,,, 19 | Gambia,1644,65.1,1990924,,,,, 20 | Burkina Faso,1654,62.8,18105570,,,,, 21 | Uganda,1680,60.8,39032383,,,,, 22 | Mali,1684,57.6,17599694,,,,, 23 | Haiti,1710,65.3,10711067,,,,, 24 | Zimbabwe,1801,60.01,15602751,,,,, 25 | Kiribati,1824,62.4,112423,,,,, 26 | Benin,1830,65.5,10879829,,,,, 27 | Afghanistan,1925,57.63,32526562,,,,, 28 | Solomon Islands,2047,64.1,583591,,,,, 29 | Sierra Leone,2085,58.5,6453184,,,,, 30 | Timor-Leste,2086,72.4,1184765,,,,, 31 | Chad,2191,57.7,14037472,,,,, 32 | Senegal,2251,66.1,15129273,,,,, 33 | Nepal,2352,71.2,28513700,,,,, 34 | Papua New Guinea,2529,60.6,7619321,,,,, 35 | Tanzania,2571,63.43,53470420,,,,, 36 | Tajikistan,2582,71,8481855,,,,, 37 | Lesotho,2598,48.5,2135022,,,,, 38 | Cameroon,2897,59.5,23344179,,,,, 39 | Kenya,2898,66.63,46050302,,,,, 40 | Vanuatu,2912,65,264652,,,,, 41 | Sao Tome and Principe,3003,68.8,190344,,,,, 42 | South Sudan,3047,58,12339812,,,,, 43 | Djibouti,3139,64.63,887861,,,,, 44 | Bangladesh,3161,70.1,160995642,,,,, 45 | Kyrgyz Republic,3245,69,5939962,,,,, 46 | Cambodia,3267,68.4,15577899,,,,, 47 | Cote d'Ivoire,3491,60.33,22701556,,,,, 48 | "Micronesia Fed. Sts.",3510,67,104460,,,,, 49 | Marshall Islands,3661,65.1,52993,,,,, 50 | Mauritania,3877,65.7,4067564,,,,, 51 | Yemen,3887,67.6,26832215,,,,, 52 | Sudan,3975,69.5,40234882,,,,, 53 | Myanmar,4012,67.9,53897154,,,,, 54 | Zambia,4034,58.96,16211767,,,,, 55 | Ghana,4099,65.5,27409893,,,,, 56 | Honduras,4270,72.4,8075060,,,,, 57 | West Bank and Gaza,4319,75.2,4668466,,,,, 58 | Syria,4637,70.26,18502413,,,,, 59 | Nicaragua,4712,76.8,6082032,,,,, 60 | Pakistan,4743,66.5,188924874,,,,, 61 | Moldova,4896,72.7,4068897,,,,, 62 | Tonga,5069,70.5,106170,,,,, 63 | Lao,5212,66.4,6802023,,,,, 64 | Samoa,5558,72.2,193228,,,,, 65 | Uzbekistan,5598,70.1,29893488,,,,, 66 | Vietnam,5623,76.5,93447601,,,,, 67 | Nigeria,5727,61.33,182201962,,,,, 68 | India,5903,66.8,1311050527,,,,, 69 | Swaziland,6095,51.5,1286970,,,,, 70 | "Congo Rep.",6220,61.9,4620330,,,,, 71 | Bolivia,6295,72.3,10724705,,,,, 72 | Cape Verde,6514,74.6,520502,,,,, 73 | Guyana,6816,64.4,767085,,,,, 74 | Philippines,6876,70.2,100699395,,,,, 75 | Guatemala,7279,73.1,16342897,,,,, 76 | Morocco,7319,74.7,34377511,,,,, 77 | Georgia,7474,73.3,3999812,,,,, 78 | Angola,7615,61,25021974,,,,, 79 | Armenia,7763,74.4,3017712,,,,, 80 | El Salvador,7776,74.1,6126583,,,,, 81 | Fiji,7925,66.3,892145,,,,, 82 | Bhutan,7983,70.2,774830,,,,, 83 | Paraguay,8219,73.9,6639123,,,,, 84 | Ukraine,8449,72.1,44823765,,,,, 85 | Belize,8501,70,359287,,,,, 86 | Jamaica,8606,75.5,2793335,,,,, 87 | Bosnia and Herzegovina,9833,77.9,3810416,,,,, 88 | St. Lucia,9997,74.5,184999,,,,, 89 | Namibia,10040,61,2458830,,,,, 90 | St. Vincent and the Grenadines,10435,72.9,109462,,,,, 91 | Dominica,10503,74.6,72680,,,,, 92 | Indonesia,10504,70.9,257563815,,,,, 93 | Albania,10620,76,2896679,,,,, 94 | Sri Lanka,10624,76.5,20715010,,,,, 95 | Ecuador,10996,75.2,16144363,,,,, 96 | Egypt,11031,71.3,91508084,,,,, 97 | Tunisia,11126,77.3,11253554,,,,, 98 | Grenada,11593,71.7,106825,,,,, 99 | Jordan,11752,78.3,7594547,,,,, 100 | Mongolia,11819,65.3,2959134,,,,, 101 | Peru,11903,77.5,31376670,,,,, 102 | South Africa,12509,63.72,54490406,,,,, 103 | "Macedonia FYR",12547,77,2078453,,,,, 104 | Colombia,12761,75.8,48228704,,,,, 105 | Dominican Republic,12837,73.8,10528391,,,,, 106 | Serbia,12908,78.1,8850975,,,,, 107 | Barbados,12984,75.8,284215,,,,, 108 | China,13334,76.9,1376048943,,,,, 109 | Algeria,13434,76.5,39666519,,,,, 110 | Costa Rica,14132,80,4807850,,,,, 111 | Maldives,14408,79.5,363657,,,,, 112 | Thailand,14512,75.1,67959359,,,,, 113 | Iraq,14646,72.1,36423395,,,,, 114 | Montenegro,14833,75.8,625781,,,,, 115 | Brazil,15441,75.6,207847528,,,,, 116 | Iran,15573,78.5,79109272,,,,, 117 | Venezuela,15753,75.8,31108083,,,,, 118 | Turkmenistan,15865,67.9,5373502,,,,, 119 | Bulgaria,16371,74.9,7149787,,,,, 120 | Mexico,16850,74.5,127017224,,,,, 121 | Azerbaijan,16986,72.9,9753968,,,,, 122 | Lebanon,17050,78.5,5850743,,,,, 123 | Suriname,17125,70.5,542975,,,,, 124 | Botswana,17196,66.4,2262485,,,,, 125 | Libya,17261,76.2,6278438,,,,, 126 | Argentina,17344,76.2,43416755,,,,, 127 | Belarus,17415,70.4,9495826,,,,, 128 | Mauritius,18350,73.9,1273212,,,,, 129 | Gabon,18627,60.53,1725292,,,,, 130 | Romania,19203,76.8,19511324,,,,, 131 | Turkey,19360,76.5,78665830,,,,, 132 | Croatia,20260,78,4240317,,,,, 133 | Uruguay,20438,77.3,3431555,,,,, 134 | Panama,20485,78.2,3929141,,,,, 135 | Antigua and Barbuda,21049,75.2,91818,,,,, 136 | Cuba,21291,78.5,11389562,,,,, 137 | Chile,22465,79.3,17948141,,,,, 138 | Bahamas,22818,72.3,388019,,,,, 139 | Russia,23038,73.13,143456918,,,,, 140 | Latvia,23282,75.7,1970503,,,,, 141 | Kazakhstan,23468,68.2,17625226,,,,, 142 | Hungary,24200,76.2,9855023,,,,, 143 | Malaysia,24320,75.1,30331007,,,,, 144 | Poland,24787,77.3,38611794,,,,, 145 | Greece,25430,79.8,10954617,,,,, 146 | Seychelles,25684,73.7,96471,,,,, 147 | Portugal,26437,79.8,10349803,,,,, 148 | Lithuania,26665,75.4,2878405,,,,, 149 | Estonia,26812,76.8,1312558,,,,, 150 | Slovak Republic,27204,76.4,5426258,,,,, 151 | Slovenia,28550,80.2,2067526,,,,, 152 | Czech Republic,29437,78.6,10543186,,,,, 153 | Cyprus,29797,82.6,1165300,,,,, 154 | Trinidad and Tobago,30113,71.4,1360088,,,,, 155 | Malta,30265,82.1,418670,,,,, 156 | Equatorial Guinea,31087,60.63,845060,,,,, 157 | Israel,31590,82.4,8064036,,,,, 158 | Spain,32979,81.7,46121699,,,,, 159 | Italy,33297,82.1,59797685,,,,, 160 | New Zealand,34186,80.6,4528526,,,,, 161 | South Korea,34644,80.7,50293439,,,,, 162 | Japan,36162,83.5,126573481,,,,, 163 | France,37599,81.9,64395345,,,,, 164 | United Kingdom,38225,81.4,64715810,,,,, 165 | Finland,38923,80.8,5503457,,,,, 166 | Belgium,41240,80.4,11299192,,,,, 167 | Iceland,42182,82.8,329425,,,,, 168 | Canada,43294,81.7,35939927,,,,, 169 | Denmark,43495,80.1,5669081,,,,, 170 | Germany,44053,81.1,80688545,,,,, 171 | Australia,44056,81.8,23968973,,,,, 172 | Bahrain,44138,79.2,1377237,,,,, 173 | Austria,44401,81,8544586,,,,, 174 | Sweden,44892,82,9779426,,,,, 175 | Netherlands,45784,80.6,16924929,,,,, 176 | Andorra,46577,84.1,70473,,,,, 177 | Ireland,47758,80.4,4688465,,,,, 178 | Oman,48226,75.7,4490541,,,,, 179 | Saudi Arabia,52469,78.1,31540372,,,,, 180 | United States,53354,79.1,321773631,,,,, 181 | Switzerland,56118,82.9,8298663,,,,, 182 | United Arab Emirates,60749,76.6,9156963,,,,, 183 | Norway,64304,81.6,5210967,,,,, 184 | Brunei,73003,78.7,423188,,,,, 185 | Singapore,80794,82.1,5603740,,,,, 186 | Kuwait,82633,80.7,3892115,,,,, 187 | Luxembourg,88314,81.1,567110,,,,, 188 | Qatar,132877,82,2235355,,,,, 189 | -------------------------------------------------------------------------------- /example-lifeExpectancy/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | 3 | int main() { 4 | // this kicks off the running of my app 5 | // can be OF_WINDOW or OF_FULLSCREEN 6 | // pass in width and height too: 7 | ofSetupOpenGL(750, 410, OF_WINDOW); 8 | 9 | ofRunApp(new ofApp()); 10 | } 11 | -------------------------------------------------------------------------------- /example-lifeExpectancy/src/ofApp.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | #include "ofxGrafica.h" 3 | 4 | //-------------------------------------------------------------- 5 | void ofApp::setup() { 6 | ofSetBackgroundColor(255); 7 | 8 | // Load the cvs dataset. 9 | // The file has the following format: 10 | // country,income,health,population 11 | // Central African Republic,599,53.8,4900274 12 | // ... 13 | ofBuffer buffer = ofBufferFromFile("data.csv"); 14 | 15 | // Save the data in one ofxGPoint vector and calculate the point sizes 16 | vector points; 17 | vector pointSizes; 18 | bool firstLine = true; 19 | 20 | for (auto line : buffer.getLines()) { 21 | // Skip the header 22 | if (firstLine) { 23 | firstLine = false; 24 | } else if (line.size() > 0) { 25 | vector columns = ofSplitString(line, ","); 26 | 27 | string country = columns[0]; 28 | float income = stof(columns[1]); 29 | float health = stof(columns[2]); 30 | int population = stoi(columns[3]); 31 | points.emplace_back(income, health, country); 32 | 33 | // The point area should be proportional to the country population 34 | // population = pi * sq(diameter/2) 35 | pointSizes.emplace_back(sqrt(population / (200000 * PI))); 36 | } 37 | } 38 | 39 | // Create the plot 40 | plot.setDim(650, 300); 41 | plot.setTitleText("Life expectancy connection to average income"); 42 | plot.getXAxis().setAxisLabelText("Personal income ($/year)"); 43 | plot.getYAxis().setAxisLabelText("Life expectancy (years)"); 44 | plot.setLogScale("x"); 45 | plot.setPoints(points); 46 | plot.setPointSizes(pointSizes); 47 | plot.activatePointLabels(); 48 | plot.activatePanning(); 49 | plot.activateZooming(1.1, OF_MOUSE_BUTTON_LEFT, OF_MOUSE_BUTTON_LEFT); 50 | } 51 | 52 | //-------------------------------------------------------------- 53 | void ofApp::update() { 54 | 55 | } 56 | 57 | //-------------------------------------------------------------- 58 | void ofApp::draw() { 59 | plot.beginDraw(); 60 | plot.drawBox(); 61 | plot.drawXAxis(); 62 | plot.drawYAxis(); 63 | plot.drawTitle(); 64 | plot.drawGridLines(GRAFICA_BOTH_DIRECTIONS); 65 | plot.drawPoints(); 66 | plot.drawLabels(); 67 | plot.endDraw(); 68 | } 69 | 70 | //-------------------------------------------------------------- 71 | void ofApp::keyPressed(int key) { 72 | 73 | } 74 | 75 | //-------------------------------------------------------------- 76 | void ofApp::keyReleased(int key) { 77 | 78 | } 79 | 80 | //-------------------------------------------------------------- 81 | void ofApp::mouseMoved(int x, int y) { 82 | 83 | } 84 | 85 | //-------------------------------------------------------------- 86 | void ofApp::mouseDragged(int x, int y, int button) { 87 | 88 | } 89 | 90 | //-------------------------------------------------------------- 91 | void ofApp::mousePressed(int x, int y, int button) { 92 | 93 | } 94 | 95 | //-------------------------------------------------------------- 96 | void ofApp::mouseReleased(int x, int y, int button) { 97 | 98 | } 99 | 100 | //-------------------------------------------------------------- 101 | void ofApp::windowResized(int w, int h) { 102 | 103 | } 104 | 105 | //-------------------------------------------------------------- 106 | void ofApp::gotMessage(ofMessage msg) { 107 | 108 | } 109 | 110 | //-------------------------------------------------------------- 111 | void ofApp::dragEvent(ofDragInfo dragInfo) { 112 | 113 | } 114 | -------------------------------------------------------------------------------- /example-lifeExpectancy/src/ofApp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ofxGrafica.h" 5 | 6 | class ofApp: public ofBaseApp { 7 | public: 8 | void setup(); 9 | void update(); 10 | void draw(); 11 | 12 | void keyPressed(int key); 13 | void keyReleased(int key); 14 | void mouseMoved(int x, int y); 15 | void mouseDragged(int x, int y, int button); 16 | void mousePressed(int x, int y, int button); 17 | void mouseReleased(int x, int y, int button); 18 | void windowResized(int w, int h); 19 | void dragEvent(ofDragInfo dragInfo); 20 | void gotMessage(ofMessage msg); 21 | 22 | ofxGPlot plot; 23 | }; 24 | -------------------------------------------------------------------------------- /example-movingPoints/Makefile: -------------------------------------------------------------------------------- 1 | # Attempt to load a config.make file. 2 | # If none is found, project defaults in config.project.make will be used. 3 | ifneq ($(wildcard config.make),) 4 | include config.make 5 | endif 6 | 7 | # make sure the the OF_ROOT location is defined 8 | ifndef OF_ROOT 9 | OF_ROOT=$(realpath ../../..) 10 | endif 11 | 12 | # call the project makefile! 13 | include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk 14 | -------------------------------------------------------------------------------- /example-movingPoints/addons.make: -------------------------------------------------------------------------------- 1 | #This file is currently only for linux users! 2 | #Add your addon and all other necessary ones here (without '#') 3 | #put every addon in one line, for example 4 | ofxGrafica 5 | -------------------------------------------------------------------------------- /example-movingPoints/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | 3 | int main() { 4 | // this kicks off the running of my app 5 | // can be OF_WINDOW or OF_FULLSCREEN 6 | // pass in width and height too: 7 | ofSetupOpenGL(450, 450, OF_WINDOW); 8 | 9 | ofRunApp(new ofApp()); 10 | } 11 | -------------------------------------------------------------------------------- /example-movingPoints/src/ofApp.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | #include "ofxGrafica.h" 3 | 4 | //-------------------------------------------------------------- 5 | void ofApp::setup() { 6 | ofSetBackgroundColor(150); 7 | 8 | // Initialize the sketch variables 9 | stepsPerCycle = 100; 10 | clockwise = true; 11 | scale = 5; 12 | step = 0; 13 | 14 | // Prepare the first set of points 15 | vector points1; 16 | 17 | for (int i = 0; i < 10; ++i) { 18 | points1.push_back(calculatePoint(step, stepsPerCycle, scale)); 19 | step = clockwise ? step + 1 : step - 1; 20 | } 21 | 22 | // Prepare the second set of points 23 | vector points2; 24 | 25 | for (int i = 0; i < stepsPerCycle + 1; ++i) { 26 | points2.push_back(calculatePoint(i, stepsPerCycle, 0.9 * scale)); 27 | } 28 | 29 | // Set the plot position and the dimension 30 | plot.setPos(25, 25); 31 | plot.setDim(300, 300); 32 | 33 | // Set the plot limits (this will fix them) 34 | plot.setXLim(-1.2 * scale, 1.2 * scale); 35 | plot.setYLim(-1.2 * scale, 1.2 * scale); 36 | 37 | // Set the plot title and the axis labels 38 | plot.setTitleText("Clockwise movement"); 39 | plot.getXAxis().setAxisLabelText("x axis"); 40 | plot.getYAxis().setAxisLabelText("y axis"); 41 | 42 | // Activate the panning effect 43 | plot.activatePanning(); 44 | 45 | // Add the two sets of points to the plot 46 | plot.setPoints(points1); 47 | plot.addLayer("surface", points2); 48 | 49 | // Change the second layer line color 50 | plot.getLayer("surface").setLineColor(ofColor(100, 255, 100)); 51 | } 52 | 53 | //-------------------------------------------------------------- 54 | ofxGPoint ofApp::calculatePoint(float i, float n, float rad) { 55 | float delta = 0.1 * cos(TWO_PI * 10 * i / n); 56 | float ang = TWO_PI * i / n; 57 | return ofxGPoint(rad * (1 + delta) * sin(ang), rad * (1 + delta) * cos(ang)); 58 | } 59 | 60 | //-------------------------------------------------------------- 61 | void ofApp::update() { 62 | // Add and remove new points every 10th of a second 63 | if (ofGetElapsedTimeMillis() > 100) { 64 | if (clockwise) { 65 | // Add the point at the end of the array 66 | plot.addPoint(calculatePoint(step, stepsPerCycle, scale)); 67 | ++step; 68 | 69 | // Remove the first point 70 | plot.removePoint(0); 71 | } else { 72 | // Add the point at the beginning of the array 73 | plot.addPoint(0, calculatePoint(step, stepsPerCycle, scale)); 74 | --step; 75 | 76 | // Remove the last point 77 | plot.removePoint(plot.getPointsRef().size() - 1); 78 | } 79 | 80 | // Reset the time 81 | ofResetElapsedTimeCounter(); 82 | } 83 | } 84 | 85 | //-------------------------------------------------------------- 86 | void ofApp::draw() { 87 | plot.beginDraw(); 88 | plot.drawBackground(); 89 | plot.drawBox(); 90 | plot.drawXAxis(); 91 | plot.drawYAxis(); 92 | plot.drawTopAxis(); 93 | plot.drawRightAxis(); 94 | plot.drawTitle(); 95 | plot.getMainLayer().drawPoints(); 96 | plot.getLayer("surface").drawFilledContour(GRAFICA_HORIZONTAL_CONTOUR, 0); 97 | plot.endDraw(); 98 | } 99 | 100 | //-------------------------------------------------------------- 101 | void ofApp::keyPressed(int key) { 102 | 103 | } 104 | 105 | //-------------------------------------------------------------- 106 | void ofApp::keyReleased(int key) { 107 | 108 | } 109 | 110 | //-------------------------------------------------------------- 111 | void ofApp::mouseMoved(int x, int y) { 112 | 113 | } 114 | 115 | //-------------------------------------------------------------- 116 | void ofApp::mouseDragged(int x, int y, int button) { 117 | 118 | } 119 | 120 | //-------------------------------------------------------------- 121 | void ofApp::mousePressed(int x, int y, int button) { 122 | 123 | } 124 | 125 | //-------------------------------------------------------------- 126 | void ofApp::mouseReleased(int x, int y, int button) { 127 | // Change the movement sense 128 | clockwise = !clockwise; 129 | 130 | if (clockwise) { 131 | step += plot.getPointsRef().size() + 1; 132 | plot.setTitleText("Clockwise movement"); 133 | } else { 134 | step -= plot.getPointsRef().size() + 1; 135 | plot.setTitleText("Anti-clockwise movement"); 136 | } 137 | } 138 | 139 | //-------------------------------------------------------------- 140 | void ofApp::windowResized(int w, int h) { 141 | 142 | } 143 | 144 | //-------------------------------------------------------------- 145 | void ofApp::gotMessage(ofMessage msg) { 146 | 147 | } 148 | 149 | //-------------------------------------------------------------- 150 | void ofApp::dragEvent(ofDragInfo dragInfo) { 151 | 152 | } 153 | -------------------------------------------------------------------------------- /example-movingPoints/src/ofApp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ofxGrafica.h" 5 | 6 | class ofApp: public ofBaseApp { 7 | public: 8 | void setup(); 9 | void update(); 10 | void draw(); 11 | 12 | void keyPressed(int key); 13 | void keyReleased(int key); 14 | void mouseMoved(int x, int y); 15 | void mouseDragged(int x, int y, int button); 16 | void mousePressed(int x, int y, int button); 17 | void mouseReleased(int x, int y, int button); 18 | void windowResized(int w, int h); 19 | void dragEvent(ofDragInfo dragInfo); 20 | void gotMessage(ofMessage msg); 21 | 22 | int stepsPerCycle; 23 | bool clockwise; 24 | float scale; 25 | int step; 26 | ofxGPlot plot; 27 | ofxGPoint calculatePoint(float i, float n, float rad); 28 | }; 29 | -------------------------------------------------------------------------------- /example-multiplePanels/Makefile: -------------------------------------------------------------------------------- 1 | # Attempt to load a config.make file. 2 | # If none is found, project defaults in config.project.make will be used. 3 | ifneq ($(wildcard config.make),) 4 | include config.make 5 | endif 6 | 7 | # make sure the the OF_ROOT location is defined 8 | ifndef OF_ROOT 9 | OF_ROOT=$(realpath ../../..) 10 | endif 11 | 12 | # call the project makefile! 13 | include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk 14 | -------------------------------------------------------------------------------- /example-multiplePanels/addons.make: -------------------------------------------------------------------------------- 1 | #This file is currently only for linux users! 2 | #Add your addon and all other necessary ones here (without '#') 3 | #put every addon in one line, for example 4 | ofxGrafica 5 | -------------------------------------------------------------------------------- /example-multiplePanels/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | 3 | int main() { 4 | // this kicks off the running of my app 5 | // can be OF_WINDOW or OF_FULLSCREEN 6 | // pass in width and height too: 7 | ofSetupOpenGL(500, 510, OF_WINDOW); 8 | 9 | ofRunApp(new ofApp()); 10 | } 11 | -------------------------------------------------------------------------------- /example-multiplePanels/src/ofApp.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | #include "ofxGrafica.h" 3 | 4 | //-------------------------------------------------------------- 5 | void ofApp::setup() { 6 | ofSetBackgroundColor(255); 7 | 8 | array firstPlotPos = { 0, 0 }; 9 | array panelDim = { 200, 200 }; 10 | array margins = { 60, 70, 40, 30 }; 11 | 12 | // Create four plots to represent the 4 panels 13 | plot1.setPos(firstPlotPos); 14 | plot1.setMar(0, margins[1], margins[2], 0); 15 | plot1.setDim(panelDim); 16 | plot1.setAxesOffset(0); 17 | plot1.setTicksLength(-4); 18 | plot1.getXAxis().setDrawTickLabels(false); 19 | 20 | plot2.setPos(firstPlotPos[0] + margins[1] + panelDim[0], firstPlotPos[1]); 21 | plot2.setMar(0, 0, margins[2], margins[3]); 22 | plot2.setDim(panelDim); 23 | plot2.setAxesOffset(0); 24 | plot2.setTicksLength(-4); 25 | plot2.getXAxis().setDrawTickLabels(false); 26 | plot2.getYAxis().setDrawTickLabels(false); 27 | 28 | plot3.setPos(firstPlotPos[0], firstPlotPos[1] + margins[2] + panelDim[1]); 29 | plot3.setMar(margins[0], margins[1], 0, 0); 30 | plot3.setDim(panelDim); 31 | plot3.setAxesOffset(0); 32 | plot3.setTicksLength(-4); 33 | 34 | plot4.setPos(firstPlotPos[0] + margins[1] + panelDim[0], firstPlotPos[1] + margins[2] + panelDim[1]); 35 | plot4.setMar(margins[0], 0, 0, margins[3]); 36 | plot4.setDim(panelDim); 37 | plot4.setAxesOffset(0); 38 | plot4.setTicksLength(-4); 39 | plot4.getYAxis().setDrawTickLabels(false); 40 | 41 | // Prepare the points for the four plots 42 | int nPoints = 21; 43 | vector points1; 44 | vector points2; 45 | vector points3; 46 | vector points4; 47 | 48 | for (int i = 0; i < nPoints; ++i) { 49 | points1.emplace_back(sin(TWO_PI * i / (nPoints - 1)), cos(TWO_PI * i / (nPoints - 1))); 50 | points2.emplace_back(i, cos(TWO_PI * i / (nPoints - 1))); 51 | points3.emplace_back(sin(TWO_PI * i / (nPoints - 1)), i); 52 | points4.emplace_back(i, i); 53 | } 54 | 55 | // Set the points, the title and the axis labels 56 | plot1.setPoints(points1); 57 | plot1.setTitleText("Plot with multiple panels"); 58 | plot1.getTitle().setRelativePos(1); 59 | plot1.getTitle().setTextAlignment(GRAFICA_CENTER_ALIGN); 60 | plot1.getYAxis().setAxisLabelText("cos(i)"); 61 | 62 | plot2.setPoints(points2); 63 | 64 | plot3.setPoints(points3); 65 | plot3.getXAxis().setAxisLabelText("sin(i)"); 66 | plot3.getYAxis().setAxisLabelText("i"); 67 | plot3.setInvertedYScale(true); 68 | 69 | plot4.setPoints(points4); 70 | plot4.getXAxis().setAxisLabelText("i"); 71 | plot4.setInvertedYScale(true); 72 | } 73 | 74 | //-------------------------------------------------------------- 75 | void ofApp::update() { 76 | 77 | } 78 | 79 | //-------------------------------------------------------------- 80 | void ofApp::draw() { 81 | plot1.beginDraw(); 82 | plot1.drawBox(); 83 | plot1.drawXAxis(); 84 | plot1.drawYAxis(); 85 | plot1.drawTopAxis(); 86 | plot1.drawRightAxis(); 87 | plot1.drawTitle(); 88 | plot1.drawPoints(); 89 | plot1.drawLines(); 90 | plot1.endDraw(); 91 | 92 | plot2.beginDraw(); 93 | plot2.drawBox(); 94 | plot2.drawXAxis(); 95 | plot2.drawYAxis(); 96 | plot2.drawTopAxis(); 97 | plot2.drawRightAxis(); 98 | plot2.drawPoints(); 99 | plot2.drawLines(); 100 | plot2.endDraw(); 101 | 102 | plot3.beginDraw(); 103 | plot3.drawBox(); 104 | plot3.drawXAxis(); 105 | plot3.drawYAxis(); 106 | plot3.drawTopAxis(); 107 | plot3.drawRightAxis(); 108 | plot3.drawPoints(); 109 | plot3.drawLines(); 110 | plot3.endDraw(); 111 | 112 | plot4.beginDraw(); 113 | plot4.drawBox(); 114 | plot4.drawXAxis(); 115 | plot4.drawYAxis(); 116 | plot4.drawTopAxis(); 117 | plot4.drawRightAxis(); 118 | plot4.drawPoints(); 119 | plot4.drawLines(); 120 | plot4.endDraw(); 121 | } 122 | 123 | //-------------------------------------------------------------- 124 | void ofApp::keyPressed(int key) { 125 | 126 | } 127 | 128 | //-------------------------------------------------------------- 129 | void ofApp::keyReleased(int key) { 130 | 131 | } 132 | 133 | //-------------------------------------------------------------- 134 | void ofApp::mouseMoved(int x, int y) { 135 | 136 | } 137 | 138 | //-------------------------------------------------------------- 139 | void ofApp::mouseDragged(int x, int y, int button) { 140 | 141 | } 142 | 143 | //-------------------------------------------------------------- 144 | void ofApp::mousePressed(int x, int y, int button) { 145 | 146 | } 147 | 148 | //-------------------------------------------------------------- 149 | void ofApp::mouseReleased(int x, int y, int button) { 150 | 151 | } 152 | 153 | //-------------------------------------------------------------- 154 | void ofApp::windowResized(int w, int h) { 155 | 156 | } 157 | 158 | //-------------------------------------------------------------- 159 | void ofApp::gotMessage(ofMessage msg) { 160 | 161 | } 162 | 163 | //-------------------------------------------------------------- 164 | void ofApp::dragEvent(ofDragInfo dragInfo) { 165 | 166 | } 167 | -------------------------------------------------------------------------------- /example-multiplePanels/src/ofApp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ofxGrafica.h" 5 | 6 | class ofApp: public ofBaseApp { 7 | public: 8 | void setup(); 9 | void update(); 10 | void draw(); 11 | 12 | void keyPressed(int key); 13 | void keyReleased(int key); 14 | void mouseMoved(int x, int y); 15 | void mouseDragged(int x, int y, int button); 16 | void mousePressed(int x, int y, int button); 17 | void mouseReleased(int x, int y, int button); 18 | void windowResized(int w, int h); 19 | void dragEvent(ofDragInfo dragInfo); 20 | void gotMessage(ofMessage msg); 21 | 22 | ofxGPlot plot1; 23 | ofxGPlot plot2; 24 | ofxGPlot plot3; 25 | ofxGPlot plot4; 26 | }; 27 | -------------------------------------------------------------------------------- /example-multiplePlots/Makefile: -------------------------------------------------------------------------------- 1 | # Attempt to load a config.make file. 2 | # If none is found, project defaults in config.project.make will be used. 3 | ifneq ($(wildcard config.make),) 4 | include config.make 5 | endif 6 | 7 | # make sure the the OF_ROOT location is defined 8 | ifndef OF_ROOT 9 | OF_ROOT=$(realpath ../../..) 10 | endif 11 | 12 | # call the project makefile! 13 | include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk 14 | -------------------------------------------------------------------------------- /example-multiplePlots/addons.make: -------------------------------------------------------------------------------- 1 | #This file is currently only for linux users! 2 | #Add your addon and all other necessary ones here (without '#') 3 | #put every addon in one line, for example 4 | ofxGrafica 5 | -------------------------------------------------------------------------------- /example-multiplePlots/bin/data/beermug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jagracar/ofxGrafica/dea9e974f2f181bba59d2de5adceb936d4e7c8c7/example-multiplePlots/bin/data/beermug.png -------------------------------------------------------------------------------- /example-multiplePlots/bin/data/beermug.svg: -------------------------------------------------------------------------------- 1 | 2 | 16 | 18 | 19 | 21 | image/svg+xml 22 | 24 | 25 | 26 | 27 | 29 | 53 | 56 | 58 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | 172 | 173 | -------------------------------------------------------------------------------- /example-multiplePlots/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | 3 | int main() { 4 | // this kicks off the running of my app 5 | // can be OF_WINDOW or OF_FULLSCREEN 6 | // pass in width and height too: 7 | ofSetupOpenGL(850, 660, OF_WINDOW); 8 | 9 | ofRunApp(new ofApp()); 10 | } 11 | -------------------------------------------------------------------------------- /example-multiplePlots/src/ofApp.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | #include "ofxGrafica.h" 3 | 4 | //-------------------------------------------------------------- 5 | void ofApp::setup() { 6 | ofSetBackgroundColor(255); 7 | 8 | // Prepare the points for the first plot 9 | vector points1a; 10 | vector points1b; 11 | vector points1c; 12 | 13 | for (int i = 0; i < 500; ++i) { 14 | points1a.emplace_back(i, ofNoise(0.1 * i) + 1, "point " + to_string(i)); 15 | points1b.emplace_back(i, ofNoise(0.1 * i + 500) + 0.5, "point " + to_string(i)); 16 | points1c.emplace_back(i, ofNoise(0.1 * i + 1000), "point " + to_string(i)); 17 | } 18 | 19 | // Create a polygon to display inside the plot 20 | polygonPoints.emplace_back(2, 0.15); 21 | polygonPoints.emplace_back(6, 0.12); 22 | polygonPoints.emplace_back(15, 0.3); 23 | polygonPoints.emplace_back(8, 0.6); 24 | polygonPoints.emplace_back(1.5, 0.5); 25 | 26 | // Load and resize the beer mug image 27 | mug.load("beermug.png"); 28 | mug.resize(0.5 * mug.getWidth(), 0.5 * mug.getHeight()); 29 | 30 | // Setup for the first plot 31 | plot1.setPos(0, 0); 32 | plot1.setXLim(1, 100); 33 | plot1.setYLim(0.1, 3); 34 | plot1.getTitle().setText("Multiple layers plot"); 35 | plot1.getXAxis().getAxisLabel().setText("time"); 36 | plot1.getYAxis().getAxisLabel().setText("ofNoise(0.1 time)"); 37 | plot1.setLogScale("xy"); 38 | plot1.setPoints(points1a); 39 | plot1.setLineColor(ofColor(200, 200, 255)); 40 | plot1.addLayer("layer 1", points1b); 41 | plot1.getLayer("layer 1").setLineColor(ofColor(150, 150, 255)); 42 | plot1.addLayer("layer 2", points1c); 43 | plot1.getLayer("layer 2").setLineColor(ofColor(100, 100, 255)); 44 | 45 | // Leave empty the points for the second plot. We will fill them in the update method 46 | trackingMouse = false; 47 | 48 | // Create the star path that will be used as points symbol 49 | star.moveTo(7, 0); 50 | 51 | for (int i = 1; i < 5; ++i) { 52 | star.lineTo(3 * cos(TWO_PI * i / 5 - TWO_PI / 10), 3 * sin(TWO_PI * i / 5 - TWO_PI / 10)); 53 | star.lineTo(7 * cos(TWO_PI * i / 5), 7 * sin(TWO_PI * i / 5)); 54 | } 55 | 56 | star.lineTo(3 * cos(TWO_PI - TWO_PI / 10), 3 * sin(TWO_PI - TWO_PI / 10)); 57 | 58 | // Setup for the second plot 59 | plot2.setPos(460, 0); 60 | plot2.setDim(250, 250); 61 | plot2.getTitle().setText("Mouse position"); 62 | plot2.getXAxis().getAxisLabel().setText("mouseX"); 63 | plot2.getYAxis().getAxisLabel().setText("-mouseY"); 64 | 65 | // Prepare the points for the third plot 66 | gaussianCounter = 0; 67 | generator = default_random_engine(); 68 | distribution = normal_distribution(0.0, 1.0); 69 | int gaussianStackSize = gaussianStack.size(); 70 | 71 | for (int i = 0; i < 20; ++i) { 72 | int index = gaussianStackSize / 2.0 + distribution(generator); 73 | 74 | if (index >= 0 && index < gaussianStackSize) { 75 | ++gaussianStack[index]; 76 | ++gaussianCounter; 77 | } 78 | } 79 | 80 | vector points3; 81 | 82 | for (int i = 0; i < gaussianStackSize; ++i) { 83 | points3.emplace_back(i + 0.5 - gaussianStackSize / 2.0, gaussianStack[i] / gaussianCounter, "H" + to_string(i)); 84 | } 85 | 86 | // Setup for the third plot 87 | plot3.setPos(0, 300); 88 | plot3.setDim(250, 250); 89 | plot3.setYLim(-0.02, 0.45); 90 | plot3.setXLim(-5, 5); 91 | plot3.getTitle().setText("Gaussian distribution (" + to_string(gaussianCounter) + " points)"); 92 | plot3.getTitle().setTextAlignment(GRAFICA_LEFT_ALIGN); 93 | plot3.getTitle().setRelativePos(0); 94 | plot3.getYAxis().getAxisLabel().setText("Relative probability"); 95 | plot3.getYAxis().getAxisLabel().setTextAlignment(GRAFICA_RIGHT_ALIGN); 96 | plot3.getYAxis().getAxisLabel().setRelativePos(1); 97 | plot3.setPoints(points3); 98 | plot3.startHistograms(GRAFICA_VERTICAL_HISTOGRAM); 99 | plot3.getHistogram().setDrawLabels(true); 100 | plot3.getHistogram().setRotateLabels(true); 101 | plot3.getHistogram().setBgColors( { ofColor(0, 0, 255, 50), ofColor(0, 0, 255, 100), ofColor(0, 0, 255, 150), 102 | ofColor(0, 0, 255, 200) }); 103 | 104 | // Prepare the points for the fourth plot 105 | uniformCounter = 0; 106 | int uniformStackSize = uniformStack.size(); 107 | 108 | for (int i = 0; i < 20; ++i) { 109 | int index = ofRandom(uniformStackSize); 110 | 111 | if (index >= 0 && index < uniformStackSize) { 112 | ++uniformStack[index]; 113 | ++uniformCounter; 114 | } 115 | } 116 | 117 | vector points4; 118 | 119 | for (int i = 0; i < uniformStackSize; ++i) { 120 | points4.emplace_back(i + 0.5 - uniformStackSize / 2.0, uniformStack[i] / uniformCounter, 121 | "point " + to_string(i)); 122 | } 123 | 124 | // Setup for the fourth plot 125 | plot4.setPos(370, 350); 126 | plot4.setYLim(-0.005, 0.1); 127 | plot4.getTitle().setText("Uniform distribution (" + to_string(uniformCounter) + " points)"); 128 | plot4.getTitle().setTextAlignment(GRAFICA_LEFT_ALIGN); 129 | plot4.getTitle().setRelativePos(0.1); 130 | plot4.getXAxis().getAxisLabel().setText("x variable"); 131 | plot4.getYAxis().getAxisLabel().setText("Relative probability"); 132 | plot4.setPoints(points4); 133 | plot4.startHistograms(GRAFICA_VERTICAL_HISTOGRAM); 134 | 135 | // Setup the mouse actions 136 | plot1.activatePanning(); 137 | plot1.activateZooming(1.2, OF_MOUSE_BUTTON_LEFT, OF_MOUSE_BUTTON_LEFT); 138 | plot1.activatePointLabels(); 139 | plot2.activateZooming(1.5); 140 | plot3.activateCentering(OF_MOUSE_BUTTON_LEFT, OF_KEY_LEFT_CONTROL); 141 | plot4.activateZooming(); 142 | } 143 | 144 | //-------------------------------------------------------------- 145 | void ofApp::update() { 146 | // Add a news points to the second plot 147 | if (trackingMouse) { 148 | if (plot2.getPointsRef().size() == 0) { 149 | plot2.addPoint(mouseX, -mouseY, "(" + to_string(mouseX) + " , " + to_string(-mouseY) + ")"); 150 | } else { 151 | // Add a new point only if the mouse moved significantly 152 | const ofxGPoint lastPoint = plot2.getPointsRef().back(); 153 | 154 | if (!lastPoint.isValid() || pow(lastPoint.getX() - mouseX, 2) + pow(lastPoint.getY() + mouseY, 2) > 2500) { 155 | plot2.addPoint(mouseX, -mouseY, "(" + to_string(mouseX) + " , " + to_string(-mouseY) + ")"); 156 | } 157 | } 158 | } 159 | 160 | // Add one more point to the gaussian stack 161 | int gaussianStackSize = gaussianStack.size(); 162 | int index = gaussianStackSize / 2.0 + distribution(generator); 163 | 164 | if (index >= 0 && index < gaussianStackSize) { 165 | gaussianStack[index]++; 166 | gaussianCounter++; 167 | 168 | vector points3; 169 | 170 | for (int i = 0; i < gaussianStackSize; ++i) { 171 | points3.emplace_back(i + 0.5 - gaussianStackSize / 2.0, gaussianStack[i] / gaussianCounter, 172 | "H" + to_string(i)); 173 | } 174 | 175 | plot3.setPoints(points3); 176 | plot3.getTitle().setText("Gaussian distribution (" + to_string(gaussianCounter) + " points)"); 177 | } 178 | 179 | // Add one more point to the uniform stack 180 | int uniformStackSize = uniformStack.size(); 181 | index = ofRandom(uniformStackSize); 182 | 183 | if (index >= 0 && index < uniformStackSize) { 184 | uniformStack[index]++; 185 | uniformCounter++; 186 | 187 | vector points4; 188 | 189 | for (int i = 0; i < uniformStackSize; ++i) { 190 | points4.emplace_back(i + 0.5 - uniformStackSize / 2.0, uniformStack[i] / uniformCounter, 191 | "point " + to_string(i)); 192 | } 193 | 194 | plot4.setPoints(points4); 195 | plot4.getTitle().setText("Uniform distribution (" + to_string(uniformCounter) + " points)"); 196 | } 197 | 198 | // Actions over the fourth plot (scrolling) 199 | if (plot4.isOverBox(mouseX, mouseY)) { 200 | // Get the cursor relative position inside the inner plot area 201 | array relativePos = plot4.getRelativePlotPosAt(mouseX, mouseY); 202 | 203 | // Move the x axis 204 | if (relativePos[0] < 0.2) { 205 | plot4.moveHorizontalAxesLim(2); 206 | } else if (relativePos[0] > 0.8) { 207 | plot4.moveHorizontalAxesLim(-2); 208 | } 209 | 210 | // Move the y axis 211 | if (relativePos[1] < 0.2) { 212 | plot4.moveVerticalAxesLim(2); 213 | } else if (relativePos[1] > 0.8) { 214 | plot4.moveVerticalAxesLim(-2); 215 | } 216 | 217 | // Change the inner area bg color 218 | plot4.setBoxBgColor(ofColor(255, 255, 100, 50)); 219 | } else { 220 | plot4.setBoxBgColor(ofColor(200, 50)); 221 | } 222 | } 223 | 224 | //-------------------------------------------------------------- 225 | void ofApp::draw() { 226 | // Draw the first plot 227 | plot1.beginDraw(); 228 | plot1.drawBackground(); 229 | plot1.drawBox(); 230 | plot1.drawXAxis(); 231 | plot1.drawYAxis(); 232 | plot1.drawTopAxis(); 233 | plot1.drawRightAxis(); 234 | plot1.drawTitle(); 235 | plot1.drawFilledContours(GRAFICA_HORIZONTAL_CONTOUR, 0.05); 236 | plot1.drawPoint(ofxGPoint(65, 1.5), mug); 237 | plot1.drawPolygon(polygonPoints, ofColor(255, 200)); 238 | plot1.drawLabels(); 239 | plot1.endDraw(); 240 | 241 | // Draw the second plot 242 | plot2.beginDraw(); 243 | plot2.drawBackground(); 244 | plot2.drawBox(); 245 | plot2.drawXAxis(); 246 | plot2.drawYAxis(); 247 | plot2.drawTitle(); 248 | plot2.drawGridLines(GRAFICA_BOTH_DIRECTIONS); 249 | plot2.drawLines(); 250 | plot2.drawPoints(star); 251 | plot2.endDraw(); 252 | 253 | // Draw the third plot 254 | plot3.beginDraw(); 255 | plot3.drawBackground(); 256 | plot3.drawBox(); 257 | plot3.drawYAxis(); 258 | plot3.drawTitle(); 259 | plot3.drawHistograms(); 260 | plot3.endDraw(); 261 | 262 | // Draw the forth plot 263 | plot4.beginDraw(); 264 | plot4.drawBackground(); 265 | plot4.drawBox(); 266 | plot4.drawXAxis(); 267 | plot4.drawYAxis(); 268 | plot4.drawTitle(); 269 | plot4.drawHistograms(); 270 | plot4.endDraw(); 271 | } 272 | 273 | //-------------------------------------------------------------- 274 | void ofApp::keyPressed(int key) { 275 | 276 | } 277 | 278 | //-------------------------------------------------------------- 279 | void ofApp::keyReleased(int key) { 280 | // Clear the points from the second plot if the user pressed the space bar 281 | if (key == ' ') { 282 | vector emptyPoints; 283 | plot2.setPoints(emptyPoints); 284 | } 285 | } 286 | 287 | //-------------------------------------------------------------- 288 | void ofApp::mouseEntered(int x, int y) { 289 | if (!trackingMouse) { 290 | trackingMouse = true; 291 | } 292 | } 293 | 294 | //-------------------------------------------------------------- 295 | void ofApp::mouseMoved(int x, int y) { 296 | 297 | } 298 | 299 | //-------------------------------------------------------------- 300 | void ofApp::mouseDragged(int x, int y, int button) { 301 | 302 | } 303 | 304 | //-------------------------------------------------------------- 305 | void ofApp::mousePressed(int x, int y, int button) { 306 | 307 | } 308 | 309 | //-------------------------------------------------------------- 310 | void ofApp::mouseReleased(int x, int y, int button) { 311 | 312 | } 313 | 314 | //-------------------------------------------------------------- 315 | void ofApp::windowResized(int w, int h) { 316 | 317 | } 318 | 319 | //-------------------------------------------------------------- 320 | void ofApp::gotMessage(ofMessage msg) { 321 | 322 | } 323 | 324 | //-------------------------------------------------------------- 325 | void ofApp::dragEvent(ofDragInfo dragInfo) { 326 | 327 | } 328 | -------------------------------------------------------------------------------- /example-multiplePlots/src/ofApp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ofxGrafica.h" 5 | #include 6 | 7 | class ofApp: public ofBaseApp { 8 | public: 9 | void setup(); 10 | void update(); 11 | void draw(); 12 | 13 | void keyPressed(int key); 14 | void keyReleased(int key); 15 | void mouseMoved(int x, int y); 16 | void mouseDragged(int x, int y, int button); 17 | void mousePressed(int x, int y, int button); 18 | void mouseReleased(int x, int y, int button); 19 | void mouseEntered(int x, int y); 20 | void windowResized(int w, int h); 21 | void dragEvent(ofDragInfo dragInfo); 22 | void gotMessage(ofMessage msg); 23 | 24 | ofxGPlot plot1, plot2, plot3, plot4; 25 | vector polygonPoints; 26 | ofImage mug; 27 | bool trackingMouse; 28 | ofPath star; 29 | int gaussianCounter; 30 | array gaussianStack; 31 | default_random_engine generator; 32 | normal_distribution distribution; 33 | int uniformCounter; 34 | array uniformStack; 35 | }; 36 | -------------------------------------------------------------------------------- /example-oktoberfest/Makefile: -------------------------------------------------------------------------------- 1 | # Attempt to load a config.make file. 2 | # If none is found, project defaults in config.project.make will be used. 3 | ifneq ($(wildcard config.make),) 4 | include config.make 5 | endif 6 | 7 | # make sure the the OF_ROOT location is defined 8 | ifndef OF_ROOT 9 | OF_ROOT=$(realpath ../../..) 10 | endif 11 | 12 | # call the project makefile! 13 | include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk 14 | -------------------------------------------------------------------------------- /example-oktoberfest/addons.make: -------------------------------------------------------------------------------- 1 | #This file is currently only for linux users! 2 | #Add your addon and all other necessary ones here (without '#') 3 | #put every addon in one line, for example 4 | ofxGrafica 5 | -------------------------------------------------------------------------------- /example-oktoberfest/bin/data/OktoberfestVSGermanElections.csv: -------------------------------------------------------------------------------- 1 | year,month,day,oktoberfest,bundestagswahl 2 | 2004,0,1,5,1 3 | 2004,1,1,4,1 4 | 2004,2,1,6,1 5 | 2004,3,1,5,1 6 | 2004,4,1,6,1 7 | 2004,5,1,8,1 8 | 2004,6,1,12,1 9 | 2004,7,1,26,0 10 | 2004,8,1,84,1 11 | 2004,9,1,38,1 12 | 2004,10,1,5,1 13 | 2004,11,1,4,1 14 | 2005,0,1,5,1 15 | 2005,1,1,5,1 16 | 2005,2,1,5,1 17 | 2005,3,1,6,1 18 | 2005,4,1,7,2 19 | 2005,5,1,9,3 20 | 2005,6,1,12,4 21 | 2005,7,1,23,16 22 | 2005,8,1,81,64 23 | 2005,9,1,39,5 24 | 2005,10,1,5,2 25 | 2005,11,1,4,1 26 | 2006,0,1,5,1 27 | 2006,1,1,4,1 28 | 2006,2,1,5,1 29 | 2006,3,1,5,1 30 | 2006,4,1,6,0 31 | 2006,5,1,7,1 32 | 2006,6,1,11,0 33 | 2006,7,1,25,0 34 | 2006,8,1,76,1 35 | 2006,9,1,38,1 36 | 2006,10,1,5,1 37 | 2006,11,1,3,0 38 | 2007,0,1,5,0 39 | 2007,1,1,5,0 40 | 2007,2,1,5,1 41 | 2007,3,1,6,0 42 | 2007,4,1,7,0 43 | 2007,5,1,9,1 44 | 2007,6,1,12,0 45 | 2007,7,1,24,0 46 | 2007,8,1,79,0 47 | 2007,9,1,46,1 48 | 2007,10,1,5,1 49 | 2007,11,1,3,0 50 | 2008,0,1,5,1 51 | 2008,1,1,5,1 52 | 2008,2,1,5,1 53 | 2008,3,1,6,0 54 | 2008,4,1,6,0 55 | 2008,5,1,7,0 56 | 2008,6,1,11,0 57 | 2008,7,1,22,0 58 | 2008,8,1,77,1 59 | 2008,9,1,44,1 60 | 2008,10,1,5,1 61 | 2008,11,1,3,1 62 | 2009,0,1,4,2 63 | 2009,1,1,5,1 64 | 2009,2,1,5,1 65 | 2009,3,1,5,1 66 | 2009,4,1,6,2 67 | 2009,5,1,8,3 68 | 2009,6,1,12,3 69 | 2009,7,1,24,12 70 | 2009,8,1,91,79 71 | 2009,9,1,53,5 72 | 2009,10,1,6,2 73 | 2009,11,1,4,1 74 | 2010,0,1,5,2 75 | 2010,1,1,5,1 76 | 2010,2,1,6,1 77 | 2010,3,1,6,1 78 | 2010,4,1,7,1 79 | 2010,5,1,8,1 80 | 2010,6,1,13,0 81 | 2010,7,1,27,0 82 | 2010,8,1,100,1 83 | 2010,9,1,59,1 84 | 2010,10,1,7,1 85 | 2010,11,1,4,0 86 | 2011,0,1,5,1 87 | 2011,1,1,5,1 88 | 2011,2,1,5,1 89 | 2011,3,1,5,0 90 | 2011,4,1,7,1 91 | 2011,5,1,8,0 92 | 2011,6,1,13,0 93 | 2011,7,1,26,0 94 | 2011,8,1,95,1 95 | 2011,9,1,64,1 96 | 2011,10,1,10,1 97 | 2011,11,1,6,0 98 | 2012,0,1,6,1 99 | 2012,1,1,5,1 100 | 2012,2,1,5,1 101 | 2012,3,1,6,1 102 | 2012,4,1,7,1 103 | 2012,5,1,8,0 104 | 2012,6,1,13,0 105 | 2012,7,1,28,0 106 | 2012,8,1,97,1 107 | 2012,9,1,69,1 108 | 2012,10,1,9,1 109 | 2012,11,1,5,1 110 | 2013,0,1,5,2 111 | 2013,1,1,5,1 112 | 2013,2,1,5,1 113 | 2013,3,1,6,1 114 | 2013,4,1,7,2 115 | 2013,5,1,8,2 116 | 2013,6,1,11,3 117 | 2013,7,1,27,16 118 | 2013,8,1,64,32 119 | -------------------------------------------------------------------------------- /example-oktoberfest/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | 3 | int main() { 4 | // this kicks off the running of my app 5 | // can be OF_WINDOW or OF_FULLSCREEN 6 | // pass in width and height too: 7 | ofSetupOpenGL(800, 410, OF_WINDOW); 8 | 9 | ofRunApp(new ofApp()); 10 | } 11 | -------------------------------------------------------------------------------- /example-oktoberfest/src/ofApp.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | #include "ofxGrafica.h" 3 | 4 | //-------------------------------------------------------------- 5 | void ofApp::setup() { 6 | ofSetBackgroundColor(255); 7 | 8 | monthNames = {"January", "February", "March", "April", "May", "June", "July", 9 | "August", "September", "October", "November", "December"}; 10 | daysPerMonth = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 11 | daysPerMonthLeapYear = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 12 | 13 | // Load the Oktoberfest vs. Bundestagswahl (German elections day) Google 14 | // search history file (obtained from the Google trends page). 15 | // The csv file has the following format: 16 | // year,month,day,oktoberfest,bundestagswahl 17 | // 2004,0,1,5,1 18 | // ... 19 | ofBuffer buffer = ofBufferFromFile("OktoberfestVSGermanElections.csv"); 20 | 21 | // Save the data in two ofxGPoint vectors 22 | vector pointsOktoberfest; 23 | vector pointsElections; 24 | bool firstLine = true; 25 | 26 | for (auto line : buffer.getLines()) { 27 | // Skip the header 28 | if (firstLine) { 29 | firstLine = false; 30 | } else if (line.size() > 0) { 31 | vector columns = ofSplitString(line, ","); 32 | 33 | int year = stoi(columns[0]); 34 | int month = stoi(columns[1]); 35 | int day = stoi(columns[2]); 36 | int oktoberfestCount = stoi(columns[3]); 37 | int electionsCount = stoi(columns[4]); 38 | float date = getExactDate(year, month, day); 39 | 40 | pointsOktoberfest.emplace_back(date, oktoberfestCount, monthNames[month]); 41 | pointsElections.emplace_back(date, electionsCount, monthNames[month]); 42 | } 43 | } 44 | 45 | // Create the plot 46 | plot.setDim(700, 300); 47 | plot.setTitleText("Oktoberfest vs. Bundestagwahl Google search history"); 48 | plot.getXAxis().setAxisLabelText("Year"); 49 | plot.getYAxis().setAxisLabelText("Google normalized searches"); 50 | plot.getXAxis().setNTicks(10); 51 | plot.setPoints(pointsOktoberfest); 52 | plot.setLineColor(ofColor(100, 100, 100)); 53 | plot.addLayer("German elections day", pointsElections); 54 | plot.getLayer("German elections day").setLineColor(ofColor(255, 100, 255)); 55 | plot.activatePointLabels(); 56 | } 57 | 58 | //-------------------------------------------------------------- 59 | float ofApp::getExactDate(int year, int month, int day) { 60 | bool leapYear = false; 61 | 62 | if (year % 400 == 0) { 63 | leapYear = true; 64 | } else if (year % 100 == 0) { 65 | leapYear = false; 66 | } else if (year % 4 == 0) { 67 | leapYear = true; 68 | } 69 | 70 | if (leapYear) { 71 | return year + (month + (day - 1.0) / daysPerMonthLeapYear[month]) / 12.0; 72 | } else { 73 | return year + (month + (day - 1.0) / daysPerMonth[month]) / 12.0; 74 | } 75 | } 76 | 77 | //-------------------------------------------------------------- 78 | void ofApp::update() { 79 | 80 | } 81 | 82 | //-------------------------------------------------------------- 83 | void ofApp::draw() { 84 | plot.beginDraw(); 85 | plot.drawBox(); 86 | plot.drawXAxis(); 87 | plot.drawYAxis(); 88 | plot.drawTitle(); 89 | plot.drawGridLines(GRAFICA_VERTICAL_DIRECTION); 90 | plot.drawFilledContours(GRAFICA_HORIZONTAL_CONTOUR, 0); 91 | plot.drawLegend( { "Oktoberfest", "Bundestagswahl" }, { 0.07, 0.22 }, { 0.92, 0.92 }); 92 | plot.drawLabels(); 93 | plot.endDraw(); 94 | } 95 | 96 | //-------------------------------------------------------------- 97 | void ofApp::keyPressed(int key) { 98 | 99 | } 100 | 101 | //-------------------------------------------------------------- 102 | void ofApp::keyReleased(int key) { 103 | 104 | } 105 | 106 | //-------------------------------------------------------------- 107 | void ofApp::mouseMoved(int x, int y) { 108 | 109 | } 110 | 111 | //-------------------------------------------------------------- 112 | void ofApp::mouseDragged(int x, int y, int button) { 113 | 114 | } 115 | 116 | //-------------------------------------------------------------- 117 | void ofApp::mousePressed(int x, int y, int button) { 118 | 119 | } 120 | 121 | //-------------------------------------------------------------- 122 | void ofApp::mouseReleased(int x, int y, int button) { 123 | 124 | } 125 | 126 | //-------------------------------------------------------------- 127 | void ofApp::windowResized(int w, int h) { 128 | 129 | } 130 | 131 | //-------------------------------------------------------------- 132 | void ofApp::gotMessage(ofMessage msg) { 133 | 134 | } 135 | 136 | //-------------------------------------------------------------- 137 | void ofApp::dragEvent(ofDragInfo dragInfo) { 138 | 139 | } 140 | -------------------------------------------------------------------------------- /example-oktoberfest/src/ofApp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ofxGrafica.h" 5 | 6 | class ofApp: public ofBaseApp { 7 | public: 8 | void setup(); 9 | void update(); 10 | void draw(); 11 | 12 | void keyPressed(int key); 13 | void keyReleased(int key); 14 | void mouseMoved(int x, int y); 15 | void mouseDragged(int x, int y, int button); 16 | void mousePressed(int x, int y, int button); 17 | void mouseReleased(int x, int y, int button); 18 | void windowResized(int w, int h); 19 | void dragEvent(ofDragInfo dragInfo); 20 | void gotMessage(ofMessage msg); 21 | 22 | ofxGPlot plot; 23 | vector monthNames; 24 | vector daysPerMonth; 25 | vector daysPerMonthLeapYear; 26 | float getExactDate(int year, int month, int day); 27 | }; 28 | -------------------------------------------------------------------------------- /example-twoVerticalAxes/Makefile: -------------------------------------------------------------------------------- 1 | # Attempt to load a config.make file. 2 | # If none is found, project defaults in config.project.make will be used. 3 | ifneq ($(wildcard config.make),) 4 | include config.make 5 | endif 6 | 7 | # make sure the the OF_ROOT location is defined 8 | ifndef OF_ROOT 9 | OF_ROOT=$(realpath ../../..) 10 | endif 11 | 12 | # call the project makefile! 13 | include $(OF_ROOT)/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk 14 | -------------------------------------------------------------------------------- /example-twoVerticalAxes/addons.make: -------------------------------------------------------------------------------- 1 | #This file is currently only for linux users! 2 | #Add your addon and all other necessary ones here (without '#') 3 | #put every addon in one line, for example 4 | ofxGrafica 5 | -------------------------------------------------------------------------------- /example-twoVerticalAxes/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | 3 | int main() { 4 | // this kicks off the running of my app 5 | // can be OF_WINDOW or OF_FULLSCREEN 6 | // pass in width and height too: 7 | ofSetupOpenGL(440, 420, OF_WINDOW); 8 | 9 | ofRunApp(new ofApp()); 10 | } 11 | -------------------------------------------------------------------------------- /example-twoVerticalAxes/src/ofApp.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | #include "ofxGrafica.h" 3 | 4 | //-------------------------------------------------------------- 5 | void ofApp::setup() { 6 | ofSetBackgroundColor(255); 7 | 8 | // Create the first plot 9 | plot1.setPos(0, 0); 10 | plot1.setMar(60, 70, 40, 70); 11 | plot1.setDim(300, 300); 12 | plot1.setAxesOffset(4); 13 | plot1.setTicksLength(4); 14 | 15 | // Create the second plot with the same dimensions 16 | plot2.setPos(plot1.getPos()); 17 | plot2.setMar(plot1.getMar()); 18 | plot2.setDim(plot1.getDim()); 19 | plot2.setAxesOffset(4); 20 | plot2.setTicksLength(4); 21 | 22 | // Prepare the points 23 | int nPoints = 50; 24 | vector points; 25 | 26 | for (int i = 0; i < nPoints; ++i) { 27 | points.emplace_back(i, 30 + 10 * ofNoise(0.1 * i)); 28 | } 29 | 30 | // Set the points, the title and the axis labels 31 | plot1.setPoints(points); 32 | plot1.setTitleText("Temperature"); 33 | plot1.getYAxis().setAxisLabelText("T (Celsius)"); 34 | plot1.getXAxis().setAxisLabelText("Time (minutes)"); 35 | 36 | plot2.getRightAxis().setAxisLabelText("T (Kelvin)"); 37 | 38 | // Make the right axis of the second plot visible 39 | plot2.getRightAxis().setDrawTickLabels(true); 40 | 41 | // Activate the panning (only for the first plot) 42 | plot1.activatePanning(); 43 | } 44 | 45 | //-------------------------------------------------------------- 46 | float ofApp::celsiusToKelvin(float celsius) { 47 | return 273.15 + celsius; 48 | } 49 | 50 | //-------------------------------------------------------------- 51 | void ofApp::update() { 52 | // Change the second plot vertical scale from Celsius to Kelvin 53 | array yLim = plot1.getYLim(); 54 | plot2.setYLim(celsiusToKelvin(yLim[0]), celsiusToKelvin(yLim[1])); 55 | } 56 | 57 | //-------------------------------------------------------------- 58 | void ofApp::draw() { 59 | // Draw the first plot 60 | plot1.beginDraw(); 61 | plot1.drawBox(); 62 | plot1.drawXAxis(); 63 | plot1.drawYAxis(); 64 | plot1.drawTitle(); 65 | plot1.drawPoints(); 66 | plot1.drawLines(); 67 | plot1.endDraw(); 68 | 69 | // Draw only the right axis 70 | plot2.beginDraw(); 71 | plot2.drawRightAxis(); 72 | plot2.endDraw(); 73 | } 74 | 75 | //-------------------------------------------------------------- 76 | void ofApp::keyPressed(int key) { 77 | 78 | } 79 | 80 | //-------------------------------------------------------------- 81 | void ofApp::keyReleased(int key) { 82 | 83 | } 84 | 85 | //-------------------------------------------------------------- 86 | void ofApp::mouseMoved(int x, int y) { 87 | 88 | } 89 | 90 | //-------------------------------------------------------------- 91 | void ofApp::mouseDragged(int x, int y, int button) { 92 | 93 | } 94 | 95 | //-------------------------------------------------------------- 96 | void ofApp::mousePressed(int x, int y, int button) { 97 | 98 | } 99 | 100 | //-------------------------------------------------------------- 101 | void ofApp::mouseReleased(int x, int y, int button) { 102 | 103 | } 104 | 105 | //-------------------------------------------------------------- 106 | void ofApp::windowResized(int w, int h) { 107 | 108 | } 109 | 110 | //-------------------------------------------------------------- 111 | void ofApp::gotMessage(ofMessage msg) { 112 | 113 | } 114 | 115 | //-------------------------------------------------------------- 116 | void ofApp::dragEvent(ofDragInfo dragInfo) { 117 | 118 | } 119 | -------------------------------------------------------------------------------- /example-twoVerticalAxes/src/ofApp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ofxGrafica.h" 5 | 6 | class ofApp: public ofBaseApp { 7 | public: 8 | void setup(); 9 | void update(); 10 | void draw(); 11 | 12 | void keyPressed(int key); 13 | void keyReleased(int key); 14 | void mouseMoved(int x, int y); 15 | void mouseDragged(int x, int y, int button); 16 | void mousePressed(int x, int y, int button); 17 | void mouseReleased(int x, int y, int button); 18 | void windowResized(int w, int h); 19 | void dragEvent(ofDragInfo dragInfo); 20 | void gotMessage(ofMessage msg); 21 | 22 | ofxGPlot plot1; 23 | ofxGPlot plot2; 24 | float celsiusToKelvin(float celsius); 25 | }; 26 | -------------------------------------------------------------------------------- /license.md: -------------------------------------------------------------------------------- 1 | The code in this repository is available under the [MIT License](https://secure.wikimedia.org/wikipedia/en/wiki/Mit_license). 2 | 3 | Copyright (c) 2018 Javier Graciá Carpio 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /ofxaddons_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jagracar/ofxGrafica/dea9e974f2f181bba59d2de5adceb936d4e7c8c7/ofxaddons_thumbnail.png -------------------------------------------------------------------------------- /src/ofxGAxis.cpp: -------------------------------------------------------------------------------- 1 | #include "ofxGAxis.h" 2 | #include "ofxGConstants.h" 3 | #include "ofxGAxisLabel.h" 4 | #include "ofMain.h" 5 | 6 | ofxGAxis::ofxGAxis(ofxGAxisType _type, const array& _dim, const array& _lim, bool _logScale) : 7 | type(_type), dim(_dim), lim(_lim), logScale(_logScale) { 8 | // Do some sanity checks 9 | if (logScale && (lim[0] <= 0 || lim[1] <= 0)) { 10 | throw invalid_argument("The axis limits are negative and this is not allowed in logarithmic scale."); 11 | } 12 | 13 | // Format properties 14 | offset = 5; 15 | lineColor = ofColor(0); 16 | lineWidth = 1; 17 | 18 | // Ticks properties 19 | nTicks = 5; 20 | ticksSeparation = -1; 21 | fixedTicks = false; 22 | tickLength = 3; 23 | smallTickLength = 2; 24 | expTickLabels = false; 25 | rotateTickLabels = (type == GRAFICA_X_AXIS || type == GRAFICA_TOP_AXIS) ? false : true; 26 | drawTickLabels = (type == GRAFICA_X_AXIS || type == GRAFICA_Y_AXIS) ? true : false; 27 | tickLabelOffset = 8; 28 | 29 | // Label properties 30 | lab = ofxGAxisLabel(type, dim); 31 | drawAxisLabel = true; 32 | 33 | // Font properties 34 | fontName = OF_TTF_SANS; 35 | fontColor = ofColor(0); 36 | fontSize = 8; 37 | fontMakeContours = false; 38 | font.load(fontName, fontSize, true, true, fontMakeContours); 39 | 40 | // Update the tick containers 41 | updateTicks(); 42 | updatePlotTicks(); 43 | updateTicksInside(); 44 | updateTickLabels(); 45 | } 46 | 47 | int ofxGAxis::obtainSigDigits(float number) { 48 | return round(-log10(0.5 * abs(number))); 49 | } 50 | 51 | float ofxGAxis::roundPlus(float number, int sigDigits) { 52 | return round(number * pow(10, sigDigits)) / pow(10, sigDigits); 53 | } 54 | 55 | void ofxGAxis::updateTicks() { 56 | if (logScale) { 57 | obtainLogarithmicTicks(); 58 | } else { 59 | obtainLinearTicks(); 60 | } 61 | } 62 | 63 | void ofxGAxis::obtainLogarithmicTicks() { 64 | // Get the exponents of the first and last ticks in increasing order 65 | int firstExp = floor(log10(min(lim[0], lim[1]))); 66 | int lastExp = ceil(log10(max(lim[0], lim[1]))); 67 | 68 | // Fill the ticks container 69 | ticks.clear(); 70 | 71 | for (int exp = firstExp; exp < lastExp; ++exp) { 72 | float base = pow(10, exp); 73 | 74 | for (int i = 1; i < 10; ++i) { 75 | ticks.push_back(i * base); 76 | } 77 | } 78 | 79 | ticks.push_back(pow(10, lastExp)); 80 | } 81 | 82 | void ofxGAxis::obtainLinearTicks() { 83 | // Obtain the required tick precision 84 | float step = 0; 85 | int nSteps = 0; 86 | float sigDigits = 0; 87 | 88 | if (ticksSeparation > 0) { 89 | step = (lim[1] > lim[0]) ? ticksSeparation : -ticksSeparation; 90 | sigDigits = obtainSigDigits(step); 91 | 92 | while (abs(roundPlus(step, sigDigits) - step) > abs(0.001 * step)) { 93 | ++sigDigits; 94 | } 95 | 96 | nSteps = floor((lim[1] - lim[0]) / step); 97 | } else if (nTicks > 0) { 98 | step = (lim[1] - lim[0]) / nTicks; 99 | sigDigits = obtainSigDigits(step); 100 | step = roundPlus(step, sigDigits); 101 | 102 | if (step == 0 || abs(step) > abs(lim[1] - lim[0])) { 103 | ++sigDigits; 104 | step = roundPlus((lim[1] - lim[0]) / nTicks, sigDigits); 105 | } 106 | 107 | nSteps = floor((lim[1] - lim[0]) / step); 108 | } 109 | 110 | // Calculate the linear ticks 111 | ticks.clear(); 112 | 113 | if (nSteps > 0) { 114 | // Obtain the first tick 115 | float firstTick = lim[0] + ((lim[1] - lim[0]) - nSteps * step) / 2; 116 | 117 | // Subtract some steps to be sure we have all 118 | firstTick = roundPlus(firstTick - 2 * step, sigDigits); 119 | 120 | while ((lim[1] - firstTick) * (lim[0] - firstTick) > 0) { 121 | firstTick = roundPlus(firstTick + step, sigDigits); 122 | } 123 | 124 | // Calculate the rest of the ticks 125 | int n = floor((lim[1] - firstTick) / step) + 1; 126 | 127 | for (int i = 0; i < n; ++i) { 128 | ticks.push_back(roundPlus(firstTick + i * step, sigDigits)); 129 | } 130 | } 131 | } 132 | 133 | void ofxGAxis::updatePlotTicks() { 134 | float scaleFactor; 135 | plotTicks.clear(); 136 | 137 | if (logScale) { 138 | if (type == GRAFICA_X_AXIS || type == GRAFICA_TOP_AXIS) { 139 | scaleFactor = dim[0] / log10(lim[1] / lim[0]); 140 | } else { 141 | scaleFactor = -dim[1] / log10(lim[1] / lim[0]); 142 | } 143 | 144 | for (float tick : ticks) { 145 | plotTicks.push_back(log10(tick / lim[0]) * scaleFactor); 146 | } 147 | } else { 148 | if (type == GRAFICA_X_AXIS || type == GRAFICA_TOP_AXIS) { 149 | scaleFactor = dim[0] / (lim[1] - lim[0]); 150 | } else { 151 | scaleFactor = -dim[1] / (lim[1] - lim[0]); 152 | } 153 | 154 | for (float tick : ticks) { 155 | plotTicks.push_back((tick - lim[0]) * scaleFactor); 156 | } 157 | } 158 | } 159 | 160 | void ofxGAxis::updateTicksInside() { 161 | ticksInside.clear(); 162 | 163 | if (type == GRAFICA_X_AXIS || type == GRAFICA_TOP_AXIS) { 164 | for (float plotTick : plotTicks) { 165 | ticksInside.push_back((plotTick >= 0) && (plotTick <= dim[0])); 166 | } 167 | } else { 168 | for (float plotTick : plotTicks) { 169 | ticksInside.push_back((-plotTick >= 0) && (-plotTick <= dim[1])); 170 | } 171 | } 172 | } 173 | 174 | void ofxGAxis::updateTickLabels() { 175 | stringstream ss; 176 | tickLabels.clear(); 177 | 178 | if (logScale) { 179 | for (float tick : ticks) { 180 | float logValue = log10(tick); 181 | bool isExactLogValue = abs(logValue - round(logValue)) < 0.0001; 182 | 183 | if (isExactLogValue) { 184 | logValue = round(logValue); 185 | 186 | if (expTickLabels) { 187 | tickLabels.push_back("1e" + to_string((int) logValue)); 188 | } else { 189 | if (logValue > -3.1 && logValue < 3.1) { 190 | ss.str(""); 191 | ss << std::defaultfloat << tick; 192 | tickLabels.push_back(ss.str()); 193 | } else { 194 | tickLabels.push_back("1e" + to_string((int) logValue)); 195 | } 196 | } 197 | } else { 198 | tickLabels.push_back(""); 199 | } 200 | } 201 | } else { 202 | for (float tick : ticks) { 203 | ss.str(""); 204 | ss << std::defaultfloat << tick; 205 | tickLabels.push_back(ss.str()); 206 | } 207 | } 208 | } 209 | 210 | void ofxGAxis::moveLim(const array& newLim) { 211 | // Check that the new limit makes sense 212 | if (newLim[1] == newLim[0]) { 213 | throw invalid_argument("The limit range cannot be zero."); 214 | } else if (logScale && (newLim[0] <= 0 || newLim[1] <= 0)) { 215 | throw invalid_argument("The axis limits are negative and this is not allowed in logarithmic scale."); 216 | } 217 | 218 | // Update the limits 219 | lim = newLim; 220 | 221 | // Calculate the new ticks if they are not fixed 222 | if (!fixedTicks) { 223 | int n = ticks.size(); 224 | 225 | if (logScale) { 226 | obtainLogarithmicTicks(); 227 | } else if (n > 0) { 228 | // Obtain the ticks precision and the tick separation 229 | float step = 0; 230 | int sigDigits = 0; 231 | 232 | if (ticksSeparation > 0) { 233 | step = (lim[1] > lim[0]) ? ticksSeparation : -ticksSeparation; 234 | sigDigits = obtainSigDigits(step); 235 | 236 | while (abs(roundPlus(step, sigDigits) - step) > abs(0.001 * step)) { 237 | ++sigDigits; 238 | } 239 | } else { 240 | step = (n == 1) ? lim[1] - lim[0] : ticks[1] - ticks[0]; 241 | sigDigits = obtainSigDigits(step); 242 | step = roundPlus(step, sigDigits); 243 | 244 | if (step == 0 || abs(step) > abs(lim[1] - lim[0])) { 245 | ++sigDigits; 246 | step = (n == 1) ? lim[1] - lim[0] : ticks[1] - ticks[0]; 247 | step = roundPlus(step, sigDigits); 248 | } 249 | 250 | step = (lim[1] > lim[0]) ? abs(step) : -abs(step); 251 | } 252 | 253 | // Obtain the first tick 254 | float firstTick = ticks[0] + step * ceil((lim[0] - ticks[0]) / step); 255 | firstTick = roundPlus(firstTick, sigDigits); 256 | 257 | if ((lim[1] - firstTick) * (lim[0] - firstTick) > 0) { 258 | firstTick = ticks[0] + step * floor((lim[0] - ticks[0]) / step); 259 | firstTick = roundPlus(firstTick, sigDigits); 260 | } 261 | 262 | // Calculate the rest of the ticks 263 | n = floor(abs((lim[1] - firstTick) / step)) + 1; 264 | ticks.clear(); 265 | 266 | for (int i = 0; i < n; ++i) { 267 | ticks.push_back(roundPlus(firstTick + i * step, sigDigits)); 268 | } 269 | } 270 | 271 | // Obtain the new tick labels 272 | updateTickLabels(); 273 | } 274 | 275 | // Update the rest of the arrays 276 | updatePlotTicks(); 277 | updateTicksInside(); 278 | } 279 | 280 | void ofxGAxis::draw() const { 281 | switch (type) { 282 | case GRAFICA_X_AXIS: 283 | drawAsXAxis(); 284 | break; 285 | case GRAFICA_Y_AXIS: 286 | drawAsYAxis(); 287 | break; 288 | case GRAFICA_TOP_AXIS: 289 | drawAsTopAxis(); 290 | break; 291 | case GRAFICA_RIGHT_AXIS: 292 | drawAsRightAxis(); 293 | break; 294 | } 295 | 296 | if (drawAxisLabel) { 297 | lab.draw(); 298 | } 299 | } 300 | 301 | void ofxGAxis::drawAsXAxis() const { 302 | ofPushStyle(); 303 | ofSetColor(lineColor); 304 | ofSetLineWidth(lineWidth); 305 | 306 | // Draw the ticks 307 | ofDrawLine(0, offset, dim[0], offset); 308 | 309 | for (vector::size_type i = 0; i < plotTicks.size(); ++i) { 310 | if (ticksInside[i]) { 311 | if (logScale && tickLabels[i] == "") { 312 | ofDrawLine(plotTicks[i], offset, plotTicks[i], offset + smallTickLength); 313 | } else { 314 | ofDrawLine(plotTicks[i], offset, plotTicks[i], offset + tickLength); 315 | } 316 | } 317 | } 318 | 319 | // Draw the tick labels 320 | if (drawTickLabels) { 321 | ofSetColor(fontColor); 322 | 323 | if (rotateTickLabels) { 324 | for (vector::size_type i = 0; i < plotTicks.size(); ++i) { 325 | if (ticksInside[i] && tickLabels[i] != "") { 326 | ofRectangle bounds = font.getStringBoundingBox(tickLabels[i], 0, 0); 327 | 328 | ofPushMatrix(); 329 | ofTranslate(plotTicks[i] + fontSize / 2.0, offset + tickLabelOffset + bounds.width); 330 | ofRotateZDeg(-90); 331 | font.drawString(tickLabels[i], 0, 0); 332 | ofPopMatrix(); 333 | } 334 | } 335 | } else { 336 | for (vector::size_type i = 0; i < plotTicks.size(); ++i) { 337 | if (ticksInside[i] && tickLabels[i] != "") { 338 | ofRectangle bounds = font.getStringBoundingBox(tickLabels[i], 0, 0); 339 | font.drawString(tickLabels[i], plotTicks[i] - bounds.width / 2, 340 | offset + tickLabelOffset + fontSize); 341 | } 342 | } 343 | } 344 | } 345 | 346 | ofPopStyle(); 347 | } 348 | 349 | void ofxGAxis::drawAsYAxis() const { 350 | ofPushStyle(); 351 | ofSetColor(lineColor); 352 | ofSetLineWidth(lineWidth); 353 | 354 | // Draw the ticks 355 | ofDrawLine(-offset, 0, -offset, -dim[1]); 356 | 357 | for (vector::size_type i = 0; i < plotTicks.size(); ++i) { 358 | if (ticksInside[i]) { 359 | if (logScale && tickLabels[i] == "") { 360 | ofDrawLine(-offset, plotTicks[i], -offset - smallTickLength, plotTicks[i]); 361 | } else { 362 | ofDrawLine(-offset, plotTicks[i], -offset - tickLength, plotTicks[i]); 363 | } 364 | } 365 | } 366 | 367 | // Draw the tick labels 368 | if (drawTickLabels) { 369 | ofSetColor(fontColor); 370 | 371 | if (rotateTickLabels) { 372 | for (vector::size_type i = 0; i < plotTicks.size(); ++i) { 373 | if (ticksInside[i] && tickLabels[i] != "") { 374 | ofRectangle bounds = font.getStringBoundingBox(tickLabels[i], 0, 0); 375 | 376 | ofPushMatrix(); 377 | ofTranslate(-offset - tickLabelOffset, plotTicks[i] + bounds.width / 2); 378 | ofRotateZDeg(-90); 379 | font.drawString(tickLabels[i], 0, 0); 380 | ofPopMatrix(); 381 | } 382 | } 383 | } else { 384 | for (vector::size_type i = 0; i < plotTicks.size(); ++i) { 385 | if (ticksInside[i] && tickLabels[i] != "") { 386 | ofRectangle bounds = font.getStringBoundingBox(tickLabels[i], 0, 0); 387 | font.drawString(tickLabels[i], -offset - tickLabelOffset - bounds.width, 388 | plotTicks[i] + fontSize / 2.0); 389 | } 390 | } 391 | } 392 | } 393 | 394 | ofPopStyle(); 395 | } 396 | 397 | void ofxGAxis::drawAsTopAxis() const { 398 | ofPushStyle(); 399 | ofSetColor(lineColor); 400 | ofSetLineWidth(lineWidth); 401 | 402 | ofPushMatrix(); 403 | ofTranslate(0, -dim[1]); 404 | 405 | // Draw the ticks 406 | ofDrawLine(0, -offset, dim[0], -offset); 407 | 408 | for (vector::size_type i = 0; i < plotTicks.size(); ++i) { 409 | if (ticksInside[i]) { 410 | if (logScale && tickLabels[i] == "") { 411 | ofDrawLine(plotTicks[i], -offset, plotTicks[i], -offset - smallTickLength); 412 | } else { 413 | ofDrawLine(plotTicks[i], -offset, plotTicks[i], -offset - tickLength); 414 | } 415 | } 416 | } 417 | 418 | // Draw the tick labels 419 | if (drawTickLabels) { 420 | ofSetColor(fontColor); 421 | 422 | if (rotateTickLabels) { 423 | for (vector::size_type i = 0; i < plotTicks.size(); ++i) { 424 | if (ticksInside[i] && tickLabels[i] != "") { 425 | ofPushMatrix(); 426 | ofTranslate(plotTicks[i] + fontSize / 2.0, -offset - tickLabelOffset); 427 | ofRotateZDeg(-90); 428 | font.drawString(tickLabels[i], 0, 0); 429 | ofPopMatrix(); 430 | } 431 | } 432 | } else { 433 | for (vector::size_type i = 0; i < plotTicks.size(); ++i) { 434 | if (ticksInside[i] && tickLabels[i] != "") { 435 | ofRectangle bounds = font.getStringBoundingBox(tickLabels[i], 0, 0); 436 | font.drawString(tickLabels[i], plotTicks[i] - bounds.width / 2, -offset - tickLabelOffset); 437 | } 438 | } 439 | } 440 | } 441 | 442 | ofPopMatrix(); 443 | ofPopStyle(); 444 | } 445 | 446 | void ofxGAxis::drawAsRightAxis() const { 447 | ofPushStyle(); 448 | ofSetColor(lineColor); 449 | ofSetLineWidth(lineWidth); 450 | 451 | ofPushMatrix(); 452 | ofTranslate(dim[0], 0); 453 | 454 | // Draw the ticks 455 | ofDrawLine(offset, 0, offset, -dim[1]); 456 | 457 | for (vector::size_type i = 0; i < plotTicks.size(); ++i) { 458 | if (ticksInside[i]) { 459 | if (logScale && tickLabels[i] == "") { 460 | ofDrawLine(offset, plotTicks[i], offset + smallTickLength, plotTicks[i]); 461 | } else { 462 | ofDrawLine(offset, plotTicks[i], offset + tickLength, plotTicks[i]); 463 | } 464 | } 465 | } 466 | 467 | // Draw the tick labels 468 | if (drawTickLabels) { 469 | ofSetColor(fontColor); 470 | 471 | if (rotateTickLabels) { 472 | for (vector::size_type i = 0; i < plotTicks.size(); ++i) { 473 | if (ticksInside[i] && tickLabels[i] != "") { 474 | ofRectangle bounds = font.getStringBoundingBox(tickLabels[i], 0, 0); 475 | 476 | ofPushMatrix(); 477 | ofTranslate(offset + tickLabelOffset + fontSize, plotTicks[i] + bounds.width / 2); 478 | ofRotateZDeg(-90); 479 | font.drawString(tickLabels[i], 0, 0); 480 | ofPopMatrix(); 481 | } 482 | } 483 | } else { 484 | for (vector::size_type i = 0; i < plotTicks.size(); ++i) { 485 | if (ticksInside[i] && tickLabels[i] != "") { 486 | ofRectangle bounds = font.getStringBoundingBox(tickLabels[i], 0, 0); 487 | font.drawString(tickLabels[i], offset + tickLabelOffset, plotTicks[i] + fontSize / 2.0); 488 | } 489 | } 490 | } 491 | } 492 | 493 | ofPopMatrix(); 494 | ofPopStyle(); 495 | } 496 | 497 | void ofxGAxis::setDim(float xDim, float yDim) { 498 | if (xDim <= 0 || yDim <= 0) { 499 | throw invalid_argument("The dimensions should be larger than zero."); 500 | } 501 | 502 | dim = {xDim, yDim}; 503 | updatePlotTicks(); 504 | lab.setDim(dim); 505 | } 506 | 507 | void ofxGAxis::setDim(const array& newDim) { 508 | setDim(newDim[0], newDim[1]); 509 | } 510 | 511 | void ofxGAxis::setLim(const array& newLim) { 512 | // Check that the new limit makes sense 513 | if (newLim[1] == newLim[0]) { 514 | throw invalid_argument("The limit range cannot be zero."); 515 | } else if (logScale && (newLim[0] <= 0 || newLim[1] <= 0)) { 516 | throw invalid_argument("The axis limits are negative and this is not allowed in logarithmic scale."); 517 | } 518 | 519 | lim = newLim; 520 | 521 | if (!fixedTicks) { 522 | updateTicks(); 523 | updateTickLabels(); 524 | } 525 | 526 | updatePlotTicks(); 527 | updateTicksInside(); 528 | } 529 | 530 | void ofxGAxis::setLimAndLogScale(const array& newLim, bool newLogScale) { 531 | // Check that the new limit makes sense 532 | if (newLim[1] == newLim[0]) { 533 | throw invalid_argument("The limit range cannot be zero."); 534 | } else if (newLogScale && (newLim[0] <= 0 || newLim[1] <= 0)) { 535 | throw invalid_argument("The axis limits are negative and this is not allowed in logarithmic scale."); 536 | } 537 | 538 | lim = newLim; 539 | logScale = newLogScale; 540 | 541 | if (!fixedTicks) { 542 | updateTicks(); 543 | updateTickLabels(); 544 | } 545 | 546 | updatePlotTicks(); 547 | updateTicksInside(); 548 | } 549 | 550 | void ofxGAxis::setLogScale(bool newLogScale) { 551 | if (newLogScale != logScale) { 552 | // Check if the old limits still make sense 553 | if (newLogScale && (lim[0] <= 0 || lim[1] <= 0)) { 554 | throw invalid_argument("The axis limits are negative and this is not allowed in logarithmic scale."); 555 | } 556 | 557 | logScale = newLogScale; 558 | 559 | if (!fixedTicks) { 560 | updateTicks(); 561 | updateTickLabels(); 562 | } 563 | 564 | updatePlotTicks(); 565 | updateTicksInside(); 566 | } 567 | } 568 | 569 | void ofxGAxis::setOffset(float newOffset) { 570 | offset = newOffset; 571 | } 572 | 573 | void ofxGAxis::setLineColor(const ofColor& newLineColor) { 574 | lineColor = newLineColor; 575 | } 576 | 577 | void ofxGAxis::setLineWidth(float newLineWidth) { 578 | if (newLineWidth <= 0) { 579 | throw invalid_argument("The line width should be larger than zero."); 580 | } 581 | 582 | lineWidth = newLineWidth; 583 | } 584 | 585 | void ofxGAxis::setNTicks(int newNTicks) { 586 | if (newNTicks < 0) { 587 | throw invalid_argument("The number of ticks should be equal or larger than zero."); 588 | } 589 | 590 | nTicks = newNTicks; 591 | ticksSeparation = -1; 592 | fixedTicks = false; 593 | 594 | if (!logScale) { 595 | updateTicks(); 596 | updatePlotTicks(); 597 | updateTicksInside(); 598 | updateTickLabels(); 599 | } 600 | } 601 | 602 | void ofxGAxis::setTicksSeparation(float newTicksSeparation) { 603 | ticksSeparation = newTicksSeparation; 604 | fixedTicks = false; 605 | 606 | if (!logScale) { 607 | updateTicks(); 608 | updatePlotTicks(); 609 | updateTicksInside(); 610 | updateTickLabels(); 611 | } 612 | } 613 | 614 | void ofxGAxis::setTicks(const vector& newTicks) { 615 | ticks = newTicks; 616 | fixedTicks = true; 617 | updatePlotTicks(); 618 | updateTicksInside(); 619 | updateTickLabels(); 620 | } 621 | 622 | void ofxGAxis::setTickLabels(const vector& newTickLabels) { 623 | if (newTickLabels.size() != tickLabels.size()) { 624 | throw invalid_argument("The number of ticks and tick labels should be the same."); 625 | } 626 | 627 | fixedTicks = true; 628 | tickLabels = newTickLabels; 629 | } 630 | 631 | void ofxGAxis::setFixedTicks(bool newFixedTicks) { 632 | if (newFixedTicks != fixedTicks) { 633 | fixedTicks = newFixedTicks; 634 | 635 | if (!fixedTicks) { 636 | updateTicks(); 637 | updatePlotTicks(); 638 | updateTicksInside(); 639 | updateTickLabels(); 640 | } 641 | } 642 | } 643 | 644 | void ofxGAxis::setTickLength(float newTickLength) { 645 | tickLength = newTickLength; 646 | } 647 | 648 | void ofxGAxis::setSmallTickLength(float newSmallTickLength) { 649 | smallTickLength = newSmallTickLength; 650 | } 651 | 652 | void ofxGAxis::setExpTickLabels(bool newExpTickLabels) { 653 | if (newExpTickLabels != expTickLabels) { 654 | expTickLabels = newExpTickLabels; 655 | updateTickLabels(); 656 | } 657 | } 658 | 659 | void ofxGAxis::setRotateTickLabels(bool newRotateTickLabels) { 660 | rotateTickLabels = newRotateTickLabels; 661 | } 662 | 663 | void ofxGAxis::setDrawTickLabels(bool newDrawTicksLabels) { 664 | drawTickLabels = newDrawTicksLabels; 665 | } 666 | 667 | void ofxGAxis::setTickLabelOffset(float newTickLabelOffset) { 668 | tickLabelOffset = newTickLabelOffset; 669 | } 670 | 671 | void ofxGAxis::setDrawAxisLabel(bool newDrawAxisLabel) { 672 | drawAxisLabel = newDrawAxisLabel; 673 | } 674 | 675 | void ofxGAxis::setAxisLabelText(const string& text) { 676 | lab.setText(text); 677 | } 678 | 679 | void ofxGAxis::setFontName(const string& newFontName) { 680 | fontName = newFontName; 681 | font.load(fontName, fontSize, true, true, fontMakeContours); 682 | } 683 | 684 | void ofxGAxis::setFontColor(const ofColor& newFontColor) { 685 | fontColor = newFontColor; 686 | } 687 | 688 | void ofxGAxis::setFontSize(int newFontSize) { 689 | if (newFontSize <= 0) { 690 | throw invalid_argument("The font size should be larger than zero."); 691 | } 692 | 693 | fontSize = newFontSize; 694 | font.load(fontName, fontSize, true, true, fontMakeContours); 695 | } 696 | 697 | void ofxGAxis::setFontProperties(const string& newFontName, const ofColor& newFontColor, int newFontSize) { 698 | if (newFontSize <= 0) { 699 | throw invalid_argument("The font size should be larger than zero."); 700 | } 701 | 702 | fontName = newFontName; 703 | fontColor = newFontColor; 704 | fontSize = newFontSize; 705 | font.load(fontName, fontSize, true, true, fontMakeContours); 706 | } 707 | 708 | void ofxGAxis::setAllFontProperties(const string& newFontName, const ofColor& newFontColor, int newFontSize) { 709 | setFontProperties(newFontName, newFontColor, newFontSize); 710 | lab.setFontProperties(newFontName, newFontColor, newFontSize); 711 | } 712 | 713 | void ofxGAxis::setFontsMakeContours(bool newFontMakeContours) { 714 | fontMakeContours = newFontMakeContours; 715 | font.load(fontName, fontSize, true, true, fontMakeContours); 716 | lab.setFontMakeContours(fontMakeContours); 717 | } 718 | 719 | vector ofxGAxis::getTicks() const { 720 | if (fixedTicks) { 721 | return ticks; 722 | } else { 723 | // Return only the ticks that are inside the plot 724 | vector validTicks; 725 | 726 | for (vector::size_type i = 0; i < ticks.size(); ++i) { 727 | if (ticksInside[i]) { 728 | validTicks.push_back(ticks[i]); 729 | } 730 | } 731 | 732 | return validTicks; 733 | } 734 | } 735 | 736 | const vector& ofxGAxis::getTicksRef() const { 737 | return ticks; 738 | } 739 | 740 | vector ofxGAxis::getPlotTicks() const { 741 | if (fixedTicks) { 742 | return plotTicks; 743 | } else { 744 | // Return only the plot ticks that are inside the plot 745 | vector validPlotTicks; 746 | 747 | for (vector::size_type i = 0; i < plotTicks.size(); ++i) { 748 | if (ticksInside[i]) { 749 | validPlotTicks.push_back(plotTicks[i]); 750 | } 751 | } 752 | 753 | return validPlotTicks; 754 | } 755 | } 756 | 757 | const vector& ofxGAxis::getPlotTicksRef() const { 758 | return plotTicks; 759 | } 760 | 761 | ofxGAxisLabel& ofxGAxis::getAxisLabel() { 762 | return lab; 763 | } 764 | -------------------------------------------------------------------------------- /src/ofxGAxis.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofxGConstants.h" 4 | #include "ofxGAxisLabel.h" 5 | #include "ofMain.h" 6 | 7 | /** 8 | * @brief Axis class 9 | * 10 | * @author Javier Graciá Carpio 11 | */ 12 | class ofxGAxis { 13 | public: 14 | 15 | /** 16 | * @brief Constructor 17 | * 18 | * @param _type the axis type. It can be GRAFICA_X_AXIS, GRAFICA_Y_AXIS, GRAFICA_TOP_AXIS or GRAFICA_RIGHT_AXIS 19 | * @param _dim the plot box dimensions in pixels 20 | * @param _lim the limits 21 | * @param _logScale the axis scale. True if it's logarithmic 22 | */ 23 | ofxGAxis(ofxGAxisType _type = GRAFICA_X_AXIS, const array& _dim = { 100, 100 }, 24 | const array& _lim = { 0, 1 }, bool _logScale = false); 25 | 26 | /** 27 | * @brief Moves the axis limits 28 | * 29 | * @param newLim the new axis limits 30 | */ 31 | void moveLim(const array& newLim); 32 | 33 | /** 34 | * @brief Draws the axis 35 | */ 36 | void draw() const; 37 | 38 | /** 39 | * @brief Sets the plot box dimensions information 40 | * 41 | * @param xDim the new plot box x dimension 42 | * @param yDim the new plot box y dimension 43 | */ 44 | void setDim(float xDim, float yDim); 45 | 46 | /** 47 | * @brief Sets the plot box dimensions information 48 | * 49 | * @param newDim the new plot box dimensions information 50 | */ 51 | void setDim(const array& newDim); 52 | 53 | /** 54 | * @brief Sets the axis limits 55 | * 56 | * @param newLim the new axis limits 57 | */ 58 | void setLim(const array& newLim); 59 | 60 | /** 61 | * @brief Sets the axis limits and the axis scale 62 | * 63 | * @param newLim the new axis limits 64 | * @param newLogScale the new axis scale 65 | */ 66 | void setLimAndLogScale(const array& newLim, bool newLogScale); 67 | 68 | /** 69 | * @brief Sets the axis scale 70 | * 71 | * @param newLogScale the new axis scale 72 | */ 73 | void setLogScale(bool newLogScale); 74 | 75 | /** 76 | * @brief Sets the axis offset with respect to the plot box 77 | * 78 | * @param newOffset the new axis offset 79 | */ 80 | void setOffset(float newOffset); 81 | 82 | /** 83 | * @brief Sets the line color 84 | * 85 | * @param newLineColor the new line color 86 | */ 87 | void setLineColor(const ofColor& newLineColor); 88 | 89 | /** 90 | * @brief Sets the line width 91 | * 92 | * @param newLineWidth the new line width 93 | */ 94 | void setLineWidth(float newLineWidth); 95 | 96 | /** 97 | * @brief Sets the approximate number of ticks in the axis. 98 | * 99 | * The actual number of ticks depends on the axis limits and the axis scale 100 | * 101 | * @param newNTicks the new approximate number of ticks in the axis 102 | */ 103 | void setNTicks(int newNTicks); 104 | 105 | /** 106 | * @brief Sets the separation between the ticks in the axis 107 | * 108 | * @param newTicksSeparation the new ticks separation 109 | */ 110 | void setTicksSeparation(float newTicksSeparation); 111 | 112 | /** 113 | * @brief Sets the axis ticks 114 | * 115 | * @param newTicks the new axis ticks 116 | */ 117 | void setTicks(const vector& newTicks); 118 | 119 | /** 120 | * @brief Sets the axis ticks labels 121 | * 122 | * @param newTickLabels the new axis ticks labels 123 | */ 124 | void setTickLabels(const vector& newTickLabels); 125 | 126 | /** 127 | * @brief Sets if the axis ticks are fixed or not 128 | * 129 | * @param newFixedTicks true if the axis ticks should be fixed 130 | */ 131 | void setFixedTicks(bool newFixedTicks); 132 | 133 | /** 134 | * @brief Sets the tick length 135 | * 136 | * @param newTickLength the new tick length 137 | */ 138 | void setTickLength(float newTickLength); 139 | 140 | /** 141 | * @brief Sets the small tick length 142 | * 143 | * @param newSmallTickLength the new small tick length 144 | */ 145 | void setSmallTickLength(float newSmallTickLength); 146 | 147 | /** 148 | * @brief Sets if the ticks labels should be displayed in exponential form or not 149 | * 150 | * @param newExpTickLabels true if the ticks labels should be in exponential form 151 | */ 152 | void setExpTickLabels(bool newExpTickLabels); 153 | 154 | /** 155 | * @brief Sets if the ticks labels should be displayed rotated or not 156 | * 157 | * @param newRotateTickLabels true is the ticks labels should be rotated 158 | */ 159 | void setRotateTickLabels(bool newRotateTickLabels); 160 | 161 | /** 162 | * @brief Sets if the ticks labels should be drawn or not 163 | * 164 | * @param newDrawTicksLabels true it the ticks labels should be drawn 165 | */ 166 | void setDrawTickLabels(bool newDrawTicksLabels); 167 | 168 | /** 169 | * @brief Sets the tick label offset 170 | * 171 | * @param newTickLabelOffset the new tick label offset 172 | */ 173 | void setTickLabelOffset(float newTickLabelOffset); 174 | 175 | /** 176 | * @brief Sets if the axis label should be drawn or not 177 | * 178 | * @param newDrawAxisLabel true if the axis label should be drawn 179 | */ 180 | void setDrawAxisLabel(bool newDrawAxisLabel); 181 | 182 | /** 183 | * @brief Sets the axis label text 184 | * 185 | * @param text the new axis label text 186 | */ 187 | void setAxisLabelText(const string& text); 188 | 189 | /** 190 | * @brief Sets the font name 191 | * 192 | * @param newFontName the name of the new font 193 | */ 194 | void setFontName(const string& newFontName); 195 | 196 | /** 197 | * @brief Sets the font color 198 | * 199 | * @param newFontColor the new font color 200 | */ 201 | void setFontColor(const ofColor& newFontColor); 202 | 203 | /** 204 | * @brief Sets the font size 205 | * 206 | * @param newFontSize the new font size 207 | */ 208 | void setFontSize(int newFontSize); 209 | 210 | /** 211 | * @brief Sets all the font properties at once 212 | * 213 | * @param newFontName the name of the new font 214 | * @param newFontColor the new font color 215 | * @param newFontSize the new font size 216 | */ 217 | void setFontProperties(const string& newFontName, const ofColor& newFontColor, int newFontSize); 218 | 219 | /** 220 | * @brief Sets the font properties in the axis and the axis label 221 | * 222 | * @param newFontName the new font name 223 | * @param newFontColor the new font color 224 | * @param newFontSize the new font size 225 | */ 226 | void setAllFontProperties(const string& newFontName, const ofColor& newFontColor, int newFontSize); 227 | 228 | /** 229 | * @brief Sets if the fonts should be made of contours 230 | * 231 | * @param newFontMakeContours true if the fonts should be made of contours 232 | */ 233 | void setFontsMakeContours(bool newFontMakeContours); 234 | 235 | /** 236 | * @brief Returns a copy of the axis ticks 237 | * 238 | * @return a copy of the axis ticks 239 | */ 240 | vector getTicks() const; 241 | 242 | /** 243 | * @brief Returns the axis ticks 244 | * 245 | * @return the axis ticks 246 | */ 247 | const vector& getTicksRef() const; 248 | 249 | /** 250 | * @brief Returns a copy of the axis ticks positions in the plot reference system 251 | * 252 | * @return a copy of the axis ticks positions in the plot reference system 253 | */ 254 | vector getPlotTicks() const; 255 | 256 | /** 257 | * @brief Returns the axis ticks positions in the plot reference system 258 | * 259 | * @return the axis ticks positions in the plot reference system 260 | */ 261 | const vector& getPlotTicksRef() const; 262 | 263 | /** 264 | * @brief Returns the axis label 265 | * 266 | * @return the axis label 267 | */ 268 | ofxGAxisLabel& getAxisLabel(); 269 | 270 | protected: 271 | 272 | /** 273 | * @brief Calculates the optimum number of significant digits to use for a given number 274 | * 275 | * @param number the number 276 | * 277 | * @return the number of significant digits 278 | */ 279 | static int obtainSigDigits(float number); 280 | 281 | /** 282 | * @brief Rounds a number to a given number of significant digits 283 | * 284 | * @param number the number to round 285 | * @param sigDigits the number of significant digits 286 | * 287 | * @return the rounded number 288 | */ 289 | static float roundPlus(float number, int sigDigits); 290 | 291 | /** 292 | * @brief Updates the axis ticks 293 | */ 294 | void updateTicks(); 295 | 296 | /** 297 | * @brief Calculates the axis ticks for the logarithmic scale 298 | */ 299 | void obtainLogarithmicTicks(); 300 | 301 | /** 302 | * @brief Calculates the axis ticks for the linear scale 303 | */ 304 | void obtainLinearTicks(); 305 | 306 | /** 307 | * @brief Updates the positions of the axis ticks in the plot reference system 308 | */ 309 | void updatePlotTicks(); 310 | 311 | /** 312 | * @brief Updates the array that indicates which ticks are inside the axis limits 313 | */ 314 | void updateTicksInside(); 315 | 316 | /** 317 | * @brief Updates the axis tick labels 318 | */ 319 | void updateTickLabels(); 320 | 321 | /** 322 | * @brief Draws the axis as an X axis 323 | */ 324 | void drawAsXAxis() const; 325 | 326 | /** 327 | * @brief Draws the axis as a Y axis 328 | */ 329 | void drawAsYAxis() const; 330 | 331 | /** 332 | * @brief Draws the axis as a TOP axis 333 | */ 334 | void drawAsTopAxis() const; 335 | 336 | /** 337 | * @brief Draws the axis as a RIGHT axis 338 | */ 339 | void drawAsRightAxis() const; 340 | 341 | /** 342 | * @brief The axis type 343 | */ 344 | ofxGAxisType type; 345 | 346 | /** 347 | * @brief The plot box dimensions in pixels 348 | */ 349 | array dim; 350 | 351 | /** 352 | * @brief The axis limits 353 | */ 354 | array lim; 355 | 356 | /** 357 | * @brief Defines if the scale should be logarithmic or not 358 | */ 359 | bool logScale; 360 | 361 | /** 362 | * @brief The axis offset with respect to the plot box 363 | */ 364 | float offset; 365 | 366 | /** 367 | * @brief The line color 368 | */ 369 | ofColor lineColor; 370 | 371 | /** 372 | * @brief The line width 373 | */ 374 | float lineWidth; 375 | 376 | /** 377 | * @brief The approximate number of ticks in the axis 378 | */ 379 | int nTicks; 380 | 381 | /** 382 | * @brief The separation between the ticks in the axis 383 | */ 384 | float ticksSeparation; 385 | 386 | /** 387 | * @brief The axis ticks 388 | */ 389 | vector ticks; 390 | 391 | /** 392 | * @brief The ticks positions in the plot reference system 393 | */ 394 | vector plotTicks; 395 | 396 | /** 397 | * @brief Defines if the ticks are inside the axis limits 398 | */ 399 | vector ticksInside; 400 | 401 | /** 402 | * @brief The axis ticks labels 403 | */ 404 | vector tickLabels; 405 | 406 | /** 407 | * @brief Defines if the axis ticks are fixed or not 408 | */ 409 | bool fixedTicks; 410 | 411 | /** 412 | * @brief The ticks length 413 | */ 414 | float tickLength; 415 | 416 | /** 417 | * @brief The small ticks length 418 | */ 419 | float smallTickLength; 420 | 421 | /** 422 | * @brief Defines if the ticks labels should be displayed in exponential form 423 | */ 424 | bool expTickLabels; 425 | 426 | /** 427 | * @brief Defines if the ticks labels should be displayed rotated 428 | */ 429 | bool rotateTickLabels; 430 | 431 | /** 432 | * @brief Defines if the ticks labels should be drawn 433 | */ 434 | bool drawTickLabels; 435 | 436 | /** 437 | * @brief The tick label offset 438 | */ 439 | float tickLabelOffset; 440 | 441 | /** 442 | * @brief The axis label 443 | */ 444 | ofxGAxisLabel lab; 445 | 446 | /** 447 | * @brief Defines if the axis label should be drawn 448 | */ 449 | bool drawAxisLabel; 450 | 451 | /** 452 | * @brief The font name 453 | */ 454 | string fontName; 455 | 456 | /** 457 | * @brief The font color 458 | */ 459 | ofColor fontColor; 460 | 461 | /** 462 | * @brief The font size 463 | */ 464 | int fontSize; 465 | 466 | /** 467 | * @brief Defines if the font should be made of contours 468 | */ 469 | bool fontMakeContours; 470 | 471 | /** 472 | * @brief The trueType font 473 | */ 474 | ofTrueTypeFont font; 475 | }; 476 | -------------------------------------------------------------------------------- /src/ofxGAxisLabel.cpp: -------------------------------------------------------------------------------- 1 | #include "ofxGAxisLabel.h" 2 | #include "ofxGConstants.h" 3 | #include "ofMain.h" 4 | 5 | ofxGAxisLabel::ofxGAxisLabel(ofxGAxisType _type, const array& _dim, const string& _text) : 6 | type(_type), dim(_dim), text(_text) { 7 | // General properties 8 | relativePos = 0.5; 9 | plotPos = (type == GRAFICA_X_AXIS || type == GRAFICA_TOP_AXIS) ? relativePos * dim[0] : -relativePos * dim[1]; 10 | offset = 35; 11 | rotate = (type == GRAFICA_X_AXIS || type == GRAFICA_TOP_AXIS) ? false : true; 12 | 13 | // Font properties 14 | textAlignment = GRAFICA_CENTER_ALIGN; 15 | fontName = OF_TTF_SANS; 16 | fontColor = ofColor(0); 17 | fontSize = 10; 18 | fontMakeContours = false; 19 | font.load(fontName, fontSize, true, true, fontMakeContours); 20 | } 21 | 22 | void ofxGAxisLabel::draw() const { 23 | switch (type) { 24 | case GRAFICA_X_AXIS: 25 | drawAsXLabel(); 26 | break; 27 | case GRAFICA_Y_AXIS: 28 | drawAsYLabel(); 29 | break; 30 | case GRAFICA_TOP_AXIS: 31 | drawAsTopLabel(); 32 | break; 33 | case GRAFICA_RIGHT_AXIS: 34 | drawAsRightLabel(); 35 | break; 36 | } 37 | } 38 | 39 | void ofxGAxisLabel::drawAsXLabel() const { 40 | ofPushStyle(); 41 | ofSetColor(fontColor); 42 | ofRectangle bounds = font.getStringBoundingBox(text, 0, 0); 43 | 44 | if (rotate) { 45 | ofPushMatrix(); 46 | ofTranslate(plotPos + fontSize / 2.0, offset + bounds.width); 47 | ofRotateZDeg(-90); 48 | font.drawString(text, 0, 0); 49 | ofPopMatrix(); 50 | } else { 51 | switch (textAlignment) { 52 | case GRAFICA_CENTER_ALIGN: 53 | font.drawString(text, plotPos - bounds.width / 2, offset + fontSize); 54 | break; 55 | case GRAFICA_LEFT_ALIGN: 56 | font.drawString(text, plotPos, offset + fontSize); 57 | break; 58 | case GRAFICA_RIGHT_ALIGN: 59 | font.drawString(text, plotPos - bounds.width, offset + fontSize); 60 | break; 61 | default: 62 | font.drawString(text, plotPos - bounds.width / 2, offset + fontSize); 63 | break; 64 | } 65 | } 66 | 67 | ofPopStyle(); 68 | } 69 | 70 | void ofxGAxisLabel::drawAsYLabel() const { 71 | ofPushStyle(); 72 | ofSetColor(fontColor); 73 | ofRectangle bounds = font.getStringBoundingBox(text, 0, 0); 74 | 75 | if (rotate) { 76 | ofPushMatrix(); 77 | 78 | switch (textAlignment) { 79 | case GRAFICA_CENTER_ALIGN: 80 | ofTranslate(-offset, plotPos + bounds.width / 2); 81 | break; 82 | case GRAFICA_LEFT_ALIGN: 83 | ofTranslate(-offset, plotPos); 84 | break; 85 | case GRAFICA_RIGHT_ALIGN: 86 | ofTranslate(-offset, plotPos + bounds.width); 87 | break; 88 | default: 89 | ofTranslate(-offset, plotPos + bounds.width / 2); 90 | break; 91 | } 92 | 93 | ofRotateZDeg(-90); 94 | font.drawString(text, 0, 0); 95 | ofPopMatrix(); 96 | } else { 97 | font.drawString(text, -offset - bounds.width, plotPos + fontSize / 2.0); 98 | } 99 | 100 | ofPopStyle(); 101 | } 102 | 103 | void ofxGAxisLabel::drawAsTopLabel() const { 104 | ofPushStyle(); 105 | ofSetColor(fontColor); 106 | ofRectangle bounds = font.getStringBoundingBox(text, 0, 0); 107 | 108 | if (rotate) { 109 | ofPushMatrix(); 110 | ofTranslate(plotPos + fontSize / 2.0, -offset - dim[1]); 111 | ofRotateZDeg(-90); 112 | font.drawString(text, 0, 0); 113 | ofPopMatrix(); 114 | } else { 115 | switch (textAlignment) { 116 | case GRAFICA_CENTER_ALIGN: 117 | font.drawString(text, plotPos - bounds.width / 2, -offset - dim[1]); 118 | break; 119 | case GRAFICA_LEFT_ALIGN: 120 | font.drawString(text, plotPos, -offset - dim[1]); 121 | break; 122 | case GRAFICA_RIGHT_ALIGN: 123 | font.drawString(text, plotPos - bounds.width, -offset - dim[1]); 124 | break; 125 | default: 126 | font.drawString(text, plotPos - bounds.width / 2, -offset - dim[1]); 127 | break; 128 | } 129 | } 130 | 131 | ofPopStyle(); 132 | } 133 | 134 | void ofxGAxisLabel::drawAsRightLabel() const { 135 | ofPushStyle(); 136 | ofSetColor(fontColor); 137 | ofRectangle bounds = font.getStringBoundingBox(text, 0, 0); 138 | 139 | if (rotate) { 140 | ofPushMatrix(); 141 | 142 | switch (textAlignment) { 143 | case GRAFICA_CENTER_ALIGN: 144 | ofTranslate(offset + dim[0] + fontSize, plotPos + bounds.width / 2); 145 | break; 146 | case GRAFICA_LEFT_ALIGN: 147 | ofTranslate(offset + dim[0] + fontSize, plotPos); 148 | break; 149 | case GRAFICA_RIGHT_ALIGN: 150 | ofTranslate(offset + dim[0] + fontSize, plotPos + bounds.width); 151 | break; 152 | default: 153 | ofTranslate(offset + dim[0] + fontSize, plotPos + bounds.width / 2); 154 | break; 155 | } 156 | 157 | ofRotateZDeg(-90); 158 | font.drawString(text, 0, 0); 159 | ofPopMatrix(); 160 | } else { 161 | font.drawString(text, offset + dim[0], plotPos + fontSize / 2.0); 162 | } 163 | 164 | ofPopStyle(); 165 | } 166 | 167 | void ofxGAxisLabel::setDim(float xDim, float yDim) { 168 | if (xDim <= 0 || yDim <= 0) { 169 | throw invalid_argument("The dimensions should be larger than zero."); 170 | } 171 | 172 | dim = {xDim, yDim}; 173 | plotPos = (type == GRAFICA_X_AXIS || type == GRAFICA_TOP_AXIS) ? relativePos * dim[0] : -relativePos * dim[1]; 174 | } 175 | 176 | void ofxGAxisLabel::setDim(const array& newDim) { 177 | setDim(newDim[0], newDim[1]); 178 | } 179 | 180 | void ofxGAxisLabel::setRelativePos(float newRelativePos) { 181 | relativePos = newRelativePos; 182 | plotPos = (type == GRAFICA_X_AXIS || type == GRAFICA_TOP_AXIS) ? relativePos * dim[0] : -relativePos * dim[1]; 183 | } 184 | 185 | void ofxGAxisLabel::setOffset(float newOffset) { 186 | offset = newOffset; 187 | } 188 | 189 | void ofxGAxisLabel::setRotate(bool newRotate) { 190 | rotate = newRotate; 191 | } 192 | 193 | void ofxGAxisLabel::setText(const string& newText) { 194 | text = newText; 195 | } 196 | 197 | void ofxGAxisLabel::setTextAlignment(ofxGTextAlignment newTextAlignment) { 198 | textAlignment = newTextAlignment; 199 | } 200 | 201 | void ofxGAxisLabel::setFontName(const string& newFontName) { 202 | fontName = newFontName; 203 | font.load(fontName, fontSize, true, true, fontMakeContours); 204 | } 205 | 206 | void ofxGAxisLabel::setFontColor(const ofColor& newFontColor) { 207 | fontColor = newFontColor; 208 | } 209 | 210 | void ofxGAxisLabel::setFontSize(int newFontSize) { 211 | if (newFontSize <= 0) { 212 | throw invalid_argument("The font size should be larger than zero."); 213 | } 214 | 215 | fontSize = newFontSize; 216 | font.load(fontName, fontSize, true, true, fontMakeContours); 217 | } 218 | 219 | void ofxGAxisLabel::setFontProperties(const string& newFontName, const ofColor& newFontColor, int newFontSize) { 220 | if (newFontSize <= 0) { 221 | throw invalid_argument("The font size should be larger than zero."); 222 | } 223 | 224 | fontName = newFontName; 225 | fontColor = newFontColor; 226 | fontSize = newFontSize; 227 | font.load(fontName, fontSize, true, true, fontMakeContours); 228 | } 229 | 230 | void ofxGAxisLabel::setFontMakeContours(bool newFontMakeContours) { 231 | fontMakeContours = newFontMakeContours; 232 | font.load(fontName, fontSize, true, true, fontMakeContours); 233 | } 234 | -------------------------------------------------------------------------------- /src/ofxGAxisLabel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofxGConstants.h" 4 | #include "ofMain.h" 5 | 6 | /** 7 | * @brief Axis label class 8 | * 9 | * @author Javier Graciá Carpio 10 | */ 11 | class ofxGAxisLabel { 12 | public: 13 | 14 | /** 15 | * @brief Constructor 16 | * 17 | * @param _type the axis type. It can be GRAFICA_X_AXIS, GRAFICA_Y_AXIS, GRAFICA_TOP_AXIS or GRAFICA_RIGHT_AXIS 18 | * @param _dim the plot box dimensions in pixels 19 | * @param _text the label text 20 | */ 21 | ofxGAxisLabel(ofxGAxisType _type = GRAFICA_X_AXIS, const array& _dim = { 100, 100 }, const string& _text = 22 | ""); 23 | 24 | /** 25 | * @brief Draws the axis label 26 | */ 27 | void draw() const; 28 | 29 | /** 30 | * @brief Sets the plot box dimensions information 31 | * 32 | * @param xDim the new plot box x dimension 33 | * @param yDim the new plot box y dimension 34 | */ 35 | void setDim(float xDim, float yDim); 36 | 37 | /** 38 | * @brief Sets the plot box dimensions information 39 | * 40 | * @param newDim the new plot box dimensions information 41 | */ 42 | void setDim(const array& newDim); 43 | 44 | /** 45 | * @brief Sets the label relative position in the axis 46 | * 47 | * @param newRelativePos the new relative position in the axis 48 | */ 49 | void setRelativePos(float newRelativePos); 50 | 51 | /** 52 | * @brief Sets the axis label offset 53 | * 54 | * @param newOffset the new axis label offset 55 | */ 56 | void setOffset(float newOffset); 57 | 58 | /** 59 | * @brief Sets if the axis label should be rotated or not 60 | * 61 | * @param newRotate true if the axis label should be rotated 62 | */ 63 | void setRotate(bool newRotate); 64 | 65 | /** 66 | * @brief Sets the axis label text 67 | * 68 | * @param newText the new axis label text 69 | */ 70 | void setText(const string& newText); 71 | 72 | /** 73 | * @brief Sets the axis label type of text alignment 74 | * 75 | * @param newTextAlignment the new type of text alignment. It can be GRAFICA_CENTER_ALIGN, GRAFICA_LEFT_ALIGN or 76 | * GRAFICA_RIGHT_ALIGN 77 | */ 78 | void setTextAlignment(ofxGTextAlignment newTextAlignment); 79 | 80 | /** 81 | * @brief Sets the font name 82 | * 83 | * @param newFontName the name of the new font 84 | */ 85 | void setFontName(const string& newFontName); 86 | 87 | /** 88 | * @brief Sets the font color 89 | * 90 | * @param newFontColor the new font color 91 | */ 92 | void setFontColor(const ofColor& newFontColor); 93 | 94 | /** 95 | * @brief Sets the font size 96 | * 97 | * @param newFontSize the new font size 98 | */ 99 | void setFontSize(int newFontSize); 100 | 101 | /** 102 | * @brief Sets all the font properties at once 103 | * 104 | * @param newFontName the name of the new font 105 | * @param newFontColor the new font color 106 | * @param newFontSize the new font size 107 | */ 108 | void setFontProperties(const string& newFontName, const ofColor& newFontColor, int newFontSize); 109 | 110 | /** 111 | * @brief Sets if the font should be made of contours 112 | * 113 | * @param newFontMakeContours true if the font should be made of contours 114 | */ 115 | void setFontMakeContours(bool newFontMakeContours); 116 | 117 | protected: 118 | 119 | /** 120 | * @brief Draws the axis label as an X axis label 121 | */ 122 | void drawAsXLabel() const; 123 | 124 | /** 125 | * @brief Draws the axis label as an Y axis label 126 | */ 127 | void drawAsYLabel() const; 128 | 129 | /** 130 | * @brief Draws the axis label as an TOP axis label 131 | */ 132 | void drawAsTopLabel() const; 133 | 134 | /** 135 | * @brief Draws the axis label as an RIGHT axis label 136 | */ 137 | void drawAsRightLabel() const; 138 | 139 | /** 140 | * @brief The axis type 141 | */ 142 | ofxGAxisType type; 143 | 144 | /** 145 | * @brief The plot box dimensions in pixels 146 | */ 147 | array dim; 148 | 149 | /** 150 | * @brief The label text 151 | */ 152 | string text; 153 | 154 | /** 155 | * @brief The label relative position in the axis 156 | */ 157 | float relativePos; 158 | 159 | /** 160 | * @brief The label position in plot units 161 | */ 162 | float plotPos; 163 | 164 | /** 165 | * @brief The label offset 166 | */ 167 | float offset; 168 | 169 | /** 170 | * @brief Defines if the label should be rotated or not 171 | */ 172 | bool rotate; 173 | 174 | /** 175 | * @brief The text alignment 176 | */ 177 | ofxGTextAlignment textAlignment; 178 | 179 | /** 180 | * @brief The font name 181 | */ 182 | string fontName; 183 | 184 | /** 185 | * @brief The font color 186 | */ 187 | ofColor fontColor; 188 | 189 | /** 190 | * @brief The font size 191 | */ 192 | int fontSize; 193 | 194 | /** 195 | * @brief Defines if the font should be made of contours 196 | */ 197 | bool fontMakeContours; 198 | 199 | /** 200 | * @brief The trueType font 201 | */ 202 | ofTrueTypeFont font; 203 | }; 204 | -------------------------------------------------------------------------------- /src/ofxGConstants.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /** 4 | * @brief ofxGrafica axis types 5 | */ 6 | enum ofxGAxisType { 7 | GRAFICA_X_AXIS, GRAFICA_Y_AXIS, GRAFICA_TOP_AXIS, GRAFICA_RIGHT_AXIS 8 | }; 9 | 10 | /** 11 | * @brief ofxGrafica text alignment options 12 | */ 13 | enum ofxGTextAlignment { 14 | GRAFICA_CENTER_ALIGN, GRAFICA_LEFT_ALIGN, GRAFICA_RIGHT_ALIGN, GRAFICA_TOP_ALIGN, GRAFICA_BOTTOM_ALIGN 15 | }; 16 | 17 | /** 18 | * @brief ofxGrafica line directions 19 | */ 20 | enum ofxGDirection { 21 | GRAFICA_HORIZONTAL_DIRECTION, GRAFICA_VERTICAL_DIRECTION, GRAFICA_BOTH_DIRECTIONS 22 | }; 23 | 24 | /** 25 | * @brief ofxGrafica histogram types 26 | */ 27 | enum ofxGHistogramType { 28 | GRAFICA_HORIZONTAL_HISTOGRAM, GRAFICA_VERTICAL_HISTOGRAM 29 | }; 30 | 31 | /** 32 | * @brief ofxGrafica contour types 33 | */ 34 | enum ofxGContourType { 35 | GRAFICA_HORIZONTAL_CONTOUR, GRAFICA_VERTICAL_CONTOUR 36 | }; 37 | 38 | /** 39 | * @brief ofxGrafica key modifiers 40 | */ 41 | enum ofxGKeyModifiers { 42 | GRAFICA_NONE_MODIFIER = -1 43 | }; 44 | -------------------------------------------------------------------------------- /src/ofxGHistogram.cpp: -------------------------------------------------------------------------------- 1 | #include "ofxGHistogram.h" 2 | #include "ofxGConstants.h" 3 | #include "ofxGPoint.h" 4 | #include "ofMain.h" 5 | 6 | ofxGHistogram::ofxGHistogram(ofxGHistogramType _type, const array& _dim, const vector& _plotPoints) : 7 | type(_type), dim(_dim), plotPoints(_plotPoints) { 8 | // General properties 9 | visible = true; 10 | separations = {2}; 11 | bgColors = {ofColor(150, 150, 255)}; 12 | lineColors = {ofColor(100, 100, 255)}; 13 | lineWidths = {1}; 14 | 15 | // Labels properties 16 | labelsOffset = 8; 17 | drawLabels = false; 18 | rotateLabels = false; 19 | 20 | // Font properties 21 | fontName = OF_TTF_SANS; 22 | fontColor = ofColor(0); 23 | fontSize = 8; 24 | fontMakeContours = false; 25 | font.load(fontName, fontSize, true, true, fontMakeContours); 26 | 27 | // Update the histogram containers 28 | updateArrays(); 29 | } 30 | 31 | void ofxGHistogram::updateArrays() { 32 | int nPoints = plotPoints.size(); 33 | leftSides.clear(); 34 | rightSides.clear(); 35 | 36 | if (nPoints == 1) { 37 | leftSides.push_back((type == GRAFICA_VERTICAL_HISTOGRAM) ? 0.2 * dim[0] : 0.2 * dim[1]); 38 | rightSides.push_back(leftSides[0]); 39 | } else if (nPoints > 1) { 40 | // Calculate the differences between consecutive points 41 | vector differences; 42 | 43 | for (int i = 0; i < nPoints - 1; ++i) { 44 | if (plotPoints[i].isValid() && plotPoints[i + 1].isValid()) { 45 | float separation = separations[i % separations.size()]; 46 | float pointsSeparation; 47 | 48 | if (type == GRAFICA_VERTICAL_HISTOGRAM) { 49 | pointsSeparation = plotPoints[i + 1].getX() - plotPoints[i].getX(); 50 | } else { 51 | pointsSeparation = plotPoints[i + 1].getY() - plotPoints[i].getY(); 52 | } 53 | 54 | if (pointsSeparation > 0) { 55 | differences.push_back((pointsSeparation - separation) / 2); 56 | } else { 57 | differences.push_back((pointsSeparation + separation) / 2); 58 | } 59 | } else { 60 | differences.push_back(0); 61 | } 62 | } 63 | 64 | // Fill the leftSides and rightSides vectors 65 | leftSides.push_back(differences[0]); 66 | rightSides.push_back(differences[0]); 67 | 68 | for (int i = 1; i < nPoints - 1; ++i) { 69 | leftSides.push_back(differences[i - 1]); 70 | rightSides.push_back(differences[i]); 71 | } 72 | 73 | leftSides.push_back(differences.back()); 74 | rightSides.push_back(differences.back()); 75 | } 76 | } 77 | 78 | void ofxGHistogram::draw(const ofxGPoint& plotBasePoint) const { 79 | if (visible) { 80 | // Calculate the baseline for the histogram 81 | float baseline = 0; 82 | 83 | if (plotBasePoint.isValid()) { 84 | baseline = (type == GRAFICA_VERTICAL_HISTOGRAM) ? plotBasePoint.getY() : plotBasePoint.getX(); 85 | } 86 | 87 | // Draw the rectangles 88 | ofPushStyle(); 89 | ofSetRectMode(OF_RECTMODE_CORNER); 90 | 91 | for (vector::size_type i = 0; i < plotPoints.size(); ++i) { 92 | if (plotPoints[i].isValid()) { 93 | // Obtain the corners 94 | float x1, x2, y1, y2; 95 | 96 | if (type == GRAFICA_VERTICAL_HISTOGRAM) { 97 | x1 = plotPoints[i].getX() - leftSides[i]; 98 | x2 = plotPoints[i].getX() + rightSides[i]; 99 | y1 = plotPoints[i].getY(); 100 | y2 = baseline; 101 | } else { 102 | x1 = baseline; 103 | x2 = plotPoints[i].getX(); 104 | y1 = plotPoints[i].getY() - leftSides[i]; 105 | y2 = plotPoints[i].getY() + rightSides[i]; 106 | } 107 | 108 | x1 = ofClamp(x1, 0, dim[0]); 109 | x2 = ofClamp(x2, 0, dim[0]); 110 | y1 = -ofClamp(-y1, 0, dim[1]); 111 | y2 = -ofClamp(-y2, 0, dim[1]); 112 | 113 | // Draw the rectangle 114 | bool cond1 = type == GRAFICA_VERTICAL_HISTOGRAM && x2 != x1 115 | && !(y1 == y2 && (y1 == 0 || y1 == -dim[1])); 116 | bool cond2 = type == GRAFICA_HORIZONTAL_HISTOGRAM && y2 != y1 117 | && !(x1 == x2 && (x1 == 0 || x1 == dim[0])); 118 | 119 | if (cond1 || cond2) { 120 | ofFill(); 121 | ofSetColor(bgColors[i % bgColors.size()]); 122 | ofDrawRectangle(x1, y1, x2 - x1, y2 - y1); 123 | ofNoFill(); 124 | ofSetLineWidth(lineWidths[i % lineWidths.size()]); 125 | ofSetColor(lineColors[i % lineColors.size()]); 126 | ofDrawRectangle(x1, y1, x2 - x1, y2 - y1); 127 | } 128 | } 129 | } 130 | 131 | ofPopStyle(); 132 | 133 | // Draw the labels 134 | if (drawLabels) { 135 | drawHistLabels(); 136 | } 137 | } 138 | } 139 | 140 | void ofxGHistogram::drawHistLabels() const { 141 | ofPushStyle(); 142 | ofSetColor(fontColor); 143 | 144 | if (type == GRAFICA_VERTICAL_HISTOGRAM) { 145 | if (rotateLabels) { 146 | for (const ofxGPoint& p : plotPoints) { 147 | if (p.isValid() && p.getX() >= 0 && p.getX() <= dim[0]) { 148 | ofRectangle bounds = font.getStringBoundingBox(p.getLabel(), 0, 0); 149 | ofPushMatrix(); 150 | ofTranslate(p.getX() + fontSize / 2.0, labelsOffset + bounds.width); 151 | ofRotateZDeg(-90); 152 | font.drawString(p.getLabel(), 0, 0); 153 | ofPopMatrix(); 154 | } 155 | } 156 | } else { 157 | for (const ofxGPoint& p : plotPoints) { 158 | if (p.isValid() && p.getX() >= 0 && p.getX() <= dim[0]) { 159 | ofRectangle bounds = font.getStringBoundingBox(p.getLabel(), 0, 0); 160 | font.drawString(p.getLabel(), p.getX() - bounds.width / 2, labelsOffset + fontSize); 161 | } 162 | } 163 | } 164 | } else { 165 | if (rotateLabels) { 166 | for (const ofxGPoint& p : plotPoints) { 167 | if (p.isValid() && -p.getY() >= 0 && -p.getY() <= dim[1]) { 168 | ofRectangle bounds = font.getStringBoundingBox(p.getLabel(), 0, 0); 169 | ofPushMatrix(); 170 | ofTranslate(-labelsOffset, p.getY() + bounds.width / 2); 171 | ofRotateZDeg(-90); 172 | font.drawString(p.getLabel(), 0, 0); 173 | ofPopMatrix(); 174 | } 175 | } 176 | } else { 177 | for (const ofxGPoint& p : plotPoints) { 178 | if (p.isValid() && -p.getY() >= 0 && -p.getY() <= dim[1]) { 179 | ofRectangle bounds = font.getStringBoundingBox(p.getLabel(), 0, 0); 180 | font.drawString(p.getLabel(), -labelsOffset - bounds.width, p.getY() + fontSize / 2.0); 181 | } 182 | } 183 | } 184 | } 185 | 186 | ofPopStyle(); 187 | } 188 | 189 | void ofxGHistogram::setType(ofxGHistogramType newType) { 190 | if (newType != type) { 191 | type = newType; 192 | updateArrays(); 193 | } 194 | } 195 | 196 | void ofxGHistogram::setDim(float xDim, float yDim) { 197 | if (xDim <= 0 || yDim <= 0) { 198 | throw invalid_argument("The dimensions should be larger than zero."); 199 | } 200 | 201 | dim = {xDim, yDim}; 202 | updateArrays(); 203 | } 204 | 205 | void ofxGHistogram::setDim(const array& newDim) { 206 | setDim(newDim[0], newDim[1]); 207 | } 208 | 209 | void ofxGHistogram::setPlotPoints(const vector& newPlotPoints) { 210 | plotPoints = newPlotPoints; 211 | updateArrays(); 212 | } 213 | 214 | void ofxGHistogram::setPlotPoint(vector::size_type index, const ofxGPoint& newPlotPoint) { 215 | plotPoints[index] = newPlotPoint; 216 | updateArrays(); 217 | } 218 | 219 | void ofxGHistogram::addPlotPoint(const ofxGPoint& newPlotPoint) { 220 | plotPoints.push_back(newPlotPoint); 221 | updateArrays(); 222 | } 223 | 224 | void ofxGHistogram::addPlotPoint(vector::size_type index, ofxGPoint& newPlotPoint) { 225 | plotPoints.insert(plotPoints.begin() + index, newPlotPoint); 226 | updateArrays(); 227 | } 228 | 229 | void ofxGHistogram::addPlotPoints(const vector& newPlotPoints) { 230 | plotPoints.insert(plotPoints.end(), newPlotPoints.begin(), newPlotPoints.end()); 231 | updateArrays(); 232 | } 233 | 234 | void ofxGHistogram::removePlotPoint(vector::size_type index) { 235 | plotPoints.erase(plotPoints.begin() + index); 236 | updateArrays(); 237 | } 238 | 239 | void ofxGHistogram::setSeparations(const vector& newSeparations) { 240 | separations = newSeparations; 241 | updateArrays(); 242 | } 243 | 244 | void ofxGHistogram::setBgColors(const vector& newBgColors) { 245 | bgColors = newBgColors; 246 | } 247 | 248 | void ofxGHistogram::setLineColors(const vector& newLineColors) { 249 | lineColors = newLineColors; 250 | } 251 | 252 | void ofxGHistogram::setLineWidths(const vector& newLineWidths) { 253 | lineWidths = newLineWidths; 254 | } 255 | 256 | void ofxGHistogram::setVisible(bool newVisible) { 257 | visible = newVisible; 258 | } 259 | 260 | void ofxGHistogram::setLabelsOffset(float newLabelsOffset) { 261 | labelsOffset = newLabelsOffset; 262 | } 263 | 264 | void ofxGHistogram::setDrawLabels(bool newDrawLabels) { 265 | drawLabels = newDrawLabels; 266 | } 267 | 268 | void ofxGHistogram::setRotateLabels(bool newRotateLabels) { 269 | rotateLabels = newRotateLabels; 270 | } 271 | 272 | void ofxGHistogram::setFontName(const string& newFontName) { 273 | fontName = newFontName; 274 | font.load(fontName, fontSize, true, true, fontMakeContours); 275 | } 276 | 277 | void ofxGHistogram::setFontColor(const ofColor& newFontColor) { 278 | fontColor = newFontColor; 279 | } 280 | 281 | void ofxGHistogram::setFontSize(int newFontSize) { 282 | if (newFontSize <= 0) { 283 | throw invalid_argument("The font size should be larger than zero."); 284 | } 285 | 286 | fontSize = newFontSize; 287 | font.load(fontName, fontSize, true, true, fontMakeContours); 288 | } 289 | 290 | void ofxGHistogram::setFontProperties(const string& newFontName, const ofColor& newFontColor, int newFontSize) { 291 | if (newFontSize <= 0) { 292 | throw invalid_argument("The font size should be larger than zero."); 293 | } 294 | 295 | fontName = newFontName; 296 | fontColor = newFontColor; 297 | fontSize = newFontSize; 298 | font.load(fontName, fontSize, true, true, fontMakeContours); 299 | } 300 | 301 | void ofxGHistogram::setFontMakeContours(bool newFontMakeContours) { 302 | fontMakeContours = newFontMakeContours; 303 | font.load(fontName, fontSize, true, true, fontMakeContours); 304 | } 305 | -------------------------------------------------------------------------------- /src/ofxGHistogram.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofxGConstants.h" 4 | #include "ofxGPoint.h" 5 | #include "ofMain.h" 6 | 7 | /** 8 | * @brief Histogram class 9 | * 10 | * @author Javier Graciá Carpio 11 | */ 12 | class ofxGHistogram { 13 | public: 14 | 15 | /** 16 | * @brief Constructor 17 | * 18 | * @param _type the histogram type. It can be GRAFICA_HORIZONTAL_HISTOGRAM or GRAFICA_VERTICAL_HISTOGRAM 19 | * @param _dim the plot box dimensions in pixels 20 | * @param _plotPoints the points positions in the plot reference system 21 | */ 22 | ofxGHistogram(ofxGHistogramType _type = GRAFICA_VERTICAL_HISTOGRAM, const array& _dim = { 100, 100 }, 23 | const vector& _plotPoints = { }); 24 | 25 | /** 26 | * @brief Draws the histogram 27 | * 28 | * @param plotBasePoint the histogram base point in the plot reference system 29 | */ 30 | void draw(const ofxGPoint& plotBasePoint) const; 31 | 32 | /** 33 | * @brief Sets the type of histogram to display 34 | * 35 | * @param newType the new type of histogram to display. It can be GRAFICA_HORIZONTAL_HISTOGRAM or 36 | * GRAFICA_VERTICAL_HISTOGRAM 37 | */ 38 | void setType(ofxGHistogramType newType); 39 | 40 | /** 41 | * @brief Sets the plot box dimensions information 42 | * 43 | * @param xDim the new plot box x dimension 44 | * @param yDim the new plot box y dimension 45 | */ 46 | void setDim(float xDim, float yDim); 47 | 48 | /** 49 | * @brief Sets the plot box dimensions information 50 | * 51 | * @param newDim the new plot box dimensions information 52 | */ 53 | void setDim(const array& newDim); 54 | 55 | /** 56 | * @brief Sets the histogram plot points 57 | * 58 | * @param newPlotPoints the new point positions in the plot reference system 59 | */ 60 | void setPlotPoints(const vector& newPlotPoints); 61 | 62 | /** 63 | * @brief Sets one of the histogram plot points 64 | * 65 | * @param index the point position 66 | * @param newPlotPoint the new point positions in the plot reference system 67 | */ 68 | void setPlotPoint(vector::size_type index, const ofxGPoint& newPlotPoint); 69 | 70 | /** 71 | * @brief Adds a new plot point to the histogram 72 | * 73 | * @param newPlotPoint the new point position in the plot reference system 74 | */ 75 | void addPlotPoint(const ofxGPoint& newPlotPoint); 76 | 77 | /** 78 | * @brief Adds a new plot point to the histogram 79 | * 80 | * @param index the position to add the point 81 | * @param newPlotPoint the new point position in the plot reference system 82 | */ 83 | void addPlotPoint(vector::size_type index, ofxGPoint& newPlotPoint); 84 | 85 | /** 86 | * @brief Adds new plot points to the histogram 87 | * 88 | * @param newPlotPoints the new points positions in the plot reference system 89 | */ 90 | void addPlotPoints(const vector& newPlotPoints); 91 | 92 | /** 93 | * @brief Removes one of the points from the histogram 94 | * 95 | * @param index the point position 96 | */ 97 | void removePlotPoint(vector::size_type index); 98 | 99 | /** 100 | * @brief Sets the separations between the histogram elements 101 | * 102 | * @param newSeparations the new separations between the histogram elements 103 | */ 104 | void setSeparations(const vector& newSeparations); 105 | 106 | /** 107 | * @brief Sets the background colors of the histogram elements 108 | * 109 | * @param newBgColors the new background colors of the histogram elements 110 | */ 111 | void setBgColors(const vector& newBgColors); 112 | 113 | /** 114 | * @brief Sets the line colors of the histogram elements 115 | * 116 | * @param newLineColors the new line colors of the histogram elements 117 | */ 118 | void setLineColors(const vector& newLineColors); 119 | 120 | /** 121 | * @brief Sets the line widths of the histogram elements 122 | * 123 | * @param newLineWidths the new line widths of the histogram elements 124 | */ 125 | void setLineWidths(const vector& newLineWidths); 126 | 127 | /** 128 | * @brief Sets if the histogram should be visible or not 129 | * 130 | * @param newVisible true if the histogram should be visible 131 | */ 132 | void setVisible(bool newVisible); 133 | 134 | /** 135 | * @brief Sets the histogram labels offset 136 | * 137 | * @param newLabelsOffset the new histogram labels offset 138 | */ 139 | void setLabelsOffset(float newLabelsOffset); 140 | 141 | /** 142 | * @brief Sets if the histogram labels should be drawn or not 143 | * 144 | * @param newDrawLabels true if the histogram labels should be drawn 145 | */ 146 | void setDrawLabels(bool newDrawLabels); 147 | 148 | /** 149 | * @brief Sets if the histogram labels should be rotated or not 150 | * 151 | * @param newRotateLabels true if the histogram labels should be rotated 152 | */ 153 | void setRotateLabels(bool newRotateLabels); 154 | 155 | /** 156 | * @brief Sets the font name 157 | * 158 | * @param newFontName the name of the new font 159 | */ 160 | void setFontName(const string& newFontName); 161 | 162 | /** 163 | * @brief Sets the font color 164 | * 165 | * @param newFontColor the new font color 166 | */ 167 | void setFontColor(const ofColor& newFontColor); 168 | 169 | /** 170 | * @brief Sets the font size 171 | * 172 | * @param newFontSize the new font size 173 | */ 174 | void setFontSize(int newFontSize); 175 | 176 | /** 177 | * @brief Sets all the font properties at once 178 | * 179 | * @param newFontName the name of the new font 180 | * @param newFontColor the new font color 181 | * @param newFontSize the new font size 182 | */ 183 | void setFontProperties(const string& newFontName, const ofColor& newFontColor, int newFontSize); 184 | 185 | /** 186 | * @brief Sets if the font should be made of contours 187 | * 188 | * @param newFontMakeContours true if the font should be made of contours 189 | */ 190 | void setFontMakeContours(bool newFontMakeContours); 191 | 192 | protected: 193 | 194 | /** 195 | * @brief Updates the leftSides and rightSides arrays 196 | */ 197 | void updateArrays(); 198 | 199 | /** 200 | * @brief Draws the histogram labels 201 | */ 202 | void drawHistLabels() const; 203 | 204 | /** 205 | * @brief The histogram type 206 | */ 207 | ofxGHistogramType type; 208 | 209 | /** 210 | * @brief The plot box dimensions in pixels 211 | */ 212 | array dim; 213 | 214 | /** 215 | * @brief The points positions in the plot reference system 216 | */ 217 | vector plotPoints; 218 | 219 | /** 220 | * @brief Defines if the histogram should be visible or not 221 | */ 222 | bool visible; 223 | 224 | /** 225 | * @brief The separations between the histogram elements 226 | */ 227 | vector separations; 228 | 229 | /** 230 | * @brief The background colors of the histogram elements 231 | */ 232 | vector bgColors; 233 | 234 | /** 235 | * @brief The line colors of the histogram elements 236 | */ 237 | vector lineColors; 238 | 239 | /** 240 | * @brief The line widths of the histogram elements 241 | */ 242 | vector lineWidths; 243 | 244 | /** 245 | * @brief The left side sizes of the histogram elements 246 | */ 247 | vector leftSides; 248 | 249 | /** 250 | * @brief The right side sizes of the histogram elements 251 | */ 252 | vector rightSides; 253 | 254 | /** 255 | * @brief The labels offset 256 | */ 257 | float labelsOffset; 258 | 259 | /** 260 | * @brief Defines if the labels should be drawn 261 | */ 262 | bool drawLabels; 263 | 264 | /** 265 | * @brief Defines if the labels should be rotated 266 | */ 267 | bool rotateLabels; 268 | 269 | /** 270 | * @brief The font name 271 | */ 272 | string fontName; 273 | 274 | /** 275 | * @brief The font color 276 | */ 277 | ofColor fontColor; 278 | 279 | /** 280 | * @brief The font size 281 | */ 282 | int fontSize; 283 | 284 | /** 285 | * @brief Defines if the font should be made of contours 286 | */ 287 | bool fontMakeContours; 288 | 289 | /** 290 | * @brief The trueType font 291 | */ 292 | ofTrueTypeFont font; 293 | }; 294 | -------------------------------------------------------------------------------- /src/ofxGPoint.cpp: -------------------------------------------------------------------------------- 1 | #include "ofxGPoint.h" 2 | #include "ofMain.h" 3 | 4 | ofxGPoint::ofxGPoint(float _x, float _y, const string& _label) : 5 | x(_x), y(_y), label(_label), valid(isfinite(x) && isfinite(y)) { 6 | } 7 | 8 | ofxGPoint::ofxGPoint() : 9 | ofxGPoint(0.0, 0.0) { 10 | } 11 | 12 | ofxGPoint::ofxGPoint(const glm::vec2& v, const string& _label) : 13 | ofxGPoint(v.x, v.y, _label) { 14 | } 15 | 16 | void ofxGPoint::set(float newX, float newY, const string& newLabel) { 17 | x = newX; 18 | y = newY; 19 | label = newLabel; 20 | valid = isfinite(x) && isfinite(y); 21 | } 22 | 23 | void ofxGPoint::set(const glm::vec2& v, const string& newLabel) { 24 | set(v.x, v.y, newLabel); 25 | } 26 | 27 | void ofxGPoint::set(const ofxGPoint& p) { 28 | set(p.x, p.y, p.label); 29 | } 30 | 31 | void ofxGPoint::setX(float newX) { 32 | x = newX; 33 | valid = isfinite(x) && isfinite(y); 34 | } 35 | 36 | void ofxGPoint::setY(float newY) { 37 | y = newY; 38 | valid = isfinite(x) && isfinite(y); 39 | } 40 | 41 | void ofxGPoint::setXY(float newX, float newY) { 42 | x = newX; 43 | y = newY; 44 | valid = isfinite(x) && isfinite(y); 45 | } 46 | 47 | void ofxGPoint::setXY(const glm::vec2& v) { 48 | setXY(v.x, v.y); 49 | } 50 | 51 | void ofxGPoint::setXY(const ofxGPoint& p) { 52 | setXY(p.x, p.y); 53 | } 54 | 55 | void ofxGPoint::setLabel(const string& newLabel) { 56 | label = newLabel; 57 | } 58 | 59 | float ofxGPoint::getX() const { 60 | return x; 61 | } 62 | 63 | float ofxGPoint::getY() const { 64 | return y; 65 | } 66 | 67 | string ofxGPoint::getLabel() const { 68 | return label; 69 | } 70 | 71 | bool ofxGPoint::getValid() const { 72 | return valid; 73 | } 74 | 75 | bool ofxGPoint::isValid() const { 76 | return valid; 77 | } 78 | -------------------------------------------------------------------------------- /src/ofxGPoint.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | 5 | /** 6 | * @brief Point class 7 | * 8 | * An ofxGPoint is composed of two coordinates (x, y) and a text label 9 | * 10 | * @author Javier Graciá Carpio 11 | */ 12 | class ofxGPoint { 13 | public: 14 | 15 | /** 16 | * @brief Default constructor 17 | */ 18 | ofxGPoint(); 19 | 20 | /** 21 | * @brief Constructor 22 | * 23 | * @param _x the x coordinate 24 | * @param _y the y coordinate 25 | * @param _label the text label 26 | */ 27 | ofxGPoint(float _x, float _y, const string& _label = ""); 28 | 29 | /** 30 | * @brief Constructor 31 | * 32 | * @param v the 2d vector containing the point coordinates 33 | * @param _label the text label 34 | */ 35 | ofxGPoint(const glm::vec2& v, const string& _label = ""); 36 | 37 | /** 38 | * @brief Sets the point x and y coordinates and the label 39 | * 40 | * @param newX the new x coordinate 41 | * @param newY the new y coordinate 42 | * @param newLabel the new point text label 43 | */ 44 | void set(float newX, float newY, const string& newLabel); 45 | 46 | /** 47 | * @brief Sets the point x and y coordinates and the label 48 | * 49 | * @param v the 2d vector with the new point coordinates 50 | * @param newLabel the new point text label 51 | */ 52 | void set(const glm::vec2& v, const string& newLabel); 53 | 54 | /** 55 | * @brief Sets the point x and y coordinates and the label 56 | * 57 | * @param p the point to use as a reference 58 | */ 59 | void set(const ofxGPoint& p); 60 | 61 | /** 62 | * @brief Sets the point x coordinate 63 | * 64 | * @param newX the new x coordinate 65 | */ 66 | void setX(float newX); 67 | 68 | /** 69 | * @brief Sets the point y coordinate 70 | * 71 | * @param newY the new y coordinate 72 | */ 73 | void setY(float newY); 74 | 75 | /** 76 | * @brief Sets the point x and y coordinates 77 | * 78 | * @param newX the new x coordinate 79 | * @param newY the new y coordinate 80 | */ 81 | void setXY(float newX, float newY); 82 | 83 | /** 84 | * @brief Sets the point x and y coordinates 85 | * 86 | * @param v the 2d vector with the new point coordinates 87 | */ 88 | void setXY(const glm::vec2& v); 89 | 90 | /** 91 | * @brief Sets the point x and y coordinates 92 | * 93 | * @param p the point with the new point coordinates 94 | */ 95 | void setXY(const ofxGPoint& p); 96 | 97 | /** 98 | * @brief Sets the point text label 99 | * 100 | * @param newLabel the new point text label 101 | */ 102 | void setLabel(const string& newLabel); 103 | 104 | /** 105 | * @brief Returns the point x coordinate 106 | * 107 | * @return the point x coordinate 108 | */ 109 | float getX() const; 110 | 111 | /** 112 | * @brief Returns the point y coordinate 113 | * 114 | * @return the point y coordinate 115 | */ 116 | float getY() const; 117 | 118 | /** 119 | * @brief Returns the point text label 120 | * 121 | * @return the point text label 122 | */ 123 | string getLabel() const; 124 | 125 | /** 126 | * @brief Returns if the point coordinates are valid or not 127 | * 128 | * @return true if the point coordinates are valid 129 | */ 130 | bool getValid() const; 131 | 132 | /** 133 | * @brief Returns if the point coordinates are valid or not 134 | * 135 | * @return true if the point coordinates are valid 136 | */ 137 | bool isValid() const; 138 | 139 | protected: 140 | 141 | /** 142 | * @brief The point x coordinate 143 | */ 144 | float x; 145 | 146 | /** 147 | * @brief The point y coordinate 148 | */ 149 | float y; 150 | 151 | /** 152 | * @brief The point text label 153 | */ 154 | string label; 155 | 156 | /** 157 | * @brief Indicates if the point coordinates are valid or not 158 | */ 159 | bool valid; 160 | }; 161 | -------------------------------------------------------------------------------- /src/ofxGTitle.cpp: -------------------------------------------------------------------------------- 1 | #include "ofxGTitle.h" 2 | #include "ofxGConstants.h" 3 | #include "ofMain.h" 4 | 5 | ofxGTitle::ofxGTitle(const array& _dim, const string& _text) : 6 | dim(_dim), text(_text) { 7 | // General properties 8 | relativePos = 0.5; 9 | plotPos = relativePos * dim[0]; 10 | offset = 13; 11 | 12 | // Font properties 13 | textAlignment = GRAFICA_CENTER_ALIGN; 14 | fontName = OF_TTF_SANS; 15 | fontColor = ofColor(100); 16 | fontSize = 10; 17 | fontMakeContours = false; 18 | font.load(fontName, fontSize, true, true, fontMakeContours); 19 | } 20 | 21 | void ofxGTitle::draw() const { 22 | ofPushStyle(); 23 | ofSetColor(fontColor); 24 | ofRectangle bounds = font.getStringBoundingBox(text, 0, 0); 25 | 26 | switch (textAlignment) { 27 | case GRAFICA_CENTER_ALIGN: 28 | font.drawString(text, plotPos - bounds.width / 2, -offset - dim[1]); 29 | break; 30 | case GRAFICA_LEFT_ALIGN: 31 | font.drawString(text, plotPos, -offset - dim[1]); 32 | break; 33 | case GRAFICA_RIGHT_ALIGN: 34 | font.drawString(text, plotPos - bounds.width, -offset - dim[1]); 35 | break; 36 | default: 37 | font.drawString(text, plotPos - bounds.width / 2, -offset - dim[1]); 38 | break; 39 | } 40 | 41 | ofPopStyle(); 42 | } 43 | 44 | void ofxGTitle::setDim(float xDim, float yDim) { 45 | if (xDim <= 0 || yDim <= 0) { 46 | throw invalid_argument("The dimensions should be larger than zero."); 47 | } 48 | 49 | dim = {xDim, yDim}; 50 | plotPos = relativePos * dim[0]; 51 | } 52 | 53 | void ofxGTitle::setDim(const array& newDim) { 54 | setDim(newDim[0], newDim[1]); 55 | } 56 | 57 | void ofxGTitle::setRelativePos(float newRelativePos) { 58 | relativePos = newRelativePos; 59 | plotPos = relativePos * dim[0]; 60 | } 61 | 62 | void ofxGTitle::setOffset(float newOffset) { 63 | offset = newOffset; 64 | } 65 | 66 | void ofxGTitle::setText(const string& newText) { 67 | text = newText; 68 | } 69 | 70 | void ofxGTitle::setTextAlignment(ofxGTextAlignment newTextAlignment) { 71 | textAlignment = newTextAlignment; 72 | } 73 | 74 | void ofxGTitle::setFontName(const string& newFontName) { 75 | fontName = newFontName; 76 | font.load(fontName, fontSize, true, true, fontMakeContours); 77 | } 78 | 79 | void ofxGTitle::setFontColor(const ofColor& newFontColor) { 80 | fontColor = newFontColor; 81 | } 82 | 83 | void ofxGTitle::setFontSize(int newFontSize) { 84 | if (newFontSize <= 0) { 85 | throw invalid_argument("The font size should be larger than zero."); 86 | } 87 | 88 | fontSize = newFontSize; 89 | font.load(fontName, fontSize, true, true, fontMakeContours); 90 | } 91 | 92 | void ofxGTitle::setFontProperties(const string& newFontName, const ofColor& newFontColor, int newFontSize) { 93 | if (newFontSize <= 0) { 94 | throw invalid_argument("The font size should be larger than zero."); 95 | } 96 | 97 | fontName = newFontName; 98 | fontColor = newFontColor; 99 | fontSize = newFontSize; 100 | font.load(fontName, fontSize, true, true, fontMakeContours); 101 | } 102 | 103 | void ofxGTitle::setFontMakeContours(bool newFontMakeContours) { 104 | fontMakeContours = newFontMakeContours; 105 | font.load(fontName, fontSize, true, true, fontMakeContours); 106 | } 107 | -------------------------------------------------------------------------------- /src/ofxGTitle.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofxGConstants.h" 4 | #include "ofMain.h" 5 | 6 | /** 7 | * @brief Title class 8 | * 9 | * @author Javier Graciá Carpio 10 | */ 11 | class ofxGTitle { 12 | public: 13 | 14 | /** 15 | * @brief Constructor 16 | * 17 | * @param _dim the plot box dimensions in pixels 18 | * @param _text the title text 19 | */ 20 | ofxGTitle(const array& _dim = { 100, 100 }, const string& _text = ""); 21 | 22 | /** 23 | * @brief Draws the plot title 24 | */ 25 | void draw() const; 26 | 27 | /** 28 | * @brief Sets the plot box dimensions information 29 | * 30 | * @param xDim the new plot box x dimension 31 | * @param yDim the new plot box y dimension 32 | */ 33 | void setDim(float xDim, float yDim); 34 | 35 | /** 36 | * @brief Sets the plot box dimensions information 37 | * 38 | * @param newDim the new plot box dimensions information 39 | */ 40 | void setDim(const array& newDim); 41 | 42 | /** 43 | * @brief Sets the title relative position in the plot 44 | * 45 | * @param newRelativePos the new relative position in the plot 46 | */ 47 | void setRelativePos(float newRelativePos); 48 | 49 | /** 50 | * @brief Sets the title offset 51 | * 52 | * @param newOffset the new title offset 53 | */ 54 | void setOffset(float newOffset); 55 | 56 | /** 57 | * @brief Sets the title text 58 | * 59 | * @param newText the new title text 60 | */ 61 | void setText(const string& newText); 62 | 63 | /** 64 | * @brief Sets the title type of text alignment 65 | * 66 | * @param newTextAlignment the new type of text alignment. It can be GRAFICA_CENTER_ALIGN, GRAFICA_LEFT_ALIGN or 67 | * GRAFICA_RIGHT_ALIGN 68 | */ 69 | void setTextAlignment(ofxGTextAlignment newTextAlignment); 70 | 71 | /** 72 | * @brief Sets the font name 73 | * 74 | * @param newFontName the name of the new font 75 | */ 76 | void setFontName(const string& newFontName); 77 | 78 | /** 79 | * @brief Sets the font color 80 | * 81 | * @param newFontColor the new font color 82 | */ 83 | void setFontColor(const ofColor& newFontColor); 84 | 85 | /** 86 | * @brief Sets the font size 87 | * 88 | * @param newFontSize the new font size 89 | */ 90 | void setFontSize(int newFontSize); 91 | 92 | /** 93 | * @brief Sets all the font properties at once 94 | * 95 | * @param newFontName the name of the new font 96 | * @param newFontColor the new font color 97 | * @param newFontSize the new font size 98 | */ 99 | void setFontProperties(const string& newFontName, const ofColor& newFontColor, int newFontSize); 100 | 101 | /** 102 | * @brief Sets if the font should be made of contours 103 | * 104 | * @param newFontMakeContours true if the font should be made of contours 105 | */ 106 | void setFontMakeContours(bool newFontMakeContours); 107 | 108 | protected: 109 | 110 | /** 111 | * @brief The plot box dimensions in pixels 112 | */ 113 | array dim; 114 | 115 | /** 116 | * @brief The title text 117 | */ 118 | string text; 119 | 120 | /** 121 | * @brief The title relative position in the plot 122 | */ 123 | float relativePos; 124 | 125 | /** 126 | * @brief The title position in plot units 127 | */ 128 | float plotPos; 129 | 130 | /** 131 | * @brief The title offset 132 | */ 133 | float offset; 134 | 135 | /** 136 | * @brief The text alignment 137 | */ 138 | ofxGTextAlignment textAlignment; 139 | 140 | /** 141 | * @brief The font name 142 | */ 143 | string fontName; 144 | 145 | /** 146 | * @brief The font color 147 | */ 148 | ofColor fontColor; 149 | 150 | /** 151 | * @brief The font size 152 | */ 153 | int fontSize; 154 | 155 | /** 156 | * @brief Defines if the font should be made of contours 157 | */ 158 | bool fontMakeContours; 159 | 160 | /** 161 | * @brief The trueType font 162 | */ 163 | ofTrueTypeFont font; 164 | }; 165 | -------------------------------------------------------------------------------- /src/ofxGrafica.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofxGConstants.h" 4 | #include "ofxGPoint.h" 5 | #include "ofxGTitle.h" 6 | #include "ofxGAxisLabel.h" 7 | #include "ofxGAxis.h" 8 | #include "ofxGHistogram.h" 9 | #include "ofxGLayer.h" 10 | #include "ofxGPlot.h" 11 | --------------------------------------------------------------------------------