Виталий Антипов
Виталий Антипов16 января 2018 г. 4:57

ChartView. Отображение метки данных точки серии при наведении курсора

Добрый день! Подскажите, как отобразить метки данных точки в LineSeries при наведении курсора? Из документации понял, что перехватить событие наведения можно через onHovered(), но как получить индекс/позицию/значение нужной точки?

ChartView {
                id: chartIzmerHh
                objectName: "chartIzmerHh"
                property int count
                property var array_dateX
                property var array_valueY
                property var array_valueY1
                property var array_valueY2
                visible: true
                anchors.top: rec_filter.bottom
                anchors.left: parent.left
                anchors.right: parent.right
                anchors.bottom: parent.bottom
                antialiasing: true
                legend.visible: false
                title: "Средняя вибрация на холостом ходу"
                ValueAxis {
                    id: axiY
                    min: 0
                }
                DateTimeAxis {
                    id: axiX
                    format: "dd-MM-yyyy"
                    min: rec_filter.date_begin
                    max: rec_filter.date_end
                }
                LineSeries {
                    id: line1
                    property bool myBool: false
                    color: "lightgreen"
                    axisY: axiY
                    axisX: axiX
                    width: 5
                    onHovered: {
                       // ???
                    }
                }
                LineSeries {
                    id: line2
                    color: "tomato"
                    axisY: axiY
                    axisX: axiX
                    width: 5
                }
                LineSeries {
                    id: line
                    color: "#03a9f5"
                    axisY: axiY
                    axisX: axiX
                    width: 5
                }
                Component.onCompleted: {
                    var xx = []
                    var yy = []
                    var yy1 = []
                    var yy2 = []
                    var max = 0
                    for(var i=0;i<count;i++){
                        xx[i] = Date.parse(array_dateX[i])
                        yy[i] = Number(array_valueY[i])
                        yy1[i] = Number(array_valueY1[i])
                        yy2[i] = Number(array_valueY2[i])
                        if(yy[i]>max){
                            max = yy[i]
                        }
                        if(yy1[i]>max){
                            max = yy1[i]
                        }
                        if(yy2[i]>max){
                            max = yy2[i]
                        }
                        line.append(xx[i], yy[i])
                        line1.append(xx[i], yy1[i])
                        line2.append(xx[i], yy2[i])
                    }
                    max = Math.round(max) + 1
                    axiY.max = max
                }
            }
Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Вам это нравится? Поделитесь в социальных сетях!

8
Evgenii Legotckoi
  • 16 января 2018 г. 9:07
  • Ответ был помечен как решение.

Добрый день!
Обработчик onHovered навешивается автоматически на сигнал hovered.

В документации дана следующая сигнатура этого сигнала
hovered(point point, bool state)
Вот описание из документации

This signal is emitted when a mouse is hovered over the point point in the chart. When the mouse moves over the point, state turns true , and when the mouse moves away again, it turns false .

Соответственно обработчик можно написать так
onHovered: {
    console.log(point);
    console.log(point.x);
    console.log(point.y);
    console.log(state);
}
    Виталий Антипов
    • 16 января 2018 г. 9:21
    • (ред.)

    Спасибо, тоже нашел и получил значения благодаря point.x и point.y. Отформатировал значение даты и вывел искомые значения в прямоугольник. Теперь столкнулся с проблемой перемещения прямоугольника к курсору мыши при срабатывании onHovered(). Использовать MouseArea и брать оттуда mouseX и mouseY не вариант, так как MouseArea перекроет LineSeries и события onHovered никогда не получим. Подскажите, есть какие-нибудь варианты решить проблему?

    ChartView {
                    id: chartIzmerHh
                    objectName: "chartIzmerHh"
                    property int count
                    property var array_dateX
                    property var array_valueY
                    property var array_valueY1
                    property var array_valueY2
                    visible: false
                    anchors.top: rec_filter.bottom
                    anchors.left: parent.left
                    anchors.right: parent.right
                    anchors.bottom: parent.bottom
                    antialiasing: true
                    legend.visible: false
                    title: "Средняя вибрация на холостом ходу"
                    Rectangle {
                        id: rec_hovered
                        color: "yellow"
                        width: text_hovered1.width
                        height: text_hovered1.height + text_hovered2.height
                        Text {
                            id: text_hovered1
                            anchors.bottom: text_hovered2.top
                            text: line1.date_x //сюда выводим значение x при срабатывании onHovered
                        }
                        Text {
                            id: text_hovered2
                            anchors.bottom: parent.bottom
                            text: line1.value_y ////сюда выводим значение y при срабатывании onHovered
                        }
                    }
                    ValueAxis {
                        id: axiY
                        min: 0
                    }
                    DateTimeAxis {
                        id: axiX
                        format: "dd-MM-yyyy"
                        min: rec_filter.date_begin
                        max: rec_filter.date_end
                    }
                    LineSeries {
                        id: line1
                        property string date_x
                        property string value_y
                        color: "lightgreen"
                        axisY: axiY
                        axisX: axiX
                        width: 5
                        onHovered: {
                            var d = new Date(point.x),                    //форматируем дату
                            month = '' + (d.getMonth() + 1),
                            day = '' + d.getDate(),
                            year = d.getFullYear();
                            if (month.length < 2) month = '0' + month;
                            if (day.length < 2) day = '0' + day;
                            date_x = ([day, month, year].join('-')).toString()
                            value_y = ((point.y).toFixed(2)).toString()   //форматируем значение по y
                        }
    
                    }
                    LineSeries {
                        id: line2
                        color: "tomato"
                        axisY: axiY
                        axisX: axiX
                        width: 5
                    }
                    LineSeries {
                        id: line
                        color: "#03a9f5"
                        axisY: axiY
                        axisX: axiX
                        width: 5
                    }
                    Component.onCompleted: {
                        var xx = []
                        var yy = []
                        var yy1 = []
                        var yy2 = []
                        var max = 0
                        for(var i=0;i<count;i++){
                            xx[i] = Date.parse(array_dateX[i])
                            yy[i] = Number(array_valueY[i])
                            yy1[i] = Number(array_valueY1[i])
                            yy2[i] = Number(array_valueY2[i])
                            if(yy[i]>max){
                                max = yy[i]
                            }
                            if(yy1[i]>max){
                                max = yy1[i]
                            }
                            if(yy2[i]>max){
                                max = yy2[i]
                            }
                            line.append(xx[i], yy[i])
                            line1.append(xx[i], yy1[i])
                            line2.append(xx[i], yy2[i])
                        }
                        max = Math.round(max) + 1
                        axiY.max = max
                    }
                }

      Evgenii Legotckoi
      • 16 января 2018 г. 9:38
      • (ред.)

      Пока мыслей нет, но попробуйте всё-таки MouseArea. Дело в том, что у неё есть свойство propagateComposedEvents , которое по умолчанию установлено на false , а если его установить на true, то события должны передаваться на объекты, которые перекрываются этой самой MouseArea.

        Виталий Антипов
        • 16 января 2018 г. 9:46

        Спасибо, попробую! Тут еще вариант придумал - создать ScatterSeries и при onHovered создать точку с требуемыми координатами. Попробовал scatter.append(point.x, point.y) - получается очень красиво. Только надо изучить как ее заменять на новую и как форматировать значения pointLabels

          Evgenii Legotckoi
          • 16 января 2018 г. 10:04

          У ScatterSeries есть методы

          • remove(int index),
          • remove(real x, real y),
          • removePoints(int index, int count)
          Если будете оперировать только одной точкой в каждом графике ScatterSeries для каждой LineSeries (то есть один ScatterSeries для одной LineSeries ), то удалять можно будет точку по индекс при каждом срабатывании onHovered , то есть scatter1.remove(0), а потом просто добавлять новую точку. Ну или наверняк можно просто изменить координаты точки через метод replace.
            Виталий Антипов
            • 16 января 2018 г. 10:10

            Спасибо за ответ! Кстати, propagateComposedEvents: true не дает получить событие onHovered .

              Evgenii Legotckoi
              • 16 января 2018 г. 10:25
              • (ред.)

              Если честно у меня пока только одна идиотская идея есть. Брать по таймеру текущую позицию курсора глобально из C++ специальным классом. И этот класс будет зарегистрирован в QML, у него будет сигнал, который будет высылать информацию о положении курсора, что позволит обновлять информацию так, как вам будет нужно (используя конечно манипуляции с мапингом глобальных координат в координаты графика).

              Ещё я бы рекомендовал покапаться в исходниках, хотя бы заголовочных файлах QQuickItem, от которого, по моему мнению, должен быть наследован ChartView в результате. Дело в том, что в официальной документации нет полного описания всех методов, которыми обладают Quick компоненты, я это заметил, когда разбирался с написанием кастомных Quick компонентов и использованием OpenGL в них. Часто приходилось заглядывать в заголовочники того же самого QQuickItem и не все публичные методы были описаны в документации.
                Виталий Антипов
                • 16 января 2018 г. 11:47

                Спасибо большущее за советы! Все получилось через ScatterSeries. Методы remove() как-то сходу не дались, удаляет в первый раз, а потом программа падает... Не стал тратить время и воспользовался методом replace(). Все идеально, работает шустро! Еще раз спасибо!

                ChartView {
                                id: chartIzmerHh
                                objectName: "chartIzmerHh"
                                property int count
                                property var array_dateX
                                property var array_valueY
                                property var array_valueY1
                                property var array_valueY2
                                property real oldX        //сюда записываем координату текущей точки scatter для метода replace()
                                property real oldY        //сюда записываем координату текущей точки scatter для метода replace()
                                visible: false
                                anchors.top: rec_filter.bottom
                                anchors.left: parent.left
                                anchors.right: parent.right
                                anchors.bottom: parent.bottom
                                antialiasing: true
                                legend.visible: false                
                                title: "Средняя вибрация на холостом ходу"
                                ValueAxis {
                                    id: axiY
                                    min: 0
                                }
                                DateTimeAxis {
                                    id: axiX
                                    format: "dd-MM-yyyy"
                                    min: rec_filter.date_begin
                                    max: rec_filter.date_end
                                }
                                LineSeries {
                                    id: line1
                                    property string date_x
                                    property string value_y
                                    color: "lightgreen"
                                    axisY: axiY
                                    axisX: axiX
                                    width: 5
                                    onHovered: {
                //форматируем дату по x и значение по y
                                        var d = new Date(point.x),
                                        month = '' + (d.getMonth() + 1),
                                        day = '' + d.getDate(),
                                        year = d.getFullYear();
                                        if (month.length < 2) month = '0' + month;
                                        if (day.length < 2) day = '0' + day;
                                        date_x = ([day, month, year].join('-')).toString()
                                        value_y = ((point.y).toFixed(2)).toString()
                //заменяем старую точку на новую
                                        scatter.replace(chartIzmerHh.oldX, chartIzmerHh.oldY, point.x, point.y)
                //перезаписываем текущие координаты, они станут старыми при следующем вызове onHovered и уйдут в replace()
                                        chartIzmerHh.oldX = point.x
                                        chartIzmerHh.oldY = point.y
                                    }
                                }
                                ScatterSeries {
                                    id: scatter
                                    pointLabelsVisible: true
                                    pointLabelsClipping: false
                                    pointLabelsFont: bold
                                    pointLabelsFormat: "" + line1.value_y +" ; "+ line1.date_x + ""  //сюда пишем отформатированные текущие значения
                                    color: "lightgreen"
                                    borderColor: "black"
                                    axisY: axiY
                                    axisX: axiX
                                }
                                LineSeries {
                                    id: line2
                                    color: "tomato"
                                    axisY: axiY
                                    axisX: axiX
                                    width: 5
                                }
                                LineSeries {
                                    id: line
                                    color: "#03a9f5"
                                    axisY: axiY
                                    axisX: axiX
                                    width: 5
                                }
                                Component.onCompleted: {
                                    var xx = []
                                    var yy = []
                                    var yy1 = []
                                    var yy2 = []
                                    var max = 0
                                    for(var i=0;i<count;i++){
                                        xx[i] = Date.parse(array_dateX[i])
                                        yy[i] = Number(array_valueY[i])
                                        yy1[i] = Number(array_valueY1[i])
                                        yy2[i] = Number(array_valueY2[i])
                                        if(yy[i]>max){
                                            max = yy[i]
                                        }
                                        if(yy1[i]>max){
                                            max = yy1[i]
                                        }
                                        if(yy2[i]>max){
                                            max = yy2[i]
                                        }
                                        line.append(xx[i], yy[i])
                                        line1.append(xx[i], yy1[i])
                                        line2.append(xx[i], yy2[i])                        
                                    }
                //ставим сразу точку на график (меня интересует последняя) и записываем ее текущее значение, которое потом уйдет в replace()
                                    oldX = xx[count-1]
                                    oldY = yy1[count-1]
                                    scatter.append(xx[count-1], yy1[count-1])
                                    max = Math.round(max) + 1
                                    axiY.max = max
                                    console.log(oldX,oldY)
                                }
                            }

                  Комментарии

                  Только авторизованные пользователи могут публиковать комментарии.
                  Пожалуйста, авторизуйтесь или зарегистрируйтесь
                  AD

                  C++ - Тест 004. Указатели, Массивы и Циклы

                  • Результат:50баллов,
                  • Очки рейтинга-4
                  m
                  • molni99
                  • 26 октября 2024 г. 11:37

                  C++ - Тест 004. Указатели, Массивы и Циклы

                  • Результат:80баллов,
                  • Очки рейтинга4
                  m
                  • molni99
                  • 26 октября 2024 г. 11:29

                  C++ - Тест 004. Указатели, Массивы и Циклы

                  • Результат:20баллов,
                  • Очки рейтинга-10
                  Последние комментарии
                  i
                  innorwall14 ноября 2024 г. 22:42
                  Как Копировать Файлы в Linux If only females relatives with DZ offspring were considered these percentages were 23 order priligy online uk
                  i
                  innorwall14 ноября 2024 г. 20:09
                  Qt/C++ - Урок 068. Hello World с использованием системы сборки CMAKE в CLion ditropan pristiq dosing With the Yankees leading, 4 3, Rivera jogged in from the bullpen to a standing ovation as he prepared for his final appearance in Chicago buy priligy pakistan
                  i
                  innorwall14 ноября 2024 г. 15:05
                  EVILEG-CORE. Использование Google reCAPTCHA 2001; 98 29 34 priligy buy
                  i
                  innorwall14 ноября 2024 г. 15:00
                  PyQt5 - Урок 007. Работаем с QML QtQuick (Сигналы и слоты) priligy 30mg Am J Obstet Gynecol 171 1488 505
                  Сейчас обсуждают на форуме
                  i
                  innorwall14 ноября 2024 г. 14:39
                  добавить qlineseries в функции priligy amazon canada 93 GREB1 protein GREB1 AB011147 6
                  i
                  innorwall11 ноября 2024 г. 21:55
                  Всё ещё разбираюсь с кешем. priligy walgreens levitra dulcolax carbs The third ring was found to be made up of ultra relativistic electrons, which are also present in both the outer and inner rings
                  9
                  9Anonim25 октября 2024 г. 19:10
                  Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…
                  ИМ
                  Игорь Максимов3 октября 2024 г. 14:05
                  Реализация навигации по разделам Спасибо Евгений!

                  Следите за нами в социальных сетях