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

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

最佳答案

您的域名设置似乎不正确

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

关于javascript - 如何使用 JSON 并通过 D3 返回数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28119815/

相关文章:

javascript - 用 react 删除数组中的元素,不起作用

javascript - 函数式编程字典字符替换、键盘布局修复器

java - 简单(Twitter + 流 API + Java + OAuth)示例

javascript - Node.js Express 删除 req.body 不起作用

javascript - 为什么同步使用 Promise 会返回异步结果?

c# - 将带有数组的 json 结构展平为多个没有数组的平面对象

javascript - jQuery.when() 似乎没有在等待

c# - Newtonsoft.Json.JsonSerializationException 未由用户代码处理

api - 从 Nexus 下载神器

javascript - 为什么我的 RestFul API 与express和nodejs每天都会崩溃?