将d3.js svg元素内嵌到HTML

时间:2018-02-10 06:21:12

标签: html d3.js svg

我有一个(最终)表现良好的响应式d3.js v4 svg图表,我想在我的HTML代码中内嵌,即我的HTML标题和其他元素应位于我的窗口顶部,然后是图表。而是在图表上绘制HTML元素。我可以填充边距以使其工作,但更喜欢有一种方法来控制svg的垂直排序。 这是一些代码:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Plot Viewer</title>
    <script src="js/lib/d3.v4.min.js"></script>
    <script src="js/lib/jquery.min.js"></script>

    <style>

      h1 {
        margin: 0 0 22px 0;
        font-size: 14px;
        color: #333;
      }

      .line { 
        fill: none;
        stroke: steelblue;
        stroke-width: 3px;
      }

      #chart { 
        float: inherit;
        clear: both;
      }

      .grid line {
        stroke: lightgrey; stroke-opacity: 0.7; shape-rendering: crispEdges;
      }

      .grid path { stroke-width: 0;
      }

    </style>
  </head>

  <body>

    <h1>Solar Insolation, in W/m2</h1>
    <div id="chart"></div>

    <script>

      var chartDiv = document.getElementById("chart");
      var svg = d3.select(chartDiv).append("svg");

      // parse the date time
      var parseTime = d3.timeParse("%m/%d %H:%M");

      function render() {

        $("svg").empty();

        // Extract the width and height that was computed by CSS.
        var width = chartDiv.clientWidth;
        var height = chartDiv.clientHeight;

        // Use the extracted size to set the size of an SVG element.
        svg
          .attr("width", width)
          .attr("height", height);

        // set the dimensions and margins of the graph
        var margin = {top: 10, right: 10, bottom: 55, left: 55},
          width = width - margin.left - margin.right,
          height = height - margin.top - margin.bottom;

        // set the ranges
        var x = d3.scaleTime().range([0, width]);
        var y = d3.scaleLinear().range([height, 0]);

        // define the line
        var valueline = d3.line()
          .x(function(d) { return x(d.time); })
          .y(function(d) { return y(d.solar); });

        // gridlines in x axis function
        function make_x_gridlines() { return d3.axisBottom(x)
        .ticks(24)
        }

        // gridlines in y axis function
        function make_y_gridlines() { return d3.axisLeft(y)
        .ticks(10)
        }

        // Get the data
        d3.csv("data.csv", function(error, data) {

          if (error) throw error;

          // format the data
          data.forEach(function(d) {
            d.time = parseTime(d.time);
            d.solar = +d.solar;
          });

          // Scale the range of the data
          x.domain(d3.extent(data, function(d) { return d.time; }));
          y.domain(d3.extent(data, function(d) { return d.solar; }));

          // Add the valueline path.
          svg.append("path")
            .data([data])
            .attr("class", "line")
            .attr("d", valueline)
            .attr("transform", "translate(40, 10)");

          // make room for text at top of Y axis

          var extraHeight = height + 10;

          // Add the X Axis
          svg.append("g")
            .attr("transform", "translate(40," + extraHeight + ")")
            .call(d3.axisBottom(x)
              .tickFormat(d3.timeFormat("%m/%d %H:%M  ")))
            .selectAll("text")
            .style("text-anchor", "end")
            .attr("dx", "-.8em")
            .attr("dy", ".15em")
            .attr("transform", "rotate(-45)");

          // Add the Y Axis
          svg.append("g")
            .attr("transform", "translate(40 ,10)")
            .call(d3.axisLeft(y));

          // add the X gridlines
          svg.append("g")
              .attr("class", "grid")
              .attr("transform", "translate(40," + extraHeight + ")")
              .call(make_x_gridlines()
                  .tickSize(-height)
                  .tickFormat("")
              )

          // add the Y gridlines
          svg.append("g")
              .attr("class", "grid")
              .attr("transform", "translate(40 ,10)")
              .call(make_y_gridlines()
                  .tickSize(-width)
                  .tickFormat("")
              )

        });
      }

      render();

      // Redraw based on the new size whenever the browser window is resized
      window.addEventListener("resize", render);

    </script>
  </body>
</html>

和chart.csv的一些内容:

time,solar
11/30 15:45,56.0
11/30 15:50,121.6
11/30 15:55,60.1
11/30 16:00,62.3
11/30 16:05,65.9
11/30 16:10,85.0
11/30 16:15,109.5
11/30 16:20,116.5
11/30 16:25,141.0
11/30 16:30,367.0
11/30 16:35,387.9
11/30 16:40,490.1
11/30 16:45,419.4
11/30 16:50,513.2
11/30 16:55,409.5
11/30 17:00,455.7
11/30 17:05,373.6
11/30 17:10,586.1
11/30 17:15,550.2
11/30 17:20,479.9
11/30 17:25,552.4
11/30 17:30,638.1
11/30 17:35,662.3
11/30 17:40,683.2
11/30 17:45,704.0
11/30 17:50,691.6
11/30 17:55,711.7
11/30 18:00,538.8
11/30 18:05,453.5

在当前标题之后和页脚之前是否有一种干净的方法来粘贴生成的svg元素

我意识到没有float:center属性,所以尝试继承。有趣的是,它从垂直方向开始变小,但是当垂直窗口尺寸减小时,y轴上的每次扩展都会使图表不会缩小。

感谢。

1 个答案:

答案 0 :(得分:0)

您正在以错误的方式定位图表。您的HTML也错了:h3超出了<body>!你应该这样:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Plot Viewer</title>

    <style>
      #chart, h1, h3 {
        float: left;
        clear: both;
      }
    </style>
  </head>

  <body>
    <h1>Solar Insolation, in W/m2</h1>
    <div id="chart"></div>
    <h3> Blah, blah, blah...</h3>
  </body>
</html>

注意您的问题是关于元素的定位,而不是关于图表。

实施例

以下代码段显示最终结果。一旦图表在那里,它将在流程中呈现。

&#13;
&#13;
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Plot Viewer</title>

    <style>
      h1 {
        margin: 0 0 22px 0;
        font-size: 14px;
        color: #333;
      }
      #chart,h1,h3 {
        float: left;
        clear: both;
      }
    </style>
  </head>

  <body>

    <h1>Solar Insolation, in W/m2</h1>
    <div id="chart">
      My chart here 
      <div style="width:200px;height:200px;background-color:#ff9900"></div>
      </div>
    <h3> Blah, blah, blah...</h3>
  </body>
</html>
&#13;
&#13;
&#13;