Related
I'm working with d3, but can't seem to add an image to my SVG circle? I've tried different ways but won't give the output I want. Can someone help me?
The image loaded correctly so that shouldn't be the problem. I also tried the fill attribute but it didn't work.
import React, { Component } from "react";
import "../styles/style.css";
import $ from "jquery";
import * as d3 from "d3";
import btcImage from "../images/btc.png";
const crypto = require("../data/cryptoData.json");
const coins = [];
for (let i = 0; i < crypto.data.length; i++) {
var coin = crypto.data[i];
coins.push(coin);
}
var data = [];
coins.forEach((coin) => {
var text = coin.symbol;
var r = coin.quote.USD.market_cap / 4000000000;
data.push({
text: text,
category: coin.quote.USD.percent_change_24h,
image: btcImage,
r: r,
r_change_1: coin.quote.USD.market_cap / 4000000000,
r_change_2: coin.quote.USD.market_cap / 4000000000,
});
});
function collide(alpha) {
var quadtree = d3.geom.quadtree(data);
return function (d) {
var r = d.r + 10,
nx1 = d.x - r,
nx2 = d.x + r,
ny1 = d.y - r,
ny2 = d.y + r;
quadtree.visit(function (quad, x1, y1, x2, y2) {
if (quad.point && quad.point !== d) {
var x = d.x - quad.point.x,
y = d.y - quad.point.y,
l = Math.sqrt(x * x + y * y),
r = d.r + quad.point.r;
if (l < r) {
l = ((l - r) / l) * (1 + alpha);
d.x -= x *= l;
d.y -= y *= l;
quad.point.x += x;
quad.point.y += y;
}
}
return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
});
};
}
const bubbleCloud = (element) => {
var container = d3.select(".bubble-cloud");
var $container = $(".bubble-cloud");
var containerWidth = $container.width();
var containerHeight = $container.height();
var svgContainer = container
.append("svg")
.attr("width", containerWidth)
.attr("height", containerHeight);
// prepare layout
var force = d3.layout
.force()
.size([containerWidth, containerHeight])
.gravity(0)
.charge(0)
.friction(1);
// load data
force.nodes(data).start();
// create item groups
var node = svgContainer
.selectAll(".node")
.data(data)
.enter()
.append("g")
.attr("class", "node")
.call(force.drag);
// create circles
node
.append("defs")
.append("pattern")
.attr("height", 60)
.attr("width", 60)
.attr("x", 0)
.attr("y", 0)
.append("image")
.attr("xlink:href", function (d) {
return d.image;
})
.attr("height", 60)
.attr("width", 60)
.attr("x", 0)
.attr("y", 0);
node
.append("circle")
.attr("r", 1e-6)
.style("fill", function (d) {
return d.image;
});
// create labels
node
.append("text")
.text(function (d) {
return d.text;
})
.classed("text", true)
.style({
fill: "#ffffff",
"text-anchor": "middle",
"font-size": "12px",
"font-weight": "bold",
"text-transform": "uppercase",
"font-family": "Tahoma, Arial, sans-serif",
});
node
.append("text")
.text(function (d) {
return d.category;
})
.classed("category", true)
.style({
color: "white",
"font-family": "Tahoma, Arial, sans-serif",
"text-anchor": "middle",
"font-size": "9px",
});
node
//.append("line")
//.classed("line", true)
//.attr({
// x1: 0,
// y1: 0,
// x2: 0,
// y2: 0,
//})
.attr("stroke-width", 1)
.attr("stroke", function (d) {
return d.stroke;
});
// put circle into movement
force.on("tick", function (e) {
d3.selectAll("circle")
.each(collide(0.1))
.attr("r", function (d) {
return d.r;
})
.attr("cx", function (d) {
// boundaries
if (d.x <= d.r) {
d.x = d.r + 1;
}
if (d.x >= containerWidth - d.r) {
d.x = containerWidth - d.r - 1;
}
return d.x;
})
.attr("cy", function (d) {
// boundaries
if (d.y <= d.r) {
d.y = d.r + 1;
}
if (d.y >= containerHeight - d.r) {
d.y = containerHeight - d.r - 1;
}
return d.y;
});
d3.selectAll("line").attr({
x1: function (d) {
return d.x - d.r + 10;
},
y1: function (d) {
return d.y;
},
x2: function (d) {
return d.x + d.r - 10;
},
y2: function (d) {
return d.y;
},
});
d3.selectAll(".text")
.attr("x", function (d) {
return d.x;
})
.attr("y", function (d) {
return d.y - 10;
});
d3.selectAll(".category")
.attr("x", function (d) {
return d.x;
})
.attr("y", function (d) {
return d.y + 20;
});
force.alpha(0.1);
});
};
class Bubbles extends Component {
render() {
return <div className="bubble-cloud" ref={bubbleCloud}></div>;
}
}
export default Bubbles;
I think I'm overlooking something
Output:
I am trying to implememt this example
https://bl.ocks.org/mbostock/1256572
So I built this page
<!DOCTYPE html>
<meta charset="utf-8">
<style type="text/css">
svg {
font-family: "Helvetica Neue", Helvetica;
}
.line {
fill: none;
stroke: #000;
stroke-width: 2px;
}
</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
var m = [20, 20, 30, 20],
w = 960 - m[1] - m[3],
h = 500 - m[0] - m[2];
var x,
y,
duration = 1500,
delay = 500;
var color = d3.scale.category10();
var svg = d3.select("body").append("svg")
.attr("width", w + m[1] + m[3])
.attr("height", h + m[0] + m[2])
.append("g")
.attr("transform", "translate(" + m[3] + "," + m[0] + ")");
var stocks,
symbols;
// A line generator, for the dark stroke.
var line = d3.svg.line()
.interpolate("basis")
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.price); });
// A line generator, for the dark stroke.
var axis = d3.svg.line()
.interpolate("basis")
.x(function(d) { return x(d.date); })
.y(h);
// A area generator, for the dark stroke.
var area = d3.svg.area()
.interpolate("basis")
.x(function(d) { return x(d.date); })
.y1(function(d) { return y(d.price); });
d3.csv("stocks.csv", function(data) {
var parse = d3.time.format("%b %Y").parse;
// Nest stock values by symbol.
symbols = d3.nest()
.key(function(d) { return d.symbol; })
.entries(stocks = data);
// Parse dates and numbers. We assume values are sorted by date.
// Also compute the maximum price per symbol, needed for the y-domain.
symbols.forEach(function(s) {
s.values.forEach(function(d) { d.date = parse(d.date); d.price = +d.price; });
s.maxPrice = d3.max(s.values, function(d) { return d.price; });
s.sumPrice = d3.sum(s.values, function(d) { return d.price; });
});
// Sort by maximum price, descending.
symbols.sort(function(a, b) { return b.maxPrice - a.maxPrice; });
var g = svg.selectAll("g")
.data(symbols)
.enter().append("g")
.attr("class", "symbol");
setTimeout(lines, duration);
});
function lines() {
x = d3.time.scale().range([0, w - 60]);
y = d3.scale.linear().range([h / 4 - 20, 0]);
// Compute the minimum and maximum date across symbols.
x.domain([
d3.min(symbols, function(d) { return d.values[0].date; }),
d3.max(symbols, function(d) { return d.values[d.values.length - 1].date; })
]);
var g = svg.selectAll(".symbol")
.attr("transform", function(d, i) { return "translate(0," + (i * h / 4 + 10) + ")"; });
g.each(function(d) {
var e = d3.select(this);
e.append("path")
.attr("class", "line");
e.append("circle")
.attr("r", 5)
.style("fill", function(d) { return color(d.key); })
.style("stroke", "#000")
.style("stroke-width", "2px");
e.append("text")
.attr("x", 12)
.attr("dy", ".31em")
.text(d.key);
});
function draw(k) {
g.each(function(d) {
var e = d3.select(this);
y.domain([0, d.maxPrice]);
e.select("path")
.attr("d", function(d) { return line(d.values.slice(0, k + 1)); });
e.selectAll("circle, text")
.data(function(d) { return [d.values[k], d.values[k]]; })
.attr("transform", function(d) { return "translate(" + x(d.date) + "," + y(d.price) + ")"; });
});
}
var k = 1, n = symbols[0].values.length;
d3.timer(function() {
draw(k);
if ((k += 2) >= n - 1) {
draw(n - 1);
setTimeout(horizons, 500);
return true;
}
});
}
function horizons() {
svg.insert("defs", ".symbol")
.append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", w)
.attr("height", h / 4 - 20);
var color = d3.scale.ordinal()
.range(["#c6dbef", "#9ecae1", "#6baed6"]);
var g = svg.selectAll(".symbol")
.attr("clip-path", "url(#clip)");
area
.y0(h / 4 - 20);
g.select("circle").transition()
.duration(duration)
.attr("transform", function(d) { return "translate(" + (w - 60) + "," + (-h / 4) + ")"; })
.remove();
g.select("text").transition()
.duration(duration)
.attr("transform", function(d) { return "translate(" + (w - 60) + "," + (h / 4 - 20) + ")"; })
.attr("dy", "0em");
g.each(function(d) {
y.domain([0, d.maxPrice]);
d3.select(this).selectAll(".area")
.data(d3.range(3))
.enter().insert("path", ".line")
.attr("class", "area")
.attr("transform", function(d) { return "translate(0," + (d * (h / 4 - 20)) + ")"; })
.attr("d", area(d.values))
.style("fill", function(d, i) { return color(i); })
.style("fill-opacity", 1e-6);
y.domain([0, d.maxPrice / 3]);
d3.select(this).selectAll(".line").transition()
.duration(duration)
.attr("d", line(d.values))
.style("stroke-opacity", 1e-6);
d3.select(this).selectAll(".area").transition()
.duration(duration)
.style("fill-opacity", 1)
.attr("d", area(d.values))
.each("end", function() { d3.select(this).style("fill-opacity", null); });
});
setTimeout(areas, duration + delay);
}
function areas() {
var g = svg.selectAll(".symbol");
axis
.y(h / 4 - 21);
g.select(".line")
.attr("d", function(d) { return axis(d.values); });
g.each(function(d) {
y.domain([0, d.maxPrice]);
d3.select(this).select(".line").transition()
.duration(duration)
.style("stroke-opacity", 1)
.each("end", function() { d3.select(this).style("stroke-opacity", null); });
d3.select(this).selectAll(".area")
.filter(function(d, i) { return i; })
.transition()
.duration(duration)
.style("fill-opacity", 1e-6)
.attr("d", area(d.values))
.remove();
d3.select(this).selectAll(".area")
.filter(function(d, i) { return !i; })
.transition()
.duration(duration)
.style("fill", color(d.key))
.attr("d", area(d.values));
});
svg.select("defs").transition()
.duration(duration)
.remove();
g.transition()
.duration(duration)
.each("end", function() { d3.select(this).attr("clip-path", null); });
setTimeout(stackedArea, duration + delay);
}
function stackedArea() {
var stack = d3.layout.stack()
.values(function(d) { return d.values; })
.x(function(d) { return d.date; })
.y(function(d) { return d.price; })
.out(function(d, y0, y) { d.price0 = y0; })
.order("reverse");
stack(symbols);
y
.domain([0, d3.max(symbols[0].values.map(function(d) { return d.price + d.price0; }))])
.range([h, 0]);
line
.y(function(d) { return y(d.price0); });
area
.y0(function(d) { return y(d.price0); })
.y1(function(d) { return y(d.price0 + d.price); });
var t = svg.selectAll(".symbol").transition()
.duration(duration)
.attr("transform", "translate(0,0)")
.each("end", function() { d3.select(this).attr("transform", null); });
t.select("path.area")
.attr("d", function(d) { return area(d.values); });
t.select("path.line")
.style("stroke-opacity", function(d, i) { return i < 3 ? 1e-6 : 1; })
.attr("d", function(d) { return line(d.values); });
t.select("text")
.attr("transform", function(d) { d = d.values[d.values.length - 1]; return "translate(" + (w - 60) + "," + y(d.price / 2 + d.price0) + ")"; });
setTimeout(streamgraph, duration + delay);
}
function streamgraph() {
var stack = d3.layout.stack()
.values(function(d) { return d.values; })
.x(function(d) { return d.date; })
.y(function(d) { return d.price; })
.out(function(d, y0, y) { d.price0 = y0; })
.order("reverse")
.offset("wiggle");
stack(symbols);
line
.y(function(d) { return y(d.price0); });
var t = svg.selectAll(".symbol").transition()
.duration(duration);
t.select("path.area")
.attr("d", function(d) { return area(d.values); });
t.select("path.line")
.style("stroke-opacity", 1e-6)
.attr("d", function(d) { return line(d.values); });
t.select("text")
.attr("transform", function(d) { d = d.values[d.values.length - 1]; return "translate(" + (w - 60) + "," + y(d.price / 2 + d.price0) + ")"; });
setTimeout(overlappingArea, duration + delay);
}
function overlappingArea() {
var g = svg.selectAll(".symbol");
line
.y(function(d) { return y(d.price0 + d.price); });
g.select(".line")
.attr("d", function(d) { return line(d.values); });
y
.domain([0, d3.max(symbols.map(function(d) { return d.maxPrice; }))])
.range([h, 0]);
area
.y0(h)
.y1(function(d) { return y(d.price); });
line
.y(function(d) { return y(d.price); });
var t = g.transition()
.duration(duration);
t.select(".line")
.style("stroke-opacity", 1)
.attr("d", function(d) { return line(d.values); });
t.select(".area")
.style("fill-opacity", .5)
.attr("d", function(d) { return area(d.values); });
t.select("text")
.attr("dy", ".31em")
.attr("transform", function(d) { d = d.values[d.values.length - 1]; return "translate(" + (w - 60) + "," + y(d.price) + ")"; });
svg.append("line")
.attr("class", "line")
.attr("x1", 0)
.attr("x2", w - 60)
.attr("y1", h)
.attr("y2", h)
.style("stroke-opacity", 1e-6)
.transition()
.duration(duration)
.style("stroke-opacity", 1);
setTimeout(groupedBar, duration + delay);
}
function groupedBar() {
x = d3.scale.ordinal()
.domain(symbols[0].values.map(function(d) { return d.date; }))
.rangeBands([0, w - 60], .1);
var x1 = d3.scale.ordinal()
.domain(symbols.map(function(d) { return d.key; }))
.rangeBands([0, x.rangeBand()]);
var g = svg.selectAll(".symbol");
var t = g.transition()
.duration(duration);
t.select(".line")
.style("stroke-opacity", 1e-6)
.remove();
t.select(".area")
.style("fill-opacity", 1e-6)
.remove();
g.each(function(p, j) {
d3.select(this).selectAll("rect")
.data(function(d) { return d.values; })
.enter().append("rect")
.attr("x", function(d) { return x(d.date) + x1(p.key); })
.attr("y", function(d) { return y(d.price); })
.attr("width", x1.rangeBand())
.attr("height", function(d) { return h - y(d.price); })
.style("fill", color(p.key))
.style("fill-opacity", 1e-6)
.transition()
.duration(duration)
.style("fill-opacity", 1);
});
setTimeout(stackedBar, duration + delay);
}
function stackedBar() {
x.rangeRoundBands([0, w - 60], .1);
var stack = d3.layout.stack()
.values(function(d) { return d.values; })
.x(function(d) { return d.date; })
.y(function(d) { return d.price; })
.out(function(d, y0, y) { d.price0 = y0; })
.order("reverse");
var g = svg.selectAll(".symbol");
stack(symbols);
y
.domain([0, d3.max(symbols[0].values.map(function(d) { return d.price + d.price0; }))])
.range([h, 0]);
var t = g.transition()
.duration(duration / 2);
t.select("text")
.delay(symbols[0].values.length * 10)
.attr("transform", function(d) { d = d.values[d.values.length - 1]; return "translate(" + (w - 60) + "," + y(d.price / 2 + d.price0) + ")"; });
t.selectAll("rect")
.delay(function(d, i) { return i * 10; })
.attr("y", function(d) { return y(d.price0 + d.price); })
.attr("height", function(d) { return h - y(d.price); })
.each("end", function() {
d3.select(this)
.style("stroke", "#fff")
.style("stroke-opacity", 1e-6)
.transition()
.duration(duration / 2)
.attr("x", function(d) { return x(d.date); })
.attr("width", x.rangeBand())
.style("stroke-opacity", 1);
});
setTimeout(transposeBar, duration + symbols[0].values.length * 10 + delay);
}
function transposeBar() {
x
.domain(symbols.map(function(d) { return d.key; }))
.rangeRoundBands([0, w], .2);
y
.domain([0, d3.max(symbols.map(function(d) { return d3.sum(d.values.map(function(d) { return d.price; })); }))]);
var stack = d3.layout.stack()
.x(function(d, i) { return i; })
.y(function(d) { return d.price; })
.out(function(d, y0, y) { d.price0 = y0; });
stack(d3.zip.apply(null, symbols.map(function(d) { return d.values; }))); // transpose!
var g = svg.selectAll(".symbol");
var t = g.transition()
.duration(duration / 2);
t.selectAll("rect")
.delay(function(d, i) { return i * 10; })
.attr("y", function(d) { return y(d.price0 + d.price) - 1; })
.attr("height", function(d) { return h - y(d.price) + 1; })
.attr("x", function(d) { return x(d.symbol); })
.attr("width", x.rangeBand())
.style("stroke-opacity", 1e-6);
t.select("text")
.attr("x", 0)
.attr("transform", function(d) { return "translate(" + (x(d.key) + x.rangeBand() / 2) + "," + h + ")"; })
.attr("dy", "1.31em")
.each("end", function() { d3.select(this).attr("x", null).attr("text-anchor", "middle"); });
svg.select("line").transition()
.duration(duration)
.attr("x2", w);
setTimeout(donut, duration / 2 + symbols[0].values.length * 10 + delay);
}
function donut() {
var g = svg.selectAll(".symbol");
g.selectAll("rect").remove();
var pie = d3.layout.pie()
.value(function(d) { return d.sumPrice; });
var arc = d3.svg.arc();
g.append("path")
.style("fill", function(d) { return color(d.key); })
.data(function() { return pie(symbols); })
.transition()
.duration(duration)
.tween("arc", arcTween);
g.select("text").transition()
.duration(duration)
.attr("dy", ".31em");
svg.select("line").transition()
.duration(duration)
.attr("y1", 2 * h)
.attr("y2", 2 * h)
.remove();
function arcTween(d) {
var path = d3.select(this),
text = d3.select(this.parentNode.appendChild(this.previousSibling)),
x0 = x(d.data.key),
y0 = h - y(d.data.sumPrice);
return function(t) {
var r = h / 2 / Math.min(1, t + 1e-3),
a = Math.cos(t * Math.PI / 2),
xx = (-r + (a) * (x0 + x.rangeBand()) + (1 - a) * (w + h) / 2),
yy = ((a) * h + (1 - a) * h / 2),
f = {
innerRadius: r - x.rangeBand() / (2 - a),
outerRadius: r,
startAngle: a * (Math.PI / 2 - y0 / r) + (1 - a) * d.startAngle,
endAngle: a * (Math.PI / 2) + (1 - a) * d.endAngle
};
path.attr("transform", "translate(" + xx + "," + yy + ")");
path.attr("d", arc(f));
text.attr("transform", "translate(" + arc.centroid(f) + ")translate(" + xx + "," + yy + ")rotate(" + ((f.startAngle + f.endAngle) / 2 + 3 * Math.PI / 2) * 180 / Math.PI + ")");
};
}
setTimeout(donutExplode, duration + delay);
}
function donutExplode() {
var r0a = h / 2 - x.rangeBand() / 2,
r1a = h / 2,
r0b = 2 * h - x.rangeBand() / 2,
r1b = 2 * h,
arc = d3.svg.arc();
svg.selectAll(".symbol path")
.each(transitionExplode);
function transitionExplode(d, i) {
d.innerRadius = r0a;
d.outerRadius = r1a;
d3.select(this).transition()
.duration(duration / 2)
.tween("arc", tweenArc({
innerRadius: r0b,
outerRadius: r1b
}));
}
function tweenArc(b) {
return function(a) {
var path = d3.select(this),
text = d3.select(this.nextSibling),
i = d3.interpolate(a, b);
for (var key in b) a[key] = b[key]; // update data
return function(t) {
var a = i(t);
path.attr("d", arc(a));
text.attr("transform", "translate(" + arc.centroid(a) + ")translate(" + w / 2 + "," + h / 2 +")rotate(" + ((a.startAngle + a.endAngle) / 2 + 3 * Math.PI / 2) * 180 / Math.PI + ")");
};
}
}
setTimeout(function() {
svg.selectAll("*").remove();
svg.selectAll("g").data(symbols).enter().append("g").attr("class", "symbol");
lines();
}, duration);
}
</script>
<svg width="960" height="500">
<g transform="translate(20,20)">
<g class="symbol" transform="translate(0,10)">
<path class="line"/>
<circle r="5" style="fill: rgb(31, 119, 180); stroke: rgb(0, 0, 0); stroke-width: 2px;"/>
<text x="12" dy=".31em">AAPL</text>
</g>
<g class="symbol" transform="translate(0,122.5)">
<path class="line"/>
<circle r="5" style="fill: rgb(255, 127, 14); stroke: rgb(0, 0, 0); stroke-width: 2px;"/>
<text x="12" dy=".31em">AMZN</text>
</g>
<g class="symbol" transform="translate(0,235)">
<path class="line"/>
<circle r="5" style="fill: rgb(44, 160, 44); stroke: rgb(0, 0, 0); stroke-width: 2px;"/>
<text x="12" dy=".31em">IBM</text>
</g>
<g class="symbol" transform="translate(0,347.5)">
<path class="line"/>
<circle r="5" style="fill: rgb(214, 39, 40); stroke: rgb(0, 0, 0); stroke-width: 2px;"/>
<text x="12" dy=".31em">MSFT</text>
</g>
</g>
</svg>
</body>
</html>
and created a csv file names stocks.csv in the same folder where the html is
but I do not get any charts at all
I wonder what am I doing wrong here?
Try using "Live Server" Extension in VS code. That might help in rendering the charts using live server
I'm using D3 and javascript to create a BiLevel Partition following this example. The labels in the left side of the diagram are upside down, and I was trying to rotate them, but I've not been successful yet.
I found numerous cases of people with the same problem, but using Sunburst. Also tried to implement those solutions, but I'm still unable to solve this problem.
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
/*var margin = {top: 350, right: 480, bottom: 350, left: 480},
radius = Math.min(margin.top, margin.right, margin.bottom, margin.left) - 10;*/
var width = 1200,
height = 1200,
radius = Math.min(width, height) / 2;
function filter_min_arc_size_text(d, i) {return (d.dx*d.depth*radius/3)>14};
var hue = d3.scale.category10();
var luminance = d3.scale.sqrt()
.domain([0, 1e6])
.clamp(true)
.range([90, 20]);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + (height / 2 + 10) + ")");
var partition = d3.layout.partition()
.sort(function(a, b) { return d3.ascending(a.name, b.name); })
.size([2 * Math.PI, radius]);
var arc = d3.svg.arc()
.startAngle(function(d) { return d.x; })
.endAngle(function(d) { return d.x + d.dx - .01 / (d.depth + .5); })
.innerRadius(function(d) { return radius / 3 * d.depth; })
.outerRadius(function(d) { return radius / 3 * (d.depth + 1) - 1; });
//Tooltip description
var tooltip = d3.select("body")
.append("div")
.attr("id", "tooltip")
.style("position", "absolute")
.style("z-index", "10")
.style("opacity", 0);
function format_number(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
function format_description(d) {
var description = d.description;
return /* '<b>' + d.name + '</b></br>'+*/ d.description + '<br> (' + format_number(d.value) + ')';
}
function computeTextRotation(d) {
var ang = ((d.x + d.dx / 2) - Math.PI / 2) / Math.PI * 180;
return (ang > 90) ? 180 + ang : ang;
}
function mouseOverArc(d) {
d3.select(this).attr("stroke","black")
tooltip.html(format_description(d));
return tooltip.transition()
.duration(50)
.style("opacity", 0.9);
}
function mouseOutArc(){
d3.select(this).attr("stroke","")
return tooltip.style("opacity", 0);
}
function mouseMoveArc (d) {
return tooltip
.style("top", (d3.event.pageY-10)+"px")
.style("left", (d3.event.pageX+10)+"px");
}
var root_ = null;
d3.json("flare.json", function(error, root) {
if (error) return console.warn(error);
// Compute the initial layout on the entire tree to sum sizes.
// Also compute the full name and fill color for each node,
// and stash the children so they can be restored as we descend.
partition
.value(function(d) { return d.size; })
.nodes(root)
.forEach(function(d) {
d._children = d.children;
d.sum = d.value;
d.key = key(d);
d.fill = fill(d);
});
// Now redefine the value function to use the previously-computed sum.
partition
.children(function(d, depth) { return depth < 2 ? d._children : null; })
.value(function(d) { return d.sum; });
var center = svg.append("circle")
.attr("r", radius / 3)
.on("click", zoomOut);
center.append("title")
.text("zoom out");
var partitioned_data=partition.nodes(root).slice(1)
var path = svg.selectAll("path")
.data(partitioned_data)
.enter().append("path")
.attr("d", arc)
.style("fill", function(d) { return d.fill; })
.each(function(d) { this._current = updateArc(d); })
.on("click", zoomIn)
.on("mouseover", mouseOverArc)
.on("mousemove", mouseMoveArc)
.on("mouseout", mouseOutArc);
var texts = svg.selectAll("text")
.data(partitioned_data)
.enter().append("text")
.filter(filter_min_arc_size_text)
.attr("transform", function(d) { return "rotate(" + computeTextRotation(d) + ")"; })
.attr("x", function(d) { return radius / 3 * d.depth; })
.attr("dx", "6") // margin
.attr("dy", ".35em") // vertical-align
.text(function(d,i) {return d.name})
function zoomIn(p) {
if (p.depth > 1) p = p.parent;
if (!p.children) return;
zoom(p, p);
}
function zoomOut(p) {
if (!p.parent) return;
zoom(p.parent, p);
}
// Zoom to the specified new root.
function zoom(root, p) {
if (document.documentElement.__transition__) return;
// Rescale outside angles to match the new layout.
var enterArc,
exitArc,
outsideAngle = d3.scale.linear().domain([0, 2 * Math.PI]);
function insideArc(d) {
return p.key > d.key
? {depth: d.depth - 1, x: 0, dx: 0} : p.key < d.key
? {depth: d.depth - 1, x: 2 * Math.PI, dx: 0}
: {depth: 0, x: 0, dx: 2 * Math.PI};
}
function outsideArc(d) {
return {depth: d.depth + 1, x: outsideAngle(d.x), dx: outsideAngle(d.x + d.dx) - outsideAngle(d.x)};
}
center.datum(root);
// When zooming in, arcs enter from the outside and exit to the inside.
// Entering outside arcs start from the old layout.
if (root === p) enterArc = outsideArc, exitArc = insideArc, outsideAngle.range([p.x, p.x + p.dx]);
var new_data=partition.nodes(root).slice(1)
path = path.data(new_data, function(d) { return d.key; });
// When zooming out, arcs enter from the inside and exit to the outside.
// Exiting outside arcs transition to the new layout.
if (root !== p) enterArc = insideArc, exitArc = outsideArc, outsideAngle.range([p.x, p.x + p.dx]);
d3.transition().duration(d3.event.altKey ? 7500 : 750).each(function() {
path.exit().transition()
.style("fill-opacity", function(d) { return d.depth === 1 + (root === p) ? 1 : 0; })
.attrTween("d", function(d) { return arcTween.call(this, exitArc(d)); })
.remove();
path.enter().append("path")
.style("fill-opacity", function(d) { return d.depth === 2 - (root === p) ? 1 : 0; })
.style("fill", function(d) { return d.fill; })
.on("click", zoomIn)
.on("mouseover", mouseOverArc)
.on("mousemove", mouseMoveArc)
.on("mouseout", mouseOutArc)
.each(function(d) { this._current = enterArc(d); });
path.transition()
.style("fill-opacity", 1)
.attrTween("d", function(d) { return arcTween.call(this, updateArc(d)); });
});
texts = texts.data(new_data, function(d) { return d.key; })
texts.exit()
.remove()
texts.enter()
.append("text")
texts.style("opacity", 0)
.attr("transform", function(d) { return "rotate(" + computeTextRotation(d) + ")"; })
.attr("x", function(d) { return radius / 3 * d.depth; })
.attr("dx", "6") // margin
.attr("dy", ".35em") // vertical-align
.filter(filter_min_arc_size_text)
.text(function(d,i) {return d.name})
.transition().delay(750).style("opacity", 1)
}
});
function key(d) {
var k = [], p = d;
while (p.depth) k.push(p.name), p = p.parent;
return k.reverse().join(".");
}
function fill(d) {
var p = d;
while (p.depth > 1) p = p.parent;
var c = d3.lab(hue(p.name));
c.l = luminance(d.sum);
return c;
}
function arcTween(b) {
var i = d3.interpolate(this._current, b);
this._current = i(0);
return function(t) {
return arc(i(t));
};
}
function updateArc(d) {
return {depth: d.depth, x: d.x, dx: d.dx};
}
d3.select(self.frameElement).style("height", margin.top + margin.bottom + "px");
</script>
The problem I have is that it is only showing the right half of the Partition.
I am have created chart using d3.js, when I zoom in or zoom out on web browser this charts do not re-size according to window.
Following is what I have done:
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<style type="text/css">
svg {
font-family: "Helvetica Neue", Helvetica;
}
.line {
fill: none;
stroke: #000;
stroke-width: 2px;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var m = [20, 20, 30, 20],
w = 960 - m[1] - m[3],
h = 500 - m[0] - m[2];
var x,
y,
duration = 1500,
delay = 500;
var color = d3.scale.category10();
var svg = d3.select("body").append("svg")
.attr("width", w + m[1] + m[3])
.attr("height", h + m[0] + m[2])
.append("g")
.attr("transform", "translate(" + m[3] + "," + m[0] + ")");
var stocks,
symbols;
// A line generator, for the dark stroke.
var line = d3.svg.line()
.interpolate("basis")
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.price); });
// A line generator, for the dark stroke.
var axis = d3.svg.line()
.interpolate("basis")
.x(function(d) { return x(d.date); })
.y(h);
// A area generator, for the dark stroke.
var area = d3.svg.area()
.interpolate("basis")
.x(function(d) { return x(d.date); })
.y1(function(d) { return y(d.price); });
d3.csv("stocks.csv", function(data) {
var parse = d3.time.format("%b %Y").parse;
// Nest stock values by symbol.
symbols = d3.nest()
.key(function(d) { return d.symbol; })
.entries(stocks = data);
// Parse dates and numbers. We assume values are sorted by date.
// Also compute the maximum price per symbol, needed for the y-domain.
symbols.forEach(function(s) {
s.values.forEach(function(d) { d.date = parse(d.date); d.price = +d.price; });
s.maxPrice = d3.max(s.values, function(d) { return d.price; });
s.sumPrice = d3.sum(s.values, function(d) { return d.price; });
});
// Sort by maximum price, descending.
symbols.sort(function(a, b) { return b.maxPrice - a.maxPrice; });
var g = svg.selectAll("g")
.data(symbols)
.enter().append("g")
.attr("class", "symbol");
setTimeout(lines, duration);
});
function lines() {
x = d3.time.scale().range([0, w - 60]);
y = d3.scale.linear().range([h / 4 - 20, 0]);
// Compute the minimum and maximum date across symbols.
x.domain([
d3.min(symbols, function(d) { return d.values[0].date; }),
d3.max(symbols, function(d) { return d.values[d.values.length - 1].date; })
]);
var g = svg.selectAll(".symbol")
.attr("transform", function(d, i) { return "translate(0," + (i * h / 4 + 10) + ")"; });
g.each(function(d) {
var e = d3.select(this);
e.append("path")
.attr("class", "line");
e.append("circle")
.attr("r", 5)
.style("fill", function(d) { return color(d.key); })
.style("stroke", "#000")
.style("stroke-width", "2px");
e.append("text")
.attr("x", 12)
.attr("dy", ".31em")
.text(d.key);
});
function draw(k) {
g.each(function(d) {
var e = d3.select(this);
y.domain([0, d.maxPrice]);
e.select("path")
.attr("d", function(d) { return line(d.values.slice(0, k + 1)); });
e.selectAll("circle, text")
.data(function(d) { return [d.values[k], d.values[k]]; })
.attr("transform", function(d) { return "translate(" + x(d.date) + "," + y(d.price) + ")"; });
});
}
var k = 1, n = symbols[0].values.length;
d3.timer(function() {
draw(k);
if ((k += 2) >= n - 1) {
draw(n - 1);
setTimeout(horizons, 500);
return true;
}
});
}
function horizons() {
svg.insert("defs", ".symbol")
.append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", w)
.attr("height", h / 4 - 20);
var color = d3.scale.ordinal()
.range(["#c6dbef", "#9ecae1", "#6baed6"]);
var g = svg.selectAll(".symbol")
.attr("clip-path", "url(#clip)");
area
.y0(h / 4 - 20);
g.select("circle").transition()
.duration(duration)
.attr("transform", function(d) { return "translate(" + (w - 60) + "," + (-h / 4) + ")"; })
.remove();
g.select("text").transition()
.duration(duration)
.attr("transform", function(d) { return "translate(" + (w - 60) + "," + (h / 4 - 20) + ")"; })
.attr("dy", "0em");
g.each(function(d) {
y.domain([0, d.maxPrice]);
d3.select(this).selectAll(".area")
.data(d3.range(3))
.enter().insert("path", ".line")
.attr("class", "area")
.attr("transform", function(d) { return "translate(0," + (d * (h / 4 - 20)) + ")"; })
.attr("d", area(d.values))
.style("fill", function(d, i) { return color(i); })
.style("fill-opacity", 1e-6);
y.domain([0, d.maxPrice / 3]);
d3.select(this).selectAll(".line").transition()
.duration(duration)
.attr("d", line(d.values))
.style("stroke-opacity", 1e-6);
d3.select(this).selectAll(".area").transition()
.duration(duration)
.style("fill-opacity", 1)
.attr("d", area(d.values))
.each("end", function() { d3.select(this).style("fill-opacity", null); });
});
setTimeout(areas, duration + delay);
}
function areas() {
var g = svg.selectAll(".symbol");
axis
.y(h / 4 - 21);
g.select(".line")
.attr("d", function(d) { return axis(d.values); });
g.each(function(d) {
y.domain([0, d.maxPrice]);
d3.select(this).select(".line").transition()
.duration(duration)
.style("stroke-opacity", 1)
.each("end", function() { d3.select(this).style("stroke-opacity", null); });
d3.select(this).selectAll(".area")
.filter(function(d, i) { return i; })
.transition()
.duration(duration)
.style("fill-opacity", 1e-6)
.attr("d", area(d.values))
.remove();
d3.select(this).selectAll(".area")
.filter(function(d, i) { return !i; })
.transition()
.duration(duration)
.style("fill", color(d.key))
.attr("d", area(d.values));
});
svg.select("defs").transition()
.duration(duration)
.remove();
g.transition()
.duration(duration)
.each("end", function() { d3.select(this).attr("clip-path", null); });
setTimeout(stackedArea, duration + delay);
}
function stackedArea() {
var stack = d3.layout.stack()
.values(function(d) { return d.values; })
.x(function(d) { return d.date; })
.y(function(d) { return d.price; })
.out(function(d, y0, y) { d.price0 = y0; })
.order("reverse");
stack(symbols);
y
.domain([0, d3.max(symbols[0].values.map(function(d) { return d.price + d.price0; }))])
.range([h, 0]);
line
.y(function(d) { return y(d.price0); });
area
.y0(function(d) { return y(d.price0); })
.y1(function(d) { return y(d.price0 + d.price); });
var t = svg.selectAll(".symbol").transition()
.duration(duration)
.attr("transform", "translate(0,0)")
.each("end", function() { d3.select(this).attr("transform", null); });
t.select("path.area")
.attr("d", function(d) { return area(d.values); });
t.select("path.line")
.style("stroke-opacity", function(d, i) { return i < 3 ? 1e-6 : 1; })
.attr("d", function(d) { return line(d.values); });
t.select("text")
.attr("transform", function(d) { d = d.values[d.values.length - 1]; return "translate(" + (w - 60) + "," + y(d.price / 2 + d.price0) + ")"; });
setTimeout(streamgraph, duration + delay);
}
function streamgraph() {
var stack = d3.layout.stack()
.values(function(d) { return d.values; })
.x(function(d) { return d.date; })
.y(function(d) { return d.price; })
.out(function(d, y0, y) { d.price0 = y0; })
.order("reverse")
.offset("wiggle");
stack(symbols);
line
.y(function(d) { return y(d.price0); });
var t = svg.selectAll(".symbol").transition()
.duration(duration);
t.select("path.area")
.attr("d", function(d) { return area(d.values); });
t.select("path.line")
.style("stroke-opacity", 1e-6)
.attr("d", function(d) { return line(d.values); });
t.select("text")
.attr("transform", function(d) { d = d.values[d.values.length - 1]; return "translate(" + (w - 60) + "," + y(d.price / 2 + d.price0) + ")"; });
setTimeout(overlappingArea, duration + delay);
}
function overlappingArea() {
var g = svg.selectAll(".symbol");
line
.y(function(d) { return y(d.price0 + d.price); });
g.select(".line")
.attr("d", function(d) { return line(d.values); });
y
.domain([0, d3.max(symbols.map(function(d) { return d.maxPrice; }))])
.range([h, 0]);
area
.y0(h)
.y1(function(d) { return y(d.price); });
line
.y(function(d) { return y(d.price); });
var t = g.transition()
.duration(duration);
t.select(".line")
.style("stroke-opacity", 1)
.attr("d", function(d) { return line(d.values); });
t.select(".area")
.style("fill-opacity", .5)
.attr("d", function(d) { return area(d.values); });
t.select("text")
.attr("dy", ".31em")
.attr("transform", function(d) { d = d.values[d.values.length - 1]; return "translate(" + (w - 60) + "," + y(d.price) + ")"; });
svg.append("line")
.attr("class", "line")
.attr("x1", 0)
.attr("x2", w - 60)
.attr("y1", h)
.attr("y2", h)
.style("stroke-opacity", 1e-6)
.transition()
.duration(duration)
.style("stroke-opacity", 1);
setTimeout(groupedBar, duration + delay);
}
function groupedBar() {
x = d3.scale.ordinal()
.domain(symbols[0].values.map(function(d) { return d.date; }))
.rangeBands([0, w - 60], .1);
var x1 = d3.scale.ordinal()
.domain(symbols.map(function(d) { return d.key; }))
.rangeBands([0, x.rangeBand()]);
var g = svg.selectAll(".symbol");
var t = g.transition()
.duration(duration);
t.select(".line")
.style("stroke-opacity", 1e-6)
.remove();
t.select(".area")
.style("fill-opacity", 1e-6)
.remove();
g.each(function(p, j) {
d3.select(this).selectAll("rect")
.data(function(d) { return d.values; })
.enter().append("rect")
.attr("x", function(d) { return x(d.date) + x1(p.key); })
.attr("y", function(d) { return y(d.price); })
.attr("width", x1.rangeBand())
.attr("height", function(d) { return h - y(d.price); })
.style("fill", color(p.key))
.style("fill-opacity", 1e-6)
.transition()
.duration(duration)
.style("fill-opacity", 1);
});
setTimeout(stackedBar, duration + delay);
}
function stackedBar() {
x.rangeRoundBands([0, w - 60], .1);
var stack = d3.layout.stack()
.values(function(d) { return d.values; })
.x(function(d) { return d.date; })
.y(function(d) { return d.price; })
.out(function(d, y0, y) { d.price0 = y0; })
.order("reverse");
var g = svg.selectAll(".symbol");
stack(symbols);
y
.domain([0, d3.max(symbols[0].values.map(function(d) { return d.price + d.price0; }))])
.range([h, 0]);
var t = g.transition()
.duration(duration / 2);
t.select("text")
.delay(symbols[0].values.length * 10)
.attr("transform", function(d) { d = d.values[d.values.length - 1]; return "translate(" + (w - 60) + "," + y(d.price / 2 + d.price0) + ")"; });
t.selectAll("rect")
.delay(function(d, i) { return i * 10; })
.attr("y", function(d) { return y(d.price0 + d.price); })
.attr("height", function(d) { return h - y(d.price); })
.each("end", function() {
d3.select(this)
.style("stroke", "#fff")
.style("stroke-opacity", 1e-6)
.transition()
.duration(duration / 2)
.attr("x", function(d) { return x(d.date); })
.attr("width", x.rangeBand())
.style("stroke-opacity", 1);
});
setTimeout(transposeBar, duration + symbols[0].values.length * 10 + delay);
}
function transposeBar() {
x
.domain(symbols.map(function(d) { return d.key; }))
.rangeRoundBands([0, w], .2);
y
.domain([0, d3.max(symbols.map(function(d) { return d3.sum(d.values.map(function(d) { return d.price; })); }))]);
var stack = d3.layout.stack()
.x(function(d, i) { return i; })
.y(function(d) { return d.price; })
.out(function(d, y0, y) { d.price0 = y0; });
stack(d3.zip.apply(null, symbols.map(function(d) { return d.values; }))); // transpose!
var g = svg.selectAll(".symbol");
var t = g.transition()
.duration(duration / 2);
t.selectAll("rect")
.delay(function(d, i) { return i * 10; })
.attr("y", function(d) { return y(d.price0 + d.price) - 1; })
.attr("height", function(d) { return h - y(d.price) + 1; })
.attr("x", function(d) { return x(d.symbol); })
.attr("width", x.rangeBand())
.style("stroke-opacity", 1e-6);
t.select("text")
.attr("x", 0)
.attr("transform", function(d) { return "translate(" + (x(d.key) + x.rangeBand() / 2) + "," + h + ")"; })
.attr("dy", "1.31em")
.each("end", function() { d3.select(this).attr("x", null).attr("text-anchor", "middle"); });
svg.select("line").transition()
.duration(duration)
.attr("x2", w);
setTimeout(donut, duration / 2 + symbols[0].values.length * 10 + delay);
}
function donut() {
var g = svg.selectAll(".symbol");
g.selectAll("rect").remove();
var pie = d3.layout.pie()
.value(function(d) { return d.sumPrice; });
var arc = d3.svg.arc();
g.append("path")
.style("fill", function(d) { return color(d.key); })
.data(function() { return pie(symbols); })
.transition()
.duration(duration)
.tween("arc", arcTween);
g.select("text").transition()
.duration(duration)
.attr("dy", ".31em");
svg.select("line").transition()
.duration(duration)
.attr("y1", 2 * h)
.attr("y2", 2 * h)
.remove();
function arcTween(d) {
var path = d3.select(this),
text = d3.select(this.parentNode.appendChild(this.previousSibling)),
x0 = x(d.data.key),
y0 = h - y(d.data.sumPrice);
return function(t) {
var r = h / 2 / Math.min(1, t + 1e-3),
a = Math.cos(t * Math.PI / 2),
xx = (-r + (a) * (x0 + x.rangeBand()) + (1 - a) * (w + h) / 2),
yy = ((a) * h + (1 - a) * h / 2),
f = {
innerRadius: r - x.rangeBand() / (2 - a),
outerRadius: r,
startAngle: a * (Math.PI / 2 - y0 / r) + (1 - a) * d.startAngle,
endAngle: a * (Math.PI / 2) + (1 - a) * d.endAngle
};
path.attr("transform", "translate(" + xx + "," + yy + ")");
path.attr("d", arc(f));
text.attr("transform", "translate(" + arc.centroid(f) + ")translate(" + xx + "," + yy + ")rotate(" + ((f.startAngle + f.endAngle) / 2 + 3 * Math.PI / 2) * 180 / Math.PI + ")");
};
}
setTimeout(donutExplode, duration + delay);
}
function donutExplode() {
var r0a = h / 2 - x.rangeBand() / 2,
r1a = h / 2,
r0b = 2 * h - x.rangeBand() / 2,
r1b = 2 * h,
arc = d3.svg.arc();
svg.selectAll(".symbol path")
.each(transitionExplode);
function transitionExplode(d, i) {
d.innerRadius = r0a;
d.outerRadius = r1a;
d3.select(this).transition()
.duration(duration / 2)
.tween("arc", tweenArc({
innerRadius: r0b,
outerRadius: r1b
}));
}
function tweenArc(b) {
return function(a) {
var path = d3.select(this),
text = d3.select(this.nextSibling),
i = d3.interpolate(a, b);
for (var key in b) a[key] = b[key]; // update data
return function(t) {
var a = i(t);
path.attr("d", arc(a));
text.attr("transform", "translate(" + arc.centroid(a) + ")translate(" + w / 2 + "," + h / 2 +")rotate(" + ((a.startAngle + a.endAngle) / 2 + 3 * Math.PI / 2) * 180 / Math.PI + ")");
};
}
}
setTimeout(function() {
svg.selectAll("*").remove();
svg.selectAll("g").data(symbols).enter().append("g").attr("class", "symbol");
lines();
}, duration);
}
</script>
</body>
</html>
I am learning d3.js, so I don't know how to do it. Please help me.
Doing this ends up being a bit code heavy, but for my graphs I tend to have 3 different parts: setup, draw and redraw. In setup I set up all the SVG containers and bind the data. In draw, I do the initial data draw (this tends to have different animations, fade-ins, etc). Then I bind window.onresize to the redraw all of the SVG data based on window/container dimensions.
I can provide you with an example of my code if you would like.
I'm trying to add text to the partition-sunburst example. I have followed a hint given on Google Group and I was able to add the text. Now I want to rotate it. The new angles seem to be correct, but all the text get gathered in one point.
This is the piece of code where I add and rotate the text:
var text = vis.data([json]).selectAll("text")
.data(partition.nodes)
.enter().append("svg:text")
.attr("x", function(d) { return radius * Math.cos(d.x + d.dx/2); } )
.attr("y", function(d) { return radius * Math.sin(d.x + d.dx/2); } )
.attr("dy", ".31em")
.style("font-size", "5px")
.attr("transform", function(d) {
var angle = (2 * Math.PI - d.x) * (180/Math.PI);
var rotation = "rotate(" + angle + ")";
console.log(rotation);
console.log("d.x=" + d.x + ", d.y=" + d.y);
return rotation;
})
.text(function(d) { return d.name; });
This is an image of what I get:
and this is the full script:
var width = 1000,
height = 1000,
radius = 350,
x = d3.scale.linear().range([0, 2 * Math.PI]),
y = d3.scale.pow().exponent(1.3).domain([0, 1]).range([0, radius]),
padding = 5,
color = d3.scale.category20c();
var vis = d3.select("#chart").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var partition = d3.layout.partition()
.sort(null)
.size([2 * Math.PI, radius * radius])
.value(function(d) { return 1; });
var arc = d3.svg.arc()
.startAngle(function(d) { return d.x; })
.endAngle(function(d) { return d.x + d.dx; })
.innerRadius(function(d) { return Math.sqrt(d.y); })
.outerRadius(function(d) { return Math.sqrt(d.y + d.dy); });
d3.json("fracking.json", function(json) {
var path = vis.data([json]).selectAll("path")
.data(partition.nodes)
.enter().append("svg:path")
.attr("display", function(d) { return d.depth ? null : "none"; })
// hide inner ring
.attr("d", arc)
.attr("fill-rule", "evenodd")
.style("stroke", "#fff")
.style("fill", function(d) { return color((d.children ? d : d.parent).name); })
.each(stash);
var text = vis.data([json]).selectAll("text")
.data(partition.nodes)
.enter().append("svg:text")
.attr("x", function(d) { return radius * Math.cos(d.x + d.dx/2); } )
.attr("y", function(d) { return radius * Math.sin(d.x + d.dx/2); } )
.attr("dy", ".31em")
.style("font-size", "5px")
.attr("transform", function(d) {
var angle = (2 * Math.PI - d.x) * (180/Math.PI);
var rotation = "rotate(" + angle + ")";
console.log(rotation);
console.log("d.x=" + d.x + ", d.y=" + d.y);
return rotation;
})
.text(function(d) { return d.name; });
d3.select("#size").on("click", function() {
path
.data(partition.value(function(d) { return d.size; }))
.transition()
.duration(1500)
.attrTween("d", arcTween);
d3.select("#size").classed("active", true);
d3.select("#count").classed("active", false);
});
d3.select("#count").on("click", function() {
path
.data(partition.value(function(d) { return 1; }))
.transition()
.duration(1500)
.attrTween("d", arcTween);
d3.select("#size").classed("active", false);
d3.select("#count").classed("active", true);
});
});
// Stash the old values for transition.
function stash(d) {
d.x0 = d.x;
d.dx0 = d.dx;
}
// Interpolate the arcs in data space.
function arcTween(a) {
var i = d3.interpolate({x: a.x0, dx: a.dx0}, a);
return function(t) {
var b = i(t);
a.x0 = b.x;
a.dx0 = b.dx;
return arc(b);
};
}
I think you need to specify the center of rotation. Try this:
var text = vis.data([json]).selectAll("text")
.data(partition.nodes)
.enter().append("svg:text")
.attr("x", function(d) { return radius * Math.cos(d.x + d.dx/2); } )
.attr("y", function(d) { return radius * Math.sin(d.x + d.dx/2); } )
.attr("dy", ".31em")
.style("font-size", "5px")
.attr("transform", function(d) {
var angle = (2 * Math.PI - d.x) * (180/Math.PI);
var rotation = "rotate(" + angle + "," + d3.select(this).attr("x") + "," d3.select(this).attr("y") +")";
console.log(rotation);
console.log("d.x=" + d.x + ", d.y=" + d.y);
return rotation;
})
.text(function(d) { return d.name; });