1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "customformatter.h"
#include <QtDataVisualization/qvalue3daxis.h>
#include <QtQml/qqmlextensionplugin.h>
static const qreal oneDayMs = 60.0 * 60.0 * 24.0 * 1000.0;
CustomFormatter::CustomFormatter(QObject *parent) :
QValue3DAxisFormatter(parent)
{
qRegisterMetaType<QValue3DAxisFormatter *>();
}
CustomFormatter::~CustomFormatter()
{
}
//! [1]
QValue3DAxisFormatter *CustomFormatter::createNewInstance() const
{
return new CustomFormatter();
}
void CustomFormatter::populateCopy(QValue3DAxisFormatter ©) const
{
QValue3DAxisFormatter::populateCopy(copy);
CustomFormatter *customFormatter = static_cast<CustomFormatter *>(©);
customFormatter->m_originDate = m_originDate;
customFormatter->m_selectionFormat = m_selectionFormat;
}
//! [1]
//! [2]
void CustomFormatter::recalculate()
{
// We want our axis to always have gridlines at date breaks
// Convert range into QDateTimes
QDateTime minTime = valueToDateTime(qreal(axis()->min()));
QDateTime maxTime = valueToDateTime(qreal(axis()->max()));
// Find out the grid counts
QTime midnight(0, 0);
QDateTime minFullDate(minTime.date(), midnight);
int gridCount = 0;
if (minFullDate != minTime)
minFullDate = minFullDate.addDays(1);
QDateTime maxFullDate(maxTime.date(), midnight);
gridCount += minFullDate.daysTo(maxFullDate) + 1;
int subGridCount = axis()->subSegmentCount() - 1;
// Reserve space for position arrays and label strings
gridPositions().resize(gridCount);
subGridPositions().resize((gridCount + 1) * subGridCount);
labelPositions().resize(gridCount);
labelStrings().reserve(gridCount);
// Calculate positions and format labels
qint64 startMs = minTime.toMSecsSinceEpoch();
qint64 endMs = maxTime.toMSecsSinceEpoch();
qreal dateNormalizer = endMs - startMs;
qreal firstLineOffset = (minFullDate.toMSecsSinceEpoch() - startMs) / dateNormalizer;
qreal segmentStep = oneDayMs / dateNormalizer;
qreal subSegmentStep = 0;
if (subGridCount > 0)
subSegmentStep = segmentStep / qreal(subGridCount + 1);
for (int i = 0; i < gridCount; i++) {
qreal gridValue = firstLineOffset + (segmentStep * qreal(i));
gridPositions()[i] = float(gridValue);
labelPositions()[i] = float(gridValue);
labelStrings() << minFullDate.addDays(i).toString(axis()->labelFormat());
}
for (int i = 0; i <= gridCount; i++) {
if (subGridPositions().size()) {
for (int j = 0; j < subGridCount; j++) {
float position;
if (i)
position = gridPositions().at(i - 1) + subSegmentStep * (j + 1);
else
position = gridPositions().at(0) - segmentStep + subSegmentStep * (j + 1);
if (position > 1.0f || position < 0.0f)
position = gridPositions().at(0);
subGridPositions()[i * subGridCount + j] = position;
}
}
}
}
//! [2]
//! [3]
QString CustomFormatter::stringForValue(qreal value, const QString &format) const
{
Q_UNUSED(format);
return valueToDateTime(value).toString(m_selectionFormat);
}
//! [3]
QDate CustomFormatter::originDate() const
{
return m_originDate;
}
QString CustomFormatter::selectionFormat() const
{
return m_selectionFormat;
}
void CustomFormatter::setOriginDate(QDate date)
{
if (m_originDate != date) {
m_originDate = date;
markDirty(true);
emit originDateChanged(date);
}
}
void CustomFormatter::setSelectionFormat(const QString &format)
{
if (m_selectionFormat != format) {
m_selectionFormat = format;
markDirty(true); // Necessary to regenerate already visible selection label
emit selectionFormatChanged(format);
}
}
//! [0]
QDateTime CustomFormatter::valueToDateTime(qreal value) const
{
return m_originDate.startOfDay().addMSecs(qint64(oneDayMs * value));
}
//! [0]
|