In my d3 bar chart, I should have Y-axis dynamic ticks and grid lines for integer values (no ticks and grid lines for decimal values). But its not working , Please help me on this
var itemData =[{month: "MARCH", year: 2018, number: 26, date:1519842600000},{month: "MAY", year: 2018, number: 34, date: 1525113000000}];
createChart(itemData )
createChart(itemData) {
const router_temp = this.router;
const element = this.chartContainer.nativeElement;
const factoryId = itemData['id'];
const data = itemData.data;
d3.select(element).selectAll('*').remove();
const div = d3.select('body').append('div')
.attr('class', 'tooltip-bar-chart')
.style('display', 'none');
const svg = d3.select(element),
margin = {top: 10, right: 10, bottom: 20, left: 30},
width = +this.el.nativeElement.offsetWidth - margin.left - margin.right,
height = +svg.attr('height') - margin.top - margin.bottom;
const x = d3.scaleBand().range([10, width - 10]).padding(1),
y = d3.scaleLinear().rangeRound([height, 0]);
// add the X gridlines
svg.append('g')
.attr('class', 'grid')
.attr('transform', 'translate(30,' + height + ')')
.call(make_x_gridlines()
.tickSize(-height)
.tickFormat('')
);
// add the Y gridlines
svg.append('g')
.attr('class', 'grid')
.attr('transform', 'translate(30, 10)')
.call(make_y_gridlines()
.tickSize(-width)
.tickFormat('')
);
const g = svg.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
x.domain(data.map(function(d) { return d.month; }));
y.domain([0, d3.max(data, function(d) { return d.number; })]);
//
g.selectAll('.bar')
.data(data)
.enter().append('rect')
.attr('class', 'bar')
.attr('x', function(d) { return x(d.month); })
.attr('y', function(d) { return y(d.number); })
.attr('width', 12)
.attr('height', function(d) { return height - y(d.number); })
.on('mouseover', function(d) {
div.style('display', 'block');
div.html(
'<div class=\'main\'>' +
'<div class=\'month\'>' +
d.month +
'</div>' +
'<div class=\'number\'>' +
d.number +
'</div>' +
'<div class=\'bottom\'>' +
'Number of Applications Transformed & Migrated' +
'</div>' +
'</div>'
)
.style('left', (d3.event.pageX + 15) + 'px')
.style('top', (d3.event.pageY - 50) + 'px');
})
.on('mouseout', function(d) {
div.style('display', 'none');
})
const dataLength = data.length;
const xPositions = [];
for (let i = 0; i < dataLength; i += 1) {
xPositions.push(x(data[i].month) + margin.left);
}
const newX = d3.scaleOrdinal().range(xPositions);
const xScale = newX.domain(itemData.xlabels);
svg.append('g')
.attr('class', 'axis axis--x')
.attr('transform', 'translate(0,' + (height + 10) + ')')
.call(d3.axisBottom(xScale));
g.append('g')
.attr('class', 'axis axis--y')
.call(d3.axisLeft(y).ticks(5));
// gridlines in x axis function
function make_x_gridlines() {
return d3.axisBottom(x)
.ticks(1);
}
// gridlines in y axis function
function make_y_gridlines() {
return d3.axisLeft(y)
.ticks(5);
}
}
}
Here is sample
I created a fiddle.
that while I had to change a few things to account for no angular, but shows the axis gridlines and labels aligned. I moved everything into one g group is is then translated and the individual components are no longer translated.
Related
I would like to display text on y-axis tick point they are like always same even if data changed here are the tick point text ["Low" , "Medium" , "High"]
i have tried a lot but im unable to find the perfect solution
tick points are alway 3 and they have to show this text on each tick point ["Low" , "Medium" , "High"]
here is the image that how i want
this is what i have implemented
im unable to set the text of ["Low" , "Medium" , "High"] by replacing [5, 10, 15]
here is the array of data for plotting graph
[
{ group: 'A', value: 5 },
{ group: 'B', value: 15 },
{ group: 'C', value: 10 },
{ group: 'D', value: 15 },
{ group: 'E', value: 10 },
{ group: 'F', value: 5 },
]
here is the bar chart code
var outerWidth = convertRemToPixels(40),
outerHeight = barGraphContainerRef.current.clientHeight;
var margin = {
top: convertRemToPixels(2),
right: convertRemToPixels(2),
bottom: convertRemToPixels(2),
left: convertRemToPixels(2),
},
width = outerWidth - margin.left - margin.right,
height = outerHeight - margin.top - margin.bottom;
var x = d3.scaleBand().range([0, width]);
var y = d3.scaleLinear().range([height, 0]);
var xAxis = d3.axisBottom(x);
var yAxis = d3.axisLeft(y).ticks(3);
function make_y_gridlines() {
return d3.axisLeft(y).ticks(3);
}
//Defenining the tooltip div
var chart = d3
.select(refe.current)
.attr('width', outerWidth)
.attr('height', outerHeight);
let tooltip = d3
.select('#root .tooltipContainer')
.style('position', 'absolute')
.style('top', 0)
.style('left', 0)
.style('display', 'none');
var gradient = chart
.select('.lGradient')
.attr('id', 'gradient')
.attr('x1', '0%')
.attr('y1', '00%')
.attr('x2', '0%')
.attr('y2', '100%')
.attr('spreadMethod', 'pad');
gradient
.select('.firstStop')
.attr('offset', '-100%')
.attr('stop-color', '#0170ac')
.attr('stop-opacity', 1);
gradient
.select('.secondStop')
.attr('offset', '100%')
.attr('stop-color', '#013c5d')
.attr('stop-opacity', 1);
var main = chart
.select('.chart')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
main
.select('.x-axis')
.attr('transform', 'translate(0,' + height + ')')
.call(xAxis)
.style('color', '#a4a4a4');
main
.select('.y-axis')
.attr('transform', 'translate(0,' + 0 + ')')
.call(yAxis)
.style('color', '#a4a4a4');
y.domain([
0,
d3.max(graphData, function (d) {
return d.value;
}),
]);
x.domain(
graphData.map(function (d) {
console.log(d);
return d.group;
})
).padding([0.5]);
main
.select('.x-axis')
.call(xAxis)
.selectAll('text')
.style('text-anchor', 'end')
.attr('dx', '.3em')
.attr('dy', '1em')
.style('font-size', '.8rem')
.attr('transform', 'rotate(0)')
.style('font-family', '"Roboto", sans-serif');
main
.select('.y-axis')
.call(yAxis)
.selectAll('text')
.attr('class', 'yAxiesText')
.attr('transform', 'rotate(-90)')
.attr('y', '-2em')
.attr('x', '.4em')
.attr('dy', '.71em')
.style('font-size', '.8rem')
.style('text-anchor', 'end')
.style('font-family', '"Roboto", sans-serif');
main
.select('.gridder')
.call(make_y_gridlines().tickSize(-width).tickFormat(''))
.attr('id', 'gridSystem');
var rects = main.selectAll('.paths').data(graphData.map(e => e.value));
const names = graphData.map(e => e.group);
rects
.join('path')
.attr('class', 'paths')
.attr('d', function (d, i) {
return RectangleBarWithRadiusOneSide(
x(names[i]),
y(d),
x.bandwidth(),
height - y(d),
5 // radius
);
})
here is the RectangleBarWithRadiusOneSide function for making onside border radius
const RectangleBarWithRadiusOneSide = (x, y, width, height, radius) => {
return (
'M' +
(x + radius) +
',' +
y +
'h' +
(width - 2 * radius) +
'a' +
radius +
',' +
radius +
' 0 0 1 ' +
radius +
',' +
radius +
'v' +
(height - 2 * radius) +
'v' +
radius +
'h' +
-radius +
'h' +
(2 * radius - width) +
'h' +
-radius +
'v' +
-radius +
'v' +
(2 * radius - height) +
'a' +
radius +
',' +
radius +
' 0 0 1 ' +
radius +
',' +
-radius +
'z'
);
};
here is the convertRemToPixels function
export const convertRemToPixels = rem => {
return rem * parseFloat(getComputedStyle(document.documentElement).fontSize);
};
I hope i have explained meaningfully
if i get any solution from the anyone that is so appreciatable
thanks advance!
You can use the tickFormat() function on a d3 axis generator to format the tick values. Create a scale to map the data values to your "Low", "High", "Medium" labels and pass it to tickFormat():
const tickScale = d3.scaleOrdinal()
.domain([...new Set(data.map(d => d.value))].sort(d3.ascending)) // keep unique values in ascending order
.range(["Low", "Medium", "High"])
.unknown(""); // other values are not displayed
const yAxis = d3.axisLeft(sy)
.ticks(3)
.tickFormat(tickScale);
A working prototype can be found here: https://codepen.io/ccasenove/pen/abKNOqa
I'm trying to learn SVG graphs, I've nearly completed my graph however I currently have overlapping bars, I believe this is due to a combination of my x axis return data and my json data. My x axis lists the months from my JSON data, but my JSON data can have multiple entries from the same month. and if this is the case then my entries will overlap for that month. What I need to do is return the month + day seperately, however I haven't been able to figure out how just yet.
JSON data example where there's 2 entries for the same month:
1: {dayNo: 2, monthNo: 7, monthName: "July", year: 2018, recordDate: "2018-07-02T00:00:00",…}
avgVolume: 3585.53
dayNo: 2
monthName: "July"
monthNo: 7
recordDate: "2018-07-02T00:00:00"
volumeLastYear: 4109.47
volumeToday: 3575.34
year: 2018
2: {dayNo: 30, monthNo: 7, monthName: "July", year: 2018, recordDate: "2018-07-30T00:00:00",…}
avgVolume: 3291.55
dayNo: 30
monthName: "July"
monthNo: 7
recordDate: "2018-07-30T00:00:00"
volumeLastYear: 3996.31
volumeToday: 3414.44
year: 2018
And here is the svg code:
$request.done(function (response) {
// remove old svg
$('svg').remove();
// create svg element
var $svg = d3.select('.card.mb-3.clickable-card.highlight')
.append('svg')
.attr('width', '100%')
.attr('height', '400px')
.attr('style', 'background-color: lavender')
.classed('svg display-svg', true);
// 2 determine size of svg element
var w = $svg.node().getBoundingClientRect().width;
var h = $svg.node().getBoundingClientRect().height;
// 10 chart margins
var chartMargin = new Object();
chartMargin.left = 40;
chartMargin.right = 25;
chartMargin.top = 25;
chartMargin.bottom = 40;
// 10 cont
h = h - chartMargin.bottom - chartMargin.top;
// Max volume
var maxVolume = d3.max(response, d => d.avgVolume);
// bar Margins / width
var barMargin = 10;
var barWidth = (w - chartMargin.left - chartMargin.right) / response.length;
// yScale
var yScale = d3.scaleLinear()
.domain([0, maxVolume])
.range([h, chartMargin.top]);
// xScale
var xScale = d3.scaleBand()
.domain(response.map(function (d) { return d.monthName; }))
.range([0, w - chartMargin.left - chartMargin.right])
.paddingInner(0.15);
// chartGroup
var chartGroup = $svg.append('g')
.classed('chartGroup', true)
.attr('transform', 'translate(' + chartMargin.left + ',' + chartMargin.top + ')');
// 5
var barGroups = chartGroup
.selectAll('g')
.data(response);
// 6
var newBarGroups = barGroups.enter()
.append('g')
.attr('transform', function (d, i) {
return 'translate('
+ (xScale(d.monthName))
+ ','
+ (yScale(d.avgVolume))
+ ')';
})
// yAxis label
var yAxis = d3.axisLeft(yScale);
chartGroup.append('g')
.classed('axis y', true)
.attr('transform', 'translate(' + -20 + ', ' + h / 2 + ')')
.append('text')
.attr('transform', 'rotate(-90)')
.attr('dx', '-0.8em')
.attr('dy', '0.25em')
.attr("text-anchor", 'middle')
.text("Reservoir Volume (ML)");
// xAxis label
var xAxis = d3.axisBottom(xScale);
chartGroup.append('g')
.attr('transform', 'translate(0,' + h + ')')
.classed('axis x', true)
.call(xAxis);
newBarGroups
.append('rect')
.attr('x', 0)
.attr('height', function (d, i) {
return h - yScale(d.avgVolume);
})
// animation
.style('fill', 'transparent')
.transition().duration(function (d, i) { return i * 500; })
.delay(function (d, i) { return i + 200; })
.attr('width', barWidth - barMargin)
.style('fill', function (d, index) {
return "hsl(240, 100%, " + (d.avgVolume / maxVolume * 80) + "%)"
});
// bar text
newBarGroups
.append('text')
.attr('transform', 'rotate(-45)')
.attr('text-anchor', 'middle')
.attr('x', function () { return 0; })
.attr('y', 50)
.attr('fill', 'white')
.text(function (d, i) { return d.avgVolume; })
.style('font-size', '1em')
});
in the xScale, I have tried changing the return data from
return d.monthName
to
return d.monthName + ' ' + d.dayNo
But then all my bars overlap and I get this error for each g element:
d3.js:1211 Error: attribute transform: Expected number, "translate(undefined,25.183…".
Here is what I have currently with returning d.monthName:
Here is d.monthName + ' ' + d.dayNo:
Nevermind sorry, I fixed it
I needed to change
var newBarGroups = barGroups.enter()
.append('g')
.attr('transform', function (d, i) {
return 'translate('
+ (xScale(d.monthName))
+ ','
+ (yScale(d.avgVolume))
+ ')';
})
to
var newBarGroups = barGroups.enter()
.append('g')
.attr('transform', function (d, i) {
return 'translate('
+ (xScale(d.monthName + ' ' + d.dayNo))
+ ','
+ (yScale(d.avgVolume))
+ ')';
})
I have a line graph with two linear paths. Everything works great, only when I select area on graph, the lines goes over x-axis and also y-axis:
Please help me finding the issue. Following is my code:
var data = JSON.parse("[{\"time\": 1496511413,\"correlation\": 0.1,\"offset\": 8104}, {\"time\": 1496511414,\"correlation\": 0.2,\"offset\": 8105},{\"time\": 1496511415,\"correlation\": 0.4,\"offset\": 8106},{\"time\": 1496511416,\"correlation\": 0.5,\"offset\": 8107},{\"time\": 1496511417,\"correlation\": 0.7,\"offset\": 8120},{\"time\": 1496511418,\"correlation\": 0.8,\"offset\": 8120},{\"time\": 1496511419,\"correlation\": 0.3,\"offset\": 8108},{\"time\": 1496511420,\"correlation\": 0.6,\"offset\": 8109},{\"time\": 1496511421,\"correlation\": 0.9,\"offset\": 8110}]");
console.log(data);
var margin = {top: 30, right: 40, bottom: 30, left: 50},
width = 700 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
// Scale axis
var timeScale = d3.scaleTime().range([0, width]);
var corrScale = d3.scaleLinear().range([height, 0]);
var offsetScale = d3.scaleLinear().range([height, 0]);
// Define Axes
var timeAxis = d3.axisBottom(timeScale).ticks(5);
var corrAxis = d3.axisLeft(corrScale).ticks(5);
var offsetAxis = d3.axisRight(offsetScale).ticks(5);
// Define Lines
var corrLine = d3.line()
.x(function(d) { return timeScale(d.time); })
.y(function(d) { return corrScale(d.correlation); });
var offsetLine = d3.line()
.x(function(d) { return timeScale(d.time); })
.y(function(d) { return offsetScale(d.offset); });
// plot graph
function plot_graph() {
data.forEach(function(d) {
d.time = new Date(d.time * 1000);
d.correlation = +d.correlation;
d.offset = +d.offset / 1000;
});
console.log(data);
// Define brush
var brush = d3.brush()
.extent([[0, 0], [width, height]])
.on('end', brushEnded),
idleTimeout,
idleDelay = 350;
//Add domain for scale x-y axis
timeScale.domain(d3.extent(data, function(d) { return d.time; }));
corrScale.domain(d3.extent(data, function(d) { return d.correlation; }));
offsetScale.domain(d3.extent(data, function(d) { return d.offset; }));
// create svg element
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', 'time axis')
.attr("transform", "translate(0," + height + ")")
.call(timeAxis);
svg.append('g')
.attr('class', 'corr axis')
.style('fill', 'steelblue')
.call(corrAxis);
svg.append('g')
.attr('class', 'offset axis')
.attr('transform', 'translate(' + width + ', 0)')
.style('fill', 'red')
.call(offsetAxis);
var focus = svg.append('g')
.attr("clip-path", "url(#clip)");
focus.append('svg:path')
.datum(data)
.attr('class', 'corr line')
.attr('d', corrLine);
focus.append('svg:path')
.datum(data)
.attr('class', 'offset line')
.style('stroke', 'red')
.attr('d', offsetLine);
focus.append('g')
.attr('class', 'brush')
.call(brush);
function idled() {
idleTimeout = null;
}
function brushEnded() {
var s = d3.brushSelection(d3.select('.brush').node());
if (!s) {
if (!idleTimeout) return idleTimeout = setTimeout(idled, idleDelay);
timeScale.domain(d3.extent(data, function(d) { return d.time; }));
corrScale.domain(d3.extent(data, function(d) { return d.correlation; }));
offsetScale.domain(d3.extent(data, function(d) { return d.offset; }));
} else {
console.log(s);
console.log([s[0][0], s[1][0]].map(timeScale.invert, timeScale));
console.log([s[1][1], s[0][1]].map(offsetScale.invert, offsetScale));
console.log([s[1][1], s[0][1]].map(corrScale.invert, corrScale));
timeScale.domain([s[0][0], s[1][0]].map(timeScale.invert, timeScale));
corrScale.domain([s[1][1], s[0][1]].map(corrScale.invert, corrScale));
offsetScale.domain([s[1][1], s[0][1]].map(offsetScale.invert, offsetScale));
svg.select(".brush").call(brush.move, null);
}
zoom();
}
function zoom() {
var t = svg.transition()
.duration(750);
svg.select('.time.axis').transition(t).call(timeAxis);
svg.select('.corr.axis').transition(t).call(corrAxis);
svg.select('.offset.axis').transition(t).call(offsetAxis);
console.log(timeScale(0));
console.log(corrScale(0));
console.log(corrLine(data));
svg.select('path.corr.line')
.transition(t)
.attr('d', corrLine);
svg.select('path.offset.line')
.transition(t)
.attr('d', offsetLine);
}
}
I should have a white border when I select any bar in my d3 bar chart. So here the border is achieved using stroke, but the bottom border is getting hidden under the x domain line.
// container size
var margin = {top: 10, right: 10, bottom: 30, left: 30},
width = 400,
height = 300;
var data = [
{"month":"DEC","setup":{"count":26,"id":1,"label":"Set Up","year":"2016","graphType":"setup"}},
{"month":"JAN","setup":{"count":30,"id":1,"label":"Set Up","year":"2017","graphType":"setup"}},
{"month":"FEB","setup":{"count":30,"id":1,"label":"Set Up","year":"2017","graphType":"setup"}}];
var name = 'dashboard';
// x scale
var xScale = d3.scale.ordinal()
.rangeRoundBands([0, width], 0.2);
// set x and y scales
xScale.domain(data.map(function(d) { return d.month; }));
// x axis
var xAxis = d3.svg.axis()
.scale(xScale)
.orient('bottom')
.outerTickSize(0);
var yScale = d3.scale.linear()
.domain([0, d3.max(data, function(d) {
return d.setup.count;
})])
.range([height, 0]);
var ticks = yScale.ticks(),
lastTick = ticks[ticks.length-1];
var newLastTick = lastTick + (ticks[1] - ticks[0]);
if (lastTick < yScale.domain()[1]){
ticks.push(lastTick + (ticks[1] - ticks[0]));
}
// adjust domain for further value
yScale.domain([yScale.domain()[0], newLastTick]);
// y axis
var yAxis = d3.svg.axis()
.scale(yScale)
.orient('left')
.tickSize(-width, 0, 0)
.tickFormat(d3.format('d'))
.tickValues(ticks);
// create svg container
var svg = d3.select('#chart')
.append('svg')
.attr('class','d3-setup-barchart')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
//.on('mouseout', tip.hide);
// apply tooltip
//svg.call(tip);
// Horizontal grid (y axis gridline)
svg.append('g')
.attr('class', 'grid horizontal')
.call(d3.svg.axis()
.scale(yScale)
.orient('left')
.tickSize(-width, 0, 0)
.tickFormat('')
.tickValues(ticks)
);
// create bars
var bars = svg.selectAll('.bar')
.data(data)
.enter()
.append('g');
bars.append('rect')
.attr('class', function(d,i) {
return 'bar';
})
.attr('id', function(d, i) {
return name+'-bar-'+i;
})
.attr('x', function(d) { return xScale(d.month); })
.attr('width', xScale.rangeBand())
.attr('y', function(d) { return yScale(d.setup.count); })
.attr('height', function(d) { return height - yScale(d.setup.count); })
.on('click', function(d, i) {
d3.select(this.nextSibling)
.classed('label-text selected', true);
d3.select(this)
.classed('bar selected', true);
d3.select('#'+name+'-axis-text-'+i)
.classed('axis-text selected', true);
});
//.on('mouseover', tip.show)
//.on('mouseout', tip.hide);
// apply text at the top
bars.append('text')
.attr('class',function(d,i) {
return 'label-text';
})
.attr('x', function(d) { return xScale(d.month) + (xScale.rangeBand()/2) - 10; })
.attr('y', function(d) { return yScale(d.setup.count) + 2 ; })
.attr('transform', function() { return 'translate(10, -10)'; })
.text(function(d) { return d.setup.count; });
// draw x axis
svg.append('g')
.attr('id', name+'-x-axis')
.attr('class', 'x axis')
.attr('transform', 'translate(0,' + height + ')')
.call(xAxis);
// apply class & id to x-axis texts
d3.select('#'+name+'-x-axis')
.selectAll('text')
.attr('class', function(d,i) {
return 'axis-text';
})
.attr('id', function(d,i) { return name+'-axis-text-' + i; });
// draw y axis
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');
// remove 0 in y axis
svg.select('.y')
.selectAll('.tick')
.filter(function (d) {
return d === 0 || d % 1 !== 0;
}).remove();
svg
.select('.horizontal')
.selectAll('.tick')
.filter(function (d) {
return d === 0 || d % 1 !== 0;
}).remove();
JSFiddle
In a SVG, whoever is painted last stays on top.
That being said, simply append your x axis...
svg.append('g')
.attr('id', name + '-x-axis')
.attr('class', 'x axis')
.attr('transform', 'translate(0,' + height + ')')
.call(xAxis);
... before the bars:
var bars = svg.selectAll('.bar')
.data(data)
.enter()
.append('g');
Here is your updated fiddle: https://jsfiddle.net/5bnzt6nb/
I am currently playing with learning D3 JS and am trying to make a bar chart from the live information I am pulling from the openweather API. I am trying to get the City Name and its respective temperature at the time of the query.
While trying to set up my chart, I keep running into the problem of being unable to return a number value for each bars height and width as I get NaN for each value. Currently, what I have is a function that iterates through the data and creates an object with the temperature and name of the city. I then push them into an array, weather, which I am calling for my data.
Can somebody explain or figure out why I am getting NaN and how I might be able to pull specifically the data's temperature value?
var weather =[];
var name;
var margin = {
top: 50,
right:30,
bottom:40,
left:50
}
var height = 500 - margin.top - margin.bottom ,
width = 600 - margin.left - margin.right,
barwidth = 50,
barOffset = 5;
var yScale = d3.scale.linear()
.domain([0, d3.max(weather)])
.range([0, height]);
var xScale = d3.scale.ordinal()
.domain(d3.range(0, weather.length))
.rangeBands([0, width], .2)
var tempColor;
//Load external data//
d3.json("http://api.openweathermap.org/data/2.5/group?id=192710,2643743,1850147,2988507,524901,5368361,1816670,2177052,1835847,3128760,7533612,292223,7870410,3451190,1275339,4904381,5856195,&units=metric", function(data){
var list = data.list
for (var i = 0; i<list.length; i++){
var country = list[i]
var nameOfCountry = list[i].name
var temperature = +country.main.temp
var countryWeather = [ nameOfCountry, temperature ]
weather.push({ "temperature":temperature, "nameOfCountry":nameOfCountry})
}
console.log(weather)
// Horizontal Color Gradient for bars
var colors = d3.scale.linear()
.domain([0, weather.length*.33, weather.length*.66, weather.length])
.range(['#FFB832','#C61C6F','#268BD2','#85992C'])
//Create the canvas//
var Canvas = d3.select('#chart').append('svg')
.style('background','#FFF')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr('transform','translate(' + margin.left + ',' + margin.top + ')')
.style('background', '#C9D7D6')
.selectAll('rect').data(weather)
.enter().append('rect')
.style('fill', function(d,i){
return colors(i);
})
.attr('width', xScale.rangeBand())
.attr('height', 0)
.attr('x',function(d,i){
return xScale(i);
})
.attr('y', height)
.on('mouseover', function(d){
tooltip.transition()
.style('opacity', .9)
tooltip.html(d)
.style('left',(d3.event.pageX - 35) + 'px')
.style('top', (d3.event.pageY - 35) + 'px')
tempColor = this.style.fill;
d3.select(this)
.transition().delay(500).duration(800)
.style('opacity', .5)
.style('fill', 'yellow')
})
.on('mouseout',function(d){
d3.select(this)
.transition().delay(500).duration(800)
.style('opacity',1)
.style('fill', tempColor)
})
Canvas.transition()
.attr('height',function(d){
return yScale(d);
})
.attr('y', function(d){
return height - yScale(d);
})
.delay(function(d,i){
return i * 20;
})
.duration(800)
.ease('elastic')
var vGuideScale = d3.scale.linear()
.domain([0,d3.max(weather)])
.range([height,0])
var vAxis = d3.svg.axis()
.scale(vGuideScale)
.orient('left')
.ticks(10)
var vGuide = d3.select('svg').append('g')
vAxis(vGuide)
vGuide.attr('transform','translate(' + margin.left + ',' + margin.top +')')
vGuide.selectAll('path')
.style({
fill:'none',
stroke: '#000'
})
vGuide.selectAll('line')
.style({
stroke: '#000'
})
var hAxis = d3.svg.axis()
.scale(xScale)
.orient('bottom')
.tickValues(xScale.domain().filter(function(d,i){
return !(i % (weather.length/5))
}))
var hGuide = d3.select('svg').append('g')
hAxis(hGuide)
hGuide.attr('transform','translate(' + (margin.left-6) + ',' + (height + margin.top) +')')
hGuide.selectAll('path')
.style({
fill:'none',
stroke: "#000"
})
hGuide.selectAll('line')
.style({
stroke:"#000"
})
});
It looks like your domain is not set correctly
var yScale = d3.scale.linear()
//.domain([0, d3.max(weather)]) Remove this line
.range([0, height]);
Remove that line and insert it after weather has been populated. Use the d3.extent() method to get both the min and max of weather.temperature simultaneously
for (var i = 0; i<list.length; i++){
var country = list[i]
var nameOfCountry = list[i].name
var temperature = +country.main.temp
var countryWeather = [ nameOfCountry, temperature ]
weather.push({ "temperature":temperature, "nameOfCountry":nameOfCountry})
}
yScale.domain(d3.extent(weather, function(d) { return d.temperature; }));
console.log(weather)
Also remember you need to access the temperature attribute specifically
Canvas.transition()
.attr('height',function(d){
return yScale(d.temperature);
})
.attr('y', function(d){
return height - yScale(d.temperature);
})