带世界地图的AmCharts multiCSV数据加载器

时间:2018-08-30 06:38:02

标签: javascript amcharts

我有很多CSV文件,

我需要从他们dataSetSelector创建

enter image description here

在选择时,我需要获取表

enter image description here

但是我在表的末尾变得不确定。

基于所选数据的世界地图 enter image description here

以及地图底部的条形图 enter image description here

所以需要得到类似的东西

enter image description here

  1. 还必须根据用户屏幕尺寸自动调整屏幕
  2. 然后将鼠标悬停在每个图表栏上以在地图上突出显示相同的值,如果可能,在表格项上也相同
  3. 在图表上的新闻栏上,选择具有该值的地图区域,如果可能,在表格项上也是如此
  4. valueLegend最小值必须是表中的最小值,也必须是最大值
  5. 如果表中有重复的国家/地区字段,则在表中仅显示一个国家/地区,并突出显示该行,或将*设置为国家/地区名称(最好在鼠标悬停时显示带有所有重复项值的弹出式窗口),映射将所有重复项放入描述部分,并按换行符分隔,并使用*
  6. 显示值

我做什么 codepen.io

在学习AmCharts的第一天,我无法获取dataSetSelector并将多个csv文件中的数据放入其中。我也找不到信息如何将股票图表与地图和表格结合起来。

所以请帮助实现我的目标。

1 个答案:

答案 0 :(得分:2)

我将在2-4中专注于AmCharts特定的内容,因为这是问题的重点。我也只会为AmCharts 3.x版提供解决方案。您应该能够从那里处理1和5,因为您可以调整CSS使其更适应1,并添加满足5所需的任何逻辑。

首先要弄清容易的部分

  • dataSetSelector是一个股票图表属性。为地图和序列图重现此功能的唯一方法是使用<select>标签和JavaScript编写自己的<option>,以触发更改时所需的加载操作。
  • 股票图表仅允许基于日期的数据。不能将它用于类别/ x轴只是屏幕快照中的字符串的图表,因此它不是您的选择。

考虑到上述因素,您需要设置并放置下拉菜单,表格和图表/地图div,并添加代码以将所有内容链接在一起。

此布局的一些基本HTML和CSS

HTML:

<div id="container">
  <div id="selector-table-div">
    <select id="data-selector">
      <option value="path/to/csv-1">Dataset 1</option>
      <option value="path/to/csv-2">Dataset 2</option>
    </select>
    <div id="datatable"></div>
  </div>
  <div id="mapdiv"></div>
  <div id="chartdiv"></div>
</div>

CSS:

#mapdiv {
  width: 70%;
  height: 400px;
  float: left;
}
#chartdiv {
  width: 100%;
  height: 250px;
}
#selector-table-div {
  width: 20%;
  height: 450px;
  float: left;
}

您自己一个人来使它对身高的反应更快。为了简洁起见,我省略了数据表的内容,并突出显示了行。

在您的JS中,您需要附加一个change事件,以在选择其他下拉菜单项时触发页面更新:

document
  .getElementById("data-selector")
  .addEventListener("change", function(e) {
    updatePage(e.target.value); //update page calls AmCharts.loadFile, updates/creates the table, map and chart with new data
  });

由于您打算在同一页面上同时使用图表和地图,因此需要使用amcharts.jsammap_amcharts_extension.js。在同一页面中使用amcharts.jsammaps.js会导致图表和地图出现错误,因为这两个文件会覆盖彼此的方法。您的柱形图将需要serial.js

<script src="https://www.amcharts.com/lib/3/amcharts.js"></script>
<script src="https://www.amcharts.com/lib/3/ammap_amcharts_extension.js"></script>
<script src="https://www.amcharts.com/lib/3/serial.js"></script>
<!-- other stuff omitted -->

由于您希望将地图绑定到数据,因此,您需要提供一种简便的方法将每行映射到地图区域。在您的CSV文件中添加ISO 3166-2国家/地区代码将极大地简化该过程:

country,visits,country_code
USA,2025,US
China,1882,CN
Japan,1809,JP
...

从那里,您可以使用新创建的country_code列作为MapArea id来设置地图区域,以激活地图上的区域:

  var areas = data.map(function(row) {
      return {
        id: row.country_code, //use ISO code for area ids
        value: row.visits
      };
    });
  // ...
  AmCharts.makeChart("mapdiv", {
    // ..
    dataProvider: {
      map: "worldLow",
      areas: areas
    }
  });

要捕获最小值/最大值并将其分配给该区域,只需遍历数据并使用Math.min / Math.max

  var minValue = Number.MAX_VALUE;
  var maxValue = Number.MIN_VALUE;
  data.forEach(function(row) {
    minValue = Math.min(minValue, row.visits);
    maxValue = Math.max(maxValue, row.visits);
  });
  // ...
  AmCharts.makeChart("mapdiv", {
    // ..
    valueLegend: {
      minValue: minValue,
      maxValue: maxValue
      // ...
    }
  });      

您还需要在单独的函数中调整地图/图表创建代码,这些函数知道何时创建新的地图/图表或更新现有的地图/图表:

var map, chart;
// ...
function updateMap(data) {
  // ...
  if (map) {
     //makeChart here
  }
  else {
    map.dataProvider.areas = areas;
    map.valueLegend.minValue = minValue;
    map.valueLegend.maxValue = maxValue;
    map.validateData(); // update map
  }

对于地图,您还需要确保不仅在初始化时,而且在更新地图时都调用地图标签放置代码:

function updateMap(data) {
  // ...
  if (map) {
     //makeChart here
  }
  else {
     // data update here
  }
  updateLabel(); //update labels - same code as before

创建图表非常简单。您可以添加clickGraphItemrollOverGraphItem事件以选择相应的地图区域,并在单击/悬停时突出显示表格行:

   chart = AmCharts.makeChart("chartdiv", {
      type: "serial",
      dataProvider: data,
      // ...
      listeners: [
        {
          event: "clickGraphItem",
          method: handleBarInteraction
        }, {
          event: "rollOverGraphItem",
          method: handleBarInteraction 
        }
      ]

function handleBarInteraction(e) {
  map.selectObject(map.getObjectById(e.item.dataContext.country_code));
  var selected = document.querySelector(".selected");

  if (selected) {
    selected.classList.remove("selected");
  }
  document
    .getElementById(e.item.dataContext.country_code)
    .classList.add("selected");
}

您的未定义行可能来自CSV中的额外换行符。您可以简单地检查最后一项并将其从数组中弹出,然后再创建表格,地图和图表:

var data = AmCharts.parseCSV(response, {
   // ...
});

if (data[data.length -1].country === undefined) {
  data.pop();
}

这是一个complete codepen,其中包含上述所有内容以及一些重组的代码。请注意,标签放置在奇怪的地方。 example you pulled the label code from定义异常纬度和经度变量,以供您为特定区域设置。您需要找出这些值。