如何使用矩形作为终点误差将线拖到终点?

时间:2019-02-13 17:03:31

标签: d3.js

我是d3.js的新手,如果这听起来像是一个幼稚的问题,请原谅我。我绘制了一条线(d3 v4),可以通过其端点拖动。终点是矩形。

当前输出如下:

这是它的外观 enter image description here

我面临的挑战是-当我开始拖动该点时,该线似乎是从左上角开始的。当我拖动同一条线的第二点时,该线将按预期方式拖动/移动。

示例数据如下:

The sample data

要求您提供有关如何解决上述问题的建议/意见。

下面是我正在使用的附件代码:

var margin = { top: 0, right: 0, bottom: 0, left: 0 },
    width = +svg.attr("width") - margin.left - margin.right,
    height = +svg.attr("height") - margin.top - margin.bottom;

// Creating the colour Category
var color = d3.scaleOrdinal(d3.schemeCategory10);

var y = d3.scaleLinear().range([390, 0]);

// Scale the range of the data

y.domain([0, d3.max(data, function (d) { return Math.max(d.nonpromotedprice, d.promotedprice)*1.2; })]).nice();

// Line for the 1st Block
var lines = svg.selectAll("line")
    .data(data)
    .enter()
    .append('line')// attach a line
    .style("stroke", "#E6EAEE")
    .style("stroke-width", 8) // colour the line
    .attr("x1", function (d) { return d.x_value; }) // x position of the first end of the line
    .attr("y1", function (d) { return y(d.nonpromotedprice); }) // y position of the first end of the line
    .attr("x2", function (d) { return d.x_value; }) // x position of the second end of the line
    .attr("y2", function (d) { return y(d.promotedprice); });

// Add the Y Axis
svg.append("g")
    .attr("class", "grid")
    .attr("fill", "lightgrey")
    .attr("stroke-width", 0.7)
    .attr("stroke-opacity", 0.2)
    .call(d3.axisLeft(y)
        .tickSize(-400)
        .tickFormat(""));	
	
var topEndPoints = data.map(function (line, i) {
    return {
        'x': line.x_value,
        'y': line.nonpromotedprice,
        'marker': 'marker-start',
        'lineIndex': i
    };
});

var bottomEndPoints = data.map(function (line, i) {
    return {
        'x': line.x_value,
        'y': line.promotedprice,
        'marker': 'marker-end',
        'lineIndex': i
    };
});

var MiddleEndPoints = data.map(function (line, i) {
    return {
        'x': line.x_value,
        'y': line.avgprice,
        'marker': 'marker-middle',
        'lineIndex': i
    };
});
var endPointsData = topEndPoints.concat(bottomEndPoints, MiddleEndPoints);

// Pointer to d3 rectangles
var endPoints = svg
    .selectAll('rect')
    .data(endPointsData)
    .enter()
    .append('rect')
    .attr("width", 12)
    .attr("height", 8)
    .attr("x", function (d) { return d.x - 6; })
    .attr("y", function (d) { return y(d.y); })
    //.attr("cx", function (d) { return d.x; })
    //.attr("cy", function (d) { return d.y; })
    //.attr('r',7)
    .attr("fill", function (d) { return color(d.x); })
    .call(d3.drag()
		//.origin(function(d) { return y(d.y); })
		 .subject(function() { 
				var t = d3.select(this);
				return {x: t.attr("x"), y: t.attr("y")};
			})		
        .on("start", dragstarted)
        .on("drag", dragged)
        .on("end", dragended));


// draw the logo
svg.selectAll("image")
    .data(data)
    .enter()
    .append("svg:image")
    .attr("xlink:href", function (d) { return d.logo; })
    //.append("rect")  
    .attr("x", function (d) { return d.x_value - 13; })
    .attr("y", function (d) { return y(d.nonpromotedprice + 35); })
    .attr("height", 25)
    .attr("width", 25);



function dragstarted() {
    d3.select(this).classed("active", true).attr('y', d.y = y(d3.event.y));
}

function dragged(d, i) {
    var marker = d3.select(this);

    // Update the marker properties
    marker
        //.attr('cx', d.x = d3.event.x)
        .attr('y', d.y = d3.event.y);
	

    // Update the line properties
    lines
        .filter(function (lineData, lineIndex) {
            return lineIndex === d.lineIndex;
        })
        .attr('x1', function (lineData) {
            return d.marker === 'marker-start' ? lineData.x1 = d.x : lineData.x1;
        })
        .attr('y1', function (lineData) {
            return d.marker === 'marker-start' ? lineData.y1 = d.y : lineData.y1;
        })

        .attr('x2', function (lineData) {
            return d.marker === 'marker-end' ? lineData.x2 = d.x : lineData.x2;

        })
        .attr('y2', function (lineData) {
            return d.marker === 'marker-end' ? lineData.y2 = d.y : lineData.y2;
        });
}

function dragended() {
    d3.select(this).classed("active", false);
		Shiny.setInputValue("pricechanged",
            {price: (d3.max(data, function (d) { return Math.max(d.nonpromotedprice, d.promotedprice); }) -(d3.event.y / 390)* d3.max(data, function (d) { return Math.max(d.nonpromotedprice, d.promotedprice); }))*1.19}, 
			{priority: "event"}
          );
		  
}

0 个答案:

没有答案