簡體   English   中英

使用d3.json處理

[英]Handle with d3.json

我正在嘗試使d3散點圖重復到json數據。 我知道d3具有d3.json來加載json數據,但是我的代碼無法正常工作。 我對js的處理不太好(這是我第一次使用這種語言),這就是為什么我需要這方面的幫助。 基本上,我需要繪制此數據(xAxis中的日期和yAxis中的IADP_mGycm2):

[
    {
        "imageID": 1,
        "value": 288.3,
        "date": "2015-10-22"
    },
    {
        "imageID": 2,
        "value": 188.1,
        "date": "2015-10-22"
    }
]

JS:

var margin = { top: 50, right: 300, bottom: 50, left: 50 },
outerWidth = 1050,
outerHeight = 500,
width = outerWidth - margin.left - margin.right,
height = outerHeight - margin.top - margin.bottom;


var x = d3.scale.linear()
    .range([0, width]).nice();

var y = d3.scale.linear()
    .range([height, 0]).nice();

var xCat = "date",
    yCat = "value";


d3.json("CR.json", function(error, rawData) {
    if (error) {
        console.error(error);
        return;
    }

    var data = rawData.map(function (d) {
        return {
            date: d.date,
            value: d.value

        }
    });


    var xMax = d3.max(data, function(d) { return d["date"]; }),
        xMin = d3.min(data, function(d) { return d["date"]; }),
        xMin = xMin > 0 ? 0 : xMin,
        yMax = d3.max(data, function(d) { return d["value"]; }) ,
        yMin = d3.min(data, function(d) { return d["value"]; }),
        yMin = yMin > 0 ? 0 : yMin;

    x.domain([xMin, xMax]);
    y.domain([yMin, yMax]);

    var xAxis = d3.svg.axis()
      .scale(x)
      .orient("bottom")
      .tickSize(-height);

    var yAxis = d3.svg.axis()
      .scale(y)
      .orient("left")
      .tickSize(-width);

    var color = d3.scale.category10();

    var tip = d3.tip()
      .attr("class", "d3-tip")
      .offset([-10, 0])
      .html(function(d) {
        return xCat + ": " + d["date"] + "<br>" + yCat + ": " + d["value"];
      });

    var zoomBeh = d3.behavior.zoom()
      .x(x)
      .y(y)
      .scaleExtent([0, 500])
      .on("zoom", zoom);

    var svg = d3.select("#scatter")
        .append("svg")
            .attr("width", outerWidth)
            .attr("height", outerHeight)
        .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
            .call(zoomBeh);

    svg.call(tip);

    svg.append("rect")
      .attr("width", width)
      .attr("height", height);

    svg.append("g")
        .classed("x axis", true)
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis)
    .append("text")
        .classed("label", true)
        .attr("x", width)
        .attr("y", margin.bottom - 10)
        .style("text-anchor", "end")
        .text(xCat);

    svg.append("g")
        .classed("y axis", true)
        .call(yAxis)
    .append("text")
        .classed("label", true)
        .attr("transform", "rotate(-90)")
        .attr("y", -margin.left)
        .attr("dy", ".71em")
        .style("text-anchor", "end")
        .text(yCat);

    var objects = svg.append("svg")
      .classed("objects", true)
      .attr("width", width)
      .attr("height", height);

    objects.append("svg:line")
      .classed("axisLine hAxisLine", true)
      .attr("x1", 0)
      .attr("y1", 0)
      .attr("x2", width)
      .attr("y2", 0)
      .attr("transform", "translate(0," + height + ")");

    objects.append("svg:line")
      .classed("axisLine vAxisLine", true)
      .attr("x1", 0)
      .attr("y1", 0)
      .attr("x2", 0)
      .attr("y2", height);

    objects.selectAll(".dot")
        .data(data)
    .enter().append("circle")
      .classed("dot", true)
      .attr("cy", function (d) { return d.value; })
      .attr("cx", function (d) { return d.date; })
      .attr("transform", transform)
      .style("fill", "red")
      .on("mouseover", tip.show)
      .on("mouseout", tip.hide);

    var legend = svg.selectAll(".legend")
      .data(color.domain())
    .enter().append("g")
      .classed("legend", true)
      .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });

    legend.append("circle")
      .attr("r", 3.5)
      .attr("cx", width + 20)
      .attr("fill", color);

    legend.append("text")
      .attr("x", width + 26)
      .attr("dy", ".35em")
      .text(function(d) { return d; });

    d3.select("input").on("click", change);

    function change() {
        xCat = "date";
        xMax = d3.max(data, function(d) { return d["date"]; });
        xMin = d3.min(data, function(d) { return d["date"]; });

        zoomBeh.x(x.domain([xMin, xMax])).y(y.domain([yMin, yMax]));

        var svg = d3.select("#scatter").transition();

        svg.select(".x.axis").duration(750).call(xAxis).select(".label").text("date");

        objects.selectAll(".dot").transition().duration(1000).attr("transform", transform);
    }

    function zoom() {
        svg.select(".x.axis").call(xAxis);
        svg.select(".y.axis").call(yAxis);

        svg.selectAll(".dot")
            .attr("transform", transform);
    }

    function transform(d) {
        return "translate(" + x(d["date"]) + "," + y(d["value"]) + ")";
    }

});

HTML:

<html>
  <head>
    <meta charset="utf-8">
    <title>Visualization</title>
    <link rel="stylesheet" href="scatter.css" charset="utf-8">
  </head>
  <body>
    <div id="scatter"></div>

    <input type="button" name="xAxis" value="xAxis">

    <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
    <script src="http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script>
    <script src="scatter.js" charset="utf-8"></script>
  </body>
</html>

CSS:

rect {
  fill: transparent;
  shape-rendering: crispEdges;
}

.axis path,
.axis line {
  fill: none;
  stroke: rgba(0, 0, 0, 0.1);
  shape-rendering: crispEdges;
}

.axisLine {
  fill: none;
  shape-rendering: crispEdges;
  stroke: rgba(0, 0, 0, 0.5);
  stroke-width: 2px;
}

.dot {
  fill-opacity: .5;
}

.d3-tip {
  line-height: 1;
  font-weight: bold;
  padding: 12px;
  background: rgba(0, 0, 0, 0.8);
  color: #fff;
  border-radius: 2px;
}

/* Creates a small triangle extender for the tooltip */
.d3-tip:after {
  box-sizing: border-box;
  display: inline;
  font-size: 10px;
  width: 100%;
  line-height: 1;
  color: rgba(0, 0, 0, 0.8);
  content: "\25BC";
  position: absolute;
  text-align: center;
}

/* Style northward tooltips differently */
.d3-tip.n:after {
  margin: -1px 0 0 0;
  top: 100%;
  left: 0;
}

提前致謝!

我看到的一個問題是,在此代碼塊的末尾缺少})

var data = rawData.map(function (d) {
    return {
        date: d.date,
        IADP_mGycm2: d.IADP_mGycm2

    };

嘗試將其更改為此:

 var data = rawData.map(function (d) {
    return {
             date: d.date,
             IADP_mGycm2: d.IADP_mGycm2
           }
    });

如果包含要獲取的特定錯誤消息,它也有助於調試。

好吧,您將xCat定義為:

var xCat = "Date"

但您的映射函數使用:

date: d.date

因此,當您引用d[xCat]時,得到的是d.Date (未定義,會導致NaN),而不是d.date 快速瀏覽一下就可以看到這些。

您可以使用d['date']d.date而不是d[xCat]來解決此問題。

好的,進一步研究之后,我發現了兩個問題。 主要問題是您要模擬的圖表在x和y軸上都有數值。 但是,您正在嘗試使用日期。 為此,您必須對x軸使用d3.time.scale()而不是線性比例尺。 您還必須將日期字符串從數據轉換為日期對象,並使用時間標度縮放X軸值。 這是具有更改的scatter.js:

var margin      = { top: 50, right: 300, bottom: 50, left: 50 },
    outerWidth  = 1050,
    outerHeight = 500,
    width       = outerWidth - margin.left - margin.right,
    height      = outerHeight - margin.top - margin.bottom;

// Use a time scale for the x-axis
var x = d3.time.scale()
          .range([0, width]).nice();

var y = d3.scale.linear()
          .range([height, 0]).nice();

var xCat = "date",
    yCat = "Dose";


d3.json("CR.json", function(error, rawData) {
    if (error) {
        console.error(error);
        return;
    }

    var data = rawData.map(function(d) {
        return {
            // Create date objects, not strings
            date:        new Date(d.date),
            IADP_mGycm2: d.IADP_mGycm2
        }
    });


    var xMax = d3.max(data, function(d) { return d["date"]; }),
        xMin = d3.min(data, function(d) { return d["date"]; }),
        //xMin = xMin > 0 ? 0 : xMin,
        yMax = d3.max(data, function(d) { return d["IADP_mGycm2"]; }),
        yMin = d3.min(data, function(d) { return d["IADP_mGycm2"]; });
        //yMin = yMin > 0 ? 0 : yMin;

    x.domain([xMin, xMax]);
    y.domain([yMin, yMax]);

    var xAxis = d3.svg.axis()
                  .scale(x)
                  .orient("bottom")
                  .tickSize(-height);

    var yAxis = d3.svg.axis()
                  .scale(y)
                  .orient("left")
                  .tickSize(-width);

    var color = d3.scale.category10();

    var tip = d3.tip()
                .attr("class", "d3-tip")
                .offset([-10, 0])
                .html(function(d) {
                    return xCat + ": " + d["date"] + "<br>" + yCat + ": " + d["IADP_mGycm2"];
                });

    var zoomBeh = d3.behavior.zoom()
                    .x(x)
                    .y(y)
                    .scaleExtent([0, 500])
                    .on("zoom", zoom);

    var svg = d3.select("#scatter")
                .append("svg")
                .attr("width", outerWidth)
                .attr("height", outerHeight)
                .append("g")
                .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
                .call(zoomBeh);

    svg.call(tip);

    svg.append("rect")
       .attr("width", width)
       .attr("height", height);

    svg.append("g")
       .classed("x axis", true)
       .attr("transform", "translate(0," + height + ")")
       .call(xAxis)
       .append("text")
       .classed("label", true)
       .attr("x", width)
       .attr("y", margin.bottom - 10)
       .style("text-anchor", "end")
       .text(xCat);

    svg.append("g")
       .classed("y axis", true)
       .call(yAxis)
       .append("text")
       .classed("label", true)
       .attr("transform", "rotate(-90)")
       .attr("y", -margin.left)
       .attr("dy", ".71em")
       .style("text-anchor", "end")
       .text(yCat);

    var objects = svg.append("svg")
                     .classed("objects", true)
                     .attr("width", width)
                     .attr("height", height);

    objects.append("svg:line")
           .classed("axisLine hAxisLine", true)
           .attr("x1", 0)
           .attr("y1", 0)
           .attr("x2", width)
           .attr("y2", 0)
           .attr("transform", "translate(0," + height + ")");

    objects.append("svg:line")
           .classed("axisLine vAxisLine", true)
           .attr("x1", 0)
           .attr("y1", 0)
           .attr("x2", 0)
           .attr("y2", height);

    objects.selectAll(".dot")
           .data(data)
           .enter().append("circle")
           .classed("dot", true)
           .attr("cy", function(d) { return d.IADP_mGycm2; })
           // Use the time scale to scale the values for the x-axis
           .attr("cx", function(d) { return x(d.date); })
           .attr("transform", transform)
           .style("fill", "red")
           .on("mouseover", tip.show)
           .on("mouseout", tip.hide);

    var legend = svg.selectAll(".legend")
                    .data(color.domain())
                    .enter().append("g")
                    .classed("legend", true)
                    .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });

    legend.append("circle")
          .attr("r", 3.5)
          .attr("cx", width + 20)
          .attr("fill", color);

    legend.append("text")
          .attr("x", width + 26)
          .attr("dy", ".35em")
          .text(function(d) { return d; });

    d3.select("input").on("click", change);

    function change() {
        xCat = "date";
        xMax = d3.max(data, function(d) { return d["date"]; });
        xMin = d3.min(data, function(d) { return d["date"]; });

        zoomBeh.x(x.domain([xMin, xMax])).y(y.domain([yMin, yMax]));

        var svg = d3.select("#scatter").transition();

        svg.select(".x.axis").duration(750).call(xAxis).select(".label").text("date");

        objects.selectAll(".dot").transition().duration(1000).attr("transform", transform);
    }

    function zoom() {
        svg.select(".x.axis").call(xAxis);
        svg.select(".y.axis").call(yAxis);

        svg.selectAll(".dot")
           .attr("transform", transform);
    }

    function transform(d) {
        return "translate(" + x(d["date"]) + "," + y(d["IADP_mGycm2"]) + ")";
    }
});

這消除了您看到的錯誤,但是仍然無法正確繪制圓。 抱歉,我沒有時間解決所有問題。 但是,這應該可以使您前進,並使您更容易自己解決問題。 要了解有關時標的更多信息,請參見https://github.com/mbostock/d3/wiki/Time-Scales 另外,如果您真的想學習D3,我強烈推薦Elijah Meeks撰寫的《 D3.js in Action 》一書。 https://www.manning.com/books/d3-js-in-action 我讀過的更好的編程書籍之一。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM