如何更好地组织网格线?

时间:2017-01-10 08:39:24

标签: javascript d3.js svg

点有网格线。

是否有其他解决方案具有更好的性能,因为如果我添加了许多svg元素(等等,rects,circle,paths)并增加了网格的尺寸,当我使用zoom,move元素时,我会看到冻结效果...

网格的大小已更改。

另外,如何创建无限的网格线,而不是限制(gridCountX,gridCountY)?

由于



var svg = d3.select("body").append("svg");
var svgG = svg.append("g");

var gridLines = svgG.append("g").classed("grid-lines-container", true).data(["gridLines"]);

var gridCountX = _.range(100);
var gridCountY = _.range(100);
var size = 10;

gridLines.selectAll("g").data(gridCountY)
    .enter()
    .append("g")
    .each(function(d) {
        d3.select(this).selectAll("circle").data(gridCountX).enter()
            .append("circle")
            .attr("cx", function(_d) {return _d*size;})
            .attr("cy", function(_d) {return d*size;})
            .attr("r", 0.5)
            .attr("style", function() {
                return "stroke: black;";
            });
    });

var zoomSvg = d3.zoom()
        .scaleExtent([1, 10])
        .on("zoom", function(){
            svgG.attr("transform", d3.event.transform);
        });
    
svg.call(zoomSvg);

svg {
    width: 100%;
    height: 100%;
    border: 1px solid #a1a1a1;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://d3js.org/d3.v4.min.js"></script>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

正如您所指出的,这种方法不具备可扩展性,对性能影响更大。我已经发现利用d3轴进行网格的方法具有最小的性能影响,同时也可以相对简单地结合变焦,这样你可以通过网格线以合理的方式进行无限放大,因为&#34;魔术&# 34;在d3中自动生成敏感蜱位置。

要在d3 v4中实现类似的功能,您可以按照这些方式执行某些操作:

var svg = d3.select("svg"),
    margin = {top: 20, right: 140, bottom: 50, left: 70},
    width = svg.attr("width") - margin.left - margin.right,
    height = svg.attr("height") - margin.top - margin.bottom,
    g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")"),
    innerSvg = g.append("svg").attr("width", width).attr("height", height);

// Calculate domain for x and y from data and store in x0, y0 (not shown here)
x.domain(x0);
y.domain(y0);

xGridAxis = d3.axisBottom(x).ticks(10);
yGridAxis = d3.axisLeft(y).ticks(10 * height / width); 


// Create grouping and additional set of axes for displaying grid
innerSvg.append("g")
    .attr("class", "grid x-grid")
    .attr("transform", "translate (0," + height + ")")
    .call(xGridAxis
              .tickSize(-height, 0, 0)
              .tickFormat("")
    )
  .selectAll(".tick");

innerSvg.append("g")
    .attr("class", "grid y-grid")
    .attr("transform", "translate (" + width + ", 0)")
    .call(yGridAxis
              .tickSize(width)
              .tickFormat("")
    );

// Add element to capture mouse events for drag and pan of plots
var zoom = d3.zoom()
  .on("zoom", zoomed);

var scrollZoom = innerSvg.append("rect")
    .attr("class", "zoom")
    .attr("width", width)
    .attr("height", height)
    .attr("pointer-events", "all") // Defaults to panning with mouse
    .call(zoom);

// Mouse panning and scroll-zoom implementation using d3.zoom
// Modification of : http://bl.ocks.org/lorenzopub/013c0c41f9ffab4d27f860127f79c5f5
function zoomed() {
  lastEventTransform = d3.event.transform;
  // Rescale the grid using the new transform associated with zoom/pan action
  svg.select(".x-grid").call(xGridAxis.scale(lastEventTransform.rescaleX(x)));
  svg.select(".y-grid").call(yGridAxis.scale(lastEventTransform.rescaleY(y)));

  // Calculate transformed x and y locations which are used to redraw all plot elements
  var xt = lastEventTransform.rescaleX(x),
      yt = lastEventTransform.rescaleY(y);

  // Code below just shows how you might do it. Will need to tweak based on your plot
  var line = d3.line()
      .x(function(d) { return xt(d.x); })
      .y(function(d) { return yt(d.y); });

  innerSvg.selectAll(".line")
      .attr("d", function(d) { return line(d.values); });

  innerSvg.selectAll(".dot")
      .attr("cx", function(d) {return xt(d.x); })
      .attr("cy", function(d) {return yt(d.y); });
}

以下是d3 v4中的一个成功案例,它激发了我上面的版本:

http://bl.ocks.org/lorenzopub/013c0c41f9ffab4d27f860127f79c5f5