Февраль отсутствует на оси даты и времени Qt charts (QML) - PullRequest
0 голосов
/ 31 августа 2018

Я создал диаграмму 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;
}

enter image description here

Ответы [ 3 ]

0 голосов
/ 03 сентября 2018

Как объяснил @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
        }
    }
}
0 голосов
/ 03 сентября 2018

Я нашел ответ на эту проблему (возможно, это не правильный путь ... Но можно решить) Шаг для достижения решения -

  1. Найти Последняя дата последнего месяца (скажем, 30 июня)
  2. setMax дата QDateTimeAxis.

Это работает, потому что Qt делит дни между начальной и конечной датами поровну и распределяет их по оси X в зависимости от количества тиков.

С указанными выше значениями в вопросе получите график, как показано на изображении

enter image description here

[

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));
 }
0 голосов
/ 01 сентября 2018

Я вижу, что вы устанавливаете tickCount of DateTimeAxis для числа выборок в серии, поэтому Qt делит, вычитает максимальное и минимальное время и делит их, что вычисление происходит примерно за 31 день, чтобы увидеть если мы можем изменить форму DateTimeAxis на «МММ гггг дд чч: мм: сс»:

enter image description here

Таким образом, показанные даты не равны месяцам, а промежуткам времени, и если в феврале только 28 дней, эта дата не будет отображаться.

Если вы хотите показать февраль, вам нужно будет поместить большее значение в tickCount, но оно также будет генерировать больше дат. К сожалению, в настоящее время невозможно размещать отметки нерегулярно, например, количество дней в месяцах.

...