如何使用react.js渲染d3.js的svg元素?

时间:2016-08-25 11:43:29

标签: javascript d3.js reactjs

我尝试使用react.js渲染图形。其中我试图在html页面上使用简单的ReactDOM.render()方法。当我将这个图形内容附加到正文时,它对我很有用,但我想用react.js渲染它。

程序代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<!--react js url here -->
</head>
<body>
<script>
var csv_data = "date,bucket,count\n19:37:1 164,30000,12\n19:37:1 283,30000,8\n19:37:1 349,80000,2\n19:37:1 421,30000,16\n19:37:1 599,30000,2\n19:37:1 608,40000,4\n19:37:1 755,30000,4\n19:37:1 857,30000,2\n19:37:1 915,40000,6";
var margin = {
        top : 20,
        right : 90,
        bottom : 30,
        left : 50
    }, width = 960 - margin.left - margin.right, height = 500 - margin.top
            - margin.bottom;

var svg = d3.select("#svg").attr("width",
            width + margin.left + margin.right).attr("height",
            height + margin.top + margin.bottom).append("g").attr(
            "transform",
            "translate(" + margin.left + "," + margin.top + ")");
var buckets = d3.csv.parse(csv_data);

    buckets.forEach(function(d) {
        d.date = new Date(timeFormat.parse(d.date));
        d.bucket = +d.bucket;
        d.count = +d.count;
    });

    x.domain(d3.extent(buckets, function(d) {
        return d.date;
    }));

    y.domain(d3.extent(buckets, function(d) {
        return d.bucket;
    }));

    z.domain([ 0, d3.max(buckets, function(d) {
        return d.count;
    }) ]);
x.domain([ x.domain()[0], +x.domain()[1] + xStep ]);
    y.domain([ y.domain()[0], y.domain()[1] + yStep ]);

    // Display the tiles for each non-zero bucket.
    svg.selectAll(".tile").data(buckets).enter().append("rect").attr(
            "class", "tile").attr("x", function(d) {
        return x(d.date);
    }).attr("y", function(d) {
        return y(d.bucket + yStep);
    }).attr("width", x(xStep) - x(0)).attr("height", y(0) - y(yStep))
            .style("fill", function(d) {
                return z(d.count);
            });

    // Add a legend for the color values.
    var legend = svg.selectAll(".legend").data(
            z.ticks(6).slice(1).reverse()).enter().append("g").attr(
            "class", "legend").attr("transform", function(d, i) {
        return "translate(" + (width + 20) + "," + (20 + i * 20) + ")";
    });

    legend.append("rect").attr("width", 20).attr("height", 20).style(
            "fill", z);

    legend.append("text").attr("x", 26).attr("y", 10).attr("dy", ".35em")
            .text(String);

    svg.append("text").attr("class", "label").attr("x", width + 20).attr(
            "y", 10).attr("dy", ".35em").text("Count");

    // Add an x-axis with label.
    svg.append("g").attr("class", "x axis").attr("transform",
            "translate(0," + height + ")").call(xAxis).append("text").attr(
            "class", "label").attr("x", width).attr("y", -6).attr(
            "text-anchor", "end").text("Time");

    // Add a y-axis with label.
    svg.append("g").attr("class", "y axis").call(yAxis).append("text")
            .attr("class", "label").attr("y", 6).attr("dy", ".71em").attr(
                    "text-anchor", "end").attr("transform", "rotate(-90)")
            .text("Latency");
</script>
<div id="container"></div>
<script type="text/jsx">
    ReactDOM.render(<svg id="svg"></svg>,document.getElementById('container'));     
</script>
</body>
</html>

但是,当我请求此页面时,图表在浏览器中不可见。我在这里失踪的是什么?

2 个答案:

答案 0 :(得分:0)

除非&#34; svg&#34;是页面中现有svg的ID,在我看来,您忘记在变量svg中附加SVG:

var svg = d3.select("#svg")
    .append("svg")//this appends the SVG
    .attr("width", width + margin.left + margin.right)
    .attr("height",  height + margin.top + margin.bottom)
    .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

答案 1 :(得分:0)

由于d3代码在React代码之前执行,因此svg元素尚不存在。您可以创建一个呈现svg元素的react类,然后放置d3代码componentDidMount和/或componentDidUpdate方法。在将其添加到实际DOM之前,React会将所有内容呈现在shadow DOM中,因此您需要确保该元素可用,然后才能使用d3(或jQuery等)选择它。

class MySVG extends React.Component {

  componentDidMount() {
    var svg = d3.select('#my-svg');
    //Do svg stuff
  }

  render() {
    return (
      <svg id="my-svg"></svg>
    );
  }

}

export default MySVG;

然后使用ReactDOM.render()

渲染mySVG