javascript - 如何更好地组织网格线?

标签 javascript d3.js svg

有来自点的网格线。

是否有另一种性能更好的解决方案,因为如果我添加许多 svg 元素(等矩形、圆形、路径)并增加网格的尺寸,当我使用缩放、移动元素时,我会看到卡住效果...

网格的大小已更改。

另外,如何创建无限的网格线,而不是有限的网格线(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>

最佳答案

正如您所注意到的,这种方法并不是真正可扩展的,并且对性能有更大的影响。我发现使用 d3 轴进行网格的方法对性能影响最小,同时与缩放结合也相对简单,这样您就可以无限缩放,并且由于自动生成的“魔力”,网格线以合理的方式更新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

关于javascript - 如何更好地组织网格线?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41564514/

相关文章:

javascript - 如何在另一个div为空时隐藏一个div

javascript - 不一致 %sticky 命令

javascript - 没有 hack 或其他路由器的 Backbone.js 和 jQueryMobile 路由

javascript - D3 - 图例无法可视化

javascript - D3.js 比例 : Return the smaller of a constant and the value of a scale?

javascript - D3 强制定向图问题 : nodes are stacked at coordinate (0, 0)

javascript - 使用 d3js 的 onclick 在新选项卡中绘制图表

javascript - 单击提交按钮时按索引迭代数组 Ruby on Rails

javascript - SVG:加载文档后运行脚本

javascript - IE 11 SVG 动画流畅度