javascript - 在每个数组绘图后更新图表,Highcharts

标签 javascript php ajax highcharts

我正在尝试从服务器端加载数据并将它们一一显示在 Highcharts 中。

但在将它们显示在 Highchart 上之前,我会对数据进行一些处理,然后将其渲染到 Highcharts 中。

我使用 AJAX,这样我每次都可以获取数据,而无需刷新页面并重新加载图表。

图表对于第一组数据运行良好,然后显示未定义,并且图表未显示任何下一组数据。

这里有 random.php 文件,我用它来获取数据:

header("Content-type: text/json");

$data = [];
for($i=0; $i<500; $i++)
{
    $data[] = rand(0,10);  
}

$into_mysql = json_encode($data);

echo $into_mysql;

现在我正在获取其他页面图表中的数据:

var chart;
// Prototype to Request Data using `AJAX`
function requestData() {
    $.ajax({
        url: 'random.php',
        async: false,
        success: function (data) {
            y = data;
            console.log(y);
            return (y);
        }
    });
}


// Fetch the data from the `requestData` and process it.
function fetch() {
    requestData();
    var divisor = 2;
    var count = 0;
    for (var i = 0, length = y.length; i < length; i++) {
        y[i] /= divisor;
    }
    console.log(y);
    return (y);
    setInterval(function () { requestData }, 1000);
}

var json_array = fetch();

var i = 0;
function next() {

    return json_array[i++];
    // i++;

}

Highcharts.chart('container', {
    chart: {
        type: 'line',
        animation: Highcharts.svg, // don't animate in old IE
        marginRight: 10,
        events: {
            load: function () {

                // set up the updating of the chart each second
                var series = this.series[0],
                    chart = this;
                var count = 0;
                setInterval(function () {
                    var x = (new Date()).getTime(), // current time
                        y = next();
                    console.log(y);
                    series.addPoint([x, y], false, true);
                    chart.redraw(false);
                }, 1000 / 130);
            }
        }
    },

    time: {
        useUTC: false
    },

    title: {
        text: 'ECG Graph Plot From MySQl Data'
    },
    xAxis: {
        type: 'datetime',
        labels: {
            enabled: false
        },
        tickPixelInterval: 150
    },
    yAxis: {
        //max: 1.5,
        //min: -1.5,
        title: {
            text: 'Value'
        },
        plotLines: [{
            value: 0,
            width: 1,
            color: '#808080'
        }]
    },
    tooltip: {
        headerFormat: '<b>{series.name}</b><br/>',
        pointFormat: '{point.x:%Y-%m-%d %H:%M:%S}<br/>{point.y:.2f}'
    },
    legend: {
        enabled: false
    },
    exporting: {
        enabled: false
    },
    series: [{
        animation: false,
        name: 'ECG Graph Plot From MySQl Data',
        dataGrouping: {
            enabled: false
        },
        data: (function () {
            // generate an array of random data
            var data = [],
                time = (new Date()).getTime(),
                i;

            for (i = -1000; i <= 0; i += 1) {
                data.push([
                    time + i * 10,
                    null
                ]);
            }
            return data;
        }())
    }]
});   

所以我要求的是在不破坏数据的情况下将数据一一渲染。当 random.php 中的一个数据集结束时。下一个数据应该从该数据的延续开始。

更新:

考虑这样一个场景:每隔几秒生成一个包含 500 个数据的数组。我想要的是在一个 Highcharts 中一一显示数组点。但仅显示第一组数组数据,其余数组数据未显示。

最佳答案

我想我找到了解决您的代码的可能方法。首先,您当前的方法存在一些误解:

  • return 语句之后没有执行任何操作。是的,正如您在评论中指出的那样,在函数中执行 return 后,什么也没有完成

  • 在您的 Highcharts 中,您的数据取决于 json_array (基本上您读取数组的 X 元素),但实际上您从未使用更多信息更新 json_array .

Ok... what should I do?

让我们看看。首先,您应该确保在第一次获取之后的某个时间间隔内获取数据。如何做到这一点:

function fetch() {
    requestData();
    var divisor = 2;
    var count = 0;
    for (var i = 0, length = y.length; i < length; i++) {
        y[i] /= divisor;
    }
    console.log(y);
    // Create the interval before returning, and actually calling the function
    setInterval(function () { requestData() }, 1000);
    return (y);
}

其次,您需要每个 requestData 更新您正在读取的数组: 免责声明,我正在使用您的评论的 jsfiddle 创建一个简单的示例


  var json_array = fetch();

  function requestData() {
    var data = [];

    for (var i = 0; i < 500; i++) {
      data.push(Math.random() * 10);
    }

    y = data;

    // Check that json_array have been initialized and after add the data that we fetched in it (so from [1, 2, 3] to... [1, 2, 3, 4, 5, 6]
    if (Array.isArray(json_array)) {
      json_array = json_array.concat(data);
    }
  }

使用你的ajax代码,它应该看起来像

function requestData() {
    $.ajax({
        url: 'random.php',
        async: false,
        success: function (data) {
         /// you can skip this check... I just do it for safety
         if (Array.isArray(json_array)) {
           json_array = json_array.concat(data);
         }
        }
    });
}

基本上就是这样,只要您的请求比您在图表中读取 X 的速度更快,它就应该可以正常工作。

I have here the working demo

额外 这是不需要的,因为在解决方案中,我尝试尽可能少地修改您的代码,并主要指出您的方法有什么问题,但我会考虑对您的代码进行下一步改进:

  • 服务中的抽象数据获取。基本上,您可以创建一个类/原型(prototype),一旦实例化它就会获取数据,并继续获取数据并添加它
  • 此类还将检查您当前可以访问的数据索引数量,并为您提供下一个元素。
  • 修改您的 Highcharts 以使用它。

这是实现的抽象

class DataFetcher {
constructor() {
   this.currentDataPoint = 0
   this.data = fetch(...)
   this.keepFetching()
}
keepFetching() {
   fetchMoreData().onSuccess((data) => { this.data = data }
}

getNext() {
   if (this.isThereData) {
// Return data point and increase pointer
     dataPoint = this.data[this.currentDataPoint]
     this.currentDataPoint =+ 1
     return dataPoint
   }
// Return nothing because there is no more data points
   return null
}

isThereData() { 
  return this.data.length >= this.currentDataPoint + 1
}

}

最后,您可以使用映射函数抽象此数据的划分:

function fetch() {
    requestData();
    y = y.map(value => value/2);
    console.log(y);
    // Create the interval before returning, and actually calling the function
    setInterval(function () { requestData() }, 1000);
    return (y);
}

// Also the other function
function requestData() {
    var data = [];

    for (var i = 0; i < 500; i++) {
      data.push(Math.random() * 10);
    }

    y = data.map(dataPoint => dataPoint/2);

    // Check that json_array have been initialized and after add the data that we fetched in it (so from [1, 2, 3] to... [1, 2, 3, 4, 5, 6]
    if (Array.isArray(json_array)) {
      json_array = json_array.concat(data);
    }
  }

希望这可以帮助您完善解决方案!

关于javascript - 在每个数组绘图后更新图表,Highcharts,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58743258/

相关文章:

javascript - 正则表达式参数上的 parseFloat 返回 NaN

javascript - 使用 Jquery 剥离 HTML 标签

javascript - 如果没有其他用户看到它,则呈现未转义的用户输入是否安全?

php - 调度方法

javascript - 如何在创建父记录时存储子记录

javascript - node.js:使用等待消耗 promise

javascript - 如何在react.js中像ant design一样创建自己的按钮组件

php - htaccess 带有语言和页面参数的重定向 url

java - 使用 AJAX 进行 PUT 和 DELETE 时出现 403 状态(禁止访问)

javascript - 我会使用 Ajax 或 PHP 来更改 var 值吗?