Amcharts Serial - 将多个ajax数据加载为dataprovider

时间:2017-05-18 18:59:37

标签: javascript ajax amcharts

我正在尝试创建一个包含多个ajax加载数据的串行图。到目前为止,我还没有看到有人这样做,但我能够在网上使用类似的东西。结果的问题是加载需要很长时间并且所有数据都聚集在一起。有没有办法将每个ajax返回的每个数据加载到特定图形(只有状态和计数器是唯一返回的数据)?



$(document).ready(function() {
  var chartDataResults = new Array();

  $.ajax({
    type: "POST",
    contentType: "application/json",
    url: "../NewProjectEdit.aspx/bronxBind",
    async: false,
    dataType: 'json',
    success: function(data) {
      generateChartData(data.d);
    }
  });

  $.ajax({
    type: "POST",
    contentType: "application/json",
    url: "../NewProjectEdit.aspx/brooklynBind",
    async: false,
    dataType: 'json',
    success: function(data) {
      generateChartData(data.d);
    }
  });

  $.ajax({
    type: "POST",
    contentType: "application/json",
    url: "../NewProjectEdit.aspx/manhattanBind",
    async: false,
    dataType: 'json',
    success: function(data) {
      generateChartData(data.d);
    }
  });

  $.ajax({
    type: "POST",
    contentType: "application/json",
    url: "../NewProjectEdit.aspx/queensBind",
    async: false,
    dataType: 'json',
    success: function(data) {
      generateChartData(data.d);
    }
  });

  $.ajax({
    type: "POST",
    contentType: "application/json",
    url: "../NewProjectEdit.aspx/statenIslandBind",
    data: '{}',
    async: false,
    dataType: 'json',
    success: function(data) {
      generateChartData(data.d);
    }
  });


  function generateChartData(dataValues) {
    for (var i = dataValues.length - 1; i >= 0; --i) {

      console.log(dataValues[1]);
      var chartItems = dataValues[i];
      var chartStatus = chartItems.status
      var chartCounter = chartItems.counter

      chartDataResults.push({
        status: chartStatus,
        counter: chartCounter
      });

      var chart = AmCharts.makeChart("chartdiv", {
        "type": "serial",
        "theme": "light",
        "depth3D": 20,
        "angle": 30,
        "legend": {
          "horizontalGap": 10,
          "useGraphSettings": true,
          "markerSize": 10
        },
        "valueAxes": [{
          "stackType": "regular",
          "axisAlpha": 0,
          "gridAlpha": 0
        }],
        "dataProvider": chartDataResults,
        "graphs": [{
          "balloonText": "<b>[[title]]</b><br><span style='font-size:14px'>[[category]]: <b>[[value]]</b></span>",
          "fillAlphas": 0.8,
          "labelText": "[[value]]",
          "lineAlpha": 0.3,
          "title": "Bronx",
          "type": "column",
          "color": "#000000",
          "valueField": "counter"
        }, {
          "balloonText": "<b>[[title]]</b><br><span style='font-size:14px'>[[category]]: <b>[[value]]</b></span>",
          "fillAlphas": 0.8,
          "labelText": "[[value]]",
          "lineAlpha": 0.3,
          "title": "Brooklyn",
          "type": "column",
          "color": "#000000",
          "valueField": "counter"
        }, {
          "balloonText": "<b>[[title]]</b><br><span style='font-size:14px'>[[category]]: <b>[[value]]</b></span>",
          "fillAlphas": 0.8,
          "labelText": "[[value]]",
          "lineAlpha": 0.3,
          "title": "Manhattan",
          "type": "column",
          "color": "#000000",
          "valueField": "counter"
        }, {
          "balloonText": "<b>[[title]]</b><br><span style='font-size:14px'>[[category]]: <b>[[value]]</b></span>",
          "fillAlphas": 0.8,
          "labelText": "[[value]]",
          "lineAlpha": 0.3,
          "title": "Queens",
          "type": "column",
          "color": "#000000",
          "valueField": "counter"
        }, {
          "balloonText": "<b>[[title]]</b><br><span style='font-size:14px'>[[category]]: <b>[[value]]</b></span>",
          "fillAlphas": 0.8,
          "labelText": "[[value]]",
          "lineAlpha": 0.3,
          "title": "Staten Island",
          "type": "column",
          "color": "#000000",
          "valueField": "counter"
        }],
        "categoryField": "status",
        "categoryAxis": {
          "gridPosition": "start",
          "axisAlpha": 0,
          "gridAlpha": 0,
          "position": "left",
          "labelRotation": -45
        },
        "export": {
          "enabled": true
        }

      });
    }
  }
});
&#13;
#chartdiv {
  width: 100%;
  height: 100%;
}

.amcharts-export-menu-top-right {
  top: 10px;
  right: 0;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="chartdiv" background-color: #FFFFFF; " ></div>
&#13;
&#13;
&#13; enter image description here

1 个答案:

答案 0 :(得分:1)

您的方法存在一些问题。

1)不要使用async: false。由于用户体验不佳,它在现代浏览器中被弃用,因为每个请求都会阻止浏览器直到解决。您可以使用jQuery的$.when.then来利用promises,允许您在执行回调之前等待所有AJAX请求解析以合并数据并创建图表。

$.when(
  $.ajax({
    type: "POST",
    contentType: "application/json",
    url: "../NewProjectEdit.aspx/bronxBind",
    dataType: 'json'
  }),
  // each ajax request
).then(function(bronxData, brooklynData, manhattanData, queensData, statenIslandData) {
  var chartDataResults = mergeData(bronxData[0], brooklynData[0], manhattanData[0], statenIslandData[0]);
  //makeChart here.
});

2)不要多次拨打makeChart。这会导致性能问题,因为您现在正在创建多个实例,这些实例都在同一个div中进行控制。使用第1点所示的承诺,在最终创建图表之前同步您的调用和数据。

3)每个图形的valueField必须是唯一的,因此您必须合并数据,同时为每个行政区创建单独的valueField,这样您就可以单独填充每个图形。这是我根据您的设置提出的合并方法:

function mergeData(bronxData, brooklynData, manhattanData, queensData, statenIslandData) {
  var dataMap = {}; //object map used to group all data by category.
  var chartData = [];

  //collect all the data from each borough into the dataMap
  bronxData.forEach(function(data) {
    dataMap[data.status] = { 'bronxCounter': data.counter };
  });

  brooklynData.forEach(function(data) {
    if (!dataMap[data.status]) {
      dataMap[data.status] = {};
    }
    dataMap[data.status].brooklynCounter = data.counter
  });
  manhattanData.forEach(function(data) {
    if (!dataMap[data.status]) {
      dataMap[data.status] = {};
    }
    dataMap[data.status].manhattanCounter = data.counter
  });
  queensData.forEach(function(data) {
    if (!dataMap[data.status]) {
      dataMap[data.status] = {};
    }
    dataMap[data.status].queensCounter = data.counter
  });
  statenIslandData.forEach(function(data) {
    if (!dataMap[data.status]) {
      dataMap[data.status] = {};
    }
    dataMap[data.status].statenIslandCounter = data.counter
  });

  //convert dataMap into an array:
  Object.keys(dataMap).forEach(function(status) {
    dataMap[status].status = status; //assign the status categoryField
    chartData.push(dataMap[status]);  //add object to array
  });

  return chartData;
}

这是展示所有这一切的fiddle。请注意,它使用jsfiddle的echo端点来模拟AJAX请求,但一般的想法对于您的用例是相同的。