Program Listing for File layout.h

Return to documentation for file (source/layout.h)

/*
 * layout.h
 *
 * Author:              Tom Clark  (thclark @ github)
 *
 * Copyright (c) 2019 Octue Ltd. All Rights Reserved.
 *
 */

#ifndef CPPLOT_LAYOUT_H
#define CPPLOT_LAYOUT_H

#include <exception>
#include <math.h>
#include <stdio.h>
#include <vector>
#include <string.h>
#include <Eigen/Dense>
#include <nlohmann/json.hpp>


using nlohmann::json;


namespace cpplot {


enum AxisDirection { X, Y, Z};

class Axis {
public:
    // Allow the serialiser function to access protected members
    friend void to_json(nlohmann::json& j, const Axis& p);

    explicit Axis(const AxisDirection dir) : direction(dir){
        switch(dir){
            case X:
                key = "xaxis";
                break;
            case Y:
                key = "yaxis";
                break;
            case Z:
                key = "zaxis";
                break;
        }
    };

    void setDirection(AxisDirection dir) {
        direction = dir;
    };

    void setTitle(std::string label) {
        title = label;
    };

    void setLog() {
        is_log = true;
    };

    AxisDirection getDirection() {
        return direction;
    };

    std::string getTitle() {
        return title;
    };

    bool isLog() {
        return is_log;
    };

protected:
    AxisDirection direction;
    std::string title;
    std::string key;
    bool is_log = false;
};


void to_json(nlohmann::json& j, const Axis& p) {
    nlohmann::json axis;
    axis["title"] = p.title;
    if (p.is_log) {
        axis["type"] = "log";
    };
    j[p.key] = axis;
}


class Layout {
public:

    // Allow the serialiser function to access protected members
    friend void to_json(nlohmann::json& j, const Layout& p);

    explicit Layout(const std::string title="", const bool is_scene=false) : title(title), is_scene(is_scene) {};

    Axis* getAxis(const AxisDirection &dir, bool create=false) {
        for (auto &axis: axes) {
            if (axis.getDirection() == dir) {
                return &axis;
            };
        };
        if (create) {
            Axis ax(dir);
            axes.push_back(ax);
            // If a Z axis is created, turn the plot into a 3D scene
            if (dir == Z) {
                is_scene = true;
            }
            return &axes.back();
        } else {
            InvalidAxisException e;
            throw (e);
        };
    }

    void xTitle(const std::string label) {
        AxisDirection dir = X;
        getAxis(dir, true)->setTitle(label);
    }

    void yTitle(const std::string label) {
        AxisDirection dir = Y;
        getAxis(dir, true)->setTitle(label);
    }

    void zTitle(const std::string label) {
        AxisDirection dir = Z;
        getAxis(dir, true)->setTitle(label);
    }

    void xLog() {
        AxisDirection dir = X;
        getAxis(dir, true)->setLog();
    }

    void yLog() {
        AxisDirection dir = Y;
        getAxis(dir, true)->setLog();
    }

    void zLog() {
        AxisDirection dir = Z;
        getAxis(dir, true)->setLog();
    }

protected:

    std::vector<Axis> axes;
    std::string title;
    bool is_scene;

};


void to_json(nlohmann::json& j, const Layout& p) {

    if (!p.title.empty()) {
        j["title"] = p.title;
    };
    nlohmann::json axes;
    for (auto &axis : p.axes) {
        nlohmann::json ax;
        to_json(ax, axis);
        axes.update(ax);
    };
    if (p.is_scene) {
        j["scene"] = axes;
    } else {
        j.update(axes);
    };
};


}; // end namespace cpplot

#endif // CPPLOT_LAYOUT_H