Okay I am trying to make a bar chart. This is the Javascript I have.
var data = [
{
"date": "1459468800000", // 1 April 2016
"values": [{
"name": "US",
"value": 72580613,
"domainname": "com"
}, {
"name": "US",
"value": 161645,
"domainname": "nl"
}]
}, {
"date": "1467331200000", // 1 Juli 2016
"values": [{
"name": "US",
"value": 73129243,
"domainname": "com"
}, {
"name": "US",
"value": 166152,
"domainname": "nl"
}]
}
]
var svg = d3.select("svg"),
margin = {top: 20, right: 20, bottom: 30, left: 50},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom;
var tooltip = d3.select("body").append("div").attr("class");
var x = d3.scaleBand().rangeRound([0, width]).padding(0.1),
y = d3.scaleLinear().rangeRound([height, 0]);
var colours = d3.scaleOrdinal()
.range(["#6F257F", "#CA0D59"]);
var g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
x.domain(data.map(function(d) { return d.values.domainname; }));
y.domain([0, d3.max(data, function(d) { return d.values.value; })]);
g.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
g.append("g")
.attr("class", "axis axis--y")
.call(d3.axisLeft(y).ticks(25).tickFormat(function(d) { return parseInt(d / 1000) + "K"; }).tickSizeInner([-width]))
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", "0.71em")
.attr("text-anchor", "end")
.attr("fill", "#5D6971")
.text("Aantal domeinen");
g.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("x", function(d) { return x(d.values.domainname); })
.attr("y", function(d) { return y(d.values.value); })
.attr("width", x.bandwidth())
.attr("height", function(d) { return height - y(d.values.value); })
.attr("fill", function(d) { return colours(d.values.domainname); })
As you can see I have the data in an array. In the data I have 2 different dates.
For now I only want to show the first date in the bar chart but both domains (com & nl as bars (In the future I will ad more domains to the dates). (If you are interested : The idea is to make a dropdown on the page so the user can select another date and the bars will update).
What I have now is that I can see the axises on my screen so that is working good. But I got this error :
So D3 is expecting a number but it doesn't get one on the Y axis and the heigth as I understand the error...
How can I fix that it is displaying the first date with the domains correct?
The access to the values was incorrect instead of d.values.domainname or d.values.value you have to use d.values[i].domainname and d.values[i].value.
Here you can see your example running.
var data = [
{
"date": "1459468800000", // 1 April 2016
"values": [{
"name": "US",
"value": 72580613,
"domainname": "com"
}, {
"name": "US",
"value": 161645,
"domainname": "nl"
}]
}, {
"date": "1467331200000", // 1 Juli 2016
"values": [{
"name": "US",
"value": 73129243,
"domainname": "com"
}, {
"name": "US",
"value": 166152,
"domainname": "nl"
}]
}
]
var svg = d3.select("svg"),
margin = {top: 20, right: 20, bottom: 30, left: 50},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom;
var tooltip = d3.select("body").append("div").attr("class");
var x = d3.scaleBand().rangeRound([0, width]).padding(0.1),
y = d3.scaleLinear().rangeRound([height, 0]);
var colours = d3.scaleOrdinal()
.range(["#6F257F", "#CA0D59"]);
var g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
x.domain(data.map(function(d, i) { return d.values[i].domainname; }));
y.domain([0, d3.max(data, function(d, i) { return d.values[i].value; })]);
g.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
g.append("g")
.attr("class", "axis axis--y")
.call(d3.axisLeft(y).ticks(25).tickFormat(function(d) { return parseInt(d / 1000) + "K"; }).tickSizeInner([-width]))
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", "0.71em")
.attr("text-anchor", "end")
.attr("fill", "#5D6971")
.text("Aantal domeinen");
g.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("x", function(d, i) { return x(d.values[i].domainname); })
.attr("y", function(d, i) { return y(d.values[i].value); })
.attr("width", x.bandwidth())
.attr("height", function(d, i) {return height - y(d.values[i].value)})
.attr("fill", function(d, i) { return colours(d.values[i].domainname); })
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="400" height="400"></svg>
As a note the column nl looks especially small because the values are too different.
Related
I'm trying to get an understanding of transitions in bar charts using D3. What I'm doing now is updating the chart between two different data sets. I have a transition included but it's starting from the the bottom of the axis rather than transitioning between the two. My goal is to have it transition between the two and later change the colors. I'm using this helpful example for understanding updated data (my snippet is not much different). Thank you for taking a look.
var bothData = [
{
"year": "2014",
"product": "Books & DVDs",
"purchase": "0.5"
},
{
"year": "2002",
"product": "Books & DVDs",
"purchase": "10"
},
{
"year": "2014",
"product": "Beer & Wine",
"purchase": "7"
},
{
"year": "2002",
"product": "Beer & Wine",
"purchase": "3"
},
{
"year": "2014",
"product": "Food",
"purchase": "12"
},
{
"year": "2002",
"product": "Food",
"purchase": "12"
},
{
"year": "2014",
"product": "Home Supplies",
"purchase": "7"
},
{
"year": "2002",
"product": "Home Supplies",
"purchase": "6"
}
];
var data2002 = [];
var data2014 = [];
for(var i = 0; i < bothData.length; i++){
if(bothData[i]["year"] === "2002"){
data2002.push(bothData[i]);
}else{
data2014.push(bothData[i]);
}
}
function change(value){
if(value === '2002'){
update(data2002);
}else if(value === '2014'){
update(data2014);
}
}
function update(data){
xChart.domain(data.map(function(d){ return d.product; }) );
yChart.domain( [0, d3.max(data, function(d){ return + d.purchase; })] );
var barWidth = width / data.length;
var bars = chart.selectAll(".bar")
.remove()
.exit()
.data(data, function(d){ return d.purchase; })
.enter()
.append("rect")
.attr("class", "bar")
.attr("x", function(d, i){ return i * barWidth + 1 })
.attr("y",500)
.attr("height",0)
.attr("width", barWidth - 5)
.each(function(d){
if(d.year === "2014"){
d3.select(this)
.style('fill','#ea5454');
}else{
d3.select(this)
.style('fill','#4e97c4');
};
});
bars.transition()
.duration(600)
.ease(d3.easeLinear)
.attr('y', function(d){ return yChart(d.purchase); })
.attr('height', function(d){ return height - yChart(d.purchase); });
chart.select('.y').call(yAxis);
chart.select('.xAxis')
.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(-65)";
});
}
var margin = {top: 20, right: 20, bottom: 95, left: 50};
var width = 400;
var height = 500;
var chart = d3.select(".chart")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var xChart = d3.scaleBand()
.range([0, width]);
var yChart = d3.scaleLinear()
.range([height, 0]);
var xAxis = d3.axisBottom(xChart);
var yAxis = d3.axisLeft(yChart);
chart.append("g")
.attr("class", "y axis")
.call(yAxis)
chart.append("g")
.attr("class", "xAxis")
.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(-65)";
});
chart.append("text")
.attr("transform", "translate(-35," + (height+margin.bottom)/2 + ") rotate(-90)")
.text("Purchases");
chart.append("text")
.attr("transform", "translate(" + (width/2) + "," + (height + margin.bottom - 5) + ")")
.text("Products");
update(data2002);
You have the right idea...you want to achieve object constancy as described here by Mike Bostock. The key for your constancy should be the "product" from your data (not "purchase").
In your update function, define bars like this:
var bars = chart.selectAll(".bar")
.data(data, function(d){ return d.product; })
then separate the .enter, .exit and .transition functions:
bars.exit()
.remove()
bars.enter()
....
bars.transition()
You have some strange stuff going on in your .enter function - like setting bar height to zero. So I modified your .enter and .transition functions like this:
bars.enter()
.append("rect")
.attr("class", "bar")
.attr("x", function(d, i){return i * barWidth + 1 })
.attr("y",function(d){ return yChart(d.purchase); })
.attr("height",function(d){ return height - yChart(d.purchase); })
.attr("width", barWidth - 5)
.attr('fill', function(d){
if(d.year === "2014"){
return'#ea5454'
}else{
return'#4e97c4'
}
})
bars.transition()
.duration(600)
.ease(d3.easeLinear)
.attr('y', function(d){ return yChart(d.purchase); })
.attr('height', function(d){ return height - yChart(d.purchase); })
.style('fill', function(d){
if(d.year === "2014"){
return '#ea5454'
} else {
return '#4e97c4'
}
})
Here is a working jsfiddle: https://jsfiddle.net/genestd/asoLph2w/
Note the buttons on top to achieve the transition.
I am looking for some insight on best practices/how to get started here. I have a json object with 1000 timestamps from a given day. I want to build the x-axis as a 24 hour time frame with a tick for 4 hour periods...12am - 4am, 4am - 8am, etc. I then want to build the y-axis based on volume. So that each bar for the 4-hour periods will be populated based on the number of timestamps in that period. My json looks like this (except with many more entries):
[
{"Time":"2017-02-07 16:14:06"},
{"Time":"2017-02-07 16:58:49"},
{"Time":"2017-02-07 17:07:11"},
{"Time":"2017-02-07 18:13:19"},
{"Time":"2017-02-07 13:56:06"},
{"Time":"2017-02-07 19:07:57"},
{"Time":"2017-02-07 12:08:58"},
{"Time":"2017-02-07 01:41:00"},
{"Time":"2017-02-07 11:56:49"},
{"Time":"2017-02-07 02:45:29"}
]
I have been doing a lot of reading on D3, specifically about how to use the built in 'time' method but I am hoping to get some pointers on how to get started. The end result that I would want would look something like the image attached here (disregard the black bars as those will come from another source). Any help/pointers are much appreciated.
This is not a pure D3 solution but what I would do is parse that JSON object and then create a new one that has a totals count for each time interval and then feed that into the d3 graph.
Not sure what you have tried yet, but this should get you on the right path.
https://jsfiddle.net/9f2vp8gp/
var margin = {
top: 20,
right: 20,
bottom: 70,
left: 40
},
width = 600 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
// Parse the date / time
var parseDate = d3.time.format("%m").parse;
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.time.format("%m"));
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 + ")");
var data = [{
"date": "1",
"value": 44
}, {
"date": "2",
"value": 24
} ,{
"date": "3",
"value": 31
},{
"date": "4",
"value": 38
},{
"date": "5",
"value": 46
},{
"date": "6",
"value": 23
}];
data.forEach(function(d) {
d.date = parseDate(d.date);
d.value = +d.value;
});
x.domain(data.map(function(d) {
return d.date;
}));
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.date);
})
.attr("width", x.rangeBand())
.attr("y", function(d) {
return y(d.value);
})
.attr("height", function(d) {
return height - y(d.value);
});
I'm working on a d3.js horizontal bar graph (http://bl.ocks.org/juan-cb/ab9a30d0e2ace0d2dc8c) which updates/transitions based on user selections. Currently, I have added labels to the graph but it is not updating anymore. Not sure where the issue is. The bars should start from the left side but have moved to the right for some reason as well. To add labels to the bars, I added "g" elements to hold both the rect and the text. Any help will be appreciated.
JsFiddle - https://jsfiddle.net/fewpwqhd/1/
JS
datasetTotal = [{
label: "Category 1",
value: 19
}, {
label: "Category 2",
value: 5
}, {
label: "Category 3",
value: 13
}, {
label: "Category 4",
value: 17
}, {
label: "Category 5",
value: 21
}, {
label: "Category 6",
value: 25
}];
datasetOption1 = [{
label: "Category 1",
value: 22
}, {
label: "Category 2",
value: 33
}, {
label: "Category 3",
value: 4
}, {
label: "Category 4",
value: 15
}, {
label: "Category 5",
value: 36
}, {
label: "Category 6",
value: 0
}];
datasetOption2 = [{
label: "Category 1",
value: 10
}, {
label: "Category 2",
value: 20
}, {
label: "Category 3",
value: 30
}, {
label: "Category 4",
value: 5
}, {
label: "Category 5",
value: 12
}, {
label: "Category 6",
value: 23
}];
d3.selectAll("input").on("change", selectDataset);
function selectDataset() {
var value = this.value;
if (value == "total") {
change(datasetTotal);
} else if (value == "option1") {
change(datasetOption1);
} else if (value == "option2") {
change(datasetOption2);
}
}
var margin = {
top: (parseInt(d3.select('body').style('height'), 10) / 20),
right: (parseInt(d3.select('body').style('width'), 10) / 20),
bottom: (parseInt(d3.select('body').style('height'), 10) / 20),
left: (parseInt(d3.select('body').style('width'), 10) / 5)
},
width = parseInt(d3.select('body').style('width'), 10) - margin.left - margin.right,
height = parseInt(d3.select('body').style('height'), 10) - margin.top - margin.bottom;
var div = d3.select("body").append("div").attr("class", "toolTip");
var formatPercent = d3.format("");
var y = d3.scale.ordinal()
.rangeRoundBands([height, 0], .2, 0.5);
var x = d3.scale.linear()
.range([0, width]);
var xAxis = d3.svg.axis()
.scale(x)
.tickSize(-height)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
//.tickFormat(formatPercent);
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 + ")");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
d3.select("input[value=\"total\"]").property("checked", true);
change(datasetTotal);
function change(dataset) {
y.domain(dataset.map(function(d) {
return d.label;
}));
x.domain([0, d3.max(dataset, function(d) {
return d.value;
})]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.select(".y.axis").remove();
svg.select(".x.axis").remove();
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(0)")
.attr("x", 50)
.attr("dx", ".1em")
.style("text-anchor", "end")
.text("Option %");
var bar = svg.selectAll(".bar")
.data(dataset, function(d) {
return d.label;
})
// new data:
.enter().append("g");
bar.append("rect")
.attr("class", "bar")
.attr("x", function(d) {
return x(d.value);
})
.attr("y", function(d) {
return y(d.label);
})
.attr("width", function(d) {
return width - x(d.value);
})
.attr("height", y.rangeBand());
bar.append("text")
.attr("x", function(d) {
return x(d.value) - 3;
})
.attr("text-anchor", "end")
.attr("y", function(d) {
return y(d.label) + y.rangeBand() / 2;
})
.attr("dy", ".35em")
.text(function(d) {
return d.value;
});
var bars = d3.select("svg").selectAll("g.rects").data(dataset);
// removed data:
bars.exit().remove();
// updated data:
bars.transition()
.duration(750)
.attr("x", function(d) {
return 0;
})
.attr("y", function(d) {
return y(d.label);
})
.attr("width", function(d) {
return x(d.value);
})
.attr("height", y.rangeBand());
};
Here is my suggestion: since you're appending both rectangles and texts elements to the <g> (groups), your enter-update-exit pattern should apply to the groups, not to the rectangles and texts:
var bar = svg.selectAll(".bar")
.data(dataset, function(d) {
return d.label;
});
var barExit = bar.exit().remove();
var barEnter = bar.enter()
.append("g")
.attr("class", "bar");
In fact, as your datasets always have 6 categories, you don't even need all this (the code could be substantially shorter).
Here is your updated fiddle: https://jsfiddle.net/2523onr3/
PS I took the liberty to make the bars growing from left to right, not from right to left. If that's incorrect, just change the x and width attributes.
I'd be interested in the pros and cons versus this approach?
https://jsfiddle.net/sjp700/2523onr3/2/
bar = svg.selectAll(".bar")
.data(dataset)
bar_g = bar.enter()
.append("g")
.attr("class", "bar")
.transition()
.attr("transform", function (d) { return "translate(" + x(0) + "," + y(d.label) + ")"; });
svg.selectAll(".bar")
.append("rect")
.attr("class", "rectband");
svg.selectAll(".bar")
.append("text")
.attr("class", "textband");
bar.selectAll(".textband")
.attr("transform", function (d) { return "translate(" + x(d.value) + "," + 0 + ")"; })
.attr("y", 30)
.attr("dy", ".35em")
.style("fill", "black")
.text(function (d) { return d.value; });
bar.selectAll(".rectband")
.attr("width", function (d) { return x(d.value); })
.attr("height", y.rangeBand());
I have a bar-graph where the x axis is the time. The bar graph supports negative values, I have an additional axis below for show the x-values. However, numeric values are being displayed instead of date.
Here is the code:
data = [{"value": 10, "date": "20150824"},
{"value": -21, "date": "20150924"},
{"value": 7, "date": "20151024"},
{"value": 12, "date": "20151124"},
{"value": 33, "date": "20151224"},
{"value": -10, "date": "20160124"},
{"value": -10, "date": "20160224"},
{"value": -2, "date": "20160324"},
{"value": 17, "date": "20160424"},
{"value": -4, "date": "20160524"},
{"value": 6, "date": "20160864"},
{"value": 23, "date": "20160724"},
{"value": 13, "date": "20160824"},
{"value": -19, "date": "20160924"},
{"value": -8, "date": "20161024"},
{"value": -2, "date": "20161124"},
{"value": 12, "date": "20161224"}
]
var margin = {top: 30, right: 10, bottom: 10, left: 30},
width = 960 - margin.left - margin.right,
height = 600 - margin.top - margin.bottom;
var y0 = Math.max(Math.abs(d3.min(data, function(d) { return +d.value; })), Math.abs(d3.max(data, function(d) { return +d.value; })));
var parseDate = d3.time.format("%Y%m%d").parse;
data.forEach(function(d) {
d.date = parseDate(d.date);
});
var y = d3.scale.linear()
.domain([-y0, y0])
.range([height,0])
.nice();
var x = d3.scale.ordinal()
.domain(d3.range(data.length))
.rangeRoundBands([0, width], .2);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom + 100)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
bars = svg.selectAll(".bar")
.data(data);
bars.enter().append("rect")
.attr("class", function(d) { return d.value < 0 ? "bar negative" : "bar positive"; })
.attr("x", function(d, i) { return x(i); })
.attr("width", x.rangeBand())
.attr("fill", "#A9A9A9"});
bars.transition()
.duration(1000)
.delay(function (d, i) {
return i * 40;
})
.attr("y", function(d) { return y(Math.max(0, d.value)); })
.attr("height", function(d) {return Math.abs(y(d.value) - y(0)); });
svg.append("g")
.attr("class", "x axis")
.call(yAxis);
svg.append("g")
.attr("class", "y axis")
.append("line")
.attr("y1", y(0))
.attr("y2", y(0))
.attr("x1", 0)
.attr("x2", width);
svg.append("g")
.attr("class", "xx axis")
.attr("transform", "translate(0," + parseInt(height+ 30 ).toString() + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-90)" )
bars
.exit().remove();
This does not work. I've done some fair amount of googling but I am still unable to grasp the problem here.
It'd be great if someone could explain what's wrong with the code and how to fix it.
Use d3.time.scale() for time axis
var x = d3.time.scale()
.domain(d3.extent(data, function(d){
return d.date;
}))
.range([0, width]);
var xAxis = d3.svg.axis()
.scale(x)
.tickFormat(d3.time.format("%Y%m%d"))
.orient("bottom");
I have a chart created with the code below. I want to add a second y axis positioned to the right which matches the same y scale. The reason I want the y axis on the right also is because of the limit line I have set at 16.5, the chart just doesn’t look right without the 2nd y axis.
<script>
var w = 800;
var h = 550;
var margin = {
top: 58,
bottom: 100,
left: 80,
right: 40
};
var width = w - margin.left - margin.right;
var height = h - margin.top - margin.bottom;
var threshold = 16.5;
var x = d3.scale.ordinal()
.domain(data.map(function(entry){
return entry.key;
}))
.rangeBands([0, width],.2);
var y = d3.scale.linear()
.domain([0, d3.max(data, function(d){
return d.value;
})])
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var yGridLines = d3.svg.axis()
.scale(y)
.tickSize(-width, 0, 0)
.tickFormat("")
.orient("left");
var svg = d3.select("body").append("svg")
.attr("id", "chart")
.attr("width", w)
.attr("height", h);
var chart = svg.append("g")
.classed("display", true)
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
function plot(params){
this.append("g")
.call(yGridLines)
.classed("gridline", true)
.attr("transform", "translate(0,0)")
this.selectAll(".bar")
.data(params.data)
.enter()
.append("rect")
.classed("bar", true)
.attr("x", function (d,i){
return x(d.key);
})
.attr("y", function(d,i){
return y(d.value);
})
.attr("height", function(d,i){
return height - y(d.value);
})
.attr("width", function(d){
return x.rangeBand();
});
this.selectAll(".bar-label")
.data(params.data)
.enter()
.append("text")
.classed("bar-label", true)
.attr("x", function(d,i){
return x(d.key) + (x.rangeBand()/2)
})
.attr("dx", 0)
.attr("y", function(d,i){
return y(d.value);
})
.attr("dy", -6)
.text(function(d){
return d.value;
})
this.append("g")
.classed("x axis", true)
.attr("transform", "translate(" + 0 + "," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", -8)
.attr("dy" ,8)
.attr("transform", "translate(0,0) rotate(-45)");
this.append("g")
.classed("y axis", true)
.attr("transform", "translate(0,0)")
.call(yAxis);
this.select(".y.axis")
.append("text")
.attr("x", 0)
.attr("y", 0)
.style("text-anchor", "middle")
.attr("transform", "translate(-50," + height/2 + ") rotate(-90)")
.text("Downtime [Hrs]");
this.select(".x.axis")
.append("text")
.attr("x", 0)
.attr("y", 0)
.style("text-anchor", "middle")
.attr("transform", "translate(" + width/2 + ",80)")
.text("[Stations]");
// title
this.append("text")
.attr("x", (width / 2))
.attr("y", 0 - (margin.top / 2))
.attr("text-anchor", "middle")
.style("font-size", "16px")
.style("text-decoration", "underline")
.text("Over Mould");
// limit line
this.append("line")
.attr("x1", 0)
.attr("y1", y(threshold))
.attr("x2", width)
.attr("y2", y(threshold))
.attr("stroke-width", 2)
.attr("stroke", "yellow");
}
d3.json('data.json', function(data) {
plot.call(chart, {data: data});
});
</script>
Data is coming from an external JSON file.
[
{
"key": "ING_SW_CB",
"value": "7"
},
{
"key": "SB_SW_CB",
"value": "15"
},
{
"key": "NG3_SW_CB",
"value": "3"
},
{
"key": "Mould_Close",
"value": "8"
},
{
"key": "Leak_Test",
"value": "9"
},
{
"key": "ML_Load",
"value": "2"
},
{
"key": "Pre_Heat",
"value": "1"
},
{
"key": "Dispense",
"value": "5"
},
{
"key": "A310",
"value": "6"
},
{
"key": "Gelation",
"value": "5"
},
{
"key": "Platen",
"value": "7"
},
{
"key": "Mainline_Unload",
"value": "8"
},
{
"key": "De_mould",
"value": "5"
},
{
"key": "Clean_Up",
"value": "4"
},
{
"key": "Soda_Blast",
"value": "5"
},
{
"key": "RMI",
"value": "15"
},
{
"key": "Miscellaneous",
"value": "5"
}
]
My idea was to create yAxis2 and call it later in the function that plots the chart.
var yAxis2 = d3.svg.axis()
.scale(y)
.orient("right");
this.append("g")
.classed("y axis", true)
.attr("transform", "translate(width,0)")
.call(yAxis2);
When I do this it just draws it in the same place as the first yAxis, when I adjust the transform/ translate it just gets drawn at random positions on the chart, I'm trying to line it up like the left yAxis only positioned on the right. Thanks to all for your input.
Syntax error:
.attr("transform", "translate(width,0)")
To:
.attr("transform", "translate(" + width + ",0)")
plnkr