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

时间:2015-01-23 22:31:27

标签: javascript json api d3.js

我目前正在玩学习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"
    })
});

1 个答案:

答案 0 :(得分:0)

看起来您的域名设置不正确

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