4

I have created a QML chart

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
    }
}

I am also appending at the beginning of each month to the chart. Tooltip on tick points are correct. On X axis Qt itself is doing the same as it like . How to adjust it manually

 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

Masthan
  • 727
  • 1
  • 8
  • 29

3 Answers3

2

I see that you are setting the tickCount of DateTimeAxis to the number of samples in the series, so what Qt does is divide subtract the maximum and minimum of the times and divide them, that calculation comes out about 31 days, to see it we can modify the form of DateTimeAxis to "MMM yyyy dd hh:mm:ss":

enter image description here

So the dates that are shown are not of the months but of times equally spaced, and having February only 28 days will not show that date.

If you want to show February you would have to place a larger value on tickCount but it will also generate more dates. Unfortunately, it is currently not possible to place the ticks in an irregular manner, such as the number of days of the months.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
1

I have found an answer to this problem (may not be the right way...But can be solved) Step to achieve the solution -

  1. Find Last date of the last month (say June 30)
  2. setMax date of QDateTimeAxis.

It works Because Qt divides the days between Start date and end date equally and distribute across X axis based ob the tick count .

With the values above in the question will get a chart as shown in the Image

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));
 }
Masthan
  • 727
  • 1
  • 8
  • 29
0

As explained by @eyllanesc in his answer, it is not possible to use DateTimeAxis to obtain what you want to display.

Here is some code that could help to generate something close with the use of CategoryAxis.

Note: The data is created and formatted in QML in my example, but you could do that in the C++ part where the data could actually be.

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
        }
    }
}
Julien Déramond
  • 544
  • 8
  • 17