为什么我的D3折线图显示每个实体的黑色区域? [英] Why my D3 line graphs shows black areas for each entity?
问题描述
我制作了一个网络抓取器,该抓取器获取有关不同银行的货币转移率的数据,并在D3折线图中显示其随时间的变化(每个银行都有一条线,汇率是每天).服务器端cronjob可以确保每天进行抓取.
在前端,它使用D3.json从该URL获取数据:
这是我的代码:
/*全局d3 */var margin = {最高:20右:50,底部:20左:50};var w = 1000-margin.left-margin.right,h = 500-margin.top-margin.bottom;var ratesData ="http://rateswebscraper.herokuapp.com/rates";//加载买卖数据var loadData = function(dataSet,title){//设置图表标题document.getElementById("title").innerHTML = title;//重置SVG容器元素d3.select(#chart").select("svg").remove();var svg = d3.select(#chart").append("svg").attr("width",w + margin.left + margin.right).attr("height",h + margin.top + margin.bottom).append("g").attr("transform","translate(" + margin.left +," + margin.top +)").attr("id","area");//创建比例var x = d3.scaleTime().range([0,w]),y = d3.scaleLinear().range([h,0]),z = d3.scaleOrdinal(d3.schemeCategory10);//路径的行生成器var line = d3.line().x(function(d){返回x(d.date);}).y(function(d){返回y(d.rate);});d3.json(ratesData,function(data){//将日期字符串库转换为d3.scaleTime的日期对象var rate = data.map(function(item){item.date =新的Date(item.date);归还物品;});var bank = rates [0] .data.map(function(item){//循环遍历.data数组,并获取该系列的银行名称var bank = {};bank.id = item.name;bank.values = [];退货银行});var createRates = function(type){rates.forEach(function(item){item.data.forEach(function(rate){对于(var i = 0; i< bank.length; i ++){如果(banks [i] .id === rate.name){var rateObject = {};rateObject.date =新的Date(item.date);if(type ==="buy"){rateObject.rate = Number(rate.buy);} 别的 {rateObject.rate = Number(rate.sell);}银行[i] .values.push(rateObject);}}});});};//为每组购买值创建一个费率数组if(dataSet ===购买"){createRates("buy");} 别的 {createRates("sell");}//获取日期和汇率的最小值/最大值,并根据银行ID设置颜色比例x.domain(d3.extent(rates,function(d){返回日期}));y.domain([d3.min(banks,function(c){返回d3.min(c.values,function(d){如果(d.rate!== 0){回报率} 别的 {返回}});}),d3.max(banks,function(c){返回d3.max(c.values,function(d){回报率});})]);//色阶需要银行ID的数组z.domain(banks.map(function(c){返回c.id;}));//追加x轴svg.append("g").attr("class",轴轴--x").attr("transform","translate(0," + h +)").call(d3.axisBottom(x));//附加y轴svg.append("g").attr("class",轴轴-y").call(d3.axisLeft(y)).append("text").attr("transform","rotate(-90)").attr("y",6).attr("dy","0.71em").attr(填充",#000").text(费率以HKD");//对于每个bank元素,我们都附加一个g group元素var bank = svg.selectAll(.bank").data(银行).enter().append("g").attr("class","bank");//对于每个bank元素,我们都附加一个path元素并使用行生成器bank.append("path").attr("class","line").attr("d",function(d){返回行(d.values);}).style("stroke",function(d){返回z(d.id);});//为每个银行在行旁边添加一个文本bank.append("text").datum(function(d){返回 {id:d.id,值:d.values [d.values.length-1]};}).attr("transform",function(d){返回"translate(" + x(d.value.date)+," + y(d.value.rate)+)";}).attr("x",3).attr("dy","0.35em").style("font","10px work sans").text(function(d){返回d.id;});});=};//用购买率在页面加载时调用loadData函数loadData("buy","Buy Rates");//将点击事件添加到按钮以加载购买或出售数据document.getElementById("buyData").addEventListener("click",function(){loadData("buy","Buy Rates");});document.getElementById("sellData").addEventListener("click",function(){loadData("sell","Sell Rates");})
任何人都可以帮助我在代码中做错什么吗?
在路径中添加样式:
.style("fill","none");
I made a webscraper that gets data about currency transfer rates of different banks and shows that in a D3 line graph over time (each bank has a line, and the rates are per day). A cronjob server-side makes sure the scraping occurs daily.
In the front-end, it uses D3.json to get data from this url:
http://rateswebscraper.herokuapp.com/rates
I made the line graph but instead of a line for every bank, it shows a black area, see screenshot below:
Here is my code:
/*global d3*/
var margin = {
top: 20,
right: 50,
bottom: 20,
left: 50
};
var w = 1000 - margin.left - margin.right,
h = 500 - margin.top - margin.bottom;
var ratesData = "http://rateswebscraper.herokuapp.com/rates";
//load buy or sell data
var loadData = function(dataSet, title) {
//set chart title
document.getElementById("title").innerHTML = title;
//reset SVG container element
d3.select("#chart").select("svg").remove();
var svg = d3.select("#chart")
.append("svg")
.attr("width", w + margin.left + margin.right)
.attr("height", h + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.attr("id", "area");
//Create the scales
var x = d3.scaleTime().range([0, w]),
y = d3.scaleLinear().range([h, 0]),
z = d3.scaleOrdinal(d3.schemeCategory10);
//Line generator for path
var line = d3.line()
.x(function(d) {
return x(d.date);
})
.y(function(d) {
return y(d.rate);
});
d3.json(ratesData, function(data) {
//convert date strings bank to date objects for d3.scaleTime
var rates = data.map(function(item) {
item.date = new Date(item.date);
return item;
});
var banks = rates[0].data.map(function(item) {
//loop through the .data array and get the bank names for the series
var bank = {};
bank.id = item.name;
bank.values = [];
return bank;
});
var createRates = function(type) {
rates.forEach(function(item) {
item.data.forEach(function(rate) {
for (var i = 0; i < banks.length; i++) {
if (banks[i].id === rate.name) {
var rateObject = {};
rateObject.date = new Date(item.date);
if (type === "buy") {
rateObject.rate = Number(rate.buy);
} else {
rateObject.rate = Number(rate.sell);
}
banks[i].values.push(rateObject);
}
}
});
});
};
//Create a rates array per bank of buy values
if (dataSet === "buy") {
createRates("buy");
} else {
createRates("sell");
}
//Get the Min/Max values for date and rates and setup color scale based on bank ID
x.domain(d3.extent(rates, function(d) {
return d.date;
}));
y.domain([
d3.min(banks, function(c) {
return d3.min(c.values, function(d) {
if (d.rate !== 0) {
return d.rate;
} else {
return
}
});
}),
d3.max(banks, function(c) {
return d3.max(c.values, function(d) {
return d.rate;
});
})
]);
//color scale needs an array of bank id's
z.domain(banks.map(function(c) {
return c.id;
}));
//append x Axis
svg.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + h + ")")
.call(d3.axisBottom(x));
//append y Axis
svg.append("g")
.attr("class", "axis axis--y")
.call(d3.axisLeft(y))
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", "0.71em")
.attr("fill", "#000")
.text("Rates in HKD");
//for every bank element we append a g group element
var bank = svg.selectAll(".bank")
.data(banks)
.enter().append("g")
.attr("class", "bank");
//for every bank element we append a path element and use the line generator
bank.append("path")
.attr("class", "line")
.attr("d", function(d) {
return line(d.values);
})
.style("stroke", function(d) {
return z(d.id);
});
//append a text next to the line for every bank
bank.append("text")
.datum(function(d) {
return {
id: d.id,
value: d.values[d.values.length - 1]
};
})
.attr("transform", function(d) {
return "translate(" + x(d.value.date) + "," + y(d.value.rate) + ")";
})
.attr("x", 3)
.attr("dy", "0.35em")
.style("font", "10px work sans")
.text(function(d) {
return d.id;
});
}); =
};
//Call loadData function on page load with buy rates
loadData("buy", "Buy Rates");
//Add click events to buttons to load buy or sell data
document.getElementById("buyData").addEventListener("click", function() {
loadData("buy", "Buy Rates");
});
document.getElementById("sellData").addEventListener("click", function() {
loadData("sell", "Sell Rates");
})
Anyone can help me what I am doing wrong in my code?
Add a style to the path:
.style("fill","none");
这篇关于为什么我的D3折线图显示每个实体的黑色区域?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!