Qt 图表 (QML) 日期时间轴中缺少二月
February is missing from Qt charts (QML) datetime axis
我已经创建了一个 QML 图表
ChartView {
id: chart
anchors.fill: parent
antialiasing: true
ValueAxis {
id: axisY
tickCount: 3
}
DateTimeAxis {
id: xTime
}
SplineSeries {
id: chartseries
pointsVisible: true
pointLabelsVisible: false
useOpenGL: true
axisX: xTime
axisY: axisY
}
}
我还在每个月的月初添加到图表中。刻度点上的工具提示是正确的。在 X 轴上,Qt 本身正在按照它喜欢的方式做同样的事情。如何手动调整
Xaxis->setTickCount(commonmap.size());
QMap<qint64,double>::const_iterator i = commonmap.constBegin();
while (i != commonmap.constEnd())
{
splineseries->append(i.key(),i.value());
++i;
}
我看到你将 DateTimeAxis 的 tickCount 设置为系列中的样本数,所以 Qt 所做的是除以时间的最大值和最小值,然后除以它们,计算结果大约是 31 天,要查看它,我们可以将 DateTimeAxis 的形式修改为 "MMM yyyy dd hh:mm:ss":
所以显示的日期不是月份的日期,而是时间间隔相等的日期,如果 2 月只有 28 天,则不会显示该日期。
如果您想显示二月,您必须在 tickCount 上设置一个更大的值,但它也会生成更多的日期。不幸的是,目前无法以不规则的方式放置刻度,例如月份的天数。
正如@eyllanesc 在他的回答中所解释的那样,无法使用 DateTimeAxis
来获取您想要显示的内容。
这里有一些代码可以帮助生成与使用 CategoryAxis
相近的东西。
注意:在我的示例中,数据是在 QML 中创建和格式化的,但您可以在数据实际所在的 C++ 部分中执行此操作。
import QtQuick 2.9
import QtCharts 2.2
Item {
id: root
width: 1280
height: 720
ListModel {
id: data
function toMsecsSinceEpoch(date) {
var msecs = date.getTime();
return msecs;
}
Component.onCompleted: {
var minDate = data.get(0).x;
var maxDate = data.get(0).x;
var minValue = data.get(0).y;
var maxValue = data.get(0).y;
// Find the minimum and maximum values.
// Fill the SplineSeries data.
for (var i = 0 ; i < data.count ; i++) {
if (data.get(i).x < minDate)
minDate = data.get(i).x;
if (data.get(i).x > maxDate)
maxDate = data.get(i).x;
if (data.get(i).y < minValue)
minValue = data.get(i).y;
if (data.get(i).y > maxValue)
maxValue = data.get(i).y;
chartseries.append(data.get(i).x, data.get(i).y);
}
// Fill the axis limits (x-axis and y-axis).
axisY.min = Math.floor(minValue)
axisY.max = Math.ceil(maxValue)
xTime.min = minDate;
xTime.max = maxDate;
// Fill the CategoryAxis (x-axis).
var dateReference = new Date(xTime.min);
while (dateReference < xTime.max) {
xTime.append(Qt.formatDate(dateReference, "MMM yyyy"), toMsecsSinceEpoch(new Date(dateReference.getFullYear(), dateReference.getMonth(), 1)));
dateReference.setMonth(dateReference.getMonth() + 1);
}
xTime.append(Qt.formatDate(dateReference, "MMM yyyy"), toMsecsSinceEpoch(new Date(dateReference.getFullYear(), dateReference.getMonth(), 1)));
}
ListElement { x: 1514770200000; y: 40.311 }
ListElement { x: 1517434200000; y: 40.4664 }
ListElement { x: 1519853400000; y: 39.6276 }
ListElement { x: 1522531803000; y: 39.6238 }
ListElement { x: 1525123806000; y: 40.3 }
ListElement { x: 1527802210000; y: 40.5638 }
}
ChartView {
id: chart
anchors.fill: parent
antialiasing: true
ValueAxis {
id: axisY
tickCount: 3
min: 39
max: 41
}
CategoryAxis {
id: xTime
labelsPosition: CategoryAxis.AxisLabelsPositionOnValue
}
SplineSeries {
id: chartseries
pointsVisible: true
pointLabelsVisible: false
useOpenGL: true
axisX: xTime
axisY: axisY
}
}
}
我找到了这个问题的答案(可能不是正确的方法...但是可以解决)
解决方案实现步骤-
- 查找上个月的最后一天(比如 6 月 30 日)
setMax
QDateTimeAxis
的日期。
有效,因为 Qt 平均划分开始日期和结束日期之间的天数,并根据滴答计数在 X 轴上分配。
在问题中使用上面的值将得到如图所示的图表
[
Xaxis->setMin(QDateTime::fromMSecsSinceEpoch(commonmap.firstKey()));
Xaxis->setMax(getLastDate());
getLastDate()
{
QDate firstdate =
QDateTime::fromMSecsSinceEpoch(commonmap.lastKey()).date();
int month = firstdate.month();
int day = firstdate.day();
int addday = 0;
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
addday = 31- day;
break;
case 4:
case 6:
case 9:
case 11:
addday = 30- day;
break;
case 2:
if(firstdate.isLeapYear(firstdate.year()))
{
addday = 29- day;
}
else
{
addday = 28- day;
}
break;
}
return (QDateTime::fromMSecsSinceEpoch(commonmap.lastKey()).addDays(addday));
}
我已经创建了一个 QML 图表
ChartView {
id: chart
anchors.fill: parent
antialiasing: true
ValueAxis {
id: axisY
tickCount: 3
}
DateTimeAxis {
id: xTime
}
SplineSeries {
id: chartseries
pointsVisible: true
pointLabelsVisible: false
useOpenGL: true
axisX: xTime
axisY: axisY
}
}
我还在每个月的月初添加到图表中。刻度点上的工具提示是正确的。在 X 轴上,Qt 本身正在按照它喜欢的方式做同样的事情。如何手动调整
Xaxis->setTickCount(commonmap.size());
QMap<qint64,double>::const_iterator i = commonmap.constBegin();
while (i != commonmap.constEnd())
{
splineseries->append(i.key(),i.value());
++i;
}
我看到你将 DateTimeAxis 的 tickCount 设置为系列中的样本数,所以 Qt 所做的是除以时间的最大值和最小值,然后除以它们,计算结果大约是 31 天,要查看它,我们可以将 DateTimeAxis 的形式修改为 "MMM yyyy dd hh:mm:ss":
所以显示的日期不是月份的日期,而是时间间隔相等的日期,如果 2 月只有 28 天,则不会显示该日期。
如果您想显示二月,您必须在 tickCount 上设置一个更大的值,但它也会生成更多的日期。不幸的是,目前无法以不规则的方式放置刻度,例如月份的天数。
正如@eyllanesc 在他的回答中所解释的那样,无法使用 DateTimeAxis
来获取您想要显示的内容。
这里有一些代码可以帮助生成与使用 CategoryAxis
相近的东西。
注意:在我的示例中,数据是在 QML 中创建和格式化的,但您可以在数据实际所在的 C++ 部分中执行此操作。
import QtQuick 2.9
import QtCharts 2.2
Item {
id: root
width: 1280
height: 720
ListModel {
id: data
function toMsecsSinceEpoch(date) {
var msecs = date.getTime();
return msecs;
}
Component.onCompleted: {
var minDate = data.get(0).x;
var maxDate = data.get(0).x;
var minValue = data.get(0).y;
var maxValue = data.get(0).y;
// Find the minimum and maximum values.
// Fill the SplineSeries data.
for (var i = 0 ; i < data.count ; i++) {
if (data.get(i).x < minDate)
minDate = data.get(i).x;
if (data.get(i).x > maxDate)
maxDate = data.get(i).x;
if (data.get(i).y < minValue)
minValue = data.get(i).y;
if (data.get(i).y > maxValue)
maxValue = data.get(i).y;
chartseries.append(data.get(i).x, data.get(i).y);
}
// Fill the axis limits (x-axis and y-axis).
axisY.min = Math.floor(minValue)
axisY.max = Math.ceil(maxValue)
xTime.min = minDate;
xTime.max = maxDate;
// Fill the CategoryAxis (x-axis).
var dateReference = new Date(xTime.min);
while (dateReference < xTime.max) {
xTime.append(Qt.formatDate(dateReference, "MMM yyyy"), toMsecsSinceEpoch(new Date(dateReference.getFullYear(), dateReference.getMonth(), 1)));
dateReference.setMonth(dateReference.getMonth() + 1);
}
xTime.append(Qt.formatDate(dateReference, "MMM yyyy"), toMsecsSinceEpoch(new Date(dateReference.getFullYear(), dateReference.getMonth(), 1)));
}
ListElement { x: 1514770200000; y: 40.311 }
ListElement { x: 1517434200000; y: 40.4664 }
ListElement { x: 1519853400000; y: 39.6276 }
ListElement { x: 1522531803000; y: 39.6238 }
ListElement { x: 1525123806000; y: 40.3 }
ListElement { x: 1527802210000; y: 40.5638 }
}
ChartView {
id: chart
anchors.fill: parent
antialiasing: true
ValueAxis {
id: axisY
tickCount: 3
min: 39
max: 41
}
CategoryAxis {
id: xTime
labelsPosition: CategoryAxis.AxisLabelsPositionOnValue
}
SplineSeries {
id: chartseries
pointsVisible: true
pointLabelsVisible: false
useOpenGL: true
axisX: xTime
axisY: axisY
}
}
}
我找到了这个问题的答案(可能不是正确的方法...但是可以解决) 解决方案实现步骤-
- 查找上个月的最后一天(比如 6 月 30 日)
setMax
QDateTimeAxis
的日期。
有效,因为 Qt 平均划分开始日期和结束日期之间的天数,并根据滴答计数在 X 轴上分配。
在问题中使用上面的值将得到如图所示的图表
[
Xaxis->setMin(QDateTime::fromMSecsSinceEpoch(commonmap.firstKey()));
Xaxis->setMax(getLastDate());
getLastDate()
{
QDate firstdate =
QDateTime::fromMSecsSinceEpoch(commonmap.lastKey()).date();
int month = firstdate.month();
int day = firstdate.day();
int addday = 0;
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
addday = 31- day;
break;
case 4:
case 6:
case 9:
case 11:
addday = 30- day;
break;
case 2:
if(firstdate.isLeapYear(firstdate.year()))
{
addday = 29- day;
}
else
{
addday = 28- day;
}
break;
}
return (QDateTime::fromMSecsSinceEpoch(commonmap.lastKey()).addDays(addday));
}