【问题标题】:Drawing outside graph borders绘制图形边界外
【发布时间】:2014-09-09 02:57:47
【问题描述】:

我正在创建一些数据的 d3 图,我希望具有缩放和平移功能。当我绘制我的数据并放大或平移时,数据可以移动到定义的绘图区域之外而不会被剪裁。

正如您在图像中看到的那样,橙色点出现在绿色区域上,而我本以为它们会被剪掉。

关于什么是错的任何想法?

演示http://jsfiddle.net/ng6srz4o/

var dataX = [1,3,5,7,9];
var dataY = [0,2,4,6,8];

var margin, padding, outerWidth, outerHeight, innerWidth, innerHeight;
var xAxis, yAxis, xScale, yScale, svg, container, zoom, tooltip;

// assign the dimensions here, works the best
outerWidth = Math.ceil ($(window).width() * 0.90);
outerHeight = Math.ceil ($(window).height() * 0.55);

// distance of the outerRect from the innerRect
margin = { top: 16, right: 16, bottom: 32, left: 32 };

// distance of the actual data from the innerRect
padding = { top: 0, right: 32, bottom: 0, left: 32 };

innerWidth = outerWidth - margin.left - margin.right;
innerHeight = outerHeight - margin.top - margin.bottom;

xScale = d3.scale.linear()
    .domain([ d3.min(dataX), d3.max(dataX) ])
    .range([ padding.left, innerWidth - padding.right ]);

yScale = d3.scale.linear()
    .domain([ d3.min(dataY), d3.max(dataY) ])
    .range([ innerHeight - padding.bottom, padding.top ]);

zoom = d3.behavior.zoom()
    .x(xScale).y(yScale)
    .scaleExtent([1, 20])
    .on ("zoom", onZoom);

svg = d3.select("#svgContainer")
    .append("svg:svg")
        .attr("width", outerWidth)
        .attr("height", outerHeight)
        .style("background", "green")
    .append("svg:g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
        .call(zoom);

drawAxis();

// white rect behind the graph
var rect = svg.append("svg:rect")
    .attr("width", innerWidth)
    .attr("height", innerHeight)
    .style("fill", "gray");

container = svg.append("svg:g");

var graph = container.append("svg:g").selectAll("scatter-dots")
        .data(dataY) 
    .enter().append("svg:circle")
        .attr("cy", function (d) { return yScale(d); })
        .attr("cx", function (d,i) { return xScale(dataX[i]); })
        .attr("r", 10)
        .style("fill", "orange");

function onZoom() {

    var t = d3.event.translate,
        s = d3.event.scale;

    container.attr("transform", "translate(" + t + ")scale(" + s + ")");

    svg.select(".x.axis").call(xAxis);
    svg.select(".y.axis").call(yAxis);
}

function drawAxis()
{
    xAxis = d3.svg.axis()
        .scale(xScale)
        .orient("bottom");

    svg.append("svg:g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + innerHeight + ")")
        .style("fill", "blue")
        .call(xAxis);

    yAxis = d3.svg.axis()
        .scale(yScale)
        .orient("left");

    svg.append("svg:g")
        .attr("class", "y axis")
        .style("fill", "red")
        .call(yAxis);
}

【问题讨论】:

    标签: javascript d3.js


    【解决方案1】:

    现在,您的所有点都包含在 g 元素中,它不会剪切您正在绘制的任何点。

    如果您想剪裁点,您可以在主svg 中添加一个svg 元素,这将剪裁其中包含的任何内容,如下所示:

    var mainSVG = d3.select('body').append('svg')
      .attr('width', outerWidth)
      .attr('height', outerHeight);
    
    var innerSVG = mainSVG.append('svg')
      .attr('width', innerWidth)
      .attr('height', innerHeight)
      .selectAll('scatter-dots')
      ...
    

    (updated) fiddle.

    【讨论】:

    • 刚刚看了小提琴。我仍然可以将这些点平移和缩放到绿色区域。
    • 现在,您的缩放行为会移动 g 元素,它是我创建的 svg 元素的父元素。您需要在内部 svg 内移动该元素,以便缩放行为不会移动 svg。请参阅更正的小提琴。
    • 知道我只能在光标位于其中一个橙色点上时进行缩放和平移。如果光标在灰色区域,则没有平移和缩放。
    • 我将.call(zoom) 移至svg:rect,它似乎可以正常工作。
    • 一般来说,无论你在 DOM 中放置 zoom 行为的什么,所有内容都可以用作缩放句柄。
    猜你喜欢
    • 2022-08-03
    • 2020-11-29
    • 1970-01-01
    • 1970-01-01
    • 2018-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-20
    相关资源
    最近更新 更多