0

我正在构建一个应用程序来监视应用程序服务器上运行的服务数量。有关正在运行的服务的信息将存储在数据库中,我想在网页上显示其中的一些信息。在这一点上,我只想构建一个活跃运行的服务数量的图形表示,它随着数据库的更新而动态更新。目标是创建一个简单的图表,显示最近运行的服务数量的 10 个(左右)值,类似于 ekg 读数的样子。我正在使用 dojox.charting.Chart 小部件,但无法正确更新图表,因此它仅显示 numFailedAttempts:"0" 的十个最新值。就像现在一样,图表显示所有值,并且 x 轴值不断地越来越接近以容纳所有内容。根据 dojotoolkit.org 上的 dojo api 参考和文档,我认为 dojox.charting.Chart 的“displayRange”属性应该可以解决这个问题。所以我的问题是,我做错了什么?这是代码:

<html>
<head>        
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">        
    <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.6/dojo/resources/dojo.css">        
    <script src="http://ajax.googleapis.com/ajax/libs/dojo/1.6.0/dojo/dojo.xd.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>

    <script type="text/javascript">

        dojo.require("dojox.charting.StoreSeries");
        dojo.require("dojox.charting.Chart2D");
        dojo.require("dojo.store.Memory");
        dojo.require("dojo.store.Observable");
        dojo.require("dojox.charting.Chart");
        dojo.require("dojox.charting.plot2d.Areas");

        dojo.ready(function(){renderDataChart()});

        function renderDataChart(){

            //data from a database
            var dataChartData = {
                itentifier: 'id',
                items:
                    [
                    {id: 1, serviceName:"service1", startDate:"today", endDate:"today", numFailedAttempts:"1", errorTime:"null", errorMessage:"null", suppressError:"null"},
                    {id: 2, serviceName:"service2", startDate:"today", endDate:"today", numFailedAttempts:"1", errorTime:"now", errorMessage:"broken", suppressError:"click"},
                    {id: 3, serviceName:"service3", startDate:"today", endDate:"today", numFailedAttempts:"0", errorTime:"now", errorMessage:"broken", suppressError:"click"},
                    {id: 4, serviceName:"service4", startDate:"today", endDate:"today", numFailedAttempts:"1", errorTime:"now", errorMessage:"broken", suppressError:"click"},
                    {id: 5, serviceName:"service5", startDate:"today", endDate:"today", numFailedAttempts:"0", errorTime:"null", errorMessage:"null", suppressError:"null"}
                ]                    
            };
            //data store
            var dataChartStore = dojo.store.Observable(new dojo.store.Memory({
                data: {
                    identifier: "id",
                    label: "runningServices",
                    items: dataChartData
                }
            }));    

            var dataChart = new dojox.charting.Chart("myDataChart", {

                displayRange: 10,
                stretchToFit: false,
                scrolling: true,     
                fieldName: "runningServices",
                type: dojox.charting.plot2d.Areas
            });
            dataChart.addAxis("x", {microTickStep: 1, minorTickStep: 1});
            dataChart.addAxis("y", {vertical: true, minorTickStep: 1, natural: true});
            dataChart.addSeries("y", new dojox.charting.StoreSeries(dataChartStore, {query: {numFailedAttempts: 0}}, "value"));
            dataChart.render();

            //update datastore to simulate new data
            var startNumber = dataChartData.length;
            var interval = setInterval(function(){
                 dataChartStore.notify({value: Math.ceil(Math.random()*29), id: ++startNumber, numFailedAttempts: 0});                    

            }, 1000);
        }
    </script>
</head>
<body>
    <div id="myDataChart" style="width: 500px; height: 200px;"></div>
</body>

4

1 回答 1

1

我一直在努力解决同样的问题。我还没有完全弄清楚,但我找到了一个替代方案,可以满足我的想法。这是代码(下面的解释):

<html>
<head>        
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">        
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.6/dojo/resources/dojo.css">        
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.6.0/dojo/dojo.xd.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>

<script type="text/javascript">

  dojo.require("dojox.charting.StoreSeries");
  dojo.require("dojo.store.Memory");
  dojo.require("dojo.store.Observable");

  dojo.require("dojox.charting.Chart2D");
  dojo.require("dojox.charting.Chart");
  dojo.require("dojox.charting.plot2d.Areas");

  dojo.ready(function () {
    renderArrayChart();
    renderStoreChart();
  });

  function renderArrayChart() {
    try {
      var dataChart = new dojox.charting.Chart("myArrayChart", {
        stretchToFit: false,
        scrolling: false,
        type: dojox.charting.plot2d.Areas,
        title: "update array, rerender"
      });

      // create an array of x/y pairs as the data source
      var data = [{ x: 1, y: 2.1}];

      dataChart.addAxis("x", { microTickStep: 1, minorTickStep: 1 });

      // set min/max so the Y axis scale does not change with the data
      dataChart.addAxis("y", { vertical: true, minorTickStep: 1, natural: true, min: 0, max: 30 });

      // create the series with the data array as the source
      dataChart.addSeries("y", data);
      dataChart.render();

      // this counter is used as the x value for new data points
      var startNumber = data.length;

      //update datastore to simulate new data
      var interval = setInterval(function () {

        // if we have more than 9 data points in the array, remove the first one
        if (data.length > 9) data.splice(0, 1);

        // push a new data point onto the array using the counter as the X value
        data.push({ x: ++startNumber, y: Math.ceil(Math.random() * 29) });

        // update the series with the updated arrray
        dataChart.updateSeries("y", data);

        // re-render the chart
        dataChart.render();

      }, 1000);
    }
    catch (ex) {
      alert(ex.message);
    }
  }


  function renderStoreChart() {
    try {
      // create an array as the data source
      var dataArray = [{ id: 1, value: 2.1}];

      // create the observable data store
      var dataStore = dojo.store.Observable(new dojo.store.Memory({
        data: {
          identifier: "id",
          items: dataArray
        }
      }));

      var storeChart = new dojox.charting.Chart("myStoreChart", {
        stretchToFit: false,
        scrolling: false,
        type: dojox.charting.plot2d.Areas,
        title: "data store"
      });

      storeChart.addAxis("x", { microTickStep: 1, minorTickStep: 1 });

      // set min/max so the Y axis scale does not change with the data
      storeChart.addAxis("y", { vertical: true, minorTickStep: 1, natural: true, min: 0, max: 30 });

      storeChart.addSeries("y", new dojox.charting.StoreSeries(dataStore, { bindings: { x: "id", y: "value"} }));
      storeChart.render();

      // this counter is used as the x value for new data points
      var startNumber = 1;

      //update datastore to simulate new data
      var interval = setInterval(function () {

        // if we have more than the desired number data points in the store, remove the first one
        if (startNumber > 9) dataStore.notify(null, startNumber - 10);

        // add a new point to the data store
        dataStore.notify({ id: ++startNumber, value: Math.ceil(Math.random() * 29) });

      }, 1000);
    }
    catch (ex) {
      alert(ex.message);
    }
  }

</script>
</head>
<body>
<div id="myArrayChart" style="width: 500px; height: 200px;"></div><br />
<div id="myStoreChart" style="width: 500px; height: 200px;"></div>
</body>
</html>

顶部图表使用一个简单的数组作为数据源(而不是 Observable 存储)。在区间函数中,它只是对第一个数组元素进行切片(在达到所需的元素数量之后)并添加一个新元素。然后它更新系列 (dataChart.updateSeries),然后重新呈现图表。为了使 X 轴标签正常工作,每个数组项都是对象 x 和 y 值(例如 {x: 1, y: 2.1})。

The bottom chart uses the data store (an adaptation of your example). It does get the data to scroll off the chart. The dataStore.notify(null, objectId) method will remove the object with the given id from the data store. However, the X axis labels on this chart still do not display correctly.

In either case, the chart does not scale well. Even with only about 50 data points, the rendering gets very slow. I may try looking at other options, such as Flot - which seems to perform better with a larger number of data points.

于 2012-04-19T14:46:52.747 回答