mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-25 16:50:50 +01:00
[apps/stats] Display multiple boxes
This commit is contained in:
@@ -12,6 +12,7 @@ app_objs += $(addprefix apps/statistics/,\
|
||||
histogram_controller.o\
|
||||
histogram_parameter_controller.o\
|
||||
histogram_view.o\
|
||||
multiple_boxes_view.o\
|
||||
multiple_data_view.o\
|
||||
multiple_data_view_controller.o\
|
||||
multiple_histograms_view.o\
|
||||
|
||||
@@ -7,84 +7,48 @@ using namespace Poincare;
|
||||
namespace Statistics {
|
||||
|
||||
BoxController::BoxController(Responder * parentResponder, ButtonRowController * header, Store * store, BoxView::Quantile * selectedQuantile) :
|
||||
ViewController(parentResponder),
|
||||
MultipleDataViewController(parentResponder, store, (int *)(selectedQuantile)),
|
||||
ButtonRowDelegate(header, nullptr),
|
||||
m_boxBannerView(),
|
||||
m_view(store, &m_boxBannerView, selectedQuantile),
|
||||
m_store(store),
|
||||
m_selectedSeries(0)
|
||||
m_view(store, selectedQuantile)
|
||||
{
|
||||
}
|
||||
|
||||
bool BoxController::isEmpty() const {
|
||||
for (int i = 0; i < Shared::FloatPairStore::k_numberOfSeries; i++) {
|
||||
if (m_store->sumOfOccurrences(i) == 0) {
|
||||
return true;
|
||||
}
|
||||
bool BoxController::moveSelectionHorizontally(int deltaIndex) {
|
||||
int selectedQuantile = (int)m_view.dataViewAtIndex(selectedSeries())->selectedQuantile();
|
||||
int nextSelectedQuantile = selectedQuantile + deltaIndex;
|
||||
if (m_view.dataViewAtIndex(selectedSeries())->selectQuantile(nextSelectedQuantile)) {
|
||||
reloadBannerView();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
I18n::Message BoxController::emptyMessage() {
|
||||
return I18n::Message::NoDataToPlot;
|
||||
}
|
||||
|
||||
Responder * BoxController::defaultController() {
|
||||
return tabController();
|
||||
}
|
||||
|
||||
const char * BoxController::title() {
|
||||
return I18n::translate(I18n::Message::BoxTab);
|
||||
}
|
||||
|
||||
void BoxController::viewWillAppear() {
|
||||
m_view.selectMainView(true);
|
||||
reloadBannerView();
|
||||
m_view.reload();
|
||||
}
|
||||
|
||||
bool BoxController::handleEvent(Ion::Events::Event event) {
|
||||
if (event == Ion::Events::Up) {
|
||||
m_view.selectMainView(false);
|
||||
app()->setFirstResponder(tabController());
|
||||
return true;
|
||||
}
|
||||
if (event == Ion::Events::Left || event == Ion::Events::Right) {
|
||||
int nextSelectedQuantile = event == Ion::Events::Left ? (int)m_view.selectedQuantile()-1 : (int)m_view.selectedQuantile()+1;
|
||||
if (m_view.selectQuantile(nextSelectedQuantile)) {
|
||||
reloadBannerView();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void BoxController::didBecomeFirstResponder() {
|
||||
m_view.selectMainView(true);
|
||||
m_view.reload();
|
||||
}
|
||||
|
||||
void BoxController::willExitResponderChain(Responder * nextFirstResponder) {
|
||||
if (nextFirstResponder == tabController()) {
|
||||
m_view.selectMainView(false);
|
||||
m_view.reload();
|
||||
}
|
||||
}
|
||||
|
||||
Responder * BoxController::tabController() const {
|
||||
return (parentResponder()->parentResponder()->parentResponder());
|
||||
}
|
||||
|
||||
void BoxController::reloadBannerView() {
|
||||
if (selectedSeries() < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int selectedQuantile = (int)m_view.dataViewAtIndex(selectedSeries())->selectedQuantile();
|
||||
|
||||
// Set calculation name
|
||||
I18n::Message calculationName[5] = {I18n::Message::Minimum, I18n::Message::FirstQuartile, I18n::Message::Median, I18n::Message::ThirdQuartile, I18n::Message::Maximum};
|
||||
m_boxBannerView.setMessageAtIndex(calculationName[(int)m_view.selectedQuantile()], 0);
|
||||
m_view.editableBannerView()->setMessageAtIndex(calculationName[selectedQuantile], 0);
|
||||
|
||||
// Set calculation result
|
||||
char buffer[PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)];
|
||||
CalculPointer calculationMethods[5] = {&Store::minValue, &Store::firstQuartile, &Store::median, &Store::thirdQuartile,
|
||||
&Store::maxValue};
|
||||
double calculation = (m_store->*calculationMethods[(int)m_view.selectedQuantile()])(m_selectedSeries);
|
||||
double calculation = (m_store->*calculationMethods[selectedQuantile])(selectedSeries());
|
||||
PrintFloat::convertFloatToText<double>(calculation, buffer, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits);
|
||||
m_boxBannerView.setLegendAtIndex(buffer, 1);
|
||||
m_view.editableBannerView()->setLegendAtIndex(buffer, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,37 +3,24 @@
|
||||
|
||||
#include <escher.h>
|
||||
#include "store.h"
|
||||
#include "box_view.h"
|
||||
#include "box_banner_view.h"
|
||||
#include "multiple_boxes_view.h"
|
||||
#include "multiple_data_view_controller.h"
|
||||
|
||||
namespace Statistics {
|
||||
|
||||
class BoxController : public ViewController, public ButtonRowDelegate, public AlternateEmptyViewDelegate {
|
||||
class BoxController : public MultipleDataViewController, public ButtonRowDelegate {
|
||||
public:
|
||||
BoxController(Responder * parentResponder, ButtonRowController * header, Store * store, BoxView::Quantile * selectedQuantile);
|
||||
|
||||
// AlternateEmptyViewDelegate
|
||||
bool isEmpty() const override;
|
||||
I18n::Message emptyMessage() override;
|
||||
Responder * defaultController() override;
|
||||
MultipleDataView * multipleDataView() override { return &m_view; }
|
||||
bool moveSelectionHorizontally(int deltaIndex) override;
|
||||
|
||||
// ViewController
|
||||
const char * title() override;
|
||||
View * view() override { return &m_view; }
|
||||
void viewWillAppear() override;
|
||||
ViewController::DisplayParameter displayParameter() override { return ViewController::DisplayParameter::DoNotShowOwnTitle; }
|
||||
|
||||
// Responder
|
||||
bool handleEvent(Ion::Events::Event event) override;
|
||||
void didBecomeFirstResponder() override;
|
||||
void willExitResponderChain(Responder * nextFirstResponder) override;
|
||||
private:
|
||||
Responder * tabController() const;
|
||||
void reloadBannerView();
|
||||
BoxBannerView m_boxBannerView;
|
||||
BoxView m_view;
|
||||
Store * m_store;
|
||||
int m_selectedSeries;
|
||||
Responder * tabController() const override;
|
||||
void reloadBannerView() override;
|
||||
MultipleBoxesView m_view;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -6,13 +6,14 @@ using namespace Shared;
|
||||
|
||||
namespace Statistics {
|
||||
|
||||
BoxView::BoxView(Store * store, BannerView * bannerView, Quantile * selectedQuantile) :
|
||||
BoxView::BoxView(Store * store, int series, Shared::BannerView * bannerView, Quantile * selectedQuantile, KDColor color) :
|
||||
CurveView(&m_boxRange, nullptr, bannerView, nullptr),
|
||||
m_store(store),
|
||||
m_boxRange(BoxRange(store)),
|
||||
m_labels{},
|
||||
m_series(series),
|
||||
m_selectedQuantile(selectedQuantile),
|
||||
m_series(0)
|
||||
m_selectedHistogramColor(color)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -19,10 +19,10 @@ public:
|
||||
ThirdQuartile = 3,
|
||||
Max = 4
|
||||
};
|
||||
BoxView(Store * store, Shared::BannerView * bannerView, Quantile * selectedQuantile);
|
||||
BoxView(Store * store, int series, Shared::BannerView * bannerView, Quantile * selectedQuantile, KDColor color);
|
||||
Quantile selectedQuantile() const { return *m_selectedQuantile; }
|
||||
bool selectQuantile(int selectedQuantile);
|
||||
void setSeries(int series) { m_series = series; }
|
||||
int series() const { return m_series; }
|
||||
|
||||
// CurveView
|
||||
void reload() override;
|
||||
@@ -34,8 +34,9 @@ private:
|
||||
Store * m_store;
|
||||
BoxRange m_boxRange;
|
||||
char m_labels[k_maxNumberOfXLabels][Poincare::PrintFloat::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits)];
|
||||
Quantile * m_selectedQuantile;
|
||||
int m_series;
|
||||
Quantile * m_selectedQuantile;
|
||||
KDColor m_selectedHistogramColor;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
34
apps/statistics/multiple_boxes_view.cpp
Normal file
34
apps/statistics/multiple_boxes_view.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
#include "multiple_boxes_view.h"
|
||||
#include <assert.h>
|
||||
|
||||
using namespace Shared;
|
||||
|
||||
namespace Statistics {
|
||||
|
||||
MultipleBoxesView::MultipleBoxesView(Store * store, BoxView::Quantile * selectedQuantile) :
|
||||
MultipleDataView(store),
|
||||
m_boxView1(store, 0, nullptr, selectedQuantile, Palette::Red),
|
||||
m_boxView2(store, 1, nullptr, selectedQuantile, Palette::Blue),
|
||||
m_boxView3(store, 2, nullptr, selectedQuantile, Palette::Green),
|
||||
// TODO Share colors with stats/store_controller
|
||||
m_bannerView()
|
||||
{
|
||||
for (int i = 0; i < Store::k_numberOfSeries; i++) {
|
||||
BoxView * boxView = dataViewAtIndex(i);
|
||||
boxView->setDisplayBannerView(false);
|
||||
//histView->setDisplayLabels(false); //TODO
|
||||
}
|
||||
}
|
||||
|
||||
BoxView * MultipleBoxesView::dataViewAtIndex(int index) {
|
||||
assert(index >= 0 && index < 3);
|
||||
BoxView * views[] = {&m_boxView1, &m_boxView2, &m_boxView3};
|
||||
return views[index];
|
||||
}
|
||||
|
||||
int MultipleBoxesView::seriesOfSubviewAtIndex(int index) {
|
||||
assert(index >= 0 && index < numberOfSubviews() - 1);
|
||||
return static_cast<BoxView *>(subviewAtIndex(index))->series();
|
||||
}
|
||||
|
||||
}
|
||||
28
apps/statistics/multiple_boxes_view.h
Normal file
28
apps/statistics/multiple_boxes_view.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef STATISTICS_MULTIPLE_BOXES_VIEW_H
|
||||
#define STATISTICS_MULTIPLE_BOXES_VIEW_H
|
||||
|
||||
#include <escher.h>
|
||||
#include "store.h"
|
||||
#include "box_view.h"
|
||||
#include "box_banner_view.h"
|
||||
#include "multiple_data_view.h"
|
||||
|
||||
namespace Statistics {
|
||||
|
||||
class MultipleBoxesView : public MultipleDataView {
|
||||
public:
|
||||
MultipleBoxesView(Store * store, BoxView::Quantile * selectedQuantile);
|
||||
// MultipleDataView
|
||||
int seriesOfSubviewAtIndex(int index) override;
|
||||
const BoxBannerView * bannerView() const override { return &m_bannerView; }
|
||||
BoxView * dataViewAtIndex(int index) override;
|
||||
private:
|
||||
BoxView m_boxView1;
|
||||
BoxView m_boxView2;
|
||||
BoxView m_boxView3;
|
||||
BoxBannerView m_bannerView;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -14,10 +14,6 @@ MultipleDataViewController::MultipleDataViewController(Responder * parentRespond
|
||||
{
|
||||
}
|
||||
|
||||
MultipleDataView * MultipleDataViewController::multipleDataView() {
|
||||
return static_cast<MultipleDataView *>(view());
|
||||
}
|
||||
|
||||
bool MultipleDataViewController::isEmpty() const {
|
||||
return m_store->isEmpty();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user