d3js color scale from csv files - javascript

Can you show me how to set color scales with data from csv file?
var color = d3.scaleLinear()
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<link rel="stylesheet" type="text/css" href="main.css">
<title>Zadatak 2</title>
<style>
/*.bar {
fill: dodgerblue;
}*/
</style>
</head>
<body>
<svg width="800" height="700"></svg>
<script>
var svg = d3.select("svg"),
margin = 200,
width = svg.attr("width") - margin,
height = svg.attr("height") - margin
var xScale = d3.scaleBand().range([0, width]).padding(0.4),
yScale = d3.scaleLinear().range([height, 0]);
var g = svg.append("g")
.attr("transform", "translate(" + 100 + "," + 100 + ")");
d3.csv("XYZ.csv", function(error, data) {
if (error) {
throw error;
}
var color = d3.scaleLinear()
.domain([0, d3.max(data, function(d) { return d.value; })])
.range(["red", "blue"])
xScale.domain(data.map(function(d) { return d.fruit; }));
yScale.domain([0, d3.max(data, function(d) { return d.value; })]);
g.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(xScale));
g.append("g")
.call(d3.axisLeft(yScale).tickFormat(function(d){
return d;
}).ticks(6));
g.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return xScale(d.fruit); })
.attr("y", function(d) { return yScale(d.value); })
.attr("fill",function(d){ return color(d) })
.attr("width", xScale.bandwidth())
.attr("height", function(d) { return height - yScale(d.value); });
});
</script>
</body>
</html>
.domain([0, d3.max(data, function(d) { return d.value; })])
.range(["red", "blue"])
g.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return xScale(d.fruit); })
.attr("y", function(d) { return yScale(d.value); })
.attr("fill",function(d){ return color(d) })
.attr("width", xScale.bandwidth())
.attr("height", function(d) { return height - yScale(d.value); });
});
csv file data
fruit,value
Apple,2
Orange,4
Kiwi,3
Peach,6
Grape,2
this one dont work. pls help me. Thanks

Related

how to connect d3.js and solr json response?

<!DOCTYPE html>
<meta charset="utf-8">
<head>
<style>
.axis {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
</style>
</head>
<body>
<!--/* adding d3.js lib*/-->
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="https://d3js.org/d3-dsv.v1.min.js"></script>
<script src="https://d3js.org/d3-fetch.v1.min.js"></script>
<script>
var margin = { top: 20, right: 20, bottom: 70, left: 40 },
width = 600 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
var x = d3.scale.ordinal().rangeRoundBands([0, width], .05);
var y = d3.scale.linear().range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.tickFormat(d3.num);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(10);
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 + ")");
/* my data on json server
d3.json("https://api.myjson.com/bins/xya14", function (error, data)
{
alert(data);
data.forEach(function (d) {
d.num = d.num;
d.value = +d.value;
alert(d.value);
});
x.domain(data.map(function (d) { return d.num; }));
y.domain([0, d3.max(data, function (d) { return d.value; })]);
*/
/* data on solr server*/
d3.json("http://192.168.2.4:8983/solr/vkash_collection/select?q=*:*&omitHeader=true", function (error, data)
{
alert(data);
data.forEach(function (d) {
d.num = d.num;
d.value = +d.value;
alert(d.value);
});
x.domain(data.map(function (d) { return d.num; }));
y.domain([0, d3.max(data, function (d) { return d.value; })]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-90)");
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Value ($)");
svg.selectAll("bar")
.data(data)
.enter().append("rect")
.style("fill", "steelblue")
.attr("x", function (d) { return x(d.num); })
.attr("width", x.rangeBand())
.attr("y", function (d) { return y(d.value); })
.attr("height", function (d) { return height - y(d.value); });
});
</script>
</body>
I load one json file in solr which is have only two fields num and value.i take this url and use d3.json("solr url",function (data))..but I get nothing on the browser. how to connect d3.js ??
my js code snippet is here:
my solr url response is here:

transition between two datasets, from a single line chart to a multiline chart, in d3

I'm trying to build a chart that goes from 1 line to many lines. I have built the two charts separately, but am having trouble combining them. The idea is that I want to show the total of all fruit sold per year, and then show how much of each fruit is sold per year.
This is the template I'm working from: http://bl.ocks.org/d3noob/a048edddbf83bff03a34
In my code, the single line shows up fine. When I click update, the axes update as they should, but the data doesn't. Any help would be greatly appreciated.
My code is in a plunker, here: https://plnkr.co/edit/dgwsGLIRbZ2qm7faEvSw?p=preview
The code is also below.
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body { font: 12px Arial;}
path {
stroke: #333;
stroke-width: 2;
fill: none;
}
.axis path,
.axis line {
fill: none;
stroke: grey;
stroke-width: 1;
shape-rendering: crispEdges;
}
</style>
<body>
<div id="option">
<input name="updateButton" id="updateData" type="button" value="Update" />
<input name="revertButton" type="button" value="Revert" onclick="revertData()" />
</div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script>
var margin = {top: 30, right: 20, bottom: 30, left: 50},
width = 800 - margin.left - margin.right,
height = 470 - margin.top - margin.bottom;
var x = d3.scaleLinear().range([0, width]);
var y = d3.scaleLinear().range([height, 0]);
var xAxis = d3.axisBottom().scale(x)
.ticks(7)
.tickFormat(d3.format("d"))
var yAxis = d3.axisLeft().scale(y)
.ticks(5);
var valueline = d3.line()
.x(function(d) { return x(d.Year); })
.y(function(d) { return y(d.Count); });
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 + ")");
d3.csv("datab.csv", function(error, data2) {
d3.csv("dataa.csv", function(error, data) {
data.forEach(function(d) {
d.Year = +d.Year;
d.Count = +d.Count;
});
x.domain(d3.extent(data, function(d) { return d.Year; }));
y.domain([0, d3.max(data, function(d) { return d.Count; })]);
dataNest1 = d3.nest()
.key(function(d) {return d.Type;})
.entries(data);
var result1 = dataNest1.filter(function(val,idx, arr){
return $("." + val.key)
})
var calls = d3.select("svg").selectAll(".line")
.data(result1, function(d){return d.key})
var color1 = d3.scaleOrdinal().range(["#333", "none", "none", "none", "none", "none"]);
calls.enter().append("path")
.attr("class", "line")
.attr("stroke","#333")
.attr("d", function(d){
return valueline(d.values)
})
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
d3.select('#updateData').on('click',function(){
updateData(data2)
})
});
});
function updateData(data2) {
data2.forEach(function(d) {
d.Year = +d.Year;
d.Count = +d.Count;
});
dataNest = d3.nest()
.key(function(d) {return d.Descriptor;})
.entries(data2);
var result = dataNest.filter(function(val,idx, arr){
return $("." + val.key)
})
x.domain(d3.extent(data2, function(d) { return d.Year; }));
y.domain([0, d3.max(data2, function(d) { return d.Count; })]);
var svg = d3.select("body").transition();
svg.selectAll('.circle').duration(0).remove()
d3.select("svg").selectAll(".line")
.data(result, function(d){return d.key})
d3.select("svg").selectAll("path.line")
.transition()
.duration(700)
.style("stroke", "#333")
.attr("d", function(d){
return valueline(d.values)
});
// svg.select(".line") // change the line
// .duration(750)
// .attr("d", valueline(rats));
svg.select(".x.axis")
.transition()
.duration(750)
.call(xAxis);
svg.select(".y.axis")
.duration(750)
.call(yAxis);
}
function revertData() {
// Get the data again
d3.csv("totalsbyyear.csv", function(error, data) {
data.forEach(function(d) {
d.Year = +d.Year;
d.Count = +d.Count;
});
// Scale the range of the data again
x.domain(d3.extent(data, function(d) { return d.Year; }));
y.domain([0, d3.max(data, function(d) { return d.Count; })]);
// Select the section we want to apply our changes to
var svg = d3.select("body").transition();
// Make the changes
svg.select(".line") // change the line
.duration(750)
.attr("d", valueline(data));
svg.select(".x.axis") // change the x axis
.duration(750)
.call(xAxis);
svg.select(".y.axis") // change the y axis
.duration(750)
.call(yAxis);
});
}
</script>
</body>
There are a few problems here. The first one being that your datasets are very different and I don't see anywhere in the code to compensate for there being multiple different fruit in the same year. This is something you will need to address either by modifying your csv file or in your updateData function to extract just a single fruit.
I have made some changes to your plunker that will allow the updateFunction to work but without fixing the input data it won't really matter.
https://plnkr.co/edit/DSg09NWPrBADLLbcL5cx?p=preview
The main thing that needed to be fixed was
d3.select("svg").selectAll("path.line")
.data(result, function(d){return d.key})
.transition()
.duration(700)
.style("stroke", "#337")
.attr("d", function(d){
return valueline(result)
});
And putting the d3.csv on datab.csv call in the updateData function instead of wrapping it around the main table creation function.
I was probably being unclear in my question asking. I figured out what I needed to do to make it work as intended. Code here:
https://plnkr.co/edit/YrABkbc8l9oeT1ywMspy?p=preview
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body { font: 12px Arial;}
path {
stroke: #333;
stroke-width: 2;
fill: none;
}
.axis path,
.axis line {
fill: none;
stroke: grey;
stroke-width: 1;
shape-rendering: crispEdges;
}
</style>
<body>
<div id="option">
<input name="updateButton" id="updateData" type="button" value="Update" />
<input name="revertButton" type="button" value="Revert" onclick="revertData()" />
</div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script>
var margin = {top: 30, right: 200, bottom: 30, left: 50},
width = 850 - margin.left - margin.right,
height = 470 - margin.top - margin.bottom;
var x = d3.scaleLinear().range([0, width]);
var y = d3.scaleLinear().range([height, 0]);
var xAxis = d3.axisBottom().scale(x)
.ticks(7)
.tickFormat(d3.format("d"))
var yAxis = d3.axisLeft().scale(y)
.ticks(5);
var valueline = d3.line()
.x(function(d) { return x(d.Year); })
.y(function(d) { return y(d.Count); });
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 + ")");
d3.csv("datab.csv", function(error, data2) {
d3.csv("dataa.csv", function(error, data) {
data.forEach(function(d) {
d.Year = +d.Year;
d.Count = +d.Count;
});
x.domain(d3.extent(data, function(d) { return d.Year; }));
y.domain([0, d3.max(data, function(d) { return d.Count; })]);
svg.append("path")
.attr("class", "line")
.attr("d", valueline(data));
svg.append("text")
.attr("transform", function(d) { return "translate(" + x(2017) + "," + y(35074) + ")"; })
.attr("x", 3)
.attr("dy", "0.35em")
.attr('class','toplinetext')
.style("font", "10px sans-serif")
.text(function(d) { return "All"; });
circles = svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr('class','circle')
.attr('cx',function(d){ return x(d.Year)})
.attr('cy',function(d){ return y(d.Count)})
.attr('r',3)
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
svg.exit().remove();
d3.select('#updateData').on('click',function(){
updateData(data2)
})
});
});
function updateData(data2) {
data2.forEach(function(d) {
d.Year = +d.Year;
d.Count = +d.Count;
});
var notapples = data2.filter(function(d){return d.Descriptor == "Peach" || d.Descriptor == "Pear" || d.Descriptor == "Plum" || d.Descriptor == "Banana"})
dataNest = d3.nest()
.key(function(d) {return d.Descriptor;})
.entries(notapples);
var result = dataNest.filter(function(val,idx, arr){
return $("." + val.key)
})
$('.toplinetext').text('Apples');
x.domain(d3.extent(data2, function(d) { return d.Year; }));
y.domain([0, d3.max(data2, function(d) { return d.Count; })]);
var svg = d3.select("body").transition();
svg.selectAll('.circle').duration(0).remove()
var typeOfCall = d3.select("svg").selectAll(".dline")
.data(result, function(d){return d.key})
.enter().append("g")
.attr("class", function(d){return "type " + d.key})
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
var color2 = d3.scaleOrdinal().range(["#ff0000", "#333", "#333", "#333", "#333", "#333"]);
typeOfCall.append("path")
.attr("height", 0)
.transition()
.duration(700)
.attr("class", "line")
.style("stroke", function(d,i) { return color2(d.key); })
.attr("d", function(d){
return valueline(d.values)
});
typeOfCall.append("text")
.datum(function(d) { return {id: d.Descriptor, value: d.values[d.values.length - 1]}; })
.attr("transform", function(d) { return "translate(" + x(d.value.Year) + "," + y(d.value.Count) + ")"; })
.attr("x", 3)
.attr("dy", "0.35em")
.style("font", "10px sans-serif")
.text(function(d) { return d.value.Descriptor; });
typeOfCall.exit().remove();
apples = data2.filter(function(d){return d.Descriptor == "Apple"})
svg.select(".line")
.duration(750)
.attr("d", valueline(apples));
svg.select(".x.axis")
.transition()
.duration(750)
.call(xAxis);
svg.select(".y.axis")
.duration(750)
.call(yAxis);
}
function revertData() {
// Get the data again
d3.csv("totalsbyyear.csv", function(error, data) {
data.forEach(function(d) {
d.Year = +d.Year;
d.Count = +d.Count;
});
$('.toplinetext').text('All');
$('.Peach,.Pear,.Banana,.Plum').remove();
// Scale the range of the data again
x.domain(d3.extent(data, function(d) { return d.Year; }));
y.domain([0, d3.max(data, function(d) { return d.Count; })]);
// Select the section we want to apply our changes to
var svg = d3.select("body").transition();
// Make the changes
svg.select(".line") // change the line
.duration(750)
.attr("d", valueline(data));
svg.select(".x.axis") // change the x axis
.duration(750)
.call(xAxis);
svg.select(".y.axis") // change the y axis
.duration(750)
.call(yAxis);
});
}
</script>
</body>

How to put different D3.js scripts on the same page without overlapping?

I am using D3.js to showcase my data. However, I am unable to get two different objects to not overlap. For example, the code below shows a line graph and a bar graph. I am using code from https://github.com/d3/d3/wiki/Gallery for this example to show my issue. The line graph code is from https://bl.ocks.org/mbostock/3883245. The bar graph code is from https://bl.ocks.org/mbostock/3885304. I tried using as shown in this example http://www.d3noob.org/2013/07/arranging-more-than-one-d3js-graph-on.html, but it did not work. I also made sure they both used the same version of d3.js. The data is from two tsv files that are on the links above for the line and bar graph. Any help would be appreciated!
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.bar {
fill: steelblue;
}
.bar:hover {
fill: brown;
}
.axis--x path {
display: none;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
<div id="lineg"></div>
<div id="barg"></div>
<lineg width="960" height="500"></lineg>
<barg width="960" height="500"></barg>
<script>
var svga = d3.select("#lineg"),
margina = {top: 20, right: 20, bottom: 30, left: 40},
widtha = +svga.attr("width") - margina.left - margina.right,
heighta = +svga.attr("height") - margina.top - margina.bottom;
var xa = d3.scaleBand().rangeRound([0, widtha]).padding(0.1),
ya = d3.scaleLinear().rangeRound([heighta, 0]);
var ga = svga.append("g")
.attr("transform", "translate(" + margina.left + "," + margina.top + ")");
d3.tsv("bardata.tsv", function(d) {
d.frequency = +d.frequency;
return d;
}, function(error, data) {
if (error) throw error;
xa.domain(data.map(function(d) { return d.letter; }));
ya.domain([0, d3.max(data, function(d) { return d.frequency; })]);
ga.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + heighta + ")")
.call(d3.axisBottom(xa));
ga.append("g")
.attr("class", "axis axis--y")
.call(d3.axisLeft(ya).ticks(10, "%"))
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", "0.71em")
.attr("text-anchor", "end")
.text("Frequency");
ga.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return xa(d.letter); })
.attr("y", function(d) { return ya(d.frequency); })
.attr("width", xa.bandwidth())
.attr("height", function(d) { return heighta - ya(d.frequency); });
});
</script>
<script>
var svgb = d3.select("barg"),
marginb = {top: 20, right: 20, bottom: 30, left: 50},
widthb = +svgb.attr("width") - marginb.left - marginb.right,
heightb = +svgb.attr("height") - marginb.top - marginb.bottom,
gb = svgb.append("g").attr("transform", "translate(" + marginb.left + "," + marginb.top + ")");
var parseTime = d3.timeParse("%d-%b-%y");
var xb = d3.scaleTime()
.rangeRound([0, widthb]);
var yb = d3.scaleLinear()
.rangeRound([heightb, 0]);
var line = d3.line()
.x(function(d) { return xb(d.date); })
.y(function(d) { return yb(d.close); });
d3.tsv("linedata.tsv", function(d) {
d.date = parseTime(d.date);
d.close = +d.close;
return d;
}, function(error, data) {
if (error) throw error;
xb.domain(d3.extent(data, function(d) { return d.date; }));
yb.domain(d3.extent(data, function(d) { return d.close; }));
gb.append("g")
.attr("transform", "translate(0," + heightb + ")")
.call(d3.axisBottom(xb))
.select(".domain")
.remove();
gb.append("g")
.call(d3.axisLeft(yb))
.append("text")
.attr("fill", "#000")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", "0.71em")
.attr("text-anchor", "end")
.text("Price ($)");
gb.append("path")
.datum(data)
.attr("fill", "none")
.attr("stroke", "steelblue")
.attr("stroke-linejoin", "round")
.attr("stroke-linecap", "round")
.attr("stroke-width", 1.5)
.attr("d", line);
});
</script>
In your code barg and lineg are just divs:
<div id="lineg"></div>
<div id="barg"></div>
Instead of that, they should be SVG elements, like this:
<svg id="barg" width="960" height="500"></svg>
<svg id="lineg" width="960" height="500"></svg>
Or, alternatively, append an SVG in your selection:
var svga = d3.select("#lineg").append("svg");
var svgb = d3.select("#barg").append("svg");
However, in that case, you cannot use the getters to get the width and height of the SVGs.
Finally, there is no HTML tag named <lineg> or <barg>.

d3 stacked bar chart not updating correctly

I have a stacked bar chart created using d3.
I am trying to update my bar graph with data from a different .csv using buttons.
Here is my code so far:
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<style>
#title {
font-family: serif;
font-variant: small-caps;
font-size: 20px;
text-align: left;
text-decoration: underline;
text-shadow: 2px 2px 2px gray;
}
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.bar {
fill: steelblue;
}
.x.axis path {
display: none;
}
.exit {
opacity: 0;
}
</style>
</head>
<body>
<p id="title">Server/Client Relationship with Groups Algorithm</p>
<div id="option">
<input name="updateButton"
type="button"
value="Update"
onclick="updateData()" />
<input name="revertButton"
type="button"
value="Revert"
onclick="revertData()" />
</div>
<script type="text/javascript" src="d3.js"></script>
<script>
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 1100 - margin.left - margin.right,
height = 700 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var y = d3.scale.linear()
.rangeRound([height, 0]);
var color = d3.scale.category20();
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickFormat(d3.format(".2s"));
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 + ")");
d3.csv("before.csv", function(error, data) {
color.domain(d3.keys(data[0]).filter(function(key) { return key !== "Servers"; }));
data.forEach(function(d) {
var y0 = 0;
d.ages = color.domain().map(function(name) { return {name: name, y0: y0, y1: y0 += +d[name]}; });
d.total = d.ages[d.ages.length - 1].y1;
});
x.domain(data.map(function(d) { return d.Servers; }));
y.domain([0, d3.max(data, function(d) { return d.total; })]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Number of Clients");
var servers = svg.selectAll(".servers")
.data(data)
.enter().append("g")
.attr("class", "g")
.attr("transform", function(d) { return "translate(" + x(d.Servers) + ",0)"; });
servers.selectAll("rect")
.data(function(d) { return d.ages; })
.enter().append("rect")
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.y1); })
.attr("height", function(d) { return y(d.y0) - y(d.y1); })
.style("fill", function(d) { return color(d.name); });
var legend = svg.selectAll(".legend")
.data(color.domain().slice().reverse())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("x", width - 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", width - 24)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function(d) { return d; });
});
function updateData() {
d3.csv("after.csv", function(error, data) {
color.domain(d3.keys(data[0]).filter(function(key) { return key !== "Servers"; }));
data.forEach(function(d) {
var y0 = 0;
d.ages = color.domain().map(function(name) { return {name: name, y0: y0, y1: y0 += +d[name]}; });
d.total = d.ages[d.ages.length - 1].y1;
});
x.domain(data.map(function(d) { return d.Servers; }));
y.domain([0, d3.max(data, function(d) { return d.total; })]);
svg.select(".x.axis").transition()
.duration(750)
.call(xAxis);
svg.select(".y.axis").transition()
.duration(750)
.call(yAxis);
var servers = svg.selectAll(".servers")
.data(data)
.enter().append("g")
.attr("class", "g")
.attr("transform", function(d) { return "translate(" + x(d.Servers) + ",0)"; });
servers.selectAll("rect")
.data(function(d) { return d.ages; })
.enter().append("rect")
.transition()
servers.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.y1); })
.attr("height", function(d) { return y(d.y0) - y(d.y1); })
.style("fill", function(d) { return color(d.name); });
});
}
function revertData() {
d3.csv("before.csv", function(error, data) {
color.domain(d3.keys(data[0]).filter(function(key) { return key !== "Servers"; }));
data.forEach(function(d) {
var y0 = 0;
d.ages = color.domain().map(function(name) { return {name: name, y0: y0, y1: y0 += +d[name]}; });
d.total = d.ages[d.ages.length - 1].y1;
});
x.domain(data.map(function(d) { return d.Servers; }));
y.domain([0, d3.max(data, function(d) { return d.total; })]);
svg.select(".x.axis").transition()
.duration(750)
.call(xAxis);
svg.select(".y.axis").transition()
.duration(750)
.call(yAxis);
var servers = svg.selectAll(".servers")
.data(data)
.enter().append("g")
.attr("class", "g")
.attr("transform", function(d) { return "translate(" + x(d.Servers) + ",0)"; });
servers.selectAll("rect")
.data(function(d) { return d.ages; })
.enter().append("rect")
.transition()
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.y1); })
.attr("height", function(d) { return y(d.y0) - y(d.y1); })
.style("fill", function(d) { return color(d.name); });
});
}
</script>
</body>
before.csv:
Servers,Group 1,Group 2,Group 3,Group 4,Group 5,Group 6,Group 7,Group 8,Group 9,Group 10
Server 1,2,0,0,0,0,3,1,0,0,1
Server 2,1,0,2,0,0,0,2,1,1,0
Server 3,2,0,1,0,2,2,1,0,0,0
Server 4,0,0,1,0,0,2,0,2,1,0
Server 5,0,0,0,2,0,1,1,1,1,3
Server 6,5,0,0,1,0,1,1,1,0,3
Server 7,1,0,2,3,0,0,0,0,0,2
Server 8,3,1,0,1,0,0,1,1,1,0
Server 9,0,1,0,0,0,0,1,0,1,0
Server 10,1,2,1,1,0,2,2,2,0,1
Server 11,2,1,1,0,1,2,2,2,3,0
Server 12,1,0,1,1,0,0,0,0,2,1
after.csv:
Servers,Group 1,Group 2,Group 3,Group 4,Group 5,Group 6,Group 7,Group 8,Group 9,Group 10
Server 1,0,0,0,0,0,13,0,0,0,0
Server 2,0,0,9,0,0,0,12,0,0,0
Server 3,0,0,0,0,3,0,0,0,0,0
Server 4,0,0,0,0,0,0,0,10,10,0
Server 5,0,0,0,0,0,0,0,0,0,11
Server 6,18,0,0,0,0,0,0,0,0,0
Server 7,0,0,0,9,0,0,0,0,0,0
Server 8,0,0,0,0,0,0,0,0,0,0
Server 9,0,0,0,0,0,0,0,0,0,0
Server 10,0,5,0,0,0,0,0,0,0,0
Server 11,0,0,0,0,0,0,0,0,0,0
Server 12,0,0,0,0,0,0,0,0,0,0
The problem is that whenever I press the buttons instead of it just displaying the new graph, the graphs overlap.
I'm fairly new to d3, so I was having trouble making it so that after a button press only the specified graph is displayed.
I've looked into different ways to use the transition, exit, and remove functions that are built into d3, but can't seem to get it right.
Can someone please point me in the right direction?
Instead of using the body to append. Add something like this:
<div id="chart"></div>
And change the variable to
var svg = d3.select("#chart").append("svg")....
After doing this, you can remove inside the elements inside using
$("#chart").empty();
in your updateData and revertData method.
Or if you want use only d3js code in a simply way which I use mostly
d3.select("svg").remove();

D3 bar charts bar values display is improper

I want to display the bar charts each bar peak value at the outer top of each bar. But as far as i could get is to represent each bar value inside the bar. But thats not what i wanted. As you can see in the image attached the bottom of the x axis is messed up. I think we have to move the svg code out of the data loop and use svg.data(someData).enter() to fix this issue but i tried ways to do it but unsuccessful. Kindly suggest how i can modify the follow code.
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.axis {
font: 12px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.chart text {
fill: black;
font: 15px sans-serif;
text-anchor: middle;
}
</style>
<svg class="chart"></svg>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var margin = {top: 30, right: 80, bottom: 40, left: 100},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var color = d3.scale.category10();
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .2);
var y = d3.scale.linear()
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
function unit (d) {
count = 0, download = 0;
num = d.value;
while((num) >= 1)
{
num/=10;
++count;
}
switch (count) {
case 4 : download = ((d.value/1000).toFixed(2)) + " MB" ;
break;
case 8 : download = ((d.value/1000 * 1000).toFixed(2)) + " GB" ;
break;
default: download = ((d.value/1000).toFixed(2)) + " MB" ;
}
return download;
}
var chart = d3.select("body").append("svg")
// line = 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 bar;
d3.csv("data.csv", type, function(error, data) {
x.domain(data.map(function(d) { return d.name; }));
y.domain([0, d3.max(data, function(d) { return d.value; })]);
chart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.append("text")
.attr("x", 790 )
.attr("y", 15 )
.style("text-anchor", "bottom")
.text("Clients");
chart.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
//.attr("transform", "rotate(-90)")
.attr("y", 1)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Kilo Bytes");
bar = chart.selectAll("g")
.data(data)
.enter().append("g")
.attr("transform", function(d) { return "translate(" + x(d.name) + ",0)"; });
bar.append("rect")
.style("fill", function(d) { return color(d.name); })
.attr("y", function(d) { return y(d.value);})
.attr("height", function(d) { return height - y(d.value); })
.attr("width", x.rangeBand());
bar.append("text")
.attr("x", x.rangeBand() / 2 )
.attr("y", function(d) { return y(d.value) + 2 ; })
.attr("dy", "1em")
.attr("text-anchor", "middle")
.attr("font-size", "14px")
.attr("fill", "black")
.text(function(d) { return unit(d); });
});
function type(d) {
d.value = +d.value; // coerce to number
return d;
}
</script>
and the data is in the csv format as below:
name,timesatmp,value
98.226.148.140,1341677167454,1
98.226.148.140,1341677167461,3
98.226.148.141,1341677167916,4
98.226.148.141,1341677167935,6
98.226.148.142,1341677167944,7
98.226.148.142,1341677167945,32
Kindly suggest how i can show the display properly.
First modify your bar charts a little, otherwise no bars will be shown there:
html:
<svg class="chart"></svg>
to
<body class="chart"></body>
js:
bar = chart.selectAll(".bar")
.data(data)
.enter().append("g")
.attr('class', 'bar')
.attr("transform", function(d) { return "translate(" + x(d.name) + ",0)"; });
and for adjusting the peak value, just add a translate as follows:
bar.append("text")
.attr("x", x.rangeBand() / 2 )
.attr("y", function(d) { return y(d.value) + 2 ; })
.attr("dy", "1em")
.attr("text-anchor", "middle")
.attr("font-size", "14px")
.attr("fill", "black")
.attr("transform", function(d) { return "translate(0, -20)"; })
.text(function(d) { return unit(d); });
Rplace:
d3.csv("data.csv", type, function(error, data) {
x.domain(data.map(function(d) { return d.name; }));
y.domain([0, d3.max(data, function(d) { return d.value; })]);
with:
d3.csv("data.csv", type, function(error, data) {
x.domain(data.map(function(d) { return d.name; }));
y.domain([0, d3.max(data, function(d) { return d.value; })]);
var nestedData = d3.nest()
.key(function(d) { return d.name; }).entries(data);
var newData = [];
nestedData.forEach(function(d){
newData.push({name:d.key, value: d3.max(d.values, function(d) {return d.value})});
});

Categories