202 lines · 7.1 KB · Text
RawDownload
////  PlotPerf.qml//  examples/utilities/render/plotperf////  Created by Sam Gateau on 3//2016//  Copyright 2016 High Fidelity, Inc.////  Distributed under the Apache License, Version 2.0.//  See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html//import QtQuick 2.5import QtQuick.Controls 1.4 Item {    id: root    width: parent.width    height: 100     // The title of the graph    property string title     // The object used as the default source object for the prop plots    property var object     // Plots is an array of plot descriptor    // a default plot descriptor expects the following object:    //     prop: [ {    //                object: {}             // Optional: this is the object from which the prop will be fetched,     //                                          if nothing than the object from root is used    //                prop:"bufferCPUCount", // Needed the name of the property from the object to feed the plot    //                label: "CPU",          // Optional: Label as displayed on the plot    //                color: "#00B4EF"       // Optional: Color of the curve    //                unit: "km/h"           // Optional: Unit added to the value displayed, if nothing then the default unit is used    //                scale: 1               // Optional: Extra scaling used to represent the value, this scale is combined with the global scale.    //            },    property var plots     // Default value scale used to define the max value of the chart    property var valueScale: 1     // Default value unit appended to the value displayed    property var valueUnit: ""     // Default number of digits displayed    property var valueNumDigits: 0         property var valueMax : 1     property var _values : new Array()    property var tick : 0     function createValues() {        for (var i =0; i < plots.length; i++) {            var plot = plots[i];            _values.push( {                object: (plot["object"] !== undefined ? plot["object"] : root.object),                value: plot["prop"],                valueMax: 1,                numSamplesConstantMax: 0,                valueHistory: new Array(),                label: (plot["label"] !== undefined ? plot["label"] : ""),                color: (plot["color"] !== undefined ? plot["color"] : "white"),                scale: (plot["scale"] !== undefined ? plot["scale"] : 1),                unit: (plot["unit"] !== undefined ? plot["unit"] : valueUnit)            })        }        pullFreshValues();    }     Component.onCompleted: {        createValues();       }     function pullFreshValues() {        // Wait until values are created to begin pulling        if (!_values) { return; }         var VALUE_HISTORY_SIZE = 100;        tick++;         var currentValueMax = 0        for (var i = 0; i < _values.length; i++) {             var currentVal = (+_values[i].object[_values[i].value]) * _values[i].scale;             _values[i].valueHistory.push(currentVal)            _values[i].numSamplesConstantMax++;             if (_values[i].valueHistory.length > VALUE_HISTORY_SIZE) {                var lostValue = _values[i].valueHistory.shift();                if (lostValue >= _values[i].valueMax) {                    _values[i].valueMax *= 0.99                    _values[i].numSamplesConstantMax = 0                }            }             if (_values[i].valueMax < currentVal) {                _values[i].valueMax = currentVal;                _values[i].numSamplesConstantMax = 0             }                                 if (_values[i].numSamplesConstantMax > VALUE_HISTORY_SIZE) {                _values[i].numSamplesConstantMax = 0                     _values[i].valueMax *= 0.95 // lower slowly the current max if no new above max since a while                                  }             if (currentValueMax < _values[i].valueMax) {                currentValueMax = _values[i].valueMax            }        }         if ((valueMax < currentValueMax) || (tick % VALUE_HISTORY_SIZE == 0)) {            valueMax = currentValueMax;        }         mycanvas.requestPaint()    }     Timer {        interval: 100; running: true; repeat: true        onTriggered: pullFreshValues()    }     Canvas {        id: mycanvas        anchors.fill:parent        onPaint: {            var lineHeight = 12;             function displayValue(val, unit) {                 return (val / root.valueScale).toFixed(root.valueNumDigits) + " " + unit            }             function pixelFromVal(val, valScale) {                return lineHeight + (height - lineHeight) * (1 - (0.9) * val / valueMax);            }            function valueFromPixel(pixY) {                return ((pixY - lineHeight) / (height - lineHeight) - 1) * valueMax / (-0.9);            }            function plotValueHistory(ctx, valHistory, color) {                var widthStep= width / (valHistory.length - 1);                 ctx.beginPath();                ctx.strokeStyle= color; // Green path                ctx.lineWidth="2";                ctx.moveTo(0, pixelFromVal(valHistory[0]));                                    for (var i = 1; i < valHistory.length; i++) {                     ctx.lineTo(i * widthStep, pixelFromVal(valHistory[i]));                 }                 ctx.stroke();            }            function displayValueLegend(ctx, val, num) {                ctx.fillStyle = val.color;                var bestValue = val.valueHistory[val.valueHistory.length -1];                             ctx.textAlign = "right";                ctx.fillText(displayValue(bestValue, val.unit), width, (num + 2) * lineHeight * 1);                ctx.textAlign = "left";                ctx.fillText(val.label, 0, (num + 2) * lineHeight * 1);            }             function displayTitle(ctx, text, maxVal) {                ctx.fillStyle = "grey";                ctx.textAlign = "right";                ctx.fillText(displayValue(valueFromPixel(lineHeight), root.valueUnit), width, lineHeight);                                ctx.fillStyle = "white";                ctx.textAlign = "left";                ctx.fillText(text, 0, lineHeight);            }            function displayBackground(ctx) {                ctx.fillStyle = Qt.rgba(0, 0, 0, 0.6);                ctx.fillRect(0, 0, width, height);                                ctx.strokeStyle= "grey";                ctx.lineWidth="2";                 ctx.beginPath();                ctx.moveTo(0, lineHeight + 1);                 ctx.lineTo(width, lineHeight + 1);                 ctx.moveTo(0, height);                 ctx.lineTo(width, height);                 ctx.stroke();            }                        var ctx = getContext("2d");            ctx.clearRect(0, 0, width, height);            ctx.font="12px Verdana";             displayBackground(ctx);                            for (var i = 0; i < _values.length; i++) {                plotValueHistory(ctx, _values[i].valueHistory, _values[i].color)                displayValueLegend(ctx, _values[i], i)            }             displayTitle(ctx, title, valueMax)        }    }}