example / ui_capno / main.qml
main.qml
Raw
import QtQuick 2.12
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import QtCharts 2.15
import QtQuick.Window 2.12

ApplicationWindow {
    visible: true
    width: 1024
    height: 768
    title: qsTr("MainStream EtCO2 Monitor")

    property var dataPoints: []
    property var dataSeries: []
    property int maxPoints: 400
    property int currentIndex: 0
    property int maxSeries: 2
    property bool replacing: false

    Rectangle {
        id: root
        anchors.fill: parent
        color: "black"

        Rectangle {
            id: header
            anchors {
                top: parent.top
                left: parent.left
                right: parent.right
            }
            height: parent.height * 0.15
            color: "black"

            Rectangle {
                id: titleRect
                anchors {
                    top: parent.top
                    left: parent.left
                    right: parent.right
                }
                height: header.height * 0.5
                color: "black"

                Text {
                    id: titleLabel
                    text: qsTr("MainStream EtCO2 Monitor")
                    color: "#ffff00"
                    anchors.centerIn: parent
                    font.pixelSize: 32
                    font.family: "Arial"
                    font.bold: true
                }
            }

            Rectangle {
                id: subHeaderRow
                anchors {
                    top: titleRect.bottom
                    left: parent.left
                    right: parent.right
                }
                height: header.height * 0.5
                color: "black"

                Rectangle {
                    id: versionRect
                    anchors {
                        top: parent.top
                        left: parent.left
                        bottom: parent.bottom
                    }
                    width: parent.width * 0.5
                    color: "black"

                    Text {
                        id: versionLabel
                        text: "Version: 1  Test OK!"
                        color: "orange"
                        anchors.centerIn: parent
                        font.pixelSize: 14
                        font.family: "Arial"
                    }
                }

                Rectangle {
                    id: dateTimeRect
                    anchors {
                        top: parent.top
                        right: parent.right
                        bottom: parent.bottom
                    }
                    width: parent.width * 0.5
                    color: "black"

                    Label {
                        id: dateTimeLabel
                        text: "2024-07-09 09:41:28"
                        color: "orange"
                        anchors.centerIn: parent
                        font.pixelSize: 14
                        font.family: "Arial"
                    }
                }
            }
        }

        Rectangle {
            id: mainContent
            anchors {
                top: header.bottom
                left: parent.left
                right: parent.right
                bottom: parent.bottom
            }
            color: "black"

            Rectangle {
                id: left
                anchors {
                    top: parent.top
                    left: parent.left
                    bottom: parent.bottom
                }
                width: parent.width * 0.3
                color: "black"


                // EtCO2 / FiCO2
                Rectangle {
                    id: etco2Rect
                    anchors {
                        top: parent.top
                        left: parent.left
                        right: parent.right
                    }
                    height: parent.height * 0.30
                    color: "black"

                    Rectangle {
                        id: etco2Column
                        anchors.fill: parent
                        color: "black"

                        Text {
                            id: etco2Label
                            text: "EtCO2 / FiCO2"
                            color: "#00ff95"
                            font.pixelSize: 18
                            font.family: "Arial"
                            anchors{
                                left: parent.left
                                leftMargin: 10
                                top: parent.top
                                topMargin: 10
                            }
                        }

                        Text {
                            id: etco2Value
                            text: "--"
                            color: "#00ff95"
                            font.pixelSize: 48
                            font.family: "Arial"
                            font.bold: true
                            anchors{
                                right: separadorCO2.left
                                top: etco2Label.bottom
                                topMargin: 20
                            }
                        }

                        Text {
                            id: separadorCO2
                            text: " / "
                            color: "#00ff95"
                            font.pixelSize: 48
                            font.family: "Arial"
                            font.bold: true
                            anchors{
                                horizontalCenter: parent.horizontalCenter
                                top: etco2Label.bottom
                                topMargin: 20
                            }
                        }

                        Text {
                            id: fiCO2Value
                            text: "--"
                            color: "#00ff95"
                            font.pixelSize: 48
                            font.family: "Arial"
                            font.bold: true
                            anchors{
                                left: separadorCO2.right
                                top: etco2Label.bottom
                                topMargin: 20
                            }
                        }

                        Text {
                            id: etco2Unit
                            text: "mmHg"
                            color: "#00ff95"
                            font.pixelSize: 18
                            font.family: "Arial"
                            anchors{
                                right: parent.right
                                rightMargin: 30
                                top: etco2Value.bottom
                                topMargin: 20
                            }
                        }
                        border.color: "white"
                    }
                }

                // AwRR
                Rectangle {
                    id: awrrRect
                    anchors {
                        top: etco2Rect.bottom
                        left: parent.left
                        right: parent.right
                    }
                    height: parent.height * 0.30
                    color: "black"

                    Rectangle {
                        id: awrrColumn
                        anchors.fill: parent
                        color: "black"

                        Text {
                            id: awrrLabel
                            text: "AwRR"
                            color: "#e11508"
                            font.pixelSize: 18
                            font.family: "Arial"
                            anchors{
                                left: parent.left
                                leftMargin: 20
                                top: parent.top
                                topMargin: 10
                            }
                        }

                        Text {
                            id: awrrValue
                            text: "0"
                            color: "#e11508"
                            font.pixelSize: 48
                            font.family: "Arial"
                            font.bold: true
                            anchors{
                                horizontalCenter: parent.horizontalCenter
                                top: awrrLabel.bottom
                                topMargin: 20
                            }
                        }

                        Text {
                            id: awrrUnit
                            text: "rpm"
                            color: "#e11508"
                            font.pixelSize: 18
                            font.family: "Arial"
                            anchors{
                                right: parent.right
                                rightMargin: 30
                                top: awrrValue.bottom
                                topMargin: 20
                            }
                        }
                        border.color: "white"
                    }
                }

                // EtO2 / FiO2
                Rectangle {
                    id: etO2Rect
                    anchors {
                        top: awrrRect.bottom
                        left: parent.left
                        right: parent.right
                    }
                    height: parent.height * 0.30
                    color: "black"

                    Rectangle {
                        id: etO2Column
                        anchors.fill: parent
                        color: "black"

                        Text {
                            id: etO2Label
                            text: "EtO2 / FiO2"
                            color: "#fdffff"
                            font.pixelSize: 18
                            font.family: "Arial"
                            anchors{
                                left: parent.left
                                leftMargin: 20
                                top: parent.top
                                topMargin: 10
                            }
                        }

                        Text {
                            id: etO2Value
                            text: "--"
                            color: "#fdffff"
                            font.pixelSize: 48
                            font.family: "Arial"
                            font.bold: true
                            anchors{
                                right: separadorO2.left
                                top: etO2Label.bottom
                                topMargin: 20
                            }
                        }

                        Text {
                            id: separadorO2
                            text: " / "
                            color: "#fdffff"
                            font.pixelSize: 48
                            font.family: "Arial"
                            font.bold: true
                            anchors{
                                horizontalCenter: parent.horizontalCenter
                                top: etO2Label.bottom
                                topMargin: 20
                            }
                        }

                        Text {
                            id: fiO2Value
                            text: "--"
                            color: "#fdffff"
                            font.pixelSize: 48
                            font.family: "Arial"
                            font.bold: true
                            anchors{
                                left: separadorO2.right
                                top: etO2Label.bottom
                                topMargin: 20
                            }
                        }

                        Text {
                            id: etO2Unit
                            text: "%"
                            color: "#fdffff"
                            font.pixelSize: 18
                            font.family: "Arial"
                            anchors{
                                right: parent.right
                                rightMargin: 30
                                top: etO2Value.bottom
                                topMargin: 20
                            }
                        }
                        border.color: "white"
                    }

                }

                Rectangle {
                    id: statusRect
                    anchors {
                        top: etO2Rect.bottom
                        left: parent.left
                        right: parent.right
                        bottom: parent.bottom
                        bottomMargin: 10
                    }
                    color: "black"
                    Text {
                        id: statusLabel
                        text: "apnea"
                        color: "#c200ac"
                        font.pixelSize: 20
                        font.family: "Arial"
                        anchors{
                            horizontalCenter: parent.horizontalCenter
                            top: parent.top
                            topMargin: 15
                        }
                    }
                    border.color: "white"
                }
            }


            Rectangle {
                id: right
                anchors {
                    top: parent.top
                    right: parent.right
                    rightMargin: 10
                    bottom: parent.bottom
                    bottomMargin: 10
                }
                width: parent.width * 0.7
                color: "black"

                Rectangle {
                    id: graph1
                    anchors {
                        top: parent.top
                        left: parent.left
                        right: parent.right
                    }
                    height: parent.height * 0.5
                    color: "black"
                    border.color: "white"

                    Text {
                        id: graph1Title
                        text: "Capnography / mmHg"
                        color: "#00ff95"
                        anchors {
                            top: parent.top
                            horizontalCenter: parent.horizontalCenter
                            topMargin: 10
                        }
                        font.pixelSize: 20
                        font.family: "Arial"
                    }

                    Text {
                        id: realTimeData
                        text: "--"
                        color: "#00ff95"
                        anchors {
                            top: parent.top
                            topMargin: 10
                            right: realTimeDataUnits.left
                            rightMargin: 5
                        }
                        font.pixelSize: 15
                        font.family: "Arial"
                    }

                    Text {
                        id: realTimeDataUnits
                        text: " mmHg"
                        color: "#00ff95"
                        anchors {
                            top: parent.top
                            topMargin: 10
                            right: parent.right
                            rightMargin: 10
                        }
                        font.pixelSize: 15
                        font.family: "Arial"
                    }

                    Row {
                        anchors {
                            top: graph1Title.bottom
                            left: parent.left
                            leftMargin: 10
                            bottom: parent.bottom
                            bottomMargin: 10
                        }
                        spacing: 10
                        Column {
                            spacing: 11
                            Repeater {
                                model: 11
                                Text {
                                    text: 100 - index * 10
                                    color: "#ffff00"
                                    font.pixelSize: 14
                                    font.family: "Arial"
                                }
                            }
                        }

                        Column {
                            spacing: (parent.height) / 60
                            Repeater {
                                model: 51
                                Rectangle {
                                    width: index % 5 == 0 ? 15 : 10
                                    height: 1
                                    color: "#ffff00"
                                }
                            }
                        }
                    }

                    Canvas {
                        id: canvas
                        anchors.fill: parent
                        onPaint: {
                            var ctx = getContext("2d");
                            ctx.clearRect(0, 0, width, height);

                            ctx.strokeStyle = "blue";
                            ctx.lineWidth = 2;
                            ctx.beginPath();

                            var scaleX = width / maxPoints;
                            var scaleY = height / 100;

                            if (dataPoints.length > 0) {
                                for (var i = 0; i < dataPoints.length; i++) {
                                    var x = 62 + (i % maxPoints) * scaleX;
                                    var y = height - 5 - dataPoints[i] * scaleY;
                                    if (i === 0 || (i === currentIndex && replacing)) {
                                        ctx.moveTo(x, y);
                                    } else if ((i === currentIndex - 1 && replacing) || (i === (currentIndex - 2 + maxPoints) % maxPoints && replacing)){
                                        ctx.moveTo(x, y);
                                    } else {
                                        ctx.lineTo(x, y);
                                    }
                                }
                            }
                            ctx.stroke();
                        }
                    }

                    Connections {
                        target: capnograph
                        function onYValueChanged(newValueY) {
                            realTimeData.text = newValueY;
                            replacing = dataPoints.length >= maxPoints;
                            if (replacing) {
                                dataPoints[currentIndex] = newValueY;
                            } else {
                                dataPoints.push(newValueY);
                            }
                            // Incrementar el índice actual y reiniciarlo si alcanza el límite
                            currentIndex = (currentIndex + 1) % maxPoints;
                            canvas.requestPaint();
                        }
                    }
                }

                Rectangle {
                    id: graph2
                    anchors {
                        top: graph1.bottom
                        left: parent.left
                        right: parent.right
                        bottom: parent.bottom
                    }
                    color: "black"
                    border.color: "white"

                    Text {
                        id: graph2Title
                        text: "O2 / %"
                        color: "#00ff95"
                        anchors {
                            top: parent.top
                            horizontalCenter: parent.horizontalCenter
                            topMargin: 10
                        }
                        font.pixelSize: 20
                        font.family: "Arial"
                    }

                    Row {
                        anchors {
                            top: graph2Title.bottom
                            left: parent.left
                            leftMargin: 10
                            bottom: parent.bottom
                            bottomMargin: 10
                        }
                        spacing: 10
                        Column {
                            spacing: 12
                            Repeater {
                                model: 11
                                Text {
                                    text: 100 - index * 10
                                    color: "#ffff00"
                                    font.pixelSize: 14
                                    font.family: "Arial"
                                }
                            }
                        }

                        Column {
                            spacing: (parent.height) / 60
                            Repeater {
                                model: 51
                                Rectangle {
                                    width: index % 5 == 0 ? 15 : 10
                                    height: 1
                                    color: "#ffff00"
                                }
                            }
                        }
                    }
                }
            }



        }
    }

    Connections {
        target: capnograph
        function onDataPacket84(etco2, insco2, awrr, eto2, inso2) {
            etco2Value.text = etco2
            fiCO2Value.text = insco2
            awrrValue.text = awrr
            etO2Value.text = eto2
            fiO2Value.text = inso2
        }
    }

    Timer {
        interval: 1000;
        running: true;
        repeat: true
        onTriggered: {
            var date = new Date();
            var hours = date.getHours().toString().padStart(2, '0');
            var minutes = date.getMinutes().toString().padStart(2, '0');
            var seconds = date.getSeconds().toString().padStart(2, '0');
            var day = date.getDate().toString().padStart(2, '0');
            var month = (date.getMonth() + 1).toString().padStart(2, '0');
            var year = date.getFullYear();
            dateTimeLabel.text = year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds;
        }
    }
}

/*
Ir guardando los puntos en un arreglo y se quedan estaticos hasta que su valor en x vuelva a ser 0
Y no se borran
Connections {
    target: capnograph
    function onXValueChanged(newValueX) {
        // console.log("New data received X: ", newValueX);
        //dataPoints.push({ xValue: capnograph.xValue, yValue: capnograph.yValue });
        //console.log(dataPoints)
        //if (newValueX === 100) {
        //    scaleX = 0;
        //    points.shift(); // Mantener solo los últimos 100 puntos
        //}
        canvas.requestPaint();
    }
}

Connections {
    target: capnograph
    function onYValueChanged(newValueY) {
        //console.log("New data received Y: ", newValueY);
        realTimeData.text = newValueY
        dataPoints.push(newValueY);
        if (dataPoints.length == 300) {
            //dataPoints.shift(); // Mantener solo los últimos 100 puntos
            //dataPoints = []
            //scaleX = 0
            // de este código es necesario identificar el primer punto en el eje x en el que se grafica y el último del límite
            // cuando llegue al valor límite empieza a graficar desde el inicio.
            for (var i = 0; i < dataPoints.length; i++) {
                dataPoints[i] = newValueY
            }
        }
        canvas.requestPaint();
    }
}
*/