more work on using qtcharts

This commit is contained in:
Michael Zanetti 2018-10-25 10:54:26 +02:00
parent 10cbc9941b
commit 37c4ed0261
6 changed files with 554 additions and 50 deletions

View File

@ -7,8 +7,7 @@
#include "types/logentry.h"
#include "logmanager.h"
LogsModelNg::LogsModelNg(QObject *parent) : QAbstractListModel(parent),
m_lineSeries(new QtCharts::QLineSeries(this))
LogsModelNg::LogsModelNg(QObject *parent) : QAbstractListModel(parent)
{
}
@ -134,14 +133,44 @@ void LogsModelNg::setEndTime(const QDateTime &endTime)
}
}
QtCharts::QLineSeries *LogsModelNg::lineSeries() const
QtCharts::QXYSeries *LogsModelNg::graphSeries() const
{
return m_lineSeries;
return m_graphSeries;
}
void LogsModelNg::setLineSeries(QtCharts::QLineSeries *lineSeries)
void LogsModelNg::setGraphSeries(QtCharts::QXYSeries *graphSeries)
{
m_lineSeries = lineSeries;
m_graphSeries = graphSeries;
}
QDateTime LogsModelNg::viewStartTime() const
{
return m_viewStartTime;
}
void LogsModelNg::setViewStartTime(const QDateTime &viewStartTime)
{
if (m_viewStartTime != viewStartTime) {
m_viewStartTime = viewStartTime;
emit viewStartTimeChanged();
if (m_list.count() == 0 || m_list.last()->timestamp() > m_viewStartTime) {
if (canFetchMore()) {
fetchMore();
}
}
}
}
QVariant LogsModelNg::minValue() const
{
qDebug() << "returning min value" << m_minValue;
return m_minValue;
}
QVariant LogsModelNg::maxValue() const
{
qDebug() << "returning max value" << m_maxValue;
return m_maxValue;
}
void LogsModelNg::logsReply(const QVariantMap &data)
@ -179,13 +208,37 @@ void LogsModelNg::logsReply(const QVariantMap &data)
}
beginInsertRows(QModelIndex(), offset, offset + newBlock.count() - 1);
QVariant newMin = m_minValue;
QVariant newMax = m_maxValue;
for (int i = 0; i < newBlock.count(); i++) {
m_list.insert(offset + i, newBlock.at(i));
qDebug() << "Adding line series point:" << i << newBlock.at(i)->timestamp().toSecsSinceEpoch() << newBlock.at(i)->value().toReal();
m_lineSeries->insert(offset + i, QPointF(newBlock.at(i)->timestamp().toSecsSinceEpoch(), newBlock.at(i)->value().toReal()));
LogEntry *entry = newBlock.at(i);
m_list.insert(offset + i, entry);
qDebug() << "Adding line series point:" << i << entry->timestamp().toSecsSinceEpoch() << entry->value().toReal();
if (m_graphSeries) {
m_graphSeries->insert(offset + i, QPointF(entry->timestamp().toMSecsSinceEpoch(), entry->value().toReal()));
}
if (!newMin.isValid() || newMin > entry->value()) {
newMin = entry->value().toReal();
}
if (!newMax.isValid() || newMax < entry->value()) {
newMax = entry->value().toReal();
}
}
endInsertRows();
emit countChanged();
qDebug() << "min" << m_minValue << "max" << m_maxValue << "newMin" << newMin << "newMax" << newMax;
if (m_minValue != newMin) {
m_minValue = newMin;
emit minValueChanged();
}
if (m_maxValue != newMax) {
m_maxValue = newMax;
emit maxValueChanged();
}
if (m_list.count() > 0 && m_list.last()->timestamp() > m_viewStartTime && canFetchMore()) {
fetchMore();
}
}
void LogsModelNg::fetchMore(const QModelIndex &parent)
@ -225,8 +278,8 @@ void LogsModelNg::fetchMore(const QModelIndex &parent)
if (!m_startTime.isNull() && !m_endTime.isNull()) {
QVariantList timeFilters;
QVariantMap timeFilter;
timeFilter.insert("startDate", m_currentFetchStartTime.toSecsSinceEpoch());
timeFilter.insert("endDate", m_currentFetchEndTime.toSecsSinceEpoch());
timeFilter.insert("startDate", m_startTime.toSecsSinceEpoch());
timeFilter.insert("endDate", m_endTime.toSecsSinceEpoch());
timeFilters.append(timeFilter);
params.insert("timeFilters", timeFilters);
}
@ -271,6 +324,9 @@ void LogsModelNg::newLogEntryReceived(const QVariantMap &data)
QVariant value = loggingEventType == LogEntry::LoggingEventTypeActiveChange ? entryMap.value("active").toBool() : entryMap.value("value");
LogEntry *entry = new LogEntry(timeStamp, value, deviceId, typeId, loggingSource, loggingEventType, this);
m_list.prepend(entry);
if (m_graphSeries) {
m_graphSeries->insert(0, QPointF(entry->timestamp().toMSecsSinceEpoch(), entry->value().toReal()));
}
endInsertRows();
emit countChanged();

View File

@ -20,8 +20,11 @@ class LogsModelNg : public QAbstractListModel
Q_PROPERTY(QStringList typeIds READ typeIds WRITE setTypeIds NOTIFY typeIdsChanged)
Q_PROPERTY(QDateTime startTime READ startTime WRITE setStartTime NOTIFY startTimeChanged)
Q_PROPERTY(QDateTime endTime READ endTime WRITE setEndTime NOTIFY endTimeChanged)
Q_PROPERTY(QVariant minValue READ minValue NOTIFY minValueChanged)
Q_PROPERTY(QVariant maxValue READ maxValue NOTIFY maxValueChanged)
Q_PROPERTY(QtCharts::QLineSeries *lineSeries READ lineSeries WRITE setLineSeries NOTIFY lineSeriesChanged)
Q_PROPERTY(QtCharts::QXYSeries *graphSeries READ graphSeries WRITE setGraphSeries NOTIFY graphSeriesChanged)
Q_PROPERTY(QDateTime viewStartTime READ viewStartTime WRITE setViewStartTime NOTIFY viewStartTimeChanged)
public:
enum Roles {
@ -59,8 +62,14 @@ public:
QDateTime endTime() const;
void setEndTime(const QDateTime &endTime);
QtCharts::QLineSeries *lineSeries() const;
void setLineSeries(QtCharts::QLineSeries *lineSeries);
QtCharts::QXYSeries *graphSeries() const;
void setGraphSeries(QtCharts::QXYSeries *lineSeries);
QDateTime viewStartTime() const;
void setViewStartTime(const QDateTime &viewStartTime);
QVariant minValue() const;
QVariant maxValue() const;
protected:
virtual void fetchMore(const QModelIndex &parent = QModelIndex()) override;
@ -75,7 +84,10 @@ signals:
void startTimeChanged();
void endTimeChanged();
void engineChanged();
void lineSeriesChanged();
void graphSeriesChanged();
void viewStartTimeChanged();
void minValueChanged();
void maxValueChanged();
private slots:
void newLogEntryReceived(const QVariantMap &data);
@ -91,12 +103,13 @@ private:
QStringList m_typeIds;
QDateTime m_startTime;
QDateTime m_endTime;
QDateTime m_currentFetchStartTime;
QDateTime m_currentFetchEndTime;
int m_blockSize = 100;
bool m_canFetchMore = true;
QDateTime m_viewStartTime;
QVariant m_minValue;
QVariant m_maxValue;
QtCharts::QLineSeries *m_lineSeries = nullptr;
QtCharts::QXYSeries *m_graphSeries = nullptr;
QList<QPair<QDateTime, bool> > m_fetchedPeriods;
};

View File

@ -148,5 +148,7 @@
<file>ui/images/view-collapse.svg</file>
<file>ui/images/view-expand.svg</file>
<file>ui/images/weather-app-symbolic.svg</file>
<file>ui/images/zoom-out.svg</file>
<file>ui/images/zoom-in.svg</file>
</qresource>
</RCC>

View File

@ -1,5 +1,6 @@
import QtQuick 2.5
import QtQuick.Controls 2.1
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Controls.Material 2.2
import QtQuick.Layouts 1.1
import Nymea 1.0
import "../components"
@ -44,7 +45,8 @@ Page {
deviceId: root.device.id
typeIds: [root.stateType.id]
live: true
lineSeries: lineSeries1
graphSeries: lineSeries1
viewStartTime: xAxis.min
}
ColumnLayout {
@ -163,7 +165,7 @@ Page {
engine: _engine
// Live doesn't work yet with ValueLogsProxyModel
// live: true
// live: true
}
}
}
@ -173,57 +175,146 @@ Page {
width: swipeView.width
height: swipeView.height
ChartView {
id: chartView
ColumnLayout {
anchors.fill: parent
ValueAxis {
id: yAxis
min: 0
max: 50
RowLayout {
Layout.alignment: Qt.AlignRight
HeaderButton {
imageSource: "../images/zoom-in.svg"
onClicked: {
var diff = xAxis.max.getTime() - xAxis.min.getTime()
var newTime = new Date(xAxis.min.getTime() + (diff / 4))
xAxis.min = newTime;
}
}
HeaderButton {
imageSource: "../images/zoom-out.svg"
onClicked: {
var diff = xAxis.max.getTime() - xAxis.min.getTime()
var newTime = new Date(xAxis.min.getTime() - (diff / 4))
xAxis.min = newTime;
}
}
}
ValueAxis {
id: xAxis
min: Math.floor(startTime.getTime() / 1000)
max: Math.floor(endTime.getTime() / 1000)
ChartView {
id: chartView
Layout.fillWidth: true
Layout.fillHeight: true
margins.top: 0
margins.bottom: 0
margins.left: 0
margins.right: 0
backgroundColor: Material.background
animationDuration: 300
animationOptions: ChartView.SeriesAnimations
property date startTime: {
var date = new Date();
date.setHours(date.getHours() - 6);
return date;
ValueAxis {
id: yAxis
min: logsModelNg.minValue
max: logsModelNg.maxValue
labelsFont.pixelSize: app.smallFont
tickCount: chartView.height / 40
}
property date endTime: new Date()
Component.onCompleted: print("creating axis:", startTime, endTime)
}
DateTimeAxis {
id: xAxis
gridVisible: false
tickCount: chartView.width / 70
labelsFont.pixelSize: app.smallFont
format: {
var timeDiff = (xAxis.max.getTime() - xAxis.min.getTime()) / 1000
if (timeDiff < 60) { // one minute
return "mm:ss"
}
if (timeDiff < 60 * 60) { // one hour
return "hh:mm"
}
if (timeDiff < 60 * 60 * 24 * 2) { // two day
return "hh:mm"
}
if (timeDiff < 60 * 60 * 24 * 7) { // one week
return "ddd hh:mm"
}
if (timeDiff < 60 * 60 * 24 * 7 * 30) { // one month
return "dd.MM."
}
return "MMM yy"
}
LineSeries {
id: lineSeries1
axisX: xAxis
axisY: yAxis
}
min: {
var date = new Date();
date.setHours(date.getHours() - 6);
return date;
}
max: new Date()
}
MouseArea {
AreaSeries {
axisX: xAxis
axisY: yAxis
name: root.stateType.displayName
borderColor: app.accentColor
borderWidth: 4
upperSeries: LineSeries {
id: lineSeries1
width: 4
}
color: Qt.rgba(app.accentColor.r, app.accentColor.g, app.accentColor.b, .3)
}
MouseArea {
anchors.fill: parent
property int lastX: 0
property int lastY: 0
function scrollRightLimited(dx) {
chartView.animationOptions = ChartView.NoAnimation
var now = new Date()
// if we're already at the limit, don't even start scrolling
if (dx < 0 || xAxis.max < now) {
chartView.scrollRight(dx)
}
// figure out if we scrolled too far
var overshoot = xAxis.max.getTime() - now.getTime()
print("overshoot is:", overshoot, "oldMax", xAxis.max, "newMax", now, "oldMin", xAxis.min, "newMin", new Date(xAxis.min.getTime() - overshoot))
if (overshoot > 0) {
var range = xAxis.max - xAxis.min
xAxis.max = now
xAxis.min = new Date(xAxis.max.getTime() - range)
}
chartView.animationOptions = ChartView.SeriesAnimations
}
function zoomInLimited(dy) {
chartView.animationOptions = ChartView.NoAnimation
var oldMax = xAxis.max;
chartView.scrollRight(dy);
var timeDiff = xAxis.max.getTime() - oldMax.getTime()
xAxis.min = new Date(xAxis.min.getTime() - timeDiff * 2)
chartView.animationOptions = ChartView.SeriesAnimations
}
onPressed: {
lastX = mouse.x
lastY = mouse.y
}
onWheel: {
scrollRightLimited(-wheel.pixelDelta.x)
// zoomInLimited(wheel.pixelDelta.y)
}
onPositionChanged: {
if (lastX !== mouse.x) {
chartView.scrollRight(lastX - mouse.x)
scrollRightLimited(lastX - mouseX)
lastX = mouse.x
}
if (lastY !== mouse.y) {
chartView.scrollDown(lastY - mouse.y)
lastY = mouse.y
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,171 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="96"
height="96"
id="svg4874"
version="1.1"
inkscape:version="0.91+devel r"
viewBox="0 0 96 96.000001"
sodipodi:docname="zoom-in.svg">
<defs
id="defs4876" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="8.7812489"
inkscape:cx="44.008543"
inkscape:cy="41.064759"
inkscape:document-units="px"
inkscape:current-layer="g4780"
showgrid="true"
showborder="true"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:snap-bbox="true"
inkscape:bbox-paths="true"
inkscape:bbox-nodes="true"
inkscape:snap-bbox-edge-midpoints="true"
inkscape:snap-bbox-midpoints="true"
inkscape:object-paths="true"
inkscape:snap-intersection-paths="true"
inkscape:object-nodes="true"
inkscape:snap-smooth-nodes="true"
inkscape:snap-midpoints="true"
inkscape:snap-object-midpoints="true"
inkscape:snap-center="true"
showguides="true"
inkscape:guide-bbox="true">
<inkscape:grid
type="xygrid"
id="grid5451"
empspacing="8" />
<sodipodi:guide
orientation="1,0"
position="8,-8.0000001"
id="guide4063" />
<sodipodi:guide
orientation="1,0"
position="4,-8.0000001"
id="guide4065" />
<sodipodi:guide
orientation="0,1"
position="-8,88.000001"
id="guide4067" />
<sodipodi:guide
orientation="0,1"
position="-8,92.000001"
id="guide4069" />
<sodipodi:guide
orientation="0,1"
position="104,4"
id="guide4071" />
<sodipodi:guide
orientation="0,1"
position="-5,8.0000001"
id="guide4073" />
<sodipodi:guide
orientation="1,0"
position="92,-8.0000001"
id="guide4075" />
<sodipodi:guide
orientation="1,0"
position="88,-8.0000001"
id="guide4077" />
<sodipodi:guide
orientation="0,1"
position="-8,84.000001"
id="guide4074" />
<sodipodi:guide
orientation="1,0"
position="12,-8.0000001"
id="guide4076" />
<sodipodi:guide
orientation="0,1"
position="-5,12"
id="guide4078" />
<sodipodi:guide
orientation="1,0"
position="84,-9.0000001"
id="guide4080" />
<sodipodi:guide
position="48,-8.0000001"
orientation="1,0"
id="guide4170" />
<sodipodi:guide
position="-8,48"
orientation="0,1"
id="guide4172" />
</sodipodi:namedview>
<metadata
id="metadata4879">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(67.857146,-78.50504)">
<g
transform="matrix(0,-1,-1,0,373.50506,516.50504)"
id="g4845"
style="display:inline">
<g
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="next01.png"
transform="matrix(-0.9996045,0,0,1,575.94296,-611.00001)"
id="g4778"
inkscape:label="Layer 1">
<g
transform="matrix(-1,0,0,1,575.99999,611)"
id="g4780"
style="display:inline">
<rect
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:4;marker:none;enable-background:accumulate"
id="rect4782"
width="96.037987"
height="96"
x="-438.00244"
y="345.36221"
transform="scale(-1,1)" />
<path
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;line-height:125%;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#808080;fill-opacity:1;stroke:none"
d="m 364.0904,368.96573 c -0.0215,-0.0161 -0.0354,-0.0404 -0.0567,-0.0566 -0.0253,-0.0201 -0.057,-0.0305 -0.0821,-0.0508 z"
id="path4157" />
<path
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;line-height:125%;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#808080;fill-opacity:1;stroke:none"
d="m 364.07673,417.80167 -0.13873,0.10742 c 0.0251,-0.0203 0.0569,-0.0307 0.0821,-0.0508 0.0214,-0.0162 0.0353,-0.0405 0.0567,-0.0566 z"
id="path4344" />
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.99999976;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="M 42 6 C 22.14111 6 6 22.142377 6 42 C 6 61.857623 22.14111 77.996094 42 77.996094 C 50.849741 77.996094 58.956757 74.785633 65.230469 69.474609 L 84.876953 89.119141 L 89.121094 84.878906 L 69.474609 65.232422 C 74.78872 58.958425 78 50.851684 78 42 C 78 22.142377 61.85889 6 42 6 z M 42 9.9980469 C 59.69585 9.9980469 73.998047 24.302852 73.998047 42 C 73.998047 59.697148 59.69585 73.998047 42 73.998047 C 24.30415 73.998047 10 59.697148 10 42 C 10 24.302852 24.30415 9.9980469 42 9.9980469 z M 40 24 L 40 39.998047 L 24 39.998047 L 24 43.998047 L 40 43.998047 L 40 60 L 44.001953 60 L 44.001953 43.998047 L 60 43.998047 L 60 39.998047 L 44.001953 39.998047 L 44.001953 24 L 40 24 z "
transform="matrix(0,-1,-1.0003957,0,438.00245,441.36222)"
id="path4116" />
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

@ -0,0 +1,171 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="96"
height="96"
id="svg4874"
version="1.1"
inkscape:version="0.91+devel r"
viewBox="0 0 96 96.000001"
sodipodi:docname="zoom-out.svg">
<defs
id="defs4876" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="8.7812489"
inkscape:cx="33.298221"
inkscape:cy="49.3096"
inkscape:document-units="px"
inkscape:current-layer="g4780"
showgrid="true"
showborder="true"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:snap-bbox="true"
inkscape:bbox-paths="true"
inkscape:bbox-nodes="true"
inkscape:snap-bbox-edge-midpoints="true"
inkscape:snap-bbox-midpoints="true"
inkscape:object-paths="true"
inkscape:snap-intersection-paths="true"
inkscape:object-nodes="true"
inkscape:snap-smooth-nodes="true"
inkscape:snap-midpoints="true"
inkscape:snap-object-midpoints="true"
inkscape:snap-center="true"
showguides="true"
inkscape:guide-bbox="true">
<inkscape:grid
type="xygrid"
id="grid5451"
empspacing="8" />
<sodipodi:guide
orientation="1,0"
position="8,-8.0000001"
id="guide4063" />
<sodipodi:guide
orientation="1,0"
position="4,-8.0000001"
id="guide4065" />
<sodipodi:guide
orientation="0,1"
position="-8,88.000001"
id="guide4067" />
<sodipodi:guide
orientation="0,1"
position="-8,92.000001"
id="guide4069" />
<sodipodi:guide
orientation="0,1"
position="104,4"
id="guide4071" />
<sodipodi:guide
orientation="0,1"
position="-5,8.0000001"
id="guide4073" />
<sodipodi:guide
orientation="1,0"
position="92,-8.0000001"
id="guide4075" />
<sodipodi:guide
orientation="1,0"
position="88,-8.0000001"
id="guide4077" />
<sodipodi:guide
orientation="0,1"
position="-8,84.000001"
id="guide4074" />
<sodipodi:guide
orientation="1,0"
position="12,-8.0000001"
id="guide4076" />
<sodipodi:guide
orientation="0,1"
position="-5,12"
id="guide4078" />
<sodipodi:guide
orientation="1,0"
position="84,-9.0000001"
id="guide4080" />
<sodipodi:guide
position="48,-8.0000001"
orientation="1,0"
id="guide4170" />
<sodipodi:guide
position="-8,48"
orientation="0,1"
id="guide4172" />
</sodipodi:namedview>
<metadata
id="metadata4879">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(67.857146,-78.50504)">
<g
transform="matrix(0,-1,-1,0,373.50506,516.50504)"
id="g4845"
style="display:inline">
<g
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="next01.png"
transform="matrix(-0.9996045,0,0,1,575.94296,-611.00001)"
id="g4778"
inkscape:label="Layer 1">
<g
transform="matrix(-1,0,0,1,575.99999,611)"
id="g4780"
style="display:inline">
<rect
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:4;marker:none;enable-background:accumulate"
id="rect4782"
width="96.037987"
height="96"
x="-438.00244"
y="345.36221"
transform="scale(-1,1)" />
<path
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;line-height:125%;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#808080;fill-opacity:1;stroke:none"
d="m 364.0904,368.96573 c -0.0215,-0.0161 -0.0354,-0.0404 -0.0567,-0.0566 -0.0253,-0.0201 -0.057,-0.0305 -0.0821,-0.0508 z"
id="path4157" />
<path
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;line-height:125%;font-family:Ubuntu;-inkscape-font-specification:Ubuntu;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#808080;fill-opacity:1;stroke:none"
d="m 364.07673,417.80167 -0.13873,0.10742 c 0.0251,-0.0203 0.0569,-0.0307 0.0821,-0.0508 0.0214,-0.0162 0.0353,-0.0405 0.0567,-0.0566 z"
id="path4344" />
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.99999976;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="M 42 6 C 22.14111 6 6 22.142377 6 42 C 6 61.857623 22.14111 77.996094 42 77.996094 C 50.849741 77.996094 58.956757 74.785633 65.230469 69.474609 L 84.876953 89.119141 L 89.121094 84.878906 L 69.474609 65.232422 C 74.78872 58.958425 78 50.851684 78 42 C 78 22.142377 61.85889 6 42 6 z M 42 9.9980469 C 59.69585 9.9980469 73.998047 24.302852 73.998047 42 C 73.998047 59.697148 59.69585 73.998047 42 73.998047 C 24.30415 73.998047 10 59.697148 10 42 C 10 24.302852 24.30415 9.9980469 42 9.9980469 z M 24 39.998047 L 24 43.998047 L 60 43.998047 L 60 39.998047 L 24 39.998047 z "
transform="matrix(0,-1,-1.0003957,0,438.00245,441.36222)"
id="path4116" />
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.1 KiB