Javascript 如何使用JSON和D3返回数据

Javascript 如何使用JSON和D3返回数据,javascript,json,api,d3.js,Javascript,Json,Api,D3.js,我目前正在学习D3JS,并试图从OpenWeatherAPI获取的实时信息中制作一个条形图。我正在尝试获取查询时的城市名称及其各自的温度 在尝试设置图表时,我一直遇到这样的问题:当我得到每个值的NaN时,无法返回每个条形高度和宽度的数值。目前,我拥有的是一个函数,它遍历数据并创建一个对象,其中包含城市的温度和名称。然后我将它们放入一个数组weather中,我正在调用该数组来获取数据 有人能解释或弄清楚我为什么会得到NaN,以及我如何能够具体提取数据的温度值吗 var weather =[]; v

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

在尝试设置图表时,我一直遇到这样的问题:当我得到每个值的NaN时,无法返回每个条形高度和宽度的数值。目前,我拥有的是一个函数,它遍历数据并创建一个对象,其中包含城市的温度和名称。然后我将它们放入一个数组weather中,我正在调用该数组来获取数据

有人能解释或弄清楚我为什么会得到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]);
移除该线路,并在天气已填充后插入。使用该方法同时获得天气温度的最小值和最大值

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)

当您不希望变量为NaN时,您能指出它在代码中的具体位置吗?抱歉,澄清一下,我在将python服务器上的代码提供给浏览器后读取控制台错误。目前,我的17个对象数组如下所示:var weather=[{nameOfCountry:Kiambu,temperature:14.64},等等]问题发生在Canvas.transition调用中。也许你指的是画布之类的东西。选择全部“rect”。转换?无论如何,看起来你的矩形并没有被正确创建。transition方法和selectAll方法都为宽度和高度添加了属性,这些属性与从数据d中收集的xScale和yScale有关。但是,由于返回的值当前为NaN,我感觉它们是字符串,可能是名称,或者无法获取温度数据。酷,这解决了我的查询。但是,现在我也遇到了沿xScale均匀分布条及其宽度的问题。“我的所有栏”当前的默认宽度为2080像素。如何设置所有条的宽度,使其均匀分布在xScale上,然后根据它们的索引分布它们的x位置?@user3208676您所要做的就是在for循环之后移动xScale.domain行,就像您在yScale上所做的那样。@user3208676我希望这个答案有所帮助。如果您认为这是您问题的最佳答案,请不要忘记单击上面的复选标记将其标记为已接受
Canvas.transition()
.attr('height',function(d){
    return yScale(d.temperature);
})
.attr('y', function(d){
    return height - yScale(d.temperature);
})