D3 positive negative updating data - javascript

I am trying to show a D3 bar chart with positive and negative values, but I cant get the domain to show both?
I also want to tell the graph to draw based on the current data after I have updated it, but it wont update?
this is my code
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 370 - margin.left - margin.right,
height = 220 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
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 updateBarGraph() {
var dataForGraph3 = [
{
"asset": "1",
"value": val1
},
{
"asset": "2",
"value": val2
},
{
"asset": "3",
"value": val3
},
{
"asset": "4",
"value": val4
}
];
console.log("updateBarGraph");
console.log(dataForGraph3);
x.domain(dataForGraph3.map(function(d) { return d.asset; }));
y.domain([0, d3.max(dataForGraph3, function(d) { return d.value; })]);
var svg = d3.select(".expReturnBar").transition();
svg.select(".bar") // change the line
.duration(750)
.attr("d", dataForGraph3);
svg.select(".x.axis") // change the x axis
.duration(750)
.call(xAxis);
svg.select(".y.axis") // change the y axis
.duration(750)
.call(yAxis);
};
function drawBarGraph() {
var dataForGraph3 = [
{
"asset": "1",
"value": val1
},
{
"asset": "2",
"value": val2
},
{
"asset": "3",
"value": val3
},
{
"asset": "4",
"value": val4
}
];
console.log("drawBarGraph");
console.log(dataForGraph3);
var svg = d3.select(".expReturnBar").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 + ")");
x.domain(dataForGraph3.map(function(d) { return d.asset; }));
y.domain([0, d3.max(dataForGraph3, function(d) { return d.value; })]);
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");
svg.selectAll(".bar")
.data(dataForGraph3)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return x(d.asset); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.value); })
.attr("height", function(d) { return height - y(d.value); });
function type(d) {
d.value = +d.value;
return d;
}
$scope.drawn = true;
};
$scope.drawn = false;
function drawGraphs() {
if(!$scope.drawn)
drawBarGraph();
else
updateBarGraph();
}
$scope.update = function(){
val1 = val1 + 10;
val2 = val2 + 10;
val3 = val3 + 10;
val4 = val4 + 10;
drawGraphs();
}
when i call update(), the first time it works.
but then after that it doesnt change anything.

If you want negative y values, you need to set the domain to include negative values. Right now, it looks like it only has non-negative values. It should probably be something like:
y.domain([d3.min(dataForGraph3, function(d) { return d.value; }), d3.max(dataForGraph3, function(d) { return d.value; })]);
You may also want to set the range to control where the points end up, but that's up to you. Have a look here: https://github.com/mbostock/d3/wiki/Quantitative-Scales
As for update not working, this won't work.
svg.select(".bar") // change the line
.duration(750)
.attr("d", dataForGraph3);
This won't update your data, it will put your data into an attribute "d". You need to update the x and y.

Related

d3.js: Stacked Bar Chart with low values

I faced with a problem when some values in a bar very small when at the same time most of the other values are big enough. As the result these chunks with low values are almost not visible. I did not find any solution hot to correctly round chunks(not manually because I now that I can round them to more higher values via scale + invert(in order to determine what values I needed to show them more or less visible)). As an example below: as you see the last bar with low values is almost not visible. So can you suggest how to fix it? It would be great to have an opportunity to be able to specify the min size of stacked bar chart chunk. Thank you in advance.
http://jsfiddle.net/vhcdt13x/
// Setup svg using Bostock's margin convention
var margin = {top: 20, right: 160, bottom: 35, left: 30};
var width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
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 + ")");
/* Data in strings like it would be if imported from a csv */
var data = [
{ year: "2006", redDelicious: "100", mcintosh: "150", oranges: "90", pears: "60" },
{ year: "2012", redDelicious: "1", mcintosh: "1", oranges: "1", pears: "1" }
];
var parse = d3.time.format("%Y").parse;
// Transpose the data into layers
var dataset = d3.layout.stack()(["redDelicious", "mcintosh", "oranges", "pears"].map(function(fruit) {
return data.map(function(d) {
return {x: parse(d.year), y: +d[fruit]};
});
}));
// Set x, y and colors
var x = d3.scale.ordinal()
.domain(dataset[0].map(function(d) { return d.x; }))
.rangeRoundBands([10, width-10], 0.02);
var y = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) { return d3.max(d, function(d) { return d.y0 + d.y; }); })])
.range([height, 0]);
var colors = ["b33040", "#d25c4d", "#f2b447", "#d9d574"];
// Define and draw axes
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(5)
.tickSize(-width, 0, 0)
.tickFormat( function(d) { return d } );
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.tickFormat(d3.time.format("%Y"));
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
// Create groups for each series, rects for each segment
var groups = svg.selectAll("g.cost")
.data(dataset)
.enter().append("g")
.attr("class", "cost")
.style("fill", function(d, i) { return colors[i]; });
var rect = groups.selectAll("rect")
.data(function(d) { return d; })
.enter()
.append("rect")
.attr("x", function(d) { return x(d.x); })
.attr("y", function(d) { return y(d.y0 + d.y); })
.attr("height", function(d) { return y(d.y0) - y(d.y0 + d.y); })
.attr("width", x.rangeBand())
.on("mouseover", function() { tooltip.style("display", null); })
.on("mouseout", function() { tooltip.style("display", "none"); })
.on("mousemove", function(d) {
var xPosition = d3.mouse(this)[0] - 15;
var yPosition = d3.mouse(this)[1] - 25;
tooltip.attr("transform", "translate(" + xPosition + "," + yPosition + ")");
tooltip.select("text").text(d.y);
});
// Draw legend
var legend = svg.selectAll(".legend")
.data(colors)
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(30," + i * 19 + ")"; });
legend.append("rect")
.attr("x", width - 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", function(d, i) {return colors.slice().reverse()[i];});
legend.append("text")
.attr("x", width + 5)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "start")
.text(function(d, i) {
switch (i) {
case 0: return "Anjou pears";
case 1: return "Naval oranges";
case 2: return "McIntosh apples";
case 3: return "Red Delicious apples";
}
});
// Prep the tooltip bits, initial display is hidden
var tooltip = svg.append("g")
.attr("class", "tooltip")
.style("display", "none");
tooltip.append("rect")
.attr("width", 30)
.attr("height", 20)
.attr("fill", "white")
.style("opacity", 0.5);
tooltip.append("text")
.attr("x", 15)
.attr("dy", "1.2em")
.style("text-anchor", "middle")
.attr("font-size", "12px")
.attr("font-weight", "bold");

Error: <path> attribute d: Expected number, "M67,0L67,0LNaN,0LNaN,0L728"

I am trying to create a line chart but I get the error...
Error: attribute d: Expected number, "M67,0L67,0LNaN,0LNaN,0L728"
... every time I have three or more elements. I want to set the date with that format in the x-axis. I have tried scaling with times, but I just want to show the dates that the JSON file contains, not a range of dates.
This is the JSON file I am using:
[{"date": "20-Jun-19", "close": "5", "text": "Test"},
{"date": "21-Jun-19", "close": "5", "text": "Test"},
{"date": "25-Jun-19", "close": "5", "text": "Test"}]
This is the Javascript I am using.
var label = d3.select(".label");
var margin = {top: 30, right: 20, bottom: 30, left: 50},
width = 1460 - margin.left - margin.right,
height = 870 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var y = d3.scale.linear().range([height, 0]);
// Define the axes
var xAxis = d3.svg.axis().scale(x)
.orient("bottom").ticks(20);
var yAxis = d3.svg.axis().scale(y)
.orient("left").ticks(15);
// Define the line
var valueline = d3.svg.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.close); });
// Adds the svg canvas
var svg = d3.select(".anxiety-graphic")
.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.json("data.json", function(error, data) {
var categoriesNames = data.map(function (d) {
return +d.date;
});
x.domain(categoriesNames);
// Scale the range of the data
x.domain(d3.extent(data, function(d) { console.log(d); return d.date; }));
y.domain([0, d3.max(data, function(d) { return d.close; })]);
// Add the valueline path.
svg.append("path") // Add the valueline path.
.attr("class", "line")
.attr("d", valueline(data));
// Add the valueline path.
svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("r", 10)
.attr("cx", function(d) {
return x(d.date)
})
.attr("cy", function(d) {
return y(d.close)
})
.on("mouseover", function(d,i) {
label.style("transform", "translate("+ x(d.date) +"px," + (y(d.close)) +"px)")
label.text(d.close)
});
// Add the X Axis
svg.append("g") // Add the X Axis
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
// Add the Y Axis
svg.append("g") // Add the Y Axis
.attr("class", "y axis")
.call(yAxis);
});
For whatever reason, you are replacing the correct domain...
x.domain(categoriesNames);
... for a wrong one in the very next line:
x.domain(d3.extent(data, function(d){ return d.date; }));
d3.extent returns an array with 2 values only, and that's why you're getting this issue when your data have three or more elements.
Also, the map for creating categoriesNames has an issue:
var categoriesNames = data.map(function (d) {
return +d.date;
});
Since the date is a string containing letters, it's not clear why you're using the unary plus (which will return NaN). Drop that:
var categoriesNames = data.map(function (d) {
return d.date;
});
Here is your code with those changes:
var label = d3.select(".label");
var margin = {
top: 30,
right: 20,
bottom: 30,
left: 50
},
width = 1460 - margin.left - margin.right,
height = 870 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var y = d3.scale.linear().range([height, 0]);
// Define the axes
var xAxis = d3.svg.axis().scale(x)
.orient("bottom").ticks(20);
var yAxis = d3.svg.axis().scale(y)
.orient("left").ticks(15);
// Define the line
var valueline = d3.svg.line()
.x(function(d) {
return x(d.date);
})
.y(function(d) {
return y(d.close);
});
// Adds the svg canvas
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 = [{
"date": "20-Jun-19",
"close": "5",
"text": "Test"
},
{
"date": "21-Jun-19",
"close": "5",
"text": "Test"
},
{
"date": "25-Jun-19",
"close": "5",
"text": "Test"
}
];
var categoriesNames = data.map(function(d) {
return d.date;
});
x.domain(categoriesNames);
y.domain([0, d3.max(data, function(d) {
return d.close;
})]);
// Add the valueline path.
svg.append("path") // Add the valueline path.
.attr("class", "line")
.attr("d", valueline(data));
// Add the valueline path.
svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("r", 10)
.attr("cx", function(d) {
return x(d.date)
})
.attr("cy", function(d) {
return y(d.close)
})
.on("mouseover", function(d, i) {
label.style("transform", "translate(" + x(d.date) + "px," + (y(d.close)) + "px)")
label.text(d.close)
});
// Add the X Axis
svg.append("g") // Add the X Axis
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
// Add the Y Axis
svg.append("g") // Add the Y Axis
.attr("class", "y axis")
.call(yAxis);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>

JS - D3 Multiline time series chart

I need to make a time series style graphic, with D3, multiple. Taking this example as a basis: example
The code is the following:
<script type="text/javascript">
var data = [{fecha: "2019-03-16", partidos: "1", goles: "0", tarjetas: "0"},
{fecha: "2019-03-23", partidos: "1", goles: "1", tarjetas: "0"},
{fecha: "2019-03-30", partidos: "1", goles: "0", tarjetas: "1"},
{fecha: "2019-04-06", partidos: "0", goles: "0", tarjetas: "0"},
{fecha: "2019-04-13", partidos: "1", goles: "2", tarjetas: "0"},
];
// Draw a line chart
var svg = d3.select('#graf_act_tiempo'),
margin = { top: 20, right: 50, bottom: 30, left: 50 },
width = +svg.attr('width') - margin.left - margin.right,
height = +svg.attr('height') - margin.top - margin.bottom,
g = svg.append('g').attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
// Function to convert a string into a time
var parseTime = d3.time.format('%Y-%m-%d').parse;
// Set the X scale
var x = d3.time.scale().range([0, width], 0.5);
// Set the Y scale
var y = d3.scale.linear().range([height, 0]);
// Set the color scale
var color = d3.scale.category10();
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.tickSize(6, 0)
.tickFormat(d3.time.format('%d/%m/%y'));
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickSize(1, 0)
.tickFormat(d3.format("d"));
var line = d3.svg.line()
// .interpolate("basis")
.x(function(d) {
return x(d.fecha);
})
.y(function(d) {
return y(d.worth);
});
// load the data
// Select the important columns
color.domain(d3.keys(data[0]).filter(function(key) {
return key !== "fecha";
}));
// Correct the types
data.forEach(function(d) {
d.fecha = parseTime(d.fecha);
});
//console.log(data);
var currencies = color.domain().map(function(name) {
return {
name: name,
values: data.map(function(d) {
return {
fecha: d.fecha,
worth: +d[name]
};
})
};
});
//console.log(currencies)
// Set the X domain
x.domain(d3.extent(data, function(d) {
return d.fecha;
}));
// Set the Y domain
y.domain([
d3.min(currencies, function(c) {
return d3.min(c.values, function(v) {
return v.worth;
});
}),
d3.max(currencies, function(c) {
return d3.max(c.values, function(v) {
return v.worth;
});
})
]);
// Set the X axis
g.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", "rotate(-65)");
// Set the Y axis
g.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
// .attr("transform", "rotate(-90)")
.attr("y", 0)
.attr("x", 60)
.attr("dy", "4px")
.style("text-anchor", "end")
.text("Cantidad");
// Draw the lines
var currency = g.selectAll(".currency")
.data(currencies)
.enter().append("g")
.attr("class", "currency");
currency.append("path")
.attr("class", "line")
.attr("d", function(d) {
return line(d.values);
})
.style("stroke", function(d) {
return color(d.name);
});
// Add the circles
currency.append("g").selectAll("circle")
.data(function(d){return d.values})
.enter()
.append("circle")
.attr("r", 2)
.attr("cx", function(dd){return x(dd.fecha)})
.attr("cy", function(dd){return y(dd.worth)})
.attr("fill", "none")
.attr("stroke", function(d){return color(this.parentNode.__data__.name)});
// Add label to the end of the line
currency.append("text")
.attr("class", "label")
.datum(function (d) {
return {
name: d.name,
value: d.values[d.values.length - 1]
};
})
.attr("transform", function (d) {
return "translate(" + x(d.value.fecha) + "," + y(d.value.worth) + ")";
})
.attr("x", 6)
.attr("dy", ".35em")
.text(function (d) {
return d.name;
});
</script>
The following result is obtained:
I need help to make these changes:
1) The legend "cantidad" of the "y" axis located above the maximum value of the axis (top) or left of axis.
2) The values of the "x" axis that are not cut, that can be read well
Thanks for the tips to improve it.
1) Add more value left to svg and .attr("x", -20) to y axis
2) Add more valur bottom to svg

D3.js Vertical to Horizontal alignment of the Stacked Bar Chart

Trying to change the responsive stacked bar chart from vertical to horizontal but its not showing anything in the svg contained except the axis.
I have referred some of the similar problem in stack overflow like after changins stuff following some other examples from stackover flow like this and this.
Code for my vertical stacked bar chart in fiddle
But the current working code is here
margin = {
top: 20,
right: 160,
bottom: 35,
left: 30
};
var width = 600 - margin.left - margin.right,
height = 600 - margin.top - margin.bottom;
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 + ")");
/* Data in strings like it would be if imported from a csv */
var data = [{
year: "A",
redDelicious: "10",
mcintosh: "5",
oranges: "19"
}, {
year: "B",
redDelicious: "12",
mcintosh: "0",
oranges: "15"
}, {
year: "C",
redDelicious: "05",
mcintosh: "0",
oranges: "28"
}, {
year: "D",
redDelicious: "14",
mcintosh: "0",
oranges: "12"
},
];
$("#btn").on("click", function(){
d3.selectAll("svg > g > g").remove();
data[1].mcintosh = (Number(data[1].mcintosh) + 1).toString();
console.log(1,data);
update();
});
update();
function update(){
var orangeData = data.map(function(d) {
return {
year: d.year,
oranges: +d.oranges
}
});
console.log(orangeData)
// Transpose the data into layers
var dataset = d3.layout.stack()(["redDelicious", "mcintosh"].map(function(skillset) {
return data.map(function(d) {
return {
y: d.year,
x: +d[skillset]
};
});
}));
console.log(dataset)
xMax = d3.max(dataset, function(group) {
return d3.max(group, function(d) {
return d.x + d.x0;
});
}),
xScale = d3.scale.linear()
.domain([0, xMax])
.range([0, width]);
months = dataset[0].map(function(d) { return d.y; });
yScale = d3.scale.ordinal()
.domain(months)
.rangeRoundBands([0, height], .1);
// Set x, y and colors
/* var y = d3.scale.ordinal()
.domain([0, d3.max(dataset, function(d) {
return d3.max(d, function(d) {
return d.y;
});
})])
.rangeRoundBands([height, 0], 0.02);
var x = d3.scale.linear()
.domain(dataset[0].map(function(d) {
return d.x0 + d.x;
}))
.range([10, width-10]); */
var colors = ["#b33040", "#d9d574"];
var backcolors = ["red", "blue","green","pink"];
// Define and draw axes
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom").ticks(5)
.tickSize(-width, 0, 0);
/* .tickFormat(function(d) {
return 0
});*/
// .tickFormat(d3.time.format("%Y"));
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis).attr("transform", "rotate(-0)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end");
// Creating the Average Bar for the Semester
svg.selectAll(".bar1").data(orangeData).enter().append("g")
.attr("class", "bar1").append("rect")
.attr("y", function(d) {
return y(d.year) ; // center it
})
.attr("width", x.rangeBand()) // make it slimmer
.attr("x", function(d) {
return x(d.oranges);
})
.attr("width", function(d) {
return width - x(d.oranges);
});
// Create groups for each series, rects for each segment in Stacked Bar
var groups = svg.selectAll("g.cost")
.data(dataset)
.enter().append("g")
.attr("class", "cost")
.style("fill", function(d, i) {
return colors[i];
});
var rect = groups.selectAll("rect")
.data(function(d) {
return d;
})
.enter()
.append("rect")
.attr("y", function(d,y) {
return yScale(d.y) + 20 ;
})
.attr("x", function(d) {
return xScale(d.x0 );
})
.attr("width", function(d) {
return xScale(d.x);
})
.attr("height", yScale.rangeBand() -40 );
}

Visually displaying JSON data in a grouped bar chart with d3.js

I need help with visually displaying JSON data using D3.JS. I can get the graphs to show but my problem is that the bars stack up ontop of each other instead of being translated into groups based on the categories they are displaying. Below you can find my code as well as a link to a screengrab of my current output as well as the JSON file im using.
link to screengrab:
http://tinypic.com/view.php?pic=15x6anl&s=8#.VH3C5HWSw8o
and here is my code:
$(document).ready(function(){
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x0 = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var x1 = d3.scale.ordinal();
var y = d3.scale.linear()
.range([height, 0]);
var color = d3.scale.ordinal()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
var xAxis = d3.svg.axis()
.scale(x0)
.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.json("ronaldo.json", function(error, data) {
console.log(data);
var playerNames = []
data.forEach(function(d){playerNames.push(d.name)})
var attr = [];
data[0]['statistics']['2005'].forEach(function(d){return attr.push(d.attr)})
console.log(attr)
x0.domain(attr.map(function(d){return d}));
//x0.domain(data.map(function(d){return d['statistics']['2005']['attr']}));
x1.domain(playerNames).rangeRoundBands([0, x0.rangeBand()]);
y.domain([0, d3.max(data, function(d) { return d3.max(d["statistics"]["2005"], function(d) { return d.value; }); })]);
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("Units");
var state = svg.selectAll(".state")
.data(data)
.enter().append("g")
.attr("class", "g")
.attr("transform", function(d) { return "translate(" + x0(+d['statistics']['2005']['attr']) + ",0)"; });
state.selectAll("rect")
.data(function(d) { return d['statistics']['2005']; })
.enter().append("rect")
.attr("class","bars")
.attr("width", x1.rangeBand())
.attr("x", function(d) { return x1(d['attr']); })
.attr("y", function(d) { return y(d.value); })
.attr("height", function(d) { return height - y(d['value']); })
.style("fill", function(d) { return color(d.attr);});
var legend = svg.selectAll(".legend")
.data(playerNames.slice())
.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; });
});
});
JSON Data:
[
{
"name": "Cristiano Ronaldo",
"age" : 28,
"team": "Real Madrid",
"statistics" : {
"2005" : [
{"attr" :"Appearances",
"value": 100},
{"attr" :"Goals",
"value": 92},
{"attr" :"Yellow Cards",
"value": 10},
{"attr" :"Red Cards",
"value": 1}
]
}
},
{
"name": "Lionel Messi",
"age" : 29,
"team": "Barcelona",
"statistics" : {
"2005" : [
{"attr" :"Appearances",
"value": 90},
{"attr" :"Goals",
"value": 87},
{"attr" :"Yellow Cards",
"value": 13},
{"attr" :"Red Cards",
"value": 43}
]
}
}
]
I don't understand why you have a x0 and a x1 scales but your issue is here.
You should have only one scale that you use in:
xAxis (be careful to override the scale of xAxis after you defined x1)
.attr("x", function(d) { return x1(d['attr']); })
I have made a small jsFiddle with the solution I suggested but since I don't know what you wanted to see exactly, I'm not sure it's perfect: http://jsfiddle.net/chrisJamesC/uzmur5kb/
All I did was: change the .attr("x", ...) line to:
.attr("x", function(d) { return x0(d['attr']); })

Categories