1/*
2 src/graph.cpp -- Simple graph widget for showing a function plot
3
4 NanoGUI was developed by Wenzel Jakob <wenzel.jakob@epfl.ch>.
5 The widget drawing code is based on the NanoVG demo application
6 by Mikko Mononen.
7
8 All rights reserved. Use of this source code is governed by a
9 BSD-style license that can be found in the LICENSE.txt file.
10*/
11
12#include <nanogui/graph.h>
13#include <nanogui/theme.h>
14#include <nanogui/opengl.h>
15#include <nanogui/serializer/core.h>
16
17NAMESPACE_BEGIN(nanogui)
18
19Graph::Graph(Widget *parent, const std::string &caption)
20 : Widget(parent), mCaption(caption) {
21 mBackgroundColor = Color(20, 128);
22 mForegroundColor = Color(255, 192, 0, 128);
23 mTextColor = Color(240, 192);
24}
25
26Vector2i Graph::preferredSize(NVGcontext *) const {
27 return Vector2i(180, 45);
28}
29
30void Graph::draw(NVGcontext *ctx) {
31 Widget::draw(ctx);
32
33 nvgBeginPath(ctx);
34 nvgRect(ctx, mPos.x(), mPos.y(), mSize.x(), mSize.y());
35 nvgFillColor(ctx, mBackgroundColor);
36 nvgFill(ctx);
37
38 if (mValues.size() < 2)
39 return;
40
41 nvgBeginPath(ctx);
42 nvgMoveTo(ctx, mPos.x(), mPos.y()+mSize.y());
43 for (size_t i = 0; i < (size_t) mValues.size(); i++) {
44 float value = mValues[i];
45 float vx = mPos.x() + i * mSize.x() / (float) (mValues.size() - 1);
46 float vy = mPos.y() + (1-value) * mSize.y();
47 nvgLineTo(ctx, vx, vy);
48 }
49
50 nvgLineTo(ctx, mPos.x() + mSize.x(), mPos.y() + mSize.y());
51 nvgStrokeColor(ctx, Color(100, 255));
52 nvgStroke(ctx);
53 nvgFillColor(ctx, mForegroundColor);
54 nvgFill(ctx);
55
56 nvgFontFace(ctx, "sans");
57
58 if (!mCaption.empty()) {
59 nvgFontSize(ctx, 14.0f);
60 nvgTextAlign(ctx, NVG_ALIGN_LEFT | NVG_ALIGN_TOP);
61 nvgFillColor(ctx, mTextColor);
62 nvgText(ctx, mPos.x() + 3, mPos.y() + 1, mCaption.c_str(), NULL);
63 }
64
65 if (!mHeader.empty()) {
66 nvgFontSize(ctx, 18.0f);
67 nvgTextAlign(ctx, NVG_ALIGN_RIGHT | NVG_ALIGN_TOP);
68 nvgFillColor(ctx, mTextColor);
69 nvgText(ctx, mPos.x() + mSize.x() - 3, mPos.y() + 1, mHeader.c_str(), NULL);
70 }
71
72 if (!mFooter.empty()) {
73 nvgFontSize(ctx, 15.0f);
74 nvgTextAlign(ctx, NVG_ALIGN_RIGHT | NVG_ALIGN_BOTTOM);
75 nvgFillColor(ctx, mTextColor);
76 nvgText(ctx, mPos.x() + mSize.x() - 3, mPos.y() + mSize.y() - 1, mFooter.c_str(), NULL);
77 }
78
79 nvgBeginPath(ctx);
80 nvgRect(ctx, mPos.x(), mPos.y(), mSize.x(), mSize.y());
81 nvgStrokeColor(ctx, Color(100, 255));
82 nvgStroke(ctx);
83}
84
85void Graph::save(Serializer &s) const {
86 Widget::save(s);
87 s.set("caption", mCaption);
88 s.set("header", mHeader);
89 s.set("footer", mFooter);
90 s.set("backgroundColor", mBackgroundColor);
91 s.set("foregroundColor", mForegroundColor);
92 s.set("textColor", mTextColor);
93 s.set("values", mValues);
94}
95
96bool Graph::load(Serializer &s) {
97 if (!Widget::load(s)) return false;
98 if (!s.get("caption", mCaption)) return false;
99 if (!s.get("header", mHeader)) return false;
100 if (!s.get("footer", mFooter)) return false;
101 if (!s.get("backgroundColor", mBackgroundColor)) return false;
102 if (!s.get("foregroundColor", mForegroundColor)) return false;
103 if (!s.get("textColor", mTextColor)) return false;
104 if (!s.get("values", mValues)) return false;
105 return true;
106}
107
108NAMESPACE_END(nanogui)
109