【问题标题】:Draggable interactive graphic element using D3使用 D3 的可拖动交互式图形元素
【发布时间】:2018-12-14 19:10:22
【问题描述】:

我有一个具有挑战性的想法要构建,但还没有想到解决方案。具有交互式/可拖动图形的设计请求,正如我通过下面的链接发送的那样。

但是,这些图形元素将分布在页面上的特定位置,周围还有其他元素(文本、图像等)。这个想法是让用户“玩”图形圆圈,只是做一些“酷而有趣”的事情。用户必须能够从图形中拖动圆圈并在整个页面上更改其视觉效果。

问题是:如果我将此元素放置在特定位置(例如,在 div 内),如果我们将圆圈拖到“画布”区域之外,则元素不再可见。

如何将此canvas-div元素放置在特定位置,同时允许其中的元素进入外部限制区域?

我曾考虑将其放置在相对或绝对位置,页面的高度和宽度为 100%,但我猜它在响应式中会不合适,或者仅使用 % 来始终放置在一个好位置非常复杂位置。有什么建议吗?

我正在使用 d3.js

谢谢!!

这是链接:https://codepen.io/A8-XPs/pen/ePWRxZ?editors=0010

HTML

<svg width="500" height="350"></svg>

JS

var svg = d3.select("svg"),
    margin = {top: 20, right: 20, bottom: 30, left: 50},
    width = +svg.attr("width") - margin.left - margin.right,
    height = +svg.attr("height") - margin.top - margin.bottom;

let points = d3.range(1, 10).map(function(i) {
    return [i * width / 10, 50 + Math.random() * (height - 100)];
});
var x = d3.scaleLinear()
    .rangeRound([0, width]);

var y = d3.scaleLinear()
    .rangeRound([height, 0]);

var xAxis = d3.axisBottom(x),
    yAxis = d3.axisLeft(y);

var line = d3.line()
    .x(function(d) { return x(d[0]); })
    .y(function(d) { return y(d[1]); })
    .curve(d3.curveCatmullRom.alpha(0.5))

let drag = d3.drag()
        .on('start', dragstarted)
        .on('drag', dragged)
        .on('end', dragended);

svg.append('rect')
    .attr('class', 'zoom')
    .attr('cursor', 'move')
    .attr('fill', 'none')
    .attr('pointer-events', 'all')
    .attr('width', width)
    .attr('height', height)
    .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')')

 var focus = svg.append("g")
                .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

x.domain(d3.extent(points, function(d) { return d[0]; }));
y.domain(d3.extent(points, function(d) { return d[1]; }));

focus.append("path")
    .datum(points)
    .attr("fill", "none")
    .attr("stroke", "steelblue")
    .attr("stroke-linejoin", "round")
    .attr("stroke-linecap", "round")
    .attr("stroke-width", 1.5)
    .attr("d", line);

focus.selectAll('circle')
    .data(points)
    .enter()
    .append('circle')
    .attr('r', 5.0)
    .attr('cx', function(d) { return x(d[0]);  })
    .attr('cy', function(d) { return y(d[1]); })
    .style('cursor', 'pointer')
    .style('fill', 'steelblue');

focus.selectAll('circle')
        .call(drag);

focus.append('g')
    .attr('class', 'axis axis--x')
    .attr('transform', 'translate(0,' + height + ')')
    .call(xAxis);

focus.append('g')
    .attr('class', 'axis axis--y')
    .call(yAxis);

function dragstarted(d) {
    d3.select(this).raise().classed('active', true);
}

function dragged(d) {
    d[0] = x.invert(d3.event.x);
    d[1] = y.invert(d3.event.y);
    d3.select(this)
        .attr('cx', x(d[0]))
        .attr('cy', y(d[1]))
    focus.select('path').attr('d', line);
}

function dragended(d) {
    d3.select(this).classed('active', false);
}

【问题讨论】:

    标签: d3.js draggable


    【解决方案1】:

    PS:我只需将简单的 CSS 应用于 SVG 即可解决问题:

    溢出:可见;

    希望它也能在真实的页面场景中工作。

    【讨论】:

    • 问题:一旦圆圈超出限制区域,就不能再拖动了
    猜你喜欢
    • 2019-10-08
    • 1970-01-01
    • 2016-10-04
    • 1970-01-01
    • 2012-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-09
    相关资源
    最近更新 更多