【问题标题】:D3-request retrieval of a google spreadsheet csv/json file fails谷歌电子表格 csv/json 文件的 D3 请求检索失败
【发布时间】:2016-12-06 20:58:04
【问题描述】:

我很难让 Google 电子表格和 D3js 的 D3-request / D3-request > header 通过 xhr 请求一起工作。

我使用以下JS:

d3.request(url)
    .header("X-Requested-With", "XMLHttpRequest")
    .mimeType("text/csv")
    .get(function(error, data) {
      if (error) throw error;
      console.log('request: '+ data);
    });

我收到以下错误:

XMLHttpRequest cannot load https://docs.google.com/spreadsheets/d/e/2PACX-1vSZyV9olwK_hx0BRFgLtTz5hs_Z…mROYhax3VD9AFXTvmcataf8LuSIpxGT2/pub?gid=1023695213&single=true&output=csv. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://fiddle.jshell.net' is therefore not allowed access.

Jsfiddle here

有什么办法绕过它吗?

【问题讨论】:

  • 请不要使用未经他人同意的电子邮件作为您的示例数据。
  • 欧普斯。让我们快速解决这个问题!
  • @MaximilianPeters:非常感谢。我对这段代码的了解太多了,以至于我忘记了我的工作表上有电子邮件。

标签: d3.js google-sheets xmlhttprequest cross-domain d3-request


【解决方案1】:

仅使用 D3

d3.json(url, function (error, result) {
    var data = [];
    for (i = 0; i < result.feed.entry.length; i += 1) {
        data.push({
            "animal": result.feed.entry[i].gsx$animal.$t,
            "population": result.feed.entry[i].gsx$population.$t
        });
    }
    pie_chart(data, "#chart1");
});

使用 jQuery

$.get(url, function (result) {
    var data = [];
    $(result.feed.entry).each(function () {
        data.push({"animal": this.gsx$animal.$t, "population": this.gsx$population.$t});
    });
    pie_chart(data, "#chart2");
});

使用tabletop

Tabletop.init({
    key: key,
    callback: function (data, tabletop) {
        pie_chart(data, "#chart3");
    },
    simpleSheet: true
});

以下只是一个从 Google 电子表格中获取数据并将其转换为 D3 pie chart 的简单示例。

//draws a pie chart with D3
function pie_chart(data, id) {
    var w = 400;
    var h = 400;
    var r = h / 2;
    var color = d3.scale.category20c();

    var vis = d3.select(id).append("svg:svg").data([data]).attr("width", w).attr("height", h).append("svg:g").attr("transform", "translate(" + r + "," + r + ")");
    var pie = d3.layout.pie().value(function (d) {
        return d.population;
    });
    var arc = d3.svg.arc().outerRadius(r);

    var arcs = vis.selectAll("g.slice").data(pie).enter().append("svg:g").attr("class", "slice");
    arcs.append("svg:path")
        .attr("fill", function (d, i) {
            return color(i);
        })
        .attr("d", function (d) {
            return arc(d);
        });

    arcs.append("svg:text").attr("transform", function (d) {
        d.innerRadius = 0;
        d.outerRadius = r;
        return "translate(" + arc.centroid(d) + ")";
    }).attr("text-anchor", "middle").text(function (d, i) {
        return data[i].animal;
    });
}

//the key of google spreadsheet
var key = "1moczdbrfFwCp0L4Ube1a4GevuDcj2XQmCnpjArF_UEY";

//the url for jQuery and D3
var url = "https://spreadsheets.google.com/feeds/list/" + key + "/od6/public/values?alt=json";

var i = 0;

//D3 only
d3.json(url, function (error, result) {
    var data = [];
    for (i = 0; i < result.feed.entry.length; i += 1) {
        data.push({
            "animal": result.feed.entry[i].gsx$animal.$t,
            "population": result.feed.entry[i].gsx$population.$t
        });
    }
    pie_chart(data, "#chart1");
});

//Jquery
$.get(url, function (result) {
    var data = [];
    $(result.feed.entry).each(function () {
        data.push({"animal": this.gsx$animal.$t, "population": this.gsx$population.$t});
    });
    pie_chart(data, "#chart2");
});

//tabletop

Tabletop.init({
    key: key,
    callback: function (data, tabletop) {
        pie_chart(data, "#chart3");
    },
    simpleSheet: true
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tabletop.js/1.4.3/tabletop.js"></script>

<div id="chart1" style="width: 480px; height: 400px;"><span>D3 only</span></div>
<hr>
<div id="chart2" style="width: 480px; height: 400px;"><span>Jquery</span></div>
<hr>
<div id="chart3" style="width: 480px; height: 400px;"><span>Tabletop</span></div>

【讨论】:

  • 你好,马克斯。我不再是 tabletopjs 的粉丝了。我今天实际上花了 3 个小时才最终找到 tabletopjs' readme.md is outdated and misleading。此外,我想获得更多功能、更强大和更灵活的东西。如果我能了解它的工作原理,D3-request 似乎很有希望。然而,感谢 tabletopjs 代码,它可能会帮助其他朋友:)
  • 感谢 JQuery,它肯定会帮助一些用户:)(我正在寻找 D3 请求解决方案)
  • 你的意思是你做了master D3-request,但认为不可能吗?我在想设置 d3-request 标头就足够了,但我可能会错过了解情况。 D3-request > header
  • O.ô ...我没有成功做 D3 + google sheet JSON。你能打开另一个答案吗? JSON 满足我的要求:D3 + google 电子表格一起工作。
  • 这非常令人沮丧。我现在已经设法将其范围缩小到没有Access-Control-Allow-Origin: * 的情况下提供了我的工作表,但提供了您的工作表。有什么建议吗?
猜你喜欢
  • 2014-01-30
  • 1970-01-01
  • 2019-05-20
  • 2014-07-01
  • 2023-03-22
  • 1970-01-01
  • 1970-01-01
  • 2013-10-05
  • 1970-01-01
相关资源
最近更新 更多