[apps/stats] Display multiple boxes

This commit is contained in:
Léa Saviot
2018-05-25 11:14:33 +02:00
parent 31ad501a14
commit 81b09501cb
8 changed files with 98 additions and 86 deletions

View File

@@ -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\

View File

@@ -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);
}
}

View File

@@ -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;
};
}

View File

@@ -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)
{
}

View File

@@ -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;
};
}

View 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();
}
}

View 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

View File

@@ -14,10 +14,6 @@ MultipleDataViewController::MultipleDataViewController(Responder * parentRespond
{
}
MultipleDataView * MultipleDataViewController::multipleDataView() {
return static_cast<MultipleDataView *>(view());
}
bool MultipleDataViewController::isEmpty() const {
return m_store->isEmpty();
}