bernii / gauge.js

100% native and cool looking JavaScript gauge
MIT License
1.42k stars 391 forks source link

Changing maxValue doesn't refresh graph until `set` is called with the actual value #234

Closed tomekit closed 3 years ago

tomekit commented 3 years ago

I need to dynamically update gauge chart when getting data from AJAX request. It does seem that if maxValue is being set: gauge.maxValue = maxValue; it doesn't always update the graph. However if you call the gauge.set(newActualValue) after maxValue is being set then the graph always update correctly.

In my use case I often need to update the maxValue without updating the actualValue, which leads to stale gauge chart.

Please find below example which illustrate this issue:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="http://bernii.github.io/gauge.js/dist/gauge.min.js"></script>

</head>
<body>
<h1>Gauge JS</h1>
<div>
    <canvas id="foo">

    </canvas>
    <p>url: <a href="http://bernii.github.io/gauge.js/">gauge.js</a></p>
</div>

<script type="text/javascript">
    var opts = {
        angle: 0, // The span of the gauge arc
        lineWidth: 0.2, // The line thickness
        radiusScale: 0.89, // Relative radius
        pointer: {
            length: 0.54, // // Relative to gauge radius
            strokeWidth: 0.053, // The thickness
            color: '#000000' // Fill color
        },
        limitMax: false,     // If false, max value increases automatically if value > maxValue
        limitMin: false,     // If true, the min value of the gauge will be fixed
        colorStart: '#6FADCF',   // Colors
        colorStop: '#8FC0DA',    // just experiment with them
        strokeColor: '#E0E0E0',  // to see which ones work best for you
        generateGradient: true,
        highDpiSupport: true,     // High resolution support
        staticZones: [
            {strokeStyle: "#00FF00", min: 0, max: 60}, // Red from 100 to 60
            {strokeStyle: "#0000FF", min: 60, max: 150}, // Yellow
            {strokeStyle: "#00FFFF", min: 150, max: 220}, // Green
            {strokeStyle: "#FFDD00", min: 220, max: 260}, // Yellow
            {strokeStyle: "#FF0000", min: 260, max: 300}  // Red
        ],

    };
    var target = document.getElementById('foo'); // your canvas element
    var gauge = new Gauge(target).setOptions(opts); // create sexy gauge!

    var maxValue = 300;
    gauge.maxValue = maxValue; // set max gauge value
    gauge.setMinValue(0);  // Prefer setter over gauge.minValue = 0
    gauge.animationSpeed = 50; // set animation speed (32 is default value)

    var actualValue = 20;
    gauge.set(actualValue); // set actual value

    setInterval(function () {
        maxValue = maxValue + 5; // Increment maxValue
        gauge.maxValue = maxValue; // Set graph maxValue
        console.log("Max: " + maxValue);

        // When you change the actualValue along with the maxValue, then the maxValue is being updated correctly on graph
        /*
         actualValue = actualValue + 10; // Increment actualValue
           gauge.set(actualValue); // Set graph actualValue
           console.log("Actual: " + actualValue);*/
    }, 1000);

</script>
</body>
</html>

Graph is being update after first few maxValue changes, then it becomes stale. However if you uncomment lines which set the actualValue, then it keeps being updated indefinitely.

Is there any way to force refresh graph? I was trying to make bogus change of actualValue:

gauge1.set(13377331); // maxValue force refresh hack
gauge1.set(myRealActualValue);

but it turns out it doesn't help.

tomekit commented 3 years ago

I was playing with using set with some random small fraction value using the setTimeout and it indeed helped force refreshing graphs, but ultimately was too hacky and too buggy.

Since I didn't need the exact values displayed on the graph, I've decided to leave the maxValue alone and change the needle using the percentage calculated and set using the set method. Simple approach change, but solved my issue.