|
//
|
|
// Created by mark on 5/30/25.
|
|
//
|
|
|
|
#ifndef CHARTJSLIBRARY_H
|
|
#define CHARTJSLIBRARY_H
|
|
|
|
#include <Wt/WAbstractItemModel.h>
|
|
#include <Wt/WContainerWidget.h>
|
|
#include <Wt/Chart/WAbstractChartModel.h>
|
|
#include <Wt/Json/Array.h>
|
|
#include <Wt/Json/Object.h>
|
|
#include <Wt/WSignal.h>
|
|
|
|
enum class ChartJSType
|
|
{
|
|
BAR, BUBBLE, DOUGHNUT, PIE, LINE, POLAR, RADAR, SCATTER
|
|
};
|
|
|
|
enum class Location
|
|
{
|
|
TOP, BOTTOM, LEFT, RIGHT
|
|
};
|
|
|
|
enum class HeaderText {
|
|
HORIZONTAL = 'H', VERTICAL = 'V'
|
|
};
|
|
// typedef std::map<std::string, cpp17::any> SettingsMapType;
|
|
|
|
// Defaults set. Override if necessary
|
|
// chart colors are as follows
|
|
// red: 'rgb(255, 99, 132)',
|
|
// orange: 'rgb(255, 159, 64)',
|
|
// yellow: 'rgb(255, 205, 86)',
|
|
// green: 'rgb(75, 192, 192)',
|
|
// blue: 'rgb(54, 162, 235)',
|
|
// purple: 'rgb(153, 102, 255)',
|
|
// grey: 'rgb(201, 203, 207)'
|
|
|
|
|
|
// This class will always take on the same size as the parent container
|
|
class WChartJSLibrary : public Wt::WContainerWidget
|
|
{
|
|
public:
|
|
WChartJSLibrary(ChartJSType);
|
|
~WChartJSLibrary() override;
|
|
|
|
Wt::JSignal<int, int>& chartClicked() { return chartClicked_; }
|
|
// Returns the WStandardItemModel indexes
|
|
[[nodiscard]] std::pair<int, int> getModelCoordinates(int datasetIndex, int dataIndex) const;
|
|
|
|
// When calling this object, all desired options must be populated and
|
|
// completed with a call to showChart(). You cannot delay showing the chart if
|
|
// it's container is visible and this may show a malformed chart if you neglect
|
|
// this call at the end of initializing the data and options.
|
|
void buildAndShowChart();
|
|
|
|
// NOTE: This object tries to be as similar in operation to the Wt charts as
|
|
// possible in terms of the WStandardItemModel and Wt::Signals to change or update
|
|
// data through the Wt engines. Also incorporated is the WText/WString methods
|
|
// in order to maintain consistency with Wt translations. WSeries is too unique to
|
|
// Wt's javascript charting, so only the Model column is kept and serves as an index
|
|
// to series specific options.
|
|
|
|
std::string getChartJSType(ChartJSType);
|
|
void setModel(const std::shared_ptr<Wt::WAbstractItemModel>& model);
|
|
void setModel(const std::shared_ptr<Wt::Chart::WAbstractChartModel>& model);
|
|
std::shared_ptr<Wt::WAbstractItemModel> itemModel() const;
|
|
void addSeries(int modelColumn, bool countForLabels, Wt::Json::Object dataSeriesOptions, bool dependantIndependantSeries);
|
|
void addRawSeries(const Wt::Json::Object& rawSeries);
|
|
void resetSeries(int modelColumn);
|
|
void removeSeries(int modelColumn);
|
|
void removeLastRawSeries();
|
|
void updateExistingSeries();
|
|
void setXaxisLabels(const std::vector<std::string>&);
|
|
void updateChartTitleOnly(const Wt::WString& title);
|
|
void setOptions(const Wt::Json::Object& chartOptions);
|
|
|
|
protected:
|
|
void layoutSizeChanged(int width, int height) override;
|
|
void render(Wt::WFlags<Wt::RenderFlag> flags) override;
|
|
void modelChanged();
|
|
void updateModel();
|
|
|
|
private:
|
|
void defineJavaScript();
|
|
Wt::JSignal<int, int> chartClicked_;
|
|
Wt::Json::Object chartjsConfigObj{}; // This is where everything is defined
|
|
ChartJSType chartType_{};
|
|
std::string chartTypeName_{};
|
|
Wt::Json::Object chartOptions_{};
|
|
Wt::Json::Object plugins_{};
|
|
Wt::Json::Object chartData_{};
|
|
Wt::Json::Object netDataChangeJson_{}; // after chart creation to add net change
|
|
std::shared_ptr<Wt::Chart::WAbstractChartModel> model_ = nullptr;
|
|
std::shared_ptr<Wt::WAbstractItemModel> standardModel_ = nullptr;
|
|
// connections with the current model, used to disconnect from a model
|
|
// when the model changes.
|
|
std::vector<Wt::Signals::connection> modelConnections_{};
|
|
|
|
struct ModelColumnInfo
|
|
{
|
|
int modelColumnNumber{};
|
|
bool countForLabels{};
|
|
bool dependantIndependantSeries{};
|
|
int lastDataCount{};
|
|
};
|
|
|
|
std::vector<ModelColumnInfo> modelColumnsLoaded_{};
|
|
Wt::Json::Array series_{};
|
|
Wt::Json::Array dataLabels_{};
|
|
bool resized_ = false;
|
|
bool legendEnabled_ = false;
|
|
std::string legendLocation_{};
|
|
Wt::WStringStream legendOptions_{};
|
|
bool countForLabels_ = false;
|
|
bool titleEnabled_ = false;
|
|
Wt::WString titleText_{};
|
|
bool fullyRendered_ = false;
|
|
bool jsDefined_{};
|
|
|
|
template <typename T>
|
|
void set(T& m, const T& v);
|
|
};
|
|
|
|
template <typename T>
|
|
void WChartJSLibrary::set(T& m, const T& v) {
|
|
if (m != v) {
|
|
m = v;
|
|
}
|
|
}
|
|
|
|
|
|
#endif //CHARTJSLIBRARY_H
|