score:8
Accepted answer
Question 1
You are probably going to have to use tickValues to pass your own custom ticks. If you are generally happy with how d3
does it, you can just add an extra check to extend the array:
var ticks = y.ticks(),
lastTick = ticks[ticks.length-1],
newLastTick = lastTick + (ticks[1] - ticks[0]);
if (lastTick<y.domain()[1]){
ticks.push(newLastTick);
}
y.domain([y.domain()[0], newLastTick]); //<-- adjust domain for further value
// Define and draw axes
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickSize(-width, 0, 0)
.tickFormat( function(d) { return d } )
.tickValues(ticks);
Running code:
// Setup svg using Bostock's margin convention
var margin = {top: 15, 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: "10", mcintosh: "15", oranges: "9", pears: "6" },
{ year: "2007", redDelicious: "12", mcintosh: "18", oranges: "9", pears: "14" },
{ year: "2008", redDelicious: "05", mcintosh: "20", oranges: "8", pears: "2" },
{ year: "2009", redDelicious: "01", mcintosh: "15", oranges: "5", pears: "4" },
{ year: "2010", redDelicious: "02", mcintosh: "10", oranges: "4", pears: "2" },
{ year: "2011", redDelicious: "03", mcintosh: "12", oranges: "6", pears: "3" },
{ year: "2012", redDelicious: "04", mcintosh: "15", oranges: "8", pears: "1" },
{ year: "2013", redDelicious: "06", mcintosh: "11", oranges: "9", pears: "4" },
{ year: "2014", redDelicious: "10", mcintosh: "13", oranges: "9", pears: "5" },
{ year: "2015", redDelicious: "16", mcintosh: "19", oranges: "6", pears: "9" },
{ year: "2016", redDelicious: "19", mcintosh: "17", oranges: "5", pears: "7" },
];
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"];
var ticks = y.ticks(),
lastTick = ticks[ticks.length-1],
newLastTick = lastTick + (ticks[1] - ticks[0]);
if (lastTick<y.domain()[1]){
ticks.push(newLastTick);
}
y.domain([y.domain()[0], newLastTick]);
// Define and draw axes
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickSize(-width, 0, 0)
.tickFormat( function(d) { return d } )
.tickValues(ticks);
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");
svg {
font: 10px sans-serif;
shape-rendering: crispEdges;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
}
path.domain {
stroke: none;
}
.y .tick line {
stroke: #ddd;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
Question 2
Again, you can let d3
come up with the ticks and then filter out the ones you don't want:
var ticks = y.ticks().filter(function(d){
return parseInt(d) === d; // is it a integer?
})
// Define and draw axes
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickSize(-width, 0, 0)
.tickValues(ticks);
Running code:
// 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: "1", mcintosh: "3" },
{ year: "2007", redDelicious: "2", mcintosh: "1"},
{ year: "2008", redDelicious: "0", mcintosh: "2"}
];
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"];
var ticks = y.ticks().filter(function(d){
return parseInt(d) === d;
})
// Define and draw axes
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickSize(-width, 0, 0)
.tickValues(ticks);
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");
svg {
font: 10px sans-serif;
shape-rendering: crispEdges;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
}
path.domain {
stroke: none;
}
.y .tick line {
stroke: #ddd;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
Source: stackoverflow.com
Related Query
- d3 bar chart y axis ticks and grid lines above max value
- NVD3 Multi Bar Chart - Add in grid lines and make sure every y axis value shows up
- d3 horizontal bar chart with background and max value of 100%
- D3.js y- axis ticks and grid lines do not align
- D3 axis ticks and grid lines do not align
- d3 Plus bar chart how to force fixed max y axis range independent of the max data value
- Need help lining up x axis ticks with bars in D3.js bar chart
- D3 hide overflow of the chart area, when Y axis has a min and max
- Specifying Ticks on D3 Bar chart with Time Series data and scaleBand
- Limit number of Y axis ticks by keeping a top tick above the bar in d3
- d3 bar chart with fixed bar width and fixed spacing to align in center axis line
- D3.js bar chart - axis and labels not working / transitioning
- Get unique max value for each y-axis in a bar chart
- D3 Bar and Linear Chart With Multiple Axis
- grouped Bar chart using D3 grid issue and console errors
- Value above each bar stacked bar chart D3.js
- horizontal lines along the y axis d3 bar chart
- d3 bar chart with custom x axis and bar width
- Unable to add grid lines to bar chart
- D3.js Line chart with relative min and max in Y axis
- How can I create a basic bar chart with unique counts on the y axis and a category on the x axis?
- d3 chart is showing some decimal value in the X axis tick, instead of showing the date and time
- Redrawing grid lines on a line chart (remove and redraw) in d3.js
- X axis label not displayed in bar chart with scroll and zoom feature - d3js, Brushing
- Showing a bar chart with expected value and current value for a series
- How to change color only for data grid or x and y axis in chart in D3.js
- dc.js Stacked Bar Chart having only one column and with elastic X Axis is not rendered properly
- Customize grid lines in d3 bar chart
- How can I make a bar chart starting from the 0 point of the y axis and not from the bottom of the svg?
- Customize grid lines in D3 grouped bar chart
More Query from same tag
- Triangle scatter plot with D3.js
- How to use default HTML DOM functions with D3js
- live streaming plot that accumulates
- D3.js - browser freezing - too many elements on updating with time?
- Creating a table with D3 where two rows are siblings
- How can I programmatically draw a nonlinear writing system with automatic graph relaxation (e.g. in d3.js)?
- d3.js forced directed graph effects on enter
- d3.js mixing data between different selections
- d3.js function to count data belonging to a category and bigger than 0
- D3 Map zoom event to keep LineString width constant
- Simple stacked row chart
- d3 donut chart with curved labels
- D3 - Stop Force Graph from moving around, nodes should only stay where moved
- d3 bind element to data points / data values
- Extract a slice of a large multi-dimensional array in Javascript
- D3 - Event binding inside another event
- Cannot render csv file retrieved with Flask with the d3.js library
- D3 - Returning the whole array with the max count
- y axis ticks disappear in responsive chart in d3.js v4
- D3 - Stacked bar chart, position bars
- Values are not reflecting Dynamically in D3 Bar Chart using. Overlapping occur with the existing Graph.
- Setting static number of ticks for a chart in NVD3 and ClojureScript
- Key binding with d3.svg.path()
- How to convert/save d3.js graph to pdf/jpeg
- D3 how to find the height of the last point in a line graph
- d3 js line graph takes two different data formats. how do I differentiate those two?
- TypeError: svg.append(...).attrs is not a function when creating charts using D3.js
- D3 fit nodes on screen
- Calculating width to create continuous horizontal bar in D3.js
- Links never show up