John Verber
John Verber

Reputation: 755

How to keep highcharts speedometer within range

I'm working on a dynamically loaded speedometer. Beyond my troubles with Ajax calls in conjunction with the speedometer, I have trouble keeping the 'needle' within the range (0-20). The integer output shows a number less than or greater than 20 as the needle spins past 0 or 20 in the wrong direction. I would like to keep it to the right of 0 and the left of 20. My code:

<!DOCTYPE HTML>
<html>
        <head>
                <meta http-equiv="content-type" content="text/html; charset=UTF-8" >
                <title>Tribble Inc Sales Meter</title>

                <script type="text/javascript" src="jquery-1.8.2.min.js"></script>
                <script type="text/javascript">
$(function () {

    var chart = new Highcharts.Chart({

            chart: {
                renderTo: 'container',
                type: 'gauge',
                plotBackgroundColor: null,
                plotBackgroundImage: null,
                plotBorderWidth: 0,
                plotShadow: false
            },

            title: {
                text: 'Sales-O-Meter'
            },

            pane: {
                startAngle: -150,
                endAngle: 150,
                background: [{
                    backgroundColor: {
                        linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
                        stops: [
                            [0, '#FFF'],
                            [1, '#333']
                        ]
                    },
                    borderWidth: 0,
                    outerRadius: '109%'
                }, {
                    backgroundColor: {
                        linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
                        stops: [
                            [0, '#333'],
                            [1, '#FFF']
                        ]
                    },
                    borderWidth: 1,
                    outerRadius: '107%'
                }, {
                    // default background
                }, {
                    backgroundColor: '#DDD',
                    borderWidth: 0,
                    outerRadius: '105%',
                    innerRadius: '103%'
                }]
            },

            // the value axis
            yAxis: {
                min: 0,
                max: 20,

                minorTickInterval: 'auto',
                minorTickWidth: 1,
                minorTickLength: 10,
                minorTickPosition: 'inside',
                minorTickColor: '#666',

                tickPixelInterval: 20,
                tickWidth: 2,
                tickPosition: 'inside',
                tickLength: 1,
                tickColor: '#666',
                labels: {
                    step: 2,
                    rotation: 'auto'
                },
                title: {
                    text: 'sales/min'
                },
                plotBands: [{
                    from: 0,
                    to: 4,
                    color: '#DF5353' // green
                }, {
                    from: 4,
                    to: 8,
                    color: '#DDDF0D' // yellow
                }, {
                    from: 8,
                    to: 20,
                    color: '#55BF3B' // red
                }]
            },

            series: [{
                name: 'Speed',
                data: [18],
                tooltip: {
                    valueSuffix: ' km/h'
                }
            }]

        },
        // Add some life
        function (chart) {
            setInterval(function () {
                var point = chart.series[0].points[0],
                    newVal,
                    inc = Math.floor((Math.random() - 1) * 20);

                newVal = point.y + inc;
                if (newVal < 0 || newVal > 20) {
                    newVal = point.y - inc;
                }

                point.update(newVal);

            }, 3000);
        });
});
                </script>
        </head>
        <body>
<script src="highcharts.js"></script>
<script src="highcharts-more.js"></script>
<!--<script src="exporting.js"></script>-->

<div id="container" style="width: 500px; height: 400px; margin: 0 auto"></div>

        </body>
</html>

I'm not entirely sure what I'm doing wrong...perhaps the Math.floor() function is off but I don't think so. Can someone help out?

Upvotes: 0

Views: 965

Answers (1)

SteveP
SteveP

Reputation: 19103

                    inc = Math.floor((Math.random() - 1) * 20);

            newVal = point.y + inc;
            if (newVal < 0 || newVal > 20) {
                newVal = point.y - inc;

This code generates a negative inc, adds it to point, making point negative, and then subtracts it to point, making point more positive. It goes wrong because inc can be larger than point.

The algorithm you need depends on how you want the chart to vary. If you want the needle to wobble, then generate a smaller inc, add it to point and then bounds check it.

                    inc = (Math.random() * 2.0)-1.0;

            newVal = point.y + inc;
            if (newVal < 0 || newVal > 20) {
                newVal = point.y - inc;

Upvotes: 1

Related Questions