Merge branch 'brush-touch' into decorative-brush-resizers
Conflicts: d3.js d3.min.js src/svg/brush.js
This commit is contained in:
Коммит
0b93bee13f
|
@ -4068,7 +4068,10 @@ d3.svg.brush = function() {
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
g.each(function() {
|
g.each(function() {
|
||||||
var g = d3.select(this).style("pointer-events", "all").on("mousedown.brush", down),
|
var g = d3.select(this)
|
||||||
|
.style("pointer-events", "all")
|
||||||
|
.on("mousedown.brush", down)
|
||||||
|
.on("touchstart.brush", down),
|
||||||
bg = g.selectAll(".background").data([0]),
|
bg = g.selectAll(".background").data([0]),
|
||||||
fg = g.selectAll(".extent").data([0]),
|
fg = g.selectAll(".extent").data([0]),
|
||||||
tz = g.selectAll(".resize").data(resizes, String),
|
tz = g.selectAll(".resize").data(resizes, String),
|
||||||
|
@ -4120,13 +4123,16 @@ d3.svg.brush = function() {
|
||||||
|
|
||||||
function down() {
|
function down() {
|
||||||
var target = d3.select(d3.event.target),
|
var target = d3.select(d3.event.target),
|
||||||
|
touches = d3.event.changedTouches,
|
||||||
resize;
|
resize;
|
||||||
|
|
||||||
// Store some global state for the duration of the brush gesture.
|
// Store some global state for the duration of the brush gesture.
|
||||||
d3_svg_brush = brush;
|
d3_svg_brush = brush;
|
||||||
d3_svg_brushTarget = this;
|
d3_svg_brushTarget = this;
|
||||||
d3_svg_brushExtent = extent;
|
d3_svg_brushExtent = extent;
|
||||||
d3_svg_brushPoint = d3.svg.mouse(d3_svg_brushTarget);
|
d3_svg_brushPoint = touches
|
||||||
|
? d3.svg.touches(d3_svg_brushTarget, touches)[0]
|
||||||
|
: d3.svg.mouse(d3_svg_brushTarget);
|
||||||
|
|
||||||
// If the extent was clicked on, drag rather than brush;
|
// If the extent was clicked on, drag rather than brush;
|
||||||
// store the point between the mouse and extent origin instead.
|
// store the point between the mouse and extent origin instead.
|
||||||
|
@ -4241,6 +4247,8 @@ d3.svg.brush = function() {
|
||||||
d3.select(window)
|
d3.select(window)
|
||||||
.on("mousemove.brush", d3_svg_brushMove)
|
.on("mousemove.brush", d3_svg_brushMove)
|
||||||
.on("mouseup.brush", d3_svg_brushUp)
|
.on("mouseup.brush", d3_svg_brushUp)
|
||||||
|
.on("touchmove.brush", d3_svg_brushMove)
|
||||||
|
.on("touchend.brush", d3_svg_brushUp)
|
||||||
.on("keydown.brush", d3_svg_brushKeydown)
|
.on("keydown.brush", d3_svg_brushKeydown)
|
||||||
.on("keyup.brush", d3_svg_brushKeyup);
|
.on("keyup.brush", d3_svg_brushKeyup);
|
||||||
|
|
||||||
|
@ -4297,7 +4305,10 @@ function d3_svg_brushKeyup() {
|
||||||
|
|
||||||
function d3_svg_brushMove() {
|
function d3_svg_brushMove() {
|
||||||
if (d3_svg_brushPoint) {
|
if (d3_svg_brushPoint) {
|
||||||
var mouse = d3.svg.mouse(d3_svg_brushTarget),
|
var touches = d3.event.changedTouches,
|
||||||
|
mouse = touches
|
||||||
|
? d3.svg.touches(d3_svg_brushTarget, touches)[0]
|
||||||
|
: d3.svg.mouse(d3_svg_brushTarget),
|
||||||
g = d3.select(d3_svg_brushTarget);
|
g = d3.select(d3_svg_brushTarget);
|
||||||
|
|
||||||
// Preserve the offset for thick resizers.
|
// Preserve the offset for thick resizers.
|
||||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -0,0 +1,236 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>PivotGraph (Rollup) Layout</title>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body { font-family: sans-serif; font-size: 10px; }
|
||||||
|
path { fill: none; stroke: #ccc; }
|
||||||
|
circle { fill: #fff; stroke: steelblue; }
|
||||||
|
</style>
|
||||||
|
<script src="../../d3.js"></script>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
var social = {
|
||||||
|
nodes: [
|
||||||
|
{gender: "M", group: 1},
|
||||||
|
{gender: "F", group: 2},
|
||||||
|
{gender: "M", group: 1},
|
||||||
|
{gender: "M", group: 2},
|
||||||
|
{gender: "F", group: 2},
|
||||||
|
{gender: "M", group: 1},
|
||||||
|
{gender: "F", group: 1},
|
||||||
|
{gender: "M", group: 2},
|
||||||
|
{gender: "F", group: 2},
|
||||||
|
{gender: "F", group: 2}
|
||||||
|
],
|
||||||
|
links: [
|
||||||
|
{source: 0, target: 1},
|
||||||
|
{source: 1, target: 2},
|
||||||
|
{source: 2, target: 3},
|
||||||
|
{source: 2, target: 4},
|
||||||
|
{source: 2, target: 5},
|
||||||
|
{source: 2, target: 6},
|
||||||
|
{source: 2, target: 7},
|
||||||
|
{source: 5, target: 6},
|
||||||
|
{source: 6, target: 7},
|
||||||
|
{source: 5, target: 8},
|
||||||
|
{source: 8, target: 6},
|
||||||
|
{source: 6, target: 9}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
var w = 100,
|
||||||
|
h = 100,
|
||||||
|
p = 30,
|
||||||
|
x = d3.scale.ordinal().domain(social.nodes.map(fx)).range([0, w]),
|
||||||
|
y = d3.scale.ordinal().domain(social.nodes.map(fy)).range([0, h]);
|
||||||
|
|
||||||
|
function fx(d) { return d.gender; }
|
||||||
|
function fy(d) { return d.group; }
|
||||||
|
|
||||||
|
var vis = d3.select("body").append("svg")
|
||||||
|
.attr("w", w + 2 * p)
|
||||||
|
.attr("h", h + 2 * p)
|
||||||
|
.append("g")
|
||||||
|
.attr("transform", "translate(" + [p, p] + ")");
|
||||||
|
|
||||||
|
var layout = rollup()
|
||||||
|
.x(function(d) { return x(fx(d)); })
|
||||||
|
.y(function(d) { return y(fy(d)); });
|
||||||
|
|
||||||
|
var g = layout(social);
|
||||||
|
|
||||||
|
vis.selectAll("path")
|
||||||
|
.data(g.links)
|
||||||
|
.enter().append("path")
|
||||||
|
.style("stroke-width", function(d) { return d.value * 1.5; })
|
||||||
|
.attr("d", function(d) {
|
||||||
|
var tx = d.target.x,
|
||||||
|
sx = d.source.x,
|
||||||
|
ty = d.target.y,
|
||||||
|
sy = d.source.y,
|
||||||
|
dx = tx - sx,
|
||||||
|
dy = ty - sy,
|
||||||
|
dr = 2 * Math.sqrt(dx * dx + dy * dy);
|
||||||
|
return "M" + sx + "," + sy + "A" + dr + "," + dr + " 0 0,1 " + tx + "," + ty;
|
||||||
|
});
|
||||||
|
|
||||||
|
vis.selectAll("circle")
|
||||||
|
.data(g.nodes)
|
||||||
|
.enter().append("circle")
|
||||||
|
.attr("r", function(d) { return Math.sqrt(d.nodes.length * 20); })
|
||||||
|
.attr("cx", function(d) { return d.x; })
|
||||||
|
.attr("cy", function(d) { return d.y; });
|
||||||
|
|
||||||
|
vis.selectAll("text.x")
|
||||||
|
.data(x.domain())
|
||||||
|
.enter().append("text")
|
||||||
|
.attr("class", "x")
|
||||||
|
.attr("x", x)
|
||||||
|
.attr("y", -10)
|
||||||
|
.attr("text-anchor", "middle")
|
||||||
|
.text(String);
|
||||||
|
|
||||||
|
vis.selectAll("text.y")
|
||||||
|
.data(y.domain())
|
||||||
|
.enter().append("text")
|
||||||
|
.attr("class", "y")
|
||||||
|
.attr("x", -10)
|
||||||
|
.attr("dy", ".3em")
|
||||||
|
.attr("y", y)
|
||||||
|
.attr("text-anchor", "end")
|
||||||
|
.text(String);
|
||||||
|
|
||||||
|
function rollup() {
|
||||||
|
var directed = true,
|
||||||
|
x_ = rollupX,
|
||||||
|
y_ = rollupY,
|
||||||
|
nodes_ = rollupNodes,
|
||||||
|
links_ = rollupLinks,
|
||||||
|
linkValue = rollupLinkValue,
|
||||||
|
linkSource = rollupLinkSource,
|
||||||
|
linkTarget = rollupLinkTarget;
|
||||||
|
|
||||||
|
function rollup(d, i) {
|
||||||
|
var nodes = nodes_.call(this, d, i),
|
||||||
|
links = links_.call(this, d, i),
|
||||||
|
n = nodes.length,
|
||||||
|
m = links.length,
|
||||||
|
i = -1,
|
||||||
|
x = [],
|
||||||
|
y = [],
|
||||||
|
rnindex = 0,
|
||||||
|
rnodes = {},
|
||||||
|
rlinks = {};
|
||||||
|
|
||||||
|
// Compute rollup nodes.
|
||||||
|
while (++i < n) {
|
||||||
|
(d = nodes[i]).index = i;
|
||||||
|
x[i] = x_.call(this, d, i);
|
||||||
|
y[i] = y_.call(this, d, i);
|
||||||
|
var nodeId = id(i),
|
||||||
|
rn = rnodes[nodeId];
|
||||||
|
if (!rn) {
|
||||||
|
rn = rnodes[nodeId] = {
|
||||||
|
index: rnindex++,
|
||||||
|
x: x[i],
|
||||||
|
y: y[i],
|
||||||
|
nodes: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
rn.nodes.push(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute rollup links.
|
||||||
|
i = -1; while (++i < m) {
|
||||||
|
var value = linkValue.call(this, d = links[i], i),
|
||||||
|
source = linkSource.call(this, d, i),
|
||||||
|
target = linkTarget.call(this, d, i),
|
||||||
|
rsource = rnodes[id(typeof source === "number" ? source : source.index)],
|
||||||
|
rtarget = rnodes[id(typeof target === "number" ? target : target.index)],
|
||||||
|
linkId = !directed && rsource.index > rtarget.index
|
||||||
|
? rtarget.index + "," + rsource.index
|
||||||
|
: rsource.index + "," + rtarget.index,
|
||||||
|
rl = rlinks[linkId];
|
||||||
|
if (!rl) {
|
||||||
|
rl = rlinks[linkId] = {
|
||||||
|
source: rsource,
|
||||||
|
target: rtarget,
|
||||||
|
value: 0,
|
||||||
|
links: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
rl.links.push(links[i]);
|
||||||
|
rl.value += value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
nodes: d3.values(rnodes),
|
||||||
|
links: d3.values(rlinks)
|
||||||
|
};
|
||||||
|
|
||||||
|
function id(i) {
|
||||||
|
return x[i] + "," + y[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rollup.x = function(x) {
|
||||||
|
if (!arguments.length) return x_;
|
||||||
|
x_ = x;
|
||||||
|
return rollup;
|
||||||
|
};
|
||||||
|
|
||||||
|
rollup.y = function(x) {
|
||||||
|
if (!arguments.length) return y_;
|
||||||
|
y_ = x;
|
||||||
|
return rollup;
|
||||||
|
};
|
||||||
|
|
||||||
|
rollup.nodes = function(x) {
|
||||||
|
if (!arguments.length) return nodes_;
|
||||||
|
nodes_ = x;
|
||||||
|
return rollup;
|
||||||
|
};
|
||||||
|
|
||||||
|
rollup.links = function(x) {
|
||||||
|
if (!arguments.length) return links_;
|
||||||
|
links_ = x;
|
||||||
|
return rollup;
|
||||||
|
};
|
||||||
|
|
||||||
|
rollup.linkSource = function(x) {
|
||||||
|
if (!arguments.length) return linkSource;
|
||||||
|
linkSource = x;
|
||||||
|
return rollup;
|
||||||
|
};
|
||||||
|
|
||||||
|
rollup.linkTarget = function(x) {
|
||||||
|
if (!arguments.length) return linkTarget;
|
||||||
|
linkTarget = x;
|
||||||
|
return rollup;
|
||||||
|
};
|
||||||
|
|
||||||
|
rollup.linkValue = function(x) {
|
||||||
|
if (!arguments.length) return linkValue;
|
||||||
|
linkValue = x;
|
||||||
|
return rollup;
|
||||||
|
};
|
||||||
|
|
||||||
|
rollup.directed = function(x) {
|
||||||
|
if (!arguments.length) return directed;
|
||||||
|
directed = x;
|
||||||
|
return rollup;
|
||||||
|
};
|
||||||
|
|
||||||
|
return rollup;
|
||||||
|
|
||||||
|
function rollupX(d) { return d.x; }
|
||||||
|
function rollupY(d) { return d.y; }
|
||||||
|
function rollupNodes(d) { return d.nodes; }
|
||||||
|
function rollupLinks(d) { return d.links; }
|
||||||
|
function rollupLinkValue(d) { return 1; }
|
||||||
|
function rollupLinkSource(d) { return d.source; }
|
||||||
|
function rollupLinkTarget(d) { return d.target; }
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -11,7 +11,10 @@ d3.svg.brush = function() {
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
g.each(function() {
|
g.each(function() {
|
||||||
var g = d3.select(this).style("pointer-events", "all").on("mousedown.brush", down),
|
var g = d3.select(this)
|
||||||
|
.style("pointer-events", "all")
|
||||||
|
.on("mousedown.brush", down)
|
||||||
|
.on("touchstart.brush", down),
|
||||||
bg = g.selectAll(".background").data([0]),
|
bg = g.selectAll(".background").data([0]),
|
||||||
fg = g.selectAll(".extent").data([0]),
|
fg = g.selectAll(".extent").data([0]),
|
||||||
tz = g.selectAll(".resize").data(resizes, String),
|
tz = g.selectAll(".resize").data(resizes, String),
|
||||||
|
@ -63,13 +66,16 @@ d3.svg.brush = function() {
|
||||||
|
|
||||||
function down() {
|
function down() {
|
||||||
var target = d3.select(d3.event.target),
|
var target = d3.select(d3.event.target),
|
||||||
|
touches = d3.event.changedTouches,
|
||||||
resize;
|
resize;
|
||||||
|
|
||||||
// Store some global state for the duration of the brush gesture.
|
// Store some global state for the duration of the brush gesture.
|
||||||
d3_svg_brush = brush;
|
d3_svg_brush = brush;
|
||||||
d3_svg_brushTarget = this;
|
d3_svg_brushTarget = this;
|
||||||
d3_svg_brushExtent = extent;
|
d3_svg_brushExtent = extent;
|
||||||
d3_svg_brushPoint = d3.svg.mouse(d3_svg_brushTarget);
|
d3_svg_brushPoint = touches
|
||||||
|
? d3.svg.touches(d3_svg_brushTarget, touches)[0]
|
||||||
|
: d3.svg.mouse(d3_svg_brushTarget);
|
||||||
|
|
||||||
// If the extent was clicked on, drag rather than brush;
|
// If the extent was clicked on, drag rather than brush;
|
||||||
// store the point between the mouse and extent origin instead.
|
// store the point between the mouse and extent origin instead.
|
||||||
|
@ -184,6 +190,8 @@ d3.svg.brush = function() {
|
||||||
d3.select(window)
|
d3.select(window)
|
||||||
.on("mousemove.brush", d3_svg_brushMove)
|
.on("mousemove.brush", d3_svg_brushMove)
|
||||||
.on("mouseup.brush", d3_svg_brushUp)
|
.on("mouseup.brush", d3_svg_brushUp)
|
||||||
|
.on("touchmove.brush", d3_svg_brushMove)
|
||||||
|
.on("touchend.brush", d3_svg_brushUp)
|
||||||
.on("keydown.brush", d3_svg_brushKeydown)
|
.on("keydown.brush", d3_svg_brushKeydown)
|
||||||
.on("keyup.brush", d3_svg_brushKeyup);
|
.on("keyup.brush", d3_svg_brushKeyup);
|
||||||
|
|
||||||
|
@ -240,7 +248,10 @@ function d3_svg_brushKeyup() {
|
||||||
|
|
||||||
function d3_svg_brushMove() {
|
function d3_svg_brushMove() {
|
||||||
if (d3_svg_brushPoint) {
|
if (d3_svg_brushPoint) {
|
||||||
var mouse = d3.svg.mouse(d3_svg_brushTarget),
|
var touches = d3.event.changedTouches,
|
||||||
|
mouse = touches
|
||||||
|
? d3.svg.touches(d3_svg_brushTarget, touches)[0]
|
||||||
|
: d3.svg.mouse(d3_svg_brushTarget),
|
||||||
g = d3.select(d3_svg_brushTarget);
|
g = d3.select(d3_svg_brushTarget);
|
||||||
|
|
||||||
// Preserve the offset for thick resizers.
|
// Preserve the offset for thick resizers.
|
||||||
|
|
Загрузка…
Ссылка в новой задаче