How do I place text at specific (x,y) locations within the plotting area of a QML ChartView type?
For example, I would like to place text at the location XYPoint{x: -3; Y: 20}
I don't want to place at window's(x,y), i want to put at plotting area's (x,y)
I read documentation,but i don't find any property !!!!!!
//ChartView for plotting points
ChartView{
id:chrt
anchors.fill: parent
height: parent.height
width: parent.width
legend.visible: false
backgroundColor: "black"
//X- axis
ValueAxis{
id: x_axis
min: -5
max: 0
tickCount: 6
}
//Right Y axis
ValueAxis{
id:right_y_axis
min:0
max:40
tickCount: 5
}
//Left Y axis
ValueAxis{
id:left_y_axis
min:0
max:40
tickCount: 5
}
//Line series for wave 1
LineSeries{
id:l1
axisY: left_y_axis
axisX:x_axis
color: "yellow"
width: 1
}
//Line series for wave 2
LineSeries{
id:l2
axisYRight: right_y_axis
style: Qt.DashLine
color: "yellow"
width: 0.6
}
}
Ok, you can use ChartView.mapToPosition to calculate the global position of the specified point from a series (or some another point inside the series), for example:
ChartView{
id:chart
anchors.fill: parent
backgroundColor: "black"
LineSeries{
id: series
XYPoint { x: 10; y: 5 }
XYPoint { x: 10; y: 1 }
XYPoint { x: 15; y: 5 }
XYPoint { x: 20; y: 10 }
XYPoint { x: 25; y: 5 }
XYPoint { x: 30; y: 20 }
XYPoint { x: 40; y: 10 }
}
Text {
id: txt
text: "Hello"
color: "white"
}
onWidthChanged: updatePointPosition();
onHeightChanged: updatePointPosition();
function updatePointPosition()
{
var p = chart.mapToPosition(series.at(3), series);
txt.x = p.x;
txt.y = p.y;
}
}
Related
I need scale and rotate a Rectangle around mouse point. When the Rectangle is not rotated my solution works fine, but if I apply Rotation transform I face the problem - my Rectangle move to an unexpected point. In my solution I use a MouseArea for drag the Rectangle, Scale and Rotation transforms for scale and rotate.
import QtQuick 2.0
Rectangle {
id: root
color: "gray"
Rectangle {
color: "black"
width: 360
height: 200
opacity: 0.5
x: 500
y: 350
}
Rectangle {
id: sample
color: "green"
width: 360
height: 200
opacity: 0.5
x: 500
y: 350
property real currX: 0
property real currY: 0
property real currZoom: 1
property real maxZoom: 5
property real minZoom: 0.5
transform: [
Scale {
id: scaler
origin.x: sample.currX
origin.y: sample.currY
xScale: sample.currZoom
yScale: sample.currZoom
},
Rotation{
id: rotation
origin.x: 180
origin.y: 100
angle: 30
}
]
MouseArea{
id: mouseArea
anchors.fill: parent
drag.target: sample
onClicked: mouse => {
zoom(true, mouse.x, mouse.y)
}
onWheel: (wheel) => {
var isIn = wheel.angleDelta.y > 0
zoom(isIn, wheel.x, wheel.y)
}
function zoom(isIn, x, y) {
var prevZoom = sample.currZoom
var prevX = sample.currX
var prevY = sample.currY
sample.currX = x
sample.currY = y
sample.currZoom = calculateZoom(isIn, prevZoom)
sample.x = sample.x + (prevX - sample.currX) * (1 - prevZoom)
sample.y = sample.y + (prevY - sample.currY) * (1 - prevZoom)
printSamplePostion()
}
function calculateZoom(isIn, prevZoom) {
var newZoom = isIn ? prevZoom + 0.1 : prevZoom - 0.1
if (newZoom > mouseArea.maxZoom)
newZoom = mouseArea.maxZoom
if (newZoom < mouseArea.minZoom)
newZoom = mouseArea.minZoom
return newZoom
}
function printSamplePostion() {
console.log("== x: 500 y: 350 ======")
console.log("-- x: " + sample.x)
console.log("-- y: " + sample.y)
console.log("=======================")
}
}
}
}
Thanks in advance
I have a qml Line Chart with DateTime X Axis and I need to measure time difference(dx) between two points similar to this chart
Here is the Chart code with sample data
ChartView {
id:chart
title: "Line"
anchors.fill: parent
antialiasing: true
DateTimeAxis {
id: axisX
format: "hh:mm:ss,ms"
tickCount: 10
}
ValueAxis {
id: axisY
min: 0
max: 10
}
LineSeries {
id:series1
name: "LineSeries"
axisX: axisX
axisY: axisY
pointsVisible: true
XYPoint { x: Date.parse("2020-10-09 05:51:00:500"); y: 0 }
XYPoint { x: Date.parse("2020-10-09 05:51:00:600"); y: 2 }
XYPoint { x: Date.parse("2020-10-09 05:52:00:100"); y: 4 }
XYPoint { x: Date.parse("2020-10-09 05:53:00:20"); y: 5 }
XYPoint { x: Date.parse("2020-10-09 05:54:00:200"); y: 8 }
XYPoint { x: Date.parse("2020-10-09 05:55:00:100"); y: 7 }
XYPoint { x: Date.parse("2020-10-09 05:56:00:200"); y: 6 }
XYPoint { x: Date.parse("2020-10-09 05:57:00:400"); y: 2 }
}
}
Any idea how to achieve this using QML or C++?
I roughly did like this. You should adjust time difference handling better.
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
property int rectangeXPosition: 0
property int rectangleYPosition: 0
property int rWidth: 0
property int rHeight: 0
property int minuteDiff: 0
ChartView {
id:chart
title: "Line"
anchors.fill: parent
antialiasing: true
Rectangle
{
x: rectangeXPosition
y: rectangleYPosition
width: rWidth
height: rHeight
color: "red"
opacity: 0.2
Text {
anchors.left: parent.right
anchors.top: parent.top
text: minuteDiff + " minutes"
}
}
MouseArea
{
anchors.fill: parent
onPositionChanged:
{
rWidth = mouse.x - rectangeXPosition
rHeight = mouse.y - rectangleYPosition
var currentPoint = chart.mapToValue(Qt.point(mouse.x, mouse.y), series1)
var startPoint = chart.mapToValue(Qt.point(rectangeXPosition,rectangleYPosition),series1)
var dateTimeDiff = new Date(currentPoint.x - startPoint.x)
minuteDiff = dateTimeDiff.getMinutes()
}
onPressed:
{
var point = Qt.point(mouse.x, mouse.y);
rectangeXPosition = point.x
rectangleYPosition = point.y
}
onReleased:
{
rectangeXPosition = 0
rectangleYPosition = 0
rWidth = 0
rHeight = 0
}
}
DateTimeAxis {
id: axisX
format: "hh:mm:ss,ms"
tickCount: 10
}
ValueAxis {
id: axisY
min: 0
max: 10
}
LineSeries {
id:series1
name: "LineSeries"
axisX: axisX
axisY: axisY
pointsVisible: true
XYPoint { x: Date.parse("2020-10-09 05:51:00:500"); y: 0 }
XYPoint { x: Date.parse("2020-10-09 05:51:00:600"); y: 2 }
XYPoint { x: Date.parse("2020-10-09 05:52:00:100"); y: 4 }
XYPoint { x: Date.parse("2020-10-09 05:53:00:20"); y: 5 }
XYPoint { x: Date.parse("2020-10-09 05:54:00:200"); y: 8 }
XYPoint { x: Date.parse("2020-10-09 05:55:00:100"); y: 7 }
XYPoint { x: Date.parse("2020-10-09 05:56:00:200"); y: 6 }
XYPoint { x: Date.parse("2020-10-09 05:57:00:400"); y: 2 }
}
}
}
I'm currently developping a qml application and I need to specify various area in the plotArea.
I'm drawing rectangles but my scatterseries dot are not visible because drawn behing the rectangle.
I tried to add transparency, or to set a z value somewhere but it is not giving a good result.
It is possible with qwidget qcharts and I'm looking to do the same in qml.
Here a working sample of code with my issue (if I comment the rectangles' part the dots are visible)
import QtQuick 2.15
import QtCharts 2.3
ChartView {
id: test
width: 600
height: 400
animationOptions: ChartView.NoAnimation
theme: ChartView.ChartThemeDark
legend.visible: false
ValueAxis {
id: axisX
min: 0
max: 100
}
ValueAxis {
id: axisY1
min: 0
max: 100
}
Rectangle {
id: rect1
color: "red"
border.width: 2
width: plotArea.width * 4 / 10
height: plotArea.height * 4/15
x: plotArea.x
y: plotArea.y
Text {
anchors.left: parent.left
anchors.leftMargin: 8
anchors.top: parent.top
anchors.topMargin: 8
text: qsTr("Rectangle 1")
}
}
Rectangle {
id: rect2
color: "orange"
border.width: 2
width: plotArea.width * 6 / 10
height: plotArea.height * 4 / 15
x: rect1.x + rect1.width
y: plotArea.y
Text {
anchors.left: parent.left
anchors.leftMargin: 8
anchors.top: parent.top
anchors.topMargin: 8
text: qsTr("Rectangle 2")
}
}
Rectangle {
id: rect3
color: "orange"
border.width: 2
width: plotArea.width * 4 / 10
height: plotArea.height * 7 / 15
x: plotArea.x
y: rect1.y + rect1.height
Text {
anchors.left: parent.left
anchors.leftMargin: 8
anchors.top: parent.top
anchors.topMargin: 8
text: qsTr("Rectangle 3")
}
}
Rectangle {
id: rect4
color: "green"
border.width: 2
width: plotArea.width * 6 / 10
height: plotArea.height * 7 / 15
x: rect3.x + rect3.width
y: rect3.y
Text {
anchors.left: parent.left
anchors.leftMargin: 8
anchors.top: parent.top
anchors.topMargin: 8
text: qsTr("Rectangle 4")
}
}
Rectangle {
id: rect5
color: "gray"
width: plotArea.width
height: plotArea.height * 4 / 15
x: plotArea.x
y: rect3.y + rect3.height
border.color: "black"
border.width: 2
}
ScatterSeries {
axisX: axisX
axisY: axisY1
color: "blue"
XYPoint {
x: 10
y: 10
}
XYPoint {
x: 98
y: 5
}
XYPoint {
x: 95
y: 89
}
XYPoint {
x: 5
y: 75
}
markerShape: ScatterSeries.MarkerShapeRectangle
}
}
I didn't find a solution on the documentation or online.
The closed question I found is Qml ChartView with sections for X Axis points but they was no answer
I found a solution by drawing AreaSeries.
import QtQuick 2.15
import QtCharts 2.3
ChartView {
id: test
width: 600
height: 400
animationOptions: ChartView.SeriesAnimations
theme: ChartView.ChartThemeDark
legend.visible: false
ValueAxis {
id: axisX
min: 0
max: 100
}
ValueAxis {
id: axisY1
min: 0
max: 100
}
AreaSeries{
axisX: axisX
axisY: axisY1
color: "red"
upperSeries: LineSeries {
XYPoint { x: 0; y: 50}
XYPoint { x: 75; y: 50}
}
lowerSeries: LineSeries {
XYPoint { x: 0; y: 0}
XYPoint { x: 75; y: 0}
}
}
AreaSeries{
axisX: axisX
axisY: axisY1
color: "orange"
upperSeries: LineSeries {
XYPoint { x: 75; y: 50}
XYPoint { x: 100; y: 50}
}
lowerSeries: LineSeries {
XYPoint { x: 75; y: 0}
XYPoint { x: 100; y: 0}
}
}
AreaSeries{
axisX: axisX
axisY: axisY1
color: "green"
upperSeries: LineSeries {
XYPoint { x: 0; y: 100}
XYPoint { x: 100; y: 100}
}
lowerSeries: LineSeries {
XYPoint { x: 0; y: 50}
XYPoint { x: 100; y: 50}
}
}
ScatterSeries {
axisX: axisX
axisY: axisY1
color: "blue"
XYPoint {
x: 10
y: 10
}
XYPoint {
x: 98
y: 5
}
XYPoint {
x: 95
y: 89
}
XYPoint {
x: 5
y: 75
}
markerShape: ScatterSeries.MarkerShapeRectangle
}
}
I have set a custom tooltip using the code
ChartView {
id: chart
anchors.fill: parent
antialiasing: true
ValueAxis {
id: axisY
tickCount: 3
}
DateTimeAxis{
id: xTime
gridVisible: false
}
ToolTip {
id: id_toolTip
contentItem: Text{
color: "#21be2b"
}
background: Rectangle {
border.color: "#21be2b"
}
}
SplineSeries{
id: chartseries
pointsVisible: true
pointLabelsVisible: false
useOpenGL: true
axisX: xTime
axisY: axisY
onClicked: {
id_toolTip.show("dd")
}
}
}
It gives an error when I click on the graph ..
TypeError: Property 'show' of object QQuickToolTip(0x37275d0) is not a function"
But below mentioned code will work.
chart.ToolTip.show("dd")
But I need custom tooltip
You can use the other properties as I show below:
ChartView {
id: chart
anchors.fill: parent
antialiasing: true
ValueAxis {
id: axisY
tickCount: 3
max: 4
min: 0
}
DateTimeAxis{
id: xTime
gridVisible: false
}
ToolTip {
id: id_tooltip
contentItem: Text{
color: "#21be2b"
text: id_tooltip.text
}
background: Rectangle {
border.color: "#21be2b"
}
}
SplineSeries{
id: chartseries
XYPoint { x: new Date('December 17, 1995 03:24:00').getTime() ; y: 0.0 }
XYPoint { x: new Date('December 18, 1995 04:25:00').getTime() ; y: 3.2 }
XYPoint { x: new Date('December 19, 1995 05:26:00').getTime() ; y: 2.4 }
XYPoint { x: new Date('December 20, 1995 06:27:00').getTime() ; y: 2.1 }
XYPoint { x: new Date('December 21, 1995 07:24:00').getTime() ; y: 0.0 }
XYPoint { x: new Date('December 22, 1995 08:25:00').getTime() ; y: 3.2 }
XYPoint { x: new Date('December 23, 1995 09:26:00').getTime() ; y: 2.4 }
XYPoint { x: new Date('December 24, 1995 10:27:00').getTime() ; y: 2.1 }
pointsVisible: true
pointLabelsVisible: false
useOpenGL: true
axisX: xTime
axisY: axisY
onClicked: {
var p = chart.mapToPosition(point)
var text = qsTr("x: %1, y: %2").arg(new Date(point.x).toLocaleDateString(Qt.locale("en_US"))).arg(point.y)
id_tooltip.x = p.x
id_tooltip.y = p.y - id_tooltip.height
id_tooltip.text = text
//id_tooltip.timeout = 1000
id_tooltip.visible = true
}
}
}
In the first case, id_toolTip.show("dd") , you try to call the show func of the instantiated version of QML::Tooltip whereas at the second case, chart.ToolTip.show("dd") you call the show function of the attached property Tooltip which exists for all the qml controls.
Acccording to the docs, if you don't provide a second parameter, then this means that show() is the func of the shared tooltip and not the one you instantiate. That might be the reason your code does not work.
How to change color of one particular point in chartview in qml.i.e now all x axis values are displaying in black color but i want odd number to be displayed in red color.I want as shown in image where label colors in y axis are of different colors.
here is my piece of code
ChartView {
id:chartView
width: 2*horizontalList.width
height:horizontalList.height
antialiasing: true
animationOptions: ChartView.SeriesAnimations
legend.visible:false
ValueAxis {
id: scaleAxisX
min: 0
max: pointsX.length
tickCount: pointsX.length+1
labelFormat: "%.0f"
titleVisible: false
gridVisible: true
}
ValueAxis {
id: scaleAxisY
min: 0
max: 1.0
tickCount: 6
//labelFormat: "%.0f"
titleVisible: false
gridVisible: false
labelsVisible: false
labelsColor: "#757575"
}
ScatterSeries {
id: scatterSeries
axisXTop: scaleAxisX
axisY: scaleAxisY
color: "black"
markerSize: 12
}
}
As shown in second image ,the top line with red circle is a X axis(valueAxis) of chartview.i want to make the number inside the red circle to be in red color.
You can add a different ScatterSeries with color value;
import QtQuick 2.0
import QtCharts 2.0
ChartView {
title: "Scatters"
anchors.fill: parent
antialiasing: true
ScatterSeries {
color: "black"
id: scatter1
name: "Scatter1"
XYPoint { x: 1; y: 1 }
XYPoint { x: 2; y: 2 }
XYPoint { x: 3; y: 3 }
XYPoint { x: 4; y: 4 }
}
ScatterSeries {
color: "red"
name: "Scatter2"
XYPoint { x: 1.5; y: 1.5 }
}
}