Reference error in d3.js code - d3.js

I am new to javascript as well as d3. I am running one of the graph codes from the website but I am getting the following error:
Uncaught TypeError: Cannot read property 'children' of null d3.v3.min.js:2
gu d3.v3.min.js:2
n d3.v3.min.js:4
e d3.v3.min.js:4
e d3.v3.min.js:4
(anonymous function) index.html:44
(anonymous function) d3.v3.min.js:1
t d3.v3.min.js:1
u d3.v3.min.js:1
Here's the whole code:
<!DOCTYPE html>
<meta charset="utf-8">
<style>
path {
stroke: #fff;
fill-rule: evenodd;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var width = 960,
height = 700,
radius = Math.min(width, height) / 2;
var x = d3.scale.linear()
.range([0, 2 * Math.PI]);
var y = d3.scale.sqrt()
.range([0, radius]);
var color = d3.scale.category20c();
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()
.value(function(d) { return d.size; });
var arc = d3.svg.arc()
.startAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x))); })
.endAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx))); })
.innerRadius(function(d) { return Math.max(0, y(d.y)); })
.outerRadius(function(d) { return Math.max(0, y(d.y + d.dy)); });
d3.json("http://bl.ocks.org/d/4063550/flare.json", function(root) {
var path = svg.selectAll("path")
.data(partition.nodes(root))
.enter().append("path")
.attr("d", arc)
.style("fill", function(d) { return color((d.children ? d : d.parent).name); })
.on("click", click);
function click(d) {
path.transition()
.duration(750)
.attrTween("d", arcTween(d));
}
});
d3.select(self.frameElement).style("height", height + "px");
// Interpolate the scales!
function arcTween(d) {
var xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]),
yd = d3.interpolate(y.domain(), [d.y, 1]),
yr = d3.interpolate(y.range(), [d.y ? 20 : 0, radius]);
return function(d, i) {
return i
? function(t) { return arc(d); }
: function(t) { x.domain(xd(t)); y.domain(yd(t)).range(yr(t)); return arc(d); };
};
}
</script>

Around line 44 of index.html you can see a possible source of the problem:
d3.json("http://bl.ocks.org/d/4063550/flare.json", function(root) {
var path = svg.selectAll("path")
.data(partition.nodes(root))
The problem is that the file http://bl.ocks.org/d/4063550/flare.json doesn't exist on your domain (which, I am guessing, is localhost).
In this case, the data is null and the error is non-null.
As suggested in the comments, try hosting the file locally (or where you are hosting your Javascript code) and it should work.
To start a local server
If you have python, then you can start a local webserver which serves static files from the current folder as:
python -mSimpleHTTPServer
This will start a local webserver serving the files in the current folder at localhost:8000. You can then point your browser to http://localhost:8000/the-dowloaded-file.html to load your webpage which contains this code.
Be sure to change the reference to the file from http://.../flare.json to just flare.json as well.

Related

Need help to break long text and display in arc in d3.js

I am facing issue to align and wrap big text in Arc segment.
I have tried to implement tspan but unable to transform it correctly.
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.arc text,
.wedge text {
font: 10px sans-serif;
text-anchor: middle;
}
.arc path,
.wedge path {
stroke: #fff;
}
</style>
<body>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script>
var width = 494,
height = 504,
radius = Math.min(width, height) / 2;
var color = d3.scale.ordinal()
.range(["#f38e36","#d79ae2","#dac2ad","#89e1ea"])
.domain(["Social", "Livability","Knowledge","Economy"]);
var arc = d3.svg.arc()
.outerRadius(radius - 0)
.innerRadius(radius - 110);
var wedge = d3.svg.arc()
.outerRadius(radius - 110)
.innerRadius(0);
var labelWedge = d3.svg.arc()
.outerRadius(radius-200)
.innerRadius(radius-200);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.count; });
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
d3.csv("data.csv", type, function(error, data) {
if (error) throw error;
nested = [{"category":"Social","count":25},{"category":"Livability","count":25},{"category":"Knowledge","count":25},{"category":"Economy","count":25}];
data1=
[{"category":"Social","subcategory":"Eduction and Employment","count":0.39},
{"category":"Social","subcategory":"Social Support","count":0.39},
{"category":"Social","subcategory":"Housing & Communities","count":0.39},
{"category":"Social","subcategory":"Civil Society","count":0.39},
{"category":"Livability","subcategory":"Activation and Calendaring","count":0.26},
{"category":"Livability","subcategory":"Mobility","count":0.26},
{"category":"Livability","subcategory":"Nature","count":0.26},
{"category":"Livability","subcategory":"Healthy and Sustainable Lifestyle","count":0.26},
{"category":"Livability","subcategory":"Marketing","count":0.26},
{"category":"Livability","subcategory":"Source of Distinctiveness","count":0.26},
{"category":"Knowledge","subcategory":"Vibrant Tech Companies","count":0.39},
{"category":"Knowledge","subcategory":"Tech Talent Attraction","count":0.39},
{"category":"Knowledge","subcategory":"Distinctive Tech Eduction","count":0.39},
{"category":"Knowledge","subcategory":"Full-Fledge R&D System","count":0.39},
{"category":"Economy","subcategory":"Business Environment Companiesetitiveness","count":0.39},
{"category":"Economy","subcategory":"Tourism","count":0.39},
{"category":"Economy","subcategory":"SME Support","count":0.39},
{"category":"Economy","subcategory":"Private Sector Incentivization","count":0.39}];
console.log("nested", nested);
console.log("nested", data1);
var g = svg.selectAll(".arc")
.data(pie(data1))
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.style("fill", function(d) { return color(d.data.category); });
g.append("text")
.attr("transform", function(d) { return transformLabel(d); })
.attr("dy", ".35em")
.text(function(d) { return d.data.subcategory; });
var g = svg.selectAll(".wedge")
.data(pie(nested))
.enter().append("g")
.attr("class", "wedge");
g.append("path")
.attr("d", wedge)
.style("fill", function(d) { return color(d.data.category); });
g.append("text")
.attr("transform", function(d) { return "translate(" + labelWedge.centroid(d) + ")"; })
.attr("dy", ".35em")
.text(function(d) { return d.data.category; });
});
function type(d) {
d.count = +d.count;
return d;
}
function transformLabel(d){
[x, y] = arc.centroid(d);
var rotation = d.endAngle < Math.PI ? (d.startAngle / 2 + d.endAngle / 2) * 180 / Math.PI : (d.startAngle / 2 + d.endAngle / 2 + Math.PI) * 180 / Math.PI;
let label = "translate(" + [x, y] + ") rotate(-90) rotate(" + rotation + ")";
return label;
}
function wrap(text, width) {
text.each(function () {
var text = d3.select(this),
words = text.text().split(/\s+/).reverse(),
word,
line = [],
lineNumber = 0,
lineHeight = 1.1, // ems
x = text.attr("x"),
y = text.attr("y"),
dy = 0, //parseFloat(text.attr("dy")),
tspan = text.text(null)
.append("tspan")
.attr("x", x)
.attr("y", y)
.attr("dy", dy + "em");
while (word = words.pop()) {
line.push(word);
tspan.text(line.join(" "));
if (tspan.node().getComputedTextLength() > width) {
line.pop();
tspan.text(line.join(" "));
line = [word];
tspan = text.append("tspan")
.attr("x", x)
.attr("y", y)
.attr("dy", ++lineNumber * lineHeight + dy + "em")
.text(word);
}
}
});
}
</script>
calling wrap text not working properly. when I call the wraptext function i got the text but they are mostly not aligned.also what is best option to add the shadow to the each segment of arc.

How ro replace d3.rainbow

With d3.v4.0.0-alpha.35.min.js used in this example, there is a rainbowColor() function which is now missing in d3.v4.min.js:
var color = rainbowColor()
.domain([0, 2 * Math.PI]);
Would anyone know if this function was moved or renamed or if a working version of that example exists using other color schemes? Thanks.
With d3v4 and d3v5, you can use:
var color = d3.scaleSequential()
.domain([0, 2 * Math.PI])
.interpolator(d3.interpolateRainbow);
instead of:
var color = d3.scaleRainbow()
.domain([0, 2 * Math.PI]);
which translates for your example into:
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height"),
size = Math.max(width, height);
var color = d3.scaleSequential()
.domain([0, 2 * Math.PI])
.interpolator(d3.interpolateRainbow);
var circles = d3.packSiblings(d3.range(2000)
.map(d3.randomUniform(8, 26))
.map(function(r) { return {r: r}; }))
.filter(function(d) { return -500 < d.x && d.x < 500 && -500 < d.y && d.y < 500; });
svg
.select("g")
.selectAll("circle")
.data(circles)
.enter().append("circle")
.style("fill", function(d) { return color(d.angle = Math.atan2(d.y, d.x)); })
.attr("cx", function(d) { return Math.cos(d.angle) * (size / Math.SQRT2 + 30); })
.attr("cy", function(d) { return Math.sin(d.angle) * (size / Math.SQRT2 + 30); })
.attr("r", function(d) { return d.r - 0.25; })
.transition()
.ease(d3.easeCubicOut)
.delay(function(d) { return Math.sqrt(d.x * d.x + d.y * d.y) * 10; })
.duration(1000)
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
body {
background: #333;
}
circle {
stroke: #000;
stroke-width: 1.5px;
}
<svg width="960" height="960"><g transform="translate(480,480)"></g></svg>
<script src="http://d3js.org/d3.v4.min.js"></script>
where scaleSequential is part of the d3-scale sub-module and interpolateRainbow is part of the d3-scale-chromatic sub-module.
There have been major api changes between d3 versions 3 and 4. d3.v4.0.0-alpha.35.min.js was probably an early alpha version of the version 4 still using the version 3 api for that particular function.
In d3v6 this has changed to
var color = d3.scaleSequential(d3.interpolateRainbow)
.domain([0, 2 * Math.PI]);

How to solve duplicate label in zoom

i have a problem when i do a zoom in my map because the labels appears duplicate. I know that my problem appears because in my zoom i dont delete the label. I know where is the problem, i need to delete the oldest label when i do a zoom but i dont know how and where to solve this.
Any idea? Ty for all.
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
margin: 0;
}
path {
fill: none;
stroke: green;
stroke-linejoin: round;
stroke-width: 1.5px;
}
</style>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/topojson/1.6.19/topojson.min.js"></script>
<script src="d3.geo.tile.min.js"></script>
<script>
var width = Math.max(960, window.innerWidth),
height = Math.max(600, window.innerHeight);
var tile = d3.geo.tile()
.size([width, height]);
var projection = d3.geo.mercator()
.scale((3 << 12) / 2 / Math.PI)
.translate([width / 2, height / 2]);
var center = projection([-3, 36]);
var path = d3.geo.path()
.projection(projection);
var zoom = d3.behavior.zoom()
.scale(projection.scale() * 2 * Math.PI)
.translate([width - center[0], height - center[1]])
.on("zoom", zoomed);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var raster = svg.append("g");
var g = svg.append("g");
var vector = svg.append("path");
d3.json("es.json", function(error, es) {
if (error) throw error;
svg.call(zoom);
vector.datum(topojson.mesh(es, es.objects.provinces));
zoomed();
});
function zoomed() {
d3.csv("data/country-capitals.csv", function(err, capitals) {
capitals.forEach(function(i){
addpoint(i.CapitalLongitude, i.CapitalLatitude, i.CapitalName );
});
});
var tiles = tile
.scale(zoom.scale())
.translate(zoom.translate())
();
projection
.scale(zoom.scale() / 2 / Math.PI)
.translate(zoom.translate());
vector
.attr("d", path);
var image = raster
.attr("transform", "scale(" + tiles.scale + ")translate(" + tiles.translate + ")")
.selectAll("image")
.data(tiles, function(d) { return d; });
image.exit()
.remove();
image.enter().append("image")
.attr("xlink:href", function(d) { return "http://" + ["a", "b", "c"][Math.random() * 3 | 0] + ".tile.openstreetmap.org/" + d[2] + "/" + d[0] + "/" + d[1] + ".png"; })
.attr("width", 1)
.attr("height", 1)
.attr("x", function(d) { return d[0]; })
.attr("y", function(d) { return d[1]; });
}
function addpoint(lat,lon,text) {
var gpoint = g.append("g").attr("class", "gpoint");
var x = projection([lat,lon])[0];
var y = projection([lat,lon])[1];
gpoint.append("svg:circle")
.attr("cx", x)
.attr("cy", y)
.attr("class","point")
.attr("r", 1.5);
//conditional in case a point has no associated text
if(text.length>0){
gpoint.append("text")
.attr("x", x+2)
.attr("y", y+2)
.attr("class","text")
.text(text);
}
}
</script>
CSV is here:
CountryName,CapitalName,CapitalLatitude,CapitalLongitude,CountryCode,ContinentName
Brazil,Brasilia,-15.783333333333333,-47.916667,BR,South America
Colombia,Bogota,4.6,-74.083333,CO,South America
Egypt,Cairo,30.05,31.250000,EG,Africa
France,Paris,48.86666666666667,2.333333,FR,Europe
Iraq,Baghdad,33.333333333333336,44.400000,IQ,Asia
South Korea,Seoul,37.55,126.983333,KR,Asia
Kosovo,Pristina,42.666666666666664,21.166667,KO,Europe
Mexico,Mexico City,19.433333333333334,-99.133333,MX,Central America
Before you zoom you can remove all the group containing text and circle like this:
function zoomed() {
d3.selectAll(".gpoint").remove();
d3.csv("my.csv", function(err, capitals) {
capitals.forEach(function(i){
addpoint(i.CapitalLongitude, i.CapitalLatitude, i.CapitalName );
});
});
//your code
Working code here

Zoomable Sunburst with % Share labeled

I want show percentage share of each block in labelled zoomable sunburst chart. I am referring http://bl.ocks.org/metmajer/5480307 this example.
here I want add (%x) share of each block. Please help.
Below is my index.html
<!DOCTYPE html>
<meta charset="utf-8"><style>
path {
stroke: #fff;
fill-rule: evenodd;
}
text {
font-family: Arial, sans-serif;
font-size: 12px;
}
</style> <body>
<script src="http://d3js.org/d3.v3.min.js">
</script> <script>
var width = 960,
height = 700,
radius = Math.min(width, height) / 2;
var x = d3.scale.linear()
.range([0, 2 * Math.PI]);
var y = d3.scale.linear()
.range([0, radius]);
var color = d3.scale.category20c();
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()
.value(function(d) { return d.size; });
var arc = d3.svg.arc()
.startAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x))); })
.endAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx))); })
.innerRadius(function(d) { return Math.max(0, y(d.y)); })
.outerRadius(function(d) { return Math.max(0, y(d.y + d.dy)); });
d3.json("atmLeads.json", function(error, root) {
var g = svg.selectAll("g")
.data(partition.nodes(root))
.enter().append("g");
var path = g.append("path")
.attr("d", arc).attr("class",function(d){return "ring_"+ d.depth;})
.style("fill", function(d) { return color((d.children ? d : d.parent).name); })
.on("click", click);
var text = g.append("text")
.attr("transform", function(d) { return "rotate(" + computeTextRotation(d) + ")"; })
.attr("x", function(d) { return y(d.y); })
.attr("dx", "6") // margin
.attr("dy", ".35em") // vertical-align
.text(function(d) { return d.name; });
function click(d) {
// fade out all text elements
text.transition().attr("opacity", 0);
path.transition()
.duration(750)
.attrTween("d", arcTween(d))
.each("end", function(e, i) {
// check if the animated element's data e lies within the visible angle span given in d
if (e.x >= d.x && e.x < (d.x + d.dx)) {
// get a selection of the associated text element
var arcText = d3.select(this.parentNode).select("text");
// fade in the text element and recalculate positions
arcText.transition().duration(750)
.attr("opacity", 1)
.attr("transform", function() { return "rotate(" + computeTextRotation(e) + ")" })
.attr("x", function(d) { return y(d.y); });
}
});
}
});
d3.select(self.frameElement).style("height", height + "px");
// Interpolate the scales!
function arcTween(d) {
var xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]),
yd = d3.interpolate(y.domain(), [d.y, 1]),
yr = d3.interpolate(y.range(), [d.y ? 20 : 0, radius]);
return function(d, i) {
return i
? function(t) { return arc(d); }
: function(t) { x.domain(xd(t)); y.domain(yd(t)).range(yr(t)); return arc(d); };
};
}
function computeTextRotation(d) {
return (x(d.x + d.dx / 2) - Math.PI / 2) / Math.PI * 180;
}
</script>
Try this code.
var path = g.append("path")
.attr("d", arc).attr("class", function(d) {
return "ring_" + d.depth;
})
.style("fill", function(d) {
return color((d.children ? d : d.parent).name);
})
.on("click", click);
var totalSize = path.node().__data__.value;
var text = g.append("text")
.attr("transform", function(d) {
return "rotate(" + computeTextRotation(d) + ")";
})
.attr("x", function(d) {
return y(d.y);
})
.attr("dx", "6") // margin
.attr("dy", ".35em") // vertical-align
.text(function(d) {
var percentage = (100 * d.value / totalSize).toPrecision(3);
var percentageString = percentage + "%";
if (percentage < 0.1) {
percentageString = "< 0.1%";
}
return d.name +" "+percentageString;
});
var width = 960,
height = 700,
radius = Math.min(width, height) / 2;
var x = d3.scale.linear()
.range([0, 2 * Math.PI]);
var y = d3.scale.linear()
.range([0, radius]);
var color = d3.scale.category20c();
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()
.value(function(d) {
return d.size;
});
var arc = d3.svg.arc()
.startAngle(function(d) {
return Math.max(0, Math.min(2 * Math.PI, x(d.x)));
})
.endAngle(function(d) {
return Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx)));
})
.innerRadius(function(d) {
return Math.max(0, y(d.y));
})
.outerRadius(function(d) {
return Math.max(0, y(d.y + d.dy));
});
var root = {
"name": "ATM Leads Converted",
"size": 34752,
"children": [
{
"name": "Converted",
"size": 417
}, {
"name": "Failure",
"size": 1366
}, {
"name": "Interested",
"size": 916
}, {
"name": "No Value",
"size": 48932
}, {
"name": "Not Interested",
"size": 14479
}, {
"name": "Not contactable",
"size": 2961
},
{
"name": "Success",
"size": 1142
}, {
"name": "Will Get Back",
"size": 1564
}, {
"name": "Wrong Number",
"size": 358
}
]
};
var g = svg.selectAll("g")
.data(partition.nodes(root))
.enter().append("g");
var path = g.append("path")
.attr("d", arc).attr("class", function(d) {
return "ring_" + d.depth;
})
.style("fill", function(d) {
return color((d.children ? d : d.parent).name);
})
.on("click", click);
var totalSize = path.node().__data__.value;
var text = g.append("text")
.attr("transform", function(d) {
return "rotate(" + computeTextRotation(d) + ")";
})
.attr("x", function(d) {
return y(d.y);
})
.attr("dx", "6") // margin
.attr("dy", ".35em") // vertical-align
.text(function(d) {
var percentage = (100 * d.value / totalSize).toPrecision(3);
var percentageString = percentage + "%";
if (percentage < 0.1) {
percentageString = "< 0.1%";
}
return d.name +" "+percentageString;
});
function click(d) {
// fade out all text elements
text.transition().attr("opacity", 0);
path.transition()
.duration(750)
.attrTween("d", arcTween(d))
.each("end", function(e, i) {
// check if the animated element's data e lies within the visible angle span given in d
if (e.x >= d.x && e.x < (d.x + d.dx)) {
// get a selection of the associated text element
var arcText = d3.select(this.parentNode).select("text");
// fade in the text element and recalculate positions
arcText.transition().duration(750)
.attr("opacity", 1)
.attr("transform", function() {
return "rotate(" + computeTextRotation(e) + ")"
})
.attr("x", function(d) {
return y(d.y);
});
}
});
}
d3.select(self.frameElement).style("height", height + "px");
// Interpolate the scales!
function arcTween(d) {
var xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]),
yd = d3.interpolate(y.domain(), [d.y, 1]),
yr = d3.interpolate(y.range(), [d.y ? 20 : 0, radius]);
return function(d, i) {
return i ? function(t) {
return arc(d);
} : function(t) {
x.domain(xd(t));
y.domain(yd(t)).range(yr(t));
return arc(d);
};
};
}
function computeTextRotation(d) {
return (x(d.x + d.dx / 2) - Math.PI / 2) / Math.PI * 180;
}
path {
stroke: #fff;
fill-rule: evenodd;
}
text {
font-family: Arial, sans-serif;
font-size: 12px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

d3 show labels only for ticks with data in a bar chart

First, I'm new with D3. :)
I have a stacked bar chart. My y axis is a ordinal scale (state).
In my data, I could have total=0 for some ticks. So, I just want to see the labels when the total > 0 but maintain all the ticks of the data.
var data = [{ "state":"A", "total":"10"},
{ "state":"B", "total":"0"},
{ "state":"C", "total":"0"},
{ "state":"D", "total":"20"},
{ "state":"E", "total":"0"},
{ "state":"F", "total":"50"}]
I've tried this code, but this remove all the ticks with total = 0. I just want to remove the label of that tick.
yAxis.tickValues(dataSet.map( function(d,i)
{
if (d.total > 0)
return d.state;
else
if(i % 4 === 0 ) return d.state;
})
.filter(function (d)
{ return !!d; } ));
Thanks,
Filipe
UPDATE
Here is the code:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" class="ocks-org do-not-copy">
<head>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<div id="timeLine"></div>
<!--style>
svg {
font: 10px sans-serif;
}
path {
fill: steelblue;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
</style-->
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var timeline;
var labels;
var margin = {
top : 20,
right : 10,
bottom : 60,
left : 80
},
width = 500 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scale.linear()
.rangeRound([0, width]);
var y = d3.scale.ordinal()
.rangeBands([height, 0], 0.1);
var color = d3.scale.ordinal()
.range(["#1f77b4", "#2ca02c", "#E53524"]);
//var color = d3.scale.category10()
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.tickFormat(d3.format(".2s"))
.ticks(10);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(5);
timeline = d3.select("#timeLine").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 dataSet;
var all_nodes_t;
var all_updates_t;
var test;
var entity = "ALL";
dataSet = [
{ "Date":"2014-01", "insert":"27", "remove":"17","updates":"427"},
{ "Date":"2014-02", "insert":"27", "remove":"17","updates":"427"},
{ "Date":"2014-03", "insert":"27", "remove":"17","updates":"427"},
{ "Date":"2014-04", "insert":"0", "remove":"0","updates":"0"},
{ "Date":"2014-05", "insert":"27", "remove":"17","updates":"427"},
];
color.domain(d3.keys(dataSet[0]).filter(function (key) {
return key !== "Date";
}));
dataSet.forEach(function (d) {
var x0 = 0;
d.ages = color.domain().map(function (name) {
return {
name : name,
x0 : x0,
x1 : x0 += +d[name]
};
});
d.total = d.ages[d.ages.length - 1].x1;
});
//HERE
yAxis.tickFormat(dataSet.map(function(d) {
d.total == 0 ? "" : d.Date;
}));
y.domain(dataSet.map(function (d) {
return d.Date;
}));
x.domain([0, d3.max(dataSet, function (d) {
return (d.total + 5);
})]);
timeline.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.append("text")
.attr("x", 1)
.attr("dx", "42em")
.attr("dy", "3em")
.style("text-anchor", "end")
.text("Operations");
timeline.append("g")
.attr("class", "y axis")
.call(yAxis);
var layer = timeline.selectAll(".state")
.data(dataSet)
.enter().append("g")
.attr("class", "rect")
.attr("transform", function (d) {
return "translate(0," + y(d.Date) + ")";
});
var rect = layer.selectAll("rect")
.data(function (d) {
return d.ages;
})
.enter().append("rect")
.attr("class", "rect")
.attr("width", 0)
.attr("x", width)
.attr('y', function (d, i) {
return y(d.Date);
})
.attr("height", y.rangeBand())
.style("fill", function (d) {
return color(d.name);
});
rect.transition()
.duration(600)
.delay(function (d, i) {
return i * 300;
})
.attr("width", function (d) {
return x(d.x1) - x(d.x0);
})
.attr("x", function (d) {
return x(d.x0);
});
</script>
</body>
</html>
You can use .tickFormat() to suppress the labels for those particular values. As the thing you want to check isn't part of the data that's available to the scale, you'll need to find it in your entire data:
yAxis.tickFormat(function(d) {
var val = 0;
dataSet.forEach(function(item) {
if(item.Date == d) val = item.total;
});
return val == 0 ? "" : d;
});
This will suppress the label (return "") if the total is 0 or the value can't be found in the data set. Complete demo here.

Resources