如何使用 JSON 并通过 D3 返回数据



我目前正在学习D3 JS,并试图从我从openweather API中提取的实时信息中制作一个条形图。我正在尝试获取查询时的城市名称及其各自的温度。

在尝试设置图表时,我一直遇到无法为每个柱线高度和宽度返回数值的问题,因为我为每个值获取 NaN。目前,我拥有一个函数,可以遍历数据并创建一个具有城市温度和名称的对象。然后我将它们推入一个数组,天气,我正在调用我的数据。

有人可以解释或弄清楚我为什么得到 NaN 以及如何能够具体提取数据的温度值吗?

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"
    })
});

您的域设置不正确

var yScale = d3.scale.linear()
    //.domain([0, d3.max(weather)]) Remove this line
    .range([0, height]);

删除该行并在填充weather后插入它。使用 d3.extent() 方法同时获取weather.temperature的最小值和最大值

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)

还要记住,您需要专门访问温度属性

Canvas.transition()
.attr('height',function(d){
    return yScale(d.temperature);
})
.attr('y', function(d){
    return height - yScale(d.temperature);
})

最新更新