【问题标题】:amCharts 4: External Data SourceamCharts 4:外部数据源
【发布时间】:2020-05-29 15:56:00
【问题描述】:

我正在努力使用外部数据源在 amCharts 4 中生成一个简单的 XY 水平条形图。

静态数据一切正常(我改编了 amCharts 文档中的一个图表演示)。

但是当我用外部数据源 URL 替换静态数据时,图表不会生成。

我怀疑问题可能是 Airtable JSON 输出与静态数据的结构不同。

但是,我的怀疑可能完全错了,所以我非常感谢任何解决方案的帮助。

(我显然已经在下面的代码中用 XXX 删除了 Airtable 信息。)

静态数据源

// Create chart instance
var chart = am4core.create("CHARTDIV", am4charts.XYChart);

// Add data
chart.data = [{
  "Name": "Brand Guidelines",
  "Aggregate Responses": 7
}, {
  "Name": "SAP",
  "Aggregate Responses": 3
}, {
  "Name": "Email",
  "Aggregate Responses": 5
}, {
  "Name": "Social Media",
  "Aggregate Responses": 3
}, {
  "Name": "Google Drive",
  "Aggregate Responses": 3
}, {
  "Name": "OneDrive",
  "Aggregate Responses": 4
}, {
  "Name": "SharePoint",
  "Aggregate Responses": 1
}, {
  "Name": "Slack",
  "Aggregate Responses": 3
}, {
  "Name": "Drupal",
  "Aggregate Responses": 2
}, {
  "Name": "Telephone",
  "Aggregate Responses": 3
}];

// Create axes

var categoryAxis = chart.yAxes.push(new am4charts.CategoryAxis());
categoryAxis.dataFields.category = "Name";
categoryAxis.renderer.grid.template.location = 0;
categoryAxis.renderer.minGridDistance = 30;

var valueAxis = chart.xAxes.push(new am4charts.ValueAxis());

// Create series
var series = chart.series.push(new am4charts.ColumnSeries());
series.dataFields.valueX = "Aggregate Responses";
series.dataFields.categoryY = "Name";
series.name = "Aggregate Responses";
series.columns.template.tooltipText = "{categoryY}: [bold]{valueX}[/]";
series.columns.template.fillOpacity = .8;

var columnTemplate = series.columns.template;
columnTemplate.strokeWidth = 2;
columnTemplate.strokeOpacity = 1;

外部数据源

// Create chart instance
var chart = am4core.create("CHARTDIV", am4charts.XYChart);

// External data source
chart.dataSource.url = "https://api.airtable.com/v0/appXXXXXXX/airtable-table-name?api_key=keyXXXXXXX";

// Create axes

var categoryAxis = chart.yAxes.push(new am4charts.CategoryAxis());
categoryAxis.dataFields.category = "Name";
categoryAxis.renderer.grid.template.location = 0;
categoryAxis.renderer.minGridDistance = 30;

var valueAxis = chart.xAxes.push(new am4charts.ValueAxis());

// Create series
var series = chart.series.push(new am4charts.ColumnSeries());
series.dataFields.valueX = "Aggregate Responses";
series.dataFields.categoryY = "Name";
series.name = "Aggregate Responses";
series.columns.template.tooltipText = "{categoryY}: [bold]{valueX}[/]";
series.columns.template.fillOpacity = .8;

var columnTemplate = series.columns.template;
columnTemplate.strokeWidth = 2;
columnTemplate.strokeOpacity = 1;

Airtable JSON 输出

{
  "records": [
    {
      "id": "recXXXXXX",
      "fields": {
        "Name": "EpiServer",
        "Typeform Responses": [
          "recXXXXXX",
          "recXXXXXX",
          "recXXXXXX"
        ],
        "Aggregate Responses": 3
      },
      "createdTime": "2020-05-22T16:11:01.000Z"
    },
    {
      "id": "recXXXXXX",
      "fields": {
        "Name": "OneDrive",
        "Typeform Responses": [
          "recXXXXXX",
          "recXXXXXX",
          "recXXXXXX",
          "recXXXXXX"
        ],
        "Aggregate Responses": 4
      },
      "createdTime": "2020-05-22T16:50:41.000Z"
    },
  ]
}

【问题讨论】:

    标签: amcharts amcharts4


    【解决方案1】:

    您对格式不同的怀疑是正确的。 AmCharts 需要一个简单的扁平对象数组,它可以在其中找到您指定的字段,因此您需要将外部数据转换为 AmCharts 可以接受的格式。您可以使用parseended 事件重新映射您的数据,如下所示:

        chart.dataSource.events.on("parseended", function(ev) {
          // parsed data is assigned to data source's `data` property
          // pluck data from the records array in your raw data
          ev.target.data = ev.target.data.records.map(function(dataItem) {
            return {
              "Aggregate Responses": dataItem.fields["Aggregate Responses"],
              "Name": dataItem.fields.Name
            }
          });
        }); 
    

    下面的示例使用您的代码和示例数据的 base64 编码数据 URL 作为演示:

    // Create chart instance
    var chart = am4core.create("CHARTDIV", am4charts.XYChart);
    
    // External data source
    //chart.dataSource.url = "https://api.airtable.com/v0/appXXXXXXX/airtable-table-name?api_key=keyXXXXXXX";
    chart.dataSource.url = dataURI(); //fake URL for demonstration purposes
    chart.dataSource.events.on("parseended", function(ev) {
      // parsed data is assigned to data source's `data` property
      ev.target.data = ev.target.data.records.map(function(dataItem) {
        return {
          "Aggregate Responses": dataItem.fields["Aggregate Responses"],
          "Name": dataItem.fields.Name
        }
      });
    }); 
    
    // Create axes
    
    var categoryAxis = chart.yAxes.push(new am4charts.CategoryAxis());
    categoryAxis.dataFields.category = "Name";
    categoryAxis.renderer.grid.template.location = 0;
    categoryAxis.renderer.minGridDistance = 30;
    
    var valueAxis = chart.xAxes.push(new am4charts.ValueAxis());
    
    // Create series
    var series = chart.series.push(new am4charts.ColumnSeries());
    series.dataFields.valueX = "Aggregate Responses";
    series.dataFields.categoryY = "Name";
    series.name = "Aggregate Responses";
    series.columns.template.tooltipText = "{categoryY}: [bold]{valueX}[/]";
    series.columns.template.fillOpacity = .8;
    
    var columnTemplate = series.columns.template;
    columnTemplate.strokeWidth = 2;
    columnTemplate.strokeOpacity = 1;
    
    // base64 encoded version of sample data as a data URI
    function dataURI() {
      return "data:application/json;base64,eyAicmVjb3JkcyI6IFsgeyAiaWQiOiAicmVjWFhYWFhYIiwgImZpZWxkcyI6IHsgIk5hbWUiOiAiRXBpU2VydmVyIiwgIlR5cGVmb3JtIFJlc3BvbnNlcyI6IFsgInJlY1hYWFhYWCIsICJyZWNYWFhYWFgiLCAicmVjWFhYWFhYIiBdLCAiQWdncmVnYXRlIFJlc3BvbnNlcyI6IDMgfSwgImNyZWF0ZWRUaW1lIjogIjIwMjAtMDUtMjJUMTY6MTE6MDEuMDAwWiIgfSwgeyAiaWQiOiAicmVjWFhYWFhYIiwgImZpZWxkcyI6IHsgIk5hbWUiOiAiT25lRHJpdmUiLCAiVHlwZWZvcm0gUmVzcG9uc2VzIjogWyAicmVjWFhYWFhYIiwgInJlY1hYWFhYWCIsICJyZWNYWFhYWFgiLCAicmVjWFhYWFhYIiBdLCAiQWdncmVnYXRlIFJlc3BvbnNlcyI6IDQgfSwgImNyZWF0ZWRUaW1lIjogIjIwMjAtMDUtMjJUMTY6NTA6NDEuMDAwWiIgfSBdIH0=";
    }
    <script src="//www.amcharts.com/lib/4/core.js"></script>
    <script src="//www.amcharts.com/lib/4/charts.js"></script>
    <div id="CHARTDIV" style="width: 100%; height: 98vh"></div>

    确保您的数据是有效的 JSON,因为您的示例的尾随逗号不正确。

    【讨论】:

    • 在 JSON 输出中,为了简洁起见,我删除了大部分值,但忘记删除尾随逗号。非常感谢您的解决方案,效果很好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多