Commit 0b1ce216 authored by Nicolas Fella's avatar Nicolas Fella Committed by Han Young
Browse files

Split chart data handling into separate file

WeatherLocation does a bit too much, split some stuff in an extra file to have better separation of concerns
parent bb02053a
......@@ -11,6 +11,7 @@ set(kweather_SRCS
weatherlocationmodel.cpp
weatherlocation.cpp
locationquerymodel.cpp
temperaturechartdata.cpp
resources.qrc
)
add_library(kweatherLib STATIC)
......
......@@ -26,6 +26,7 @@
#include "kweathersettings.h"
#include "locationquerymodel.h"
#include "temperaturechartdata.h"
#include "version.h"
#include "weatherforecastmanager.h"
#include "weatherlocation.h"
......@@ -72,6 +73,8 @@ Q_DECL_EXPORT int main(int argc, char *argv[])
engine.rootContext()->setContextProperty("settingsModel", &settings);
engine.rootContext()->setContextProperty("locationQueryModel", locationQueryModel);
qmlRegisterType<TemperatureChartData>("kweather", 1, 0, "TemperatureChartData");
qRegisterMetaType<KWeatherCore::Sunrise>();
// load setup wizard if first launch
......
......@@ -10,6 +10,7 @@ import QtQuick.Controls 2.4
import QtQuick.Layouts 1.2
import QtCharts 2.3
import org.kde.kirigami 2.13 as Kirigami
import kweather 1.0
import "backgrounds"
Control {
......@@ -42,6 +43,11 @@ Control {
width: page.maximumContentWidth
height: Math.round(Kirigami.Units.gridUnit * 8.5)
TemperatureChartData {
id: chartData
weatherData: location.dayForecasts
}
ChartView {
id: chartView
anchors.fill: parent
......@@ -71,8 +77,8 @@ Control {
id: axisY
visible: false
min: tempChartCard.location.minTempLimit
max: tempChartCard.location.maxTempLimit
min: chartData.minTempLimit
max: chartData.maxTempLimit
labelsColor: tempChartCard.textColor
}
name: i18n("temperature")
......@@ -84,12 +90,12 @@ Control {
}
Component.onCompleted: {
tempChartCard.location.initAxes(axisX, axisY);
tempChartCard.location.initSeries(chartView.series(0));
chartData.initAxes(axisX, axisY);
chartData.initSeries(chartView.series(0));
}
Component.onDestruction: {
// ensure that the series is a nullptr
tempChartCard.location.initSeries(0);
chartData.initSeries(0);
}
}
......
/*
* SPDX-FileCopyrightText: 2020 Han Young <hanyoung@protonmail.com>
* SPDX-FileCopyrightText: 2020 Devin Lin <espidev@gmail.com>
* SPDX-FileCopyrightText: 2021 Nicolas Fella <nicolas.fella@gmx.de>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "temperaturechartdata.h"
#include <QDateTimeAxis>
#include <QPointF>
#include <QValueAxis>
#include <QtCharts/QSplineSeries>
#include "global.h"
QVariantList TemperatureChartData::weatherData() const
{
return m_weatherData;
}
void TemperatureChartData::setWeatherData(const QVariantList &weatherData)
{
m_weatherData = weatherData;
Q_EMIT weatherDataChanged();
updateData();
}
void TemperatureChartData::updateData()
{
if (!m_series) {
return;
}
m_series->clear();
QVector<QPointF> result;
result.reserve(m_weatherData.size());
double minTemp = std::numeric_limits<double>::max();
double maxTemp = std::numeric_limits<double>::min();
for (const QVariant &dayVariant : qAsConst(m_weatherData)) {
const auto day = dayVariant.value<KWeatherCore::DailyWeatherForecast>();
const double dayMinTemp = Kweather::convertTemp(day.minTemp());
const double dayMaxTemp = Kweather::convertTemp(day.maxTemp());
result.append(QPointF(day.date().startOfDay().toMSecsSinceEpoch(), dayMaxTemp));
minTemp = std::min<double>(dayMinTemp, minTemp);
maxTemp = std::max<double>(dayMaxTemp, maxTemp);
}
// make enough room for the curve
m_maxTempLimit = maxTemp + 5;
m_minTempLimit = minTemp - 5;
Q_EMIT maxTempLimitChanged();
Q_EMIT minTempLimitChanged();
m_series->replace(result);
if (!m_weatherData.isEmpty()) {
m_axisX->setRange(m_weatherData.first().value<KWeatherCore::DailyWeatherForecast>().date().startOfDay(),
m_weatherData.last().value<KWeatherCore::DailyWeatherForecast>().date().startOfDay());
}
}
void TemperatureChartData::initSeries(QtCharts::QAbstractSeries *series)
{
m_series = static_cast<QtCharts::QSplineSeries *>(series);
updateData();
}
void TemperatureChartData::initAxes(QObject *axisX, QObject *axisY)
{
m_axisX = static_cast<QtCharts::QDateTimeAxis *>(axisX);
m_axisY = static_cast<QtCharts::QValueAxis *>(axisY);
}
double TemperatureChartData::maxTempLimit() const
{
return m_maxTempLimit;
}
double TemperatureChartData::minTempLimit() const
{
return m_minTempLimit;
}
/*
* SPDX-FileCopyrightText: 2020 Han Young <hanyoung@protonmail.com>
* SPDX-FileCopyrightText: 2020 Devin Lin <espidev@gmail.com>
* SPDX-FileCopyrightText: 2021 Nicolas Fella <nicolas.fella@gmx.de>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include <KWeatherCore/DailyWeatherForecast>
namespace QtCharts
{
class QAbstractSeries;
class QSplineSeries;
class QDateTimeAxis;
class QValueAxis;
}
class TemperatureChartData : public QObject
{
Q_OBJECT
Q_PROPERTY(QVariantList weatherData READ weatherData WRITE setWeatherData NOTIFY weatherDataChanged)
Q_PROPERTY(double maxTempLimit READ maxTempLimit NOTIFY maxTempLimitChanged)
Q_PROPERTY(double minTempLimit READ minTempLimit NOTIFY minTempLimitChanged)
public:
QVariantList weatherData() const;
void setWeatherData(const QVariantList &weatherData);
double maxTempLimit() const;
double minTempLimit() const;
Q_INVOKABLE void initSeries(QtCharts::QAbstractSeries *series);
Q_INVOKABLE void initAxes(QObject *axisX, QObject *axisY);
Q_SIGNALS:
void weatherDataChanged();
void maxTempLimitChanged();
void minTempLimitChanged();
private:
void updateData();
QVariantList m_weatherData;
double m_maxTempLimit = 100;
double m_minTempLimit = 0;
QtCharts::QSplineSeries *m_series = nullptr;
QtCharts::QDateTimeAxis *m_axisX = nullptr;
QtCharts::QValueAxis *m_axisY = nullptr;
};
......@@ -52,8 +52,6 @@ WeatherLocation::WeatherLocation(QString locationId,
}
Q_EMIT hourForecastsChanged();
});
updateSeries();
}
WeatherLocation *WeatherLocation::load(const QString &groupName)
{
......@@ -111,7 +109,6 @@ void WeatherLocation::updateData(KWeatherCore::WeatherForecast forecasts)
}
determineCurrentForecast();
updateSeries();
m_lastUpdated = forecasts.createdTime();
m_hourForecasts.clear();
......@@ -123,6 +120,12 @@ void WeatherLocation::updateData(KWeatherCore::WeatherForecast forecasts)
}
Q_EMIT hourForecastsChanged();
m_dayForecasts.clear();
for (const KWeatherCore::DailyWeatherForecast &day : m_forecast.dailyWeatherForecast()) {
m_dayForecasts << QVariant::fromValue(day);
}
Q_EMIT dayForecastsChanged();
emit weatherRefresh(m_forecast);
emit stopLoadingIndicator();
......@@ -218,61 +221,6 @@ void WeatherLocation::update()
});
}
void WeatherLocation::initSeries(QtCharts::QAbstractSeries *series)
{
if (series) {
m_series = static_cast<QtCharts::QSplineSeries *>(series);
updateSeries();
} else {
m_series = nullptr;
}
}
void WeatherLocation::updateSeries()
{
m_vector.clear();
m_dayForecasts.clear();
m_hourForecasts.clear();
for (const KWeatherCore::DailyWeatherForecast &day : m_forecast.dailyWeatherForecast()) {
m_dayForecasts << QVariant::fromValue(day);
}
if (m_series) {
m_series->clear();
double minTemp = std::numeric_limits<double>::max(), maxTemp = std::numeric_limits<double>::min();
for (const auto &d : m_forecast.dailyWeatherForecast()) {
const auto dayMinTemp = Kweather::convertTemp(d.minTemp()), dayMaxTemp = Kweather::convertTemp(d.maxTemp());
m_vector.append(QPointF(d.date().startOfDay().toMSecsSinceEpoch(), dayMaxTemp));
minTemp = std::min<double>(dayMinTemp, minTemp);
maxTemp = std::max<double>(dayMaxTemp, maxTemp);
}
// make enough room for the curve
m_maxTempLimit = maxTemp + 5;
m_minTempLimit = minTemp - 5;
m_series->replace(m_vector);
if (m_axisX && !m_forecast.dailyWeatherForecast().empty()) {
m_axisX->setRange(m_forecast.dailyWeatherForecast().front().date().startOfDay(), m_forecast.dailyWeatherForecast().back().date().startOfDay());
}
}
Q_EMIT dayForecastsChanged();
}
void WeatherLocation::initAxes(QObject *axisX, QObject *axisY)
{
using namespace QtCharts;
if (axisX && axisY) {
m_axisX = static_cast<QDateTimeAxis *>(axisX);
m_axisY = static_cast<QValueAxis *>(axisY);
updateAxes();
}
}
void WeatherLocation::updateAxes()
{
}
void WeatherLocation::updateCurrentDateTime()
{
m_timer->setInterval(60000);
......
......@@ -44,8 +44,6 @@ class WeatherLocation : public QObject
Q_PROPERTY(QColor cardTextColor READ cardTextColor NOTIFY currentForecastChange)
Q_PROPERTY(QColor iconColor READ iconColor NOTIFY currentForecastChange)
Q_PROPERTY(bool darkTheme READ darkTheme NOTIFY currentForecastChange)
Q_PROPERTY(double maxTempLimit READ maxTempLimit NOTIFY currentForecastChange)
Q_PROPERTY(double minTempLimit READ minTempLimit NOTIFY currentForecastChange)
public:
explicit WeatherLocation(QString locationId,
......@@ -128,15 +126,6 @@ public:
{
return m_iconColor;
}
double maxTempLimit() const
{
return m_maxTempLimit;
}
double minTempLimit() const
{
return m_minTempLimit;
}
bool darkTheme() const
{
return m_isDarkTheme;
......@@ -160,8 +149,6 @@ public:
Q_EMIT selectedDayChanged();
}
}
Q_INVOKABLE void initSeries(QtCharts::QAbstractSeries *series);
Q_INVOKABLE void initAxes(QObject *axisX, QObject *axisY);
// for restore order of locations
void saveOrder(int index);
......@@ -187,20 +174,10 @@ private slots:
private:
void determineCurrentForecast();
void updateSeries();
void updateAxes();
KWeatherCore::WeatherForecastSource m_source;
KWeatherCore::WeatherForecast m_forecast;
// chart related fields
QtCharts::QSplineSeries *m_series = nullptr;
QVector<QPointF> m_vector;
double m_maxTempLimit{100};
double m_minTempLimit{0};
QtCharts::QDateTimeAxis *m_axisX{nullptr};
QtCharts::QValueAxis *m_axisY{nullptr};
// background related fields
QColor m_backgroundColor;
QColor m_textColor;
......@@ -218,5 +195,5 @@ private:
QVariantList m_dayForecasts;
QVariantList m_hourForecasts;
int m_selectedDay;
int m_selectedDay = 0;
};
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment