Skip to content

Commit cc42f51

Browse files
committed
Change line charts in stats tab to bar charts
1 parent 9cffb60 commit cc42f51

File tree

4 files changed

+209
-53
lines changed

4 files changed

+209
-53
lines changed

src/stats/chart.cpp

+146-24
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,25 @@ SizeResponsiveChartView* Chart::createChartView(QChart* chart, int minimumHeight
170170
}
171171

172172

173+
/**
174+
* Creates and initializes a QBarSeries object.
175+
*
176+
* Initialization entails adding the series to the given chart and attaching the given axes.
177+
*
178+
* @param chart The chart to display in the chart view.
179+
* @param xAxis The chart's x-axis.
180+
* @param yAxis The chart's y-axis.
181+
* @return An initialized QHorizontalBarSeries object, of which the caller takes ownership.
182+
*/
183+
QBarSeries* Chart::createBarSeries(QChart* chart, QAbstractAxis* xAxis, QAbstractAxis* yAxis)
184+
{
185+
QBarSeries* series = new QBarSeries();
186+
chart->addSeries(series);
187+
series->attachAxis(xAxis);
188+
series->attachAxis(yAxis);
189+
return series;
190+
}
191+
173192
/**
174193
* Creates and initializes a QHorizontalBarSeries object.
175194
*
@@ -310,31 +329,136 @@ void Chart::resetAxis(QValueAxis* axis)
310329

311330

312331
/**
313-
* Creates a YearChart.
332+
* Creates a YearBarChart.
314333
*
315-
* @param chartTitle The title of the chart, to be displayed above it.
316-
* @param yAxisTitle The label text for the y-axis.
317-
* @param bufferXAxisRange The fraction of the x-axis range to add as buffer.
334+
* @param chartTitle The title of the chart, to be displayed above it.
335+
* @param yAxisTitle The label text for the y-axis.
318336
*/
319-
YearChart::YearChart(const QString& chartTitle, const QString& yAxisTitle, bool bufferXAxisRange) :
337+
YearBarChart::YearBarChart(const QString& chartTitle, const QString& yAxisTitle) :
338+
Chart(chartTitle),
339+
yAxisTitle(yAxisTitle),
340+
xAxis (nullptr),
341+
yAxis (nullptr),
342+
barSeries (nullptr),
343+
barSet (nullptr)
344+
{
345+
YearBarChart::setup();
346+
YearBarChart::reset();
347+
}
348+
349+
/**
350+
* Destroys the YearBarChart.
351+
*/
352+
YearBarChart::~YearBarChart()
353+
{
354+
// xAxis is deleted by chart
355+
// yAxis is deleted by chart
356+
// barSeries is deleted by chart
357+
// barSet is deleted by barSeries
358+
}
359+
360+
361+
362+
/**
363+
* Performs the setup for the YearBarChart during/after construction.
364+
*
365+
* Not to be called more than once (will cause memory leaks).
366+
*/
367+
void YearBarChart::setup()
368+
{
369+
chart = createChart(chartTitle);
370+
//xAxis = createBarCategoryXAxis(chart, Qt::AlignBottom);
371+
xAxis = createValueXAxis(chart);
372+
yAxis = createValueYAxis(chart, yAxisTitle, Qt::AlignLeft);
373+
barSeries = createBarSeries(chart, xAxis, yAxis);
374+
barSet = createBarSet(QString(), barSeries);
375+
chartView = createChartView(chart);
376+
377+
connect(chartView, &SizeResponsiveChartView::wasResized, this, &YearBarChart::updateView);
378+
}
379+
380+
/**
381+
* Removes all data from the chart.
382+
*/
383+
void YearBarChart::reset()
384+
{
385+
barSet->remove(0, barSet->count());
386+
hasData = false;
387+
minYear = 0;
388+
maxYear = 0;
389+
maxY = 0;
390+
resetAxis(yAxis);
391+
}
392+
393+
/**
394+
* Replaces the displayed data and stores range information for future view updates.
395+
*
396+
* Performs a view update before replacing the data.
397+
*
398+
* @param histogramData A list of data points to display in the chart. The length of the list must match the number of categories.
399+
*/
400+
void YearBarChart::updateData(const QList<qreal>& newData, int minYear, int maxYear, qreal maxY)
401+
{
402+
if (newData.isEmpty()) {
403+
reset();
404+
return;
405+
}
406+
assert(newData.size() == maxYear - minYear + 1);
407+
assert(maxY >= 0);
408+
409+
QStringList years = QStringList();
410+
for (int year = minYear; year <= maxYear; year++) {
411+
years.append(QString::number(year));
412+
}
413+
414+
barSet->remove(0, barSet->count());
415+
barSet->append(QList<qreal>(minYear, 0));
416+
barSet->append(newData);
417+
418+
this->minYear = minYear;
419+
this->maxYear = maxYear;
420+
this->maxY = maxY;
421+
hasData = true;
422+
updateView();
423+
}
424+
425+
/**
426+
* Updates the chart layout, e.g. tick spacing, without changing the displayed data.
427+
*/
428+
void YearBarChart::updateView()
429+
{
430+
if (!hasData) return;
431+
adjustAxis(xAxis, minYear, maxYear, chart->plotArea().width(), rangeBufferFactorX);
432+
adjustAxis(yAxis, 0, maxY, chart->plotArea().height(), rangeBufferFactorY);
433+
}
434+
435+
436+
437+
438+
439+
/**
440+
* Creates a TimeScatterChart.
441+
*
442+
* @param chartTitle The title of the chart, to be displayed above it.
443+
* @param yAxisTitle The label text for the y-axis.
444+
*/
445+
TimeScatterChart::TimeScatterChart(const QString& chartTitle, const QString& yAxisTitle) :
320446
Chart(chartTitle),
321447
yAxisTitle(yAxisTitle),
322-
bufferXAxisRange(bufferXAxisRange),
323448
xAxis (nullptr),
324449
yAxis (nullptr),
325450
minYear(0),
326451
maxYear(0),
327-
minY(0),
328452
maxY(0)
329453
{
330-
YearChart::setup();
331-
YearChart::reset();
454+
TimeScatterChart::setup();
455+
TimeScatterChart::reset();
332456
}
333457

334458
/**
335-
* Destroys the YearChart.
459+
* Destroys the TimeScatterChart.
336460
*/
337-
YearChart::~YearChart()
461+
TimeScatterChart::~TimeScatterChart()
338462
{
339463
// xAxis is deleted by chart
340464
// yAxis is deleted by chart
@@ -343,11 +467,11 @@ YearChart::~YearChart()
343467

344468

345469
/**
346-
* Performs the setup for the YearChart during/after construction.
470+
* Performs the setup for the TimeScatterChart during/after construction.
347471
*
348472
* Not to be called more than once (will cause memory leaks).
349473
*/
350-
void YearChart::setup()
474+
void TimeScatterChart::setup()
351475
{
352476
chart = createChart(chartTitle);
353477
xAxis = createValueXAxis(chart);
@@ -358,20 +482,19 @@ void YearChart::setup()
358482
chartView->setInteractive(true);
359483
chartView->setRubberBand(QChartView::RectangleRubberBand);
360484

361-
connect(chartView, &SizeResponsiveChartView::wasResized, this, &YearChart::updateView);
362-
connect(chartView, &SizeResponsiveChartView::receivedDoubleClick, this, &YearChart::resetZoom);
485+
connect(chartView, &SizeResponsiveChartView::wasResized, this, &TimeScatterChart::updateView);
486+
connect(chartView, &SizeResponsiveChartView::receivedDoubleClick, this, &TimeScatterChart::resetZoom);
363487
}
364488

365489
/**
366490
* Removes all data from the chart.
367491
*/
368-
void YearChart::reset()
492+
void TimeScatterChart::reset()
369493
{
370494
chart->removeAllSeries();
371495
hasData = false;
372496
this->minYear = 0;
373497
this->maxYear = 0;
374-
this->minY = 0;
375498
this->maxY = 0;
376499
resetAxis(xAxis);
377500
resetAxis(yAxis);
@@ -389,7 +512,7 @@ void YearChart::reset()
389512
* @param minY The minimum y value among all given data series.
390513
* @param maxY The maximum y value among all given data series.
391514
*/
392-
void YearChart::updateData(const QList<QXYSeries*>& newSeries, qreal minYear, qreal maxYear, qreal minY, qreal maxY)
515+
void TimeScatterChart::updateData(const QList<QXYSeries*>& newSeries, qreal minYear, qreal maxYear, qreal maxY)
393516
{
394517
bool noData = true;
395518
for (QXYSeries* const series : newSeries) {
@@ -403,7 +526,7 @@ void YearChart::updateData(const QList<QXYSeries*>& newSeries, qreal minYear, qr
403526
return;
404527
}
405528
assert(minYear <= maxYear);
406-
assert(minY <= maxY);
529+
assert(maxY >= 0);
407530

408531
if (maxYear - minYear < 1) {
409532
qreal buffer = 0.5 * (1 - (maxYear - minYear));
@@ -413,7 +536,6 @@ void YearChart::updateData(const QList<QXYSeries*>& newSeries, qreal minYear, qr
413536

414537
this->minYear = minYear;
415538
this->maxYear = maxYear;
416-
this->minY = minY;
417539
this->maxY = maxY;
418540
hasData = true;
419541
updateView();
@@ -430,19 +552,19 @@ void YearChart::updateData(const QList<QXYSeries*>& newSeries, qreal minYear, qr
430552
/**
431553
* Updates the chart layout, e.g. tick spacing, without changing the displayed data.
432554
*/
433-
void YearChart::updateView()
555+
void TimeScatterChart::updateView()
434556
{
435557
if (!hasData) return;
436-
adjustAxis(xAxis, minYear, maxYear, chart->plotArea().width(), bufferXAxisRange ? rangeBufferFactorX : 0, true);
437-
adjustAxis(yAxis, minY, maxY, chart->plotArea().height(), rangeBufferFactorY);
558+
adjustAxis(xAxis, minYear, maxYear, chart->plotArea().width(), rangeBufferFactorX, true);
559+
adjustAxis(yAxis, 0, maxY, chart->plotArea().height(), rangeBufferFactorY);
438560
}
439561

440562
/**
441563
* Resets zoom level set by user.
442564
*
443565
* To be called when user requests to reset the chart view.
444566
*/
445-
void YearChart::resetZoom()
567+
void TimeScatterChart::resetZoom()
446568
{
447569
if (!hasData) return;
448570
chart->zoomReset();

src/stats/chart.h

+47-13
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <QChartView>
2929
#include <QValueAxis>
3030
#include <QBarCategoryAxis>
31+
#include <QBarSeries>
3132
#include <QHorizontalBarSeries>
3233
#include <QLineSeries>
3334
#include <QScatterSeries>
@@ -143,6 +144,7 @@ class Chart : public QObject
143144
static QValueAxis* createValueYAxis(QChart* chart, const QString& title = QString(), const Qt::AlignmentFlag alignment = Qt::AlignLeft);
144145
static SizeResponsiveChartView* createChartView(QChart* chart, int minimumHeight = -1);
145146

147+
static QBarSeries* createBarSeries(QChart* chart, QAbstractAxis* xAxis, QAbstractAxis* yAxis);
146148
static QHorizontalBarSeries* createHorizontalBarSeries(QChart* chart, QAbstractAxis* xAxis, QAbstractAxis* yAxis);
147149
static QBarSet* createBarSet(const QString& name, QAbstractBarSeries* series);
148150

@@ -158,19 +160,53 @@ class Chart : public QObject
158160

159161

160162
/**
161-
* A class representing a scatterplot and/or line chart with a horizontal x-axis which shows time,
162-
* and a vertical real-number y-axis.
163-
*
164-
* The type of plot used for any data series is determined by the type of series put into
165-
* updateData() (either QScatterSeries or QLineSeries).
163+
* A class representing a bar chart with a horizontal x-axis which shows years, and a vertical real-
164+
* number y-axis.
165+
*/
166+
class YearBarChart : public Chart
167+
{
168+
protected:
169+
/** The translated label for the chart's y-axis. */
170+
const QString yAxisTitle;
171+
172+
/** The x-axis for the chart. */
173+
QValueAxis* xAxis;
174+
/** The y-axis for the chart. */
175+
QValueAxis* yAxis;
176+
/** The bar series for the chart. A bar series represents a set of bars, each of which belongs to another category on the x-axis, but all of which share the same label. */
177+
QBarSeries* barSeries;
178+
/** The bar set for the chart. A bar set contains one data value for each x-axis category. */
179+
QBarSet* barSet;
180+
181+
// Range data
182+
/** The minimum x value of the current data set. */
183+
int minYear;
184+
/** The maximum x value of the current data set. */
185+
int maxYear;
186+
/** The maximum y value of the current data set. */
187+
qreal maxY;
188+
189+
public:
190+
YearBarChart(const QString& chartTitle, const QString& yAxisTitle = QString());
191+
virtual ~YearBarChart();
192+
193+
virtual void setup() override;
194+
virtual void reset() override;
195+
void updateData(const QList<qreal>& newData, int minYear, int maxYear, qreal maxY);
196+
virtual void updateView() override;
197+
};
198+
199+
200+
201+
/**
202+
* A class representing a scatterplot with a horizontal x-axis which shows time, and a vertical
203+
* real-number y-axis.
166204
*/
167-
class YearChart : public Chart
205+
class TimeScatterChart : public Chart
168206
{
169207
protected:
170208
/** The translated label for the chart's y-axis. */
171209
const QString yAxisTitle;
172-
/** Indicates whether to add a small buffer to the displayed range of the x-axis. */
173-
const bool bufferXAxisRange;
174210

175211
/** The x-axis for the chart. */
176212
QValueAxis* xAxis;
@@ -182,18 +218,16 @@ class YearChart : public Chart
182218
qreal minYear;
183219
/** The maximum x value of the current data sets. */
184220
qreal maxYear;
185-
/** The minimum y value of the current data sets. */
186-
qreal minY;
187221
/** The maximum y value of the current data sets. */
188222
qreal maxY;
189223

190224
public:
191-
YearChart(const QString& chartTitle, const QString& yAxisTitle, bool bufferXAxisRange);
192-
virtual ~YearChart();
225+
TimeScatterChart(const QString& chartTitle, const QString& yAxisTitle = QString());
226+
virtual ~TimeScatterChart();
193227

194228
virtual void setup() override;
195229
virtual void reset() override;
196-
void updateData(const QList<QXYSeries*>& newSeries, qreal minYear, qreal maxYear, qreal minY, qreal maxY);
230+
void updateData(const QList<QXYSeries*>& newSeries, qreal minYear, qreal maxYear, qreal maxY);
197231
virtual void updateView() override;
198232
void resetZoom();
199233
};

0 commit comments

Comments
 (0)