我正在关注此示例http://jsfiddle.net/enigmarm/3HL4a/13/制作条形图。制作图表时我想做的是使data-labels
可拖动。我怎样才能做到这一点?我试过调用拖动行为没有任何结果。我得到的只是NaN
作为transform
函数的输入。
var w = 600;
var h = 250;
var dataset = [
{ key: 0, value: 5 },
{ key: 1, value: 10 },
{ key: 2, value: 13 },
{ key: 3, value: 19 },
{ key: 4, value: 21 },
{ key: 5, value: 25 },
{ key: 6, value: 22 },
{ key: 7, value: 18 },
{ key: 8, value: 15 },
{ key: 9, value: 13 },
{ key: 10, value: 11 },
{ key: 11, value: 12 },
{ key: 12, value: 15 },
{ key: 13, value: 20 },
{ key: 14, value: 18 },
{ key: 15, value: 17 },
{ key: 16, value: 16 },
{ key: 17, value: 18 },
{ key: 18, value: 23 },
{ key: 19, value: 25 } ];
var xScale = d3.scale.ordinal()
.domain(d3.range(dataset.length))
.rangeRoundBands([0, w], 0.05);
var yScale = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) {return d.value;})])
.range([0, h]);
var key = function(d) {
return d.key;
};
//Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
//Create bars
svg.selectAll("rect")
.data(dataset, key)
.enter()
.append("rect")
.attr("x", function(d, i) {
return xScale(i);
})
.attr("y", function(d) {
return h - yScale(d.value);
})
.attr("width", xScale.rangeBand())
.attr("height", function(d) {
return yScale(d.value);
})
.attr("fill", function(d) {
return "rgb(0, 0, " + (d.value * 10) + ")";
})
//Tooltip
.on("mouseover", function(d) {
//Get this bar's x/y values, then augment for the tooltip
var xPosition = parseFloat(d3.select(this).attr("x")) + xScale.rangeBand() / 2;
var yPosition = parseFloat(d3.select(this).attr("y")) + 14;
//Update Tooltip Position & value
d3.select("#tooltip")
.style("left", xPosition + "px")
.style("top", yPosition + "px")
.select("#value")
.text(d.value);
d3.select("#tooltip").classed("hidden", false)
})
.on("mouseout", function() {
//Remove the tooltip
d3.select("#tooltip").classed("hidden", true);
}) ;
//Create labels
svg.selectAll("text")
.data(dataset, key)
.call(drag2)
.enter()
.append("text")
.text(function(d) {
return d.value;
})
.attr("text-anchor", "middle")
.attr("x", function(d, i) {
return xScale(i) + xScale.rangeBand() / 2;
})
.attr("y", function(d) {
return h - yScale(d.value) + 14;
})
.attr("font-family", "sans-serif")
.attr("font-size", "11px")
.attr("fill", "white");
var sortOrder = false;
var sortBars = function () {
sortOrder = !sortOrder;
sortItems = function (a, b) {
if (sortOrder) {
return a.value - b.value;
}
return b.value - a.value;
};
svg.selectAll("rect")
.sort(sortItems)
.transition()
.delay(function (d, i) {
return i * 50;
})
.duration(1000)
.attr("x", function (d, i) {
return xScale(i);
});
svg.selectAll('text')
.sort(sortItems)
.transition()
.delay(function (d, i) {
return i * 50;
})
.duration(1000)
.text(function (d) {
return d.value;
})
.attr("text-anchor", "middle")
.attr("x", function (d, i) {
return xScale(i) + xScale.rangeBand() / 2;
})
.attr("y", function (d) {
return h - yScale(d.value) + 14;
});
};
// Add the onclick callback to the button
d3.select("#sort").on("click", sortBars);
d3.select("#reset").on("click", reset);
function randomSort() {
svg.selectAll("rect")
.sort(sortItems)
.transition()
.delay(function (d, i) {
return i * 50;
})
.duration(1000)
.attr("x", function (d, i) {
return xScale(i);
});
svg.selectAll('text')
.sort(sortItems)
.transition()
.delay(function (d, i) {
return i * 50;
})
.duration(1000)
.text(function (d) {
return d.value;
})
.attr("text-anchor", "middle")
.attr("x", function (d, i) {
return xScale(i) + xScale.rangeBand() / 2;
})
.attr("y", function (d) {
return h - yScale(d.value) + 14;
});
}
var drag2 = d3.behavior.drag()
.on("drag", function(d,i) {
d3.select(this)
.attr("transform", function( d, i) {
d.x += d3.event.dx;
d.y += d3.event.dy;
return "translate(" + [ d3.event.dx,d3.event.dy ] + ")"
});
function reset() {
svg.selectAll("rect")
.sort(function(a, b){
return a.key - b.key;
})
.transition()
.delay(function (d, i) {
return i * 50;
})
.duration(1000)
.attr("x", function (d, i) {
return xScale(i);
});
svg.selectAll('text')
.sort(function(a, b){
return a.key - b.key;
})
.transition()
.delay(function (d, i) {
return i * 50;
})
.duration(1000)
.text(function (d) {
return d.value;
})
.attr("text-anchor", "middle")
.attr("x", function (d, i) {
return xScale(i) + xScale.rangeBand() / 2;
})
.attr("y", function (d) {
return h - yScale(d.value) + 14;
});
};
答案 0 :(得分:3)
我不确定你希望拖拽功能如何表现,所以我已经让它发挥作用了。您可以在.on('drag')
函数中随意执行任何操作。这是fiddle。如果您有任何疑问,请随时询问。
编辑:现在您可以沿y-axis
移动文本标签。我只需使用transform
更改y
的{{1}}属性,而不是text
。
mouse