I'm using mbostock’s Bilevel Partition and I need to include each node's text on each path. I'm trying to use this Coffee Wheel example but I'm having no luck.
This is all being written with Backbone.js which is giving me some trouble with nesting "this", so that may cause a problem.
Here is my render function. I try adding in text at the bottom.
render: function(root, svgVar) {
var that = this;
$('.breadcrumb').append('<li>'+root.name+'</li>');
var svg = d3.select(".associations-container").append("svg")
.attr("width", svgVar.width)
.attr("height", svgVar.height)
.append("g")
.attr("transform", "translate(" + (svgVar.width/2) + "," + ((svgVar.height/2)-svgVar.padding) + ")");
this.partition = d3.layout.partition()
.sort(function(a, b) { return d3.ascending(a.name, b.name); })
.size([2 * Math.PI, svgVar.radius]);
this.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 svgVar.radius / 3 * d.depth; })
.outerRadius(function(d) { return svgVar.radius / 3 * (d.depth + 1) - 1; });
// 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.
this.partition
.value(function(d) { return 1; })
.nodes(root)
.forEach(function(d) {
d._children = d.children;
d.sum = d.value;
d.key = that.key(d);
d.fill = that.fill(d);
});
// Now redefine the value function to use the previously-computed sum.
this.partition
.children(function(d, depth) { return depth < 2 ? d._children : null; })
.value(function(d) { return d.sum; });
this.centerCircle = svg.append("circle")
.attr("r", svgVar.radius / 3)
.attr("fill", "grey")
.on("click", this.zoomOut);
var centerControls = svg.append("g");
centerControls.append("svg:foreignObject")
.attr("width", 40)
.attr("height", 40)
.attr("y", "-20px")
.attr("x", "-48px")
.append("xhtml:span")
.attr("class", "control glyphicon glyphicon-filter");
centerControls.append("svg:foreignObject")
.attr("width", 40)
.attr("height", 50)
.attr("y", "-20px")
.attr("x", "8px")
.append("xhtml:span")
.attr("class", "control glyphicon glyphicon-th-list toggle-list");
this.path = svg.selectAll("path")
.data(this.partition.nodes(root).slice(1))
.enter().append("path")
.attr("d", this.arc)
.style("fill", function(d) { return d.fill; })
.each(function(d) { this._current = that.updateArc(d); })
.on("click", this.zoomIn);
this.text = svg.selectAll("text").data(root);
this.textEnter = this.text.enter().append("text")
.style("fill-opacity", 1)
.style("fill", "white")
.attr("text-anchor", function(d) {
return x(d.x + d.dx / 2) >Math.PI ? "end" : "start";
})
.attr("dy", ".2em")
.attr("transform", function(d) {
var multiline = (d.name || "").split(" ").length > 1,
angle = x(d.x + d.dx / 2) * 180 / Math.PI - 90,
rotate = angle + (multiline ? -.5 : 0);
return "rotate(" + rotate + ")translate(" + (y(d.y) + padding) + ")rotate(" + (angle > 90 ? -180 : 0) + ")";
});
this.textEnter.append("tspan")
.attr("x", 0)
.text(function(d) { return d.name; });
Related
I'm trying to implement this D3 code into an empty react project but the graphic is not showing on the browser. I've tried this below code. I also installed D3 version 3 using npm i d3#3
When I just try implement using vanilla html and vanilla JS, it still doesn't work on the local browser. I'm not sure why it's not working. The author's deployed project seem to work well.
import React from "react";
import * as d3 from "d3";
class Aroma extends React.Component {
componentDidMount(){
var margin = {top: 650, right: 650, bottom: 650, left: 650},
radius = Math.min(margin.top, margin.right, margin.bottom, margin.left) - 168;
function filter_min_arc_size_text(d, i) {return (d.dx*d.depth*radius/1)>14};
var hue = d3.scale.category10();
var luminance = d3.scale.sqrt()
.domain([0, 1e6])
.clamp(true)
.range([80, 20]);
var svg = d3.select("body").append("svg")
.attr("width", margin.left + margin.right)
.attr("height", margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
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 + 6) / 3 * d.depth; })
.outerRadius(function(d) { return (radius + 6) / 3 * (d.depth + 1.) - 1; });
svg.append("image")
.attr("xlink:href", "images/grapes.png")
.attr("x", -650)
.attr("y", -650);
//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 rotation = (d.x + d.dx / 2) * 180 / Math.PI - 90;
return {
global: rotation,
correction: rotation > 90 ? 180 : 0
};
}
function isRotated(d) {
var rotation = (d.x + d.dx / 2) * 180 / Math.PI - 90;
return rotation > 90 ? true : false
}
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("data/davis-aroma-wheel.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 < 3 ? 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)
{
var r = computeTextRotation(d);
return "rotate(" + r.global + ")"
+ "translate(" + radius / 3. * d.depth + ")"
+ "rotate(" + -r.correction + ")";
})
.style("font-weight", "bold")
.style("text-anchor", "middle")
.attr("dx", function(d) {return isRotated(d) ? "-85" : "85"}) //margin
.attr("dy", ".35em") // vertical-align
.on("click", zoomIn)
.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.
//commented //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.
//commented// 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) {
var r = computeTextRotation(d);
return "rotate(" + r.global + ")"
+ "translate(" + radius / 3 * d.depth + ",0)"
+ "rotate(" + -r.correction + ")";
})
.style("font-weight", "bold")
.style("text-anchor", "middle")
.attr("dx", function(d) {return isRotated(d) ? "-85" : "85"}) //margin
.attr("dy", ".35em") // vertical-align
.filter(filter_min_arc_size_text)
.on("click", zoomIn)
.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(this.frameElement).style("height", margin.top + margin.bottom + "px");
}
render(){
return <p id="aroma" />;
}
}
export default Aroma;
I emailed the original D3 repo author and he kindly got back to me, mentioning that there's an error with d3 version 3, that it needs longer investigation. He sent me all the resources that he used to build his project 3 years ago.
So I simply decided to follow this action.
Zoomable sunburst chart shows only two layers of the hierarchy at a time in React JS
Here is my code snippet for implementing the ellipsis on x axis labels in d3 v3.
Can someone help me figure out the changes needed to my code in v4??
//function for adding '...' if length is more than 50 px
var wrap = function () {
var self = d3.select(this),
textLength = self.node().getComputedTextLength(),
text = self.text();
while (textLength > (50) && text.length > 0) {
text = text.slice(0, -1);
self.text(text + '...');
textLength = self.node().getComputedTextLength();
}
};
//calling the function
svg.select('.x.axis')
.call(xAxis)
.selectAll('text')
.style('text-anchor', 'end')
.attr('fill', '#8a9299')
.attr('transform', 'rotate(-60)')
.each(wrap);
You just need to save the group element containing x-axis into a variable and use as shown below.
var wrap = function() {
var self = d3.select(this),
textLength = self.node().getComputedTextLength(),
text = self.text();
while (textLength > (50) && text.length > 0) {
text = text.slice(0, -1);
self.text(text + '...');
textLength = self.node().getComputedTextLength();
}
};
//calling the function
xAxis.selectAll('text')
.style('text-anchor', 'end')
.attr('fill', '#8a9299')
.attr('transform', 'rotate(-60)')
.each(wrap);
// set the dimensions and margins of the graph
var margin = {
top: 20,
right: 20,
bottom: 30,
left: 40
},
width = 250 - margin.left - margin.right,
height = 250 - margin.top - margin.bottom;
// set the ranges
var x = d3.scaleBand()
.range([0, width])
.padding(0.1);
var y = d3.scaleLinear()
.range([height, 0]);
// append the svg object to the body of the page
// append a 'group' element to 'svg'
// moves the 'group' element to the top left margin
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
var data = [{
"salesperson": "Bob Patrickson",
"sales": 33
},
{
"salesperson": "Robin Dearden",
"sales": 12
},
{
"salesperson": "Anne Hathaway",
"sales": 41
},
{
"salesperson": "Mark Wahlberg",
"sales": 16
}
];
// format the data
data.forEach(function(d) {
d.sales = +d.sales;
});
// Scale the range of the data in the domains
x.domain(data.map(function(d) {
return d.salesperson;
}));
y.domain([0, d3.max(data, function(d) {
return d.sales;
})]);
// append the rectangles for the bar chart
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) {
return x(d.salesperson);
})
.attr("width", x.bandwidth())
.attr("y", function(d) {
return y(d.sales);
})
.attr("height", function(d) {
return height - y(d.sales);
});
// add the x Axis
var xAxis = svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
// add the y Axis
svg.append("g")
.call(d3.axisLeft(y));
var wrap = function() {
var self = d3.select(this),
textLength = self.node().getComputedTextLength(),
text = self.text();
while (textLength > (50) && text.length > 0) {
text = text.slice(0, -1);
self.text(text + '...');
textLength = self.node().getComputedTextLength();
}
};
//calling the function
xAxis.selectAll('text')
.style('text-anchor', 'end')
.attr('fill', '#8a9299')
.attr('transform', 'rotate(-60)')
.each(wrap);
.bar {
fill: steelblue;
}
<script src="//d3js.org/d3.v4.min.js"></script>
I am trying to create D3 charts based on elasticsearch nested aggregation. While I can plot a chart based on the first aggregation, I am not sure why I cant plot a similar chart on the nested a subsequent aggregation. Can anyone suggest what I should do?
My code:
esClient.search({
index: 'vehicle',
body: {
query:{
match:{
_all:searchTerms
}
},
aggs: {
touchdowns: {
terms: {
field: "country",
size:5
},
aggs: {
corp: {
terms: {
field: "companyName",
size:5
}
}
},
}
},
sort: [sortObject],
from: resultsPage * 10,
}
}).then(function(es_return){
deferred.resolve(es_return);
//// Pie Chart first aggregation
var touchdowns = es_return.aggregations.touchdowns.buckets;
// d3 donut chart
var width = 600,
height = 300,
radius = Math.min(width, height) / 2;
var color = ['#ff7f0e', '#d62728', '#2ca02c', '#1f77b4'];
var arc = d3.svg.arc()
.outerRadius(radius - 60)
.innerRadius(120);
var pie = d3.layout.pie()
.sort(null)
.value(function (d) { return d.doc_count; });
var svg = d3.select("#donut-chart").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width/1.4 + "," + height/2 + ")");
var g = svg.selectAll(".arc")
.data(pie(touchdowns))
.enter()
.append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.style("fill", function (d, i) { return color[i]; });
g.append("text")
.attr("transform", function (d) { return "translate(" + arc.centroid(d) + ")"; })
.attr("dy", ".35em")
.style("text-anchor", "middle")
.style("fill", "white")
.text(function (d) { return d.data.key; });
//// Pie Chart
var touchdowns = es_return.aggregations.touchdowns.buckets.corp.buckets;
// d3 donut chart
var width = 600,
height = 300,
radius = Math.min(width, height) / 2;
var color = ['#ff7f0e', '#d62728', '#2ca02c', '#1f77b4'];
var arc = d3.svg.arc()
.outerRadius(radius - 60)
.innerRadius(120);
var pie = d3.layout.pie()
.sort(null)
.value(function (d) { return d.doc_count; });
var svg = d3.select("#donut-chart").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width/1.4 + "," + height/2 + ")");
var g = svg.selectAll(".arc")
.data(pie(touchdowns))
.enter()
.append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.style("fill", function (d, i) { return color[i]; });
g.append("text")
.attr("transform", function (d) { return "translate(" + arc.centroid(d) + ")"; })
.attr("dy", ".35em")
.style("text-anchor", "middle")
.style("fill", "white")
.text(function (d) { return d.assignee.key; });
}, function(error){
deferred.reject(error);
});
return deferred.promise;};
hi I am using the following code to basically create a bar graph by consuming data from a service call. The problem with this is as the data from the service call changes, it is not reflected in the bar graph, it remains in its original state. The Appname and Appcount are two things which i am getting from the service call
jQuery(function($)
{
Appnames = []//array will be populated from service call,
Appcount = []//array will be populated from serv`enter code here`ice call,
chart,
width = 700,
bar_height = 40,
gap = 2,
height = bar_height * Appnames.length;
var margin = {top: 20, right: 120, bottom: 20, left: 120};
/* step 1 - create the background*/
chart = d3.select($("#step-1")[0])
.append('svg')
.attr('class', 'chart')
.attr('width', width)
.attr('height', height);
/* step 2 - create the bars*/
var x, y;
chart = d3.select($("#step-2")[0])
.append('svg')
.attr('class', 'chart')
.attr('width', width + margin.right + margin.left)
.attr('height', height);
x = d3.scale.linear()
.domain([0, d3.max(Appcount)])
.range([0, width]);
y = function(i) { return bar_height * i; }
chart.selectAll("rect")
.data(Appcount)
.enter().append("rect")
.attr("x", 0)
.attr("y", function(d, i) { return y(i);})
.attr("width", x)
.attr("height", bar_height);
/* step 3 - add counts to the bars*/
chart = d3.select($("#step-3")[0])
.append('svg')
.attr('class', 'chart')
.attr('width', width)
.attr('height', height);
chart.selectAll("rect")
.data(Appcount)
.enter().append("rect")
.attr("x", 0)
.attr("y", function(d, i) { return y(i);})
.attr("width", x)
.attr("height", bar_height);
chart.selectAll("text")
.data(Appcount)
.enter().append("text")
.attr("x", x)
.attr("y", function(d, i){ return y(i) + bar_height/2; } )
.attr("dx", -5)
.attr("dy", ".36em")
.attr("text-anchor", "end")
.text(String);
/* step 4 - add Appnames to bars*/
var left_width = 100;
chart = d3.select($("#step-4")[0])
.append('svg')
.attr('class', 'chart')
.attr('width', left_width + width)
.attr('height', height);
chart.selectAll("rect")
.data(Appcount)
.enter().append("rect")
.attr("x", left_width)
.attr("y", function(d, i) { return y(i);})
.attr("width", x)
.attr("height", bar_height);
chart.selectAll("text.score")
.data(Appcount)
.enter().append("text")
.attr("x", function(d) { return x(d) + left_width; })
.attr("y", function(d, i) { return y(i) + bar_height / 2;})
.attr("dx", -5)
.attr("dy", ".36em")
.attr("text-anchor", "end")
.attr('class', 'score')
.text(String);
chart.selectAll("text.name")
.data(Appnames)
.enter().append("text")
.attr("x", left_width / 2)
.attr("y", function(d, i){ return y(i) +bar_height/2; } )
.attr("dy", ".36em")
.attr("text-anchor", "middle")
.attr('class', 'name')
.text(String);
/* step 5 - add a ruler line to the bars*/
var gap = 2, yRangeBand;
// redefine y for adjusting the gap
yRangeBand = bar_height + 2 * gap;
y = function(i) { return yRangeBand * i; };
chart = d3.select($("#step-5")[0])
.append('svg')
.attr('class', 'chart')
.attr('width', left_width + width + 40)
.attr('height', (bar_height + gap * 2) * Appnames.length + 30)
.append("g")
.attr("transform", "translate(10, 20)");
chart.selectAll("line")
.data(x.ticks(d3.max(Appcount)))
.enter().append("line")
.attr("x1", function(d) { return x(d) + left_width; })
.attr("x2", function(d) { return x(d) + left_width; })
.attr("y1", 0)
.attr("y2", (bar_height + gap * 2) * Appnames.length);
chart.selectAll(".rule")
.data(x.ticks(d3.max(Appcount)))
.enter().append("text")
.attr("class", "rule")
.attr("x", function(d) { return x(d) + left_width; })
.attr("y", 0)
.attr("dy", -6)
.attr("text-anchor", "middle")
.attr("font-size", 10)
.text(String);
chart.selectAll("rect")
.data(Appcount)
.enter().append("rect")
.attr("x", left_width)
.attr("y", function(d, i) { return y(i) + gap; })
.attr("width", x)
.attr("height", bar_height);
chart.selectAll("text.score")
.data(Appcount)
.enter().append("text")
.attr("x", function(d) { return x(d) + left_width; })
.attr("y", function(d, i) { return y(i) + yRangeBand/2;})
.attr("dx", -5)
.attr("dy", ".36em")
.attr("text-anchor", "end")
.attr('class', 'score')
.text(String);
chart.selectAll("text.name")
.data(Appnames)
.enter().append("text")
.attr("x", left_width / 2)
.attr("y", function(d, i){ return y(i) + yRangeBand/2; } )
.attr("dy", ".36em")
.attr("text-anchor", "middle")
.attr('class', 'name')
.text(String); }(jQuery));
d3 uses an enter, update and exit pattern. Your code is only handling the enter state. Split it up to handle all 3 states:
var rects = chart.selectAll("rect")
.data(Appcount); //<-- create your data join
rects.enter().append("rect"); //<-- ENTER - when data enters the join append a rect element to dom
rects.exit().remove(); //<-- EXIT - when data leaves the join, remove the rect
rects.attr("x", 0) //<-- UPDATE - update the rects based on data
.attr("y", function(d, i) { return y(i);})
.attr("width", x)
.attr("height", bar_height);
I am developing bar graph using d3.js integrating with Angularjs. The angular directive code I am using is given below . My problem is ,in my real application , the bar graph is not redrawing but its axis changes when data associated with the bar graph changes
mainApp.directive('ngDatenobargraph', function() {
return {
restrict: 'AE',
scope: {
data: '='
},
link: function (scope, element) {
var margin = {top: 10, right: 10, bottom: 40, left: 60},
width = 410 - margin.left - margin.right,
height = 230 - margin.top - margin.bottom;
var chart = d3.select(element[0])
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var x = d3.scale.ordinal().rangeRoundBands([0, width], .1);
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<span style='font-size: 13px'>Date: </span><span style='color:red;font-size: 13px'>" + d.xValue+ "</span><br>"+
"<span style='font-size: 13px'>Net Value: </span><span style='color:red;font-size: 13px'>" + d.yValue+ "</span><br>"+
"<span style='font-size: 13px'>Buy Value: </span><span style='color:red;font-size: 13px'>" + d.buyValue+ "</span><br>"+
"<span style='font-size: 13px'>Sell Value: </span><span style='color:red;font-size: 13px'>" + d.sellValue+ "</span>";
});
chart.call(tip);
//Render graph based on 'data'
scope.render = function(data) {
if(data) {
var y = d3.scale.linear()
.range([height, 0])
.domain(d3.extent(data, function(d) { return d.yValue; }))
.nice();
var xAxis = d3.svg.axis().scale(x).orient("bottom");
var yAxis = d3.svg.axis().scale(y).orient("left").ticks(7);
x.domain(data.map(function(d) { return d.xValue; }));
//Redraw the axes
chart.selectAll('g.axis').remove();
chart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + (height) + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", ".15em")
.attr("transform", function(d) {
return "rotate(-20)";
});
chart.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 0-margin.left)
.attr("x",0-(height / 2))
.attr("dy", "1em")
.style("text-anchor", "middle")
.text("Net Value");
chart.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", function(d) { return d.yValue < 0 ? "bar negative" : "bar positive"; })
.attr("x", function(d) { return x(d.xValue); })
.attr("y", height)
.attr("height", 0)
.on('mouseover', tip.show)
.on('mouseout', tip.hide)
.transition().duration(2000)
.attr("y", function(d) {return y(Math.max(0, d.yValue)); })
.attr("height", function(d) {return Math.abs(y(d.yValue) - y(0)); })
// .attr("width", x.rangeBand());
.attr("width", Math.min.apply(null, [x.rangeBand()-2, 100]));
}
};
scope.$watch('data', function() {
scope.render(scope.data);
}, true);
}
};
});
I am new to d3.js . If any have solution please help me .The code in application is given http://jsfiddle.net/HB7LU/9000/