js用户,
我刚开始使用d3.js& crossfilter并试图利用Adam Pearce在meteor map上的例子来可视化天气数据。由于我热衷于分析多年来的天气变化,我有多年的记录,而不是在“名称”列中只有一个记录。以下是原始数据和我自己的数据的示例:
原始数据
name mass_g year cartodb_id ....
Vilna 1 1967 34039
Silistra 1 1917 34017
我的数据
名称降雨年份cartodb_id ....
station_A 100 1997 34039
station_A 200 1998 34039
station_B 300 1997 34017
station_B 400 1998 34017
我不确定哪里出错,因为它没有产生任何错误。然而,
下面是我的js脚本来替换原来的drawMap.js(对不起,它有点太长了;谢谢你提出任何建议!):
var width = 1000,
height = 500;
var proj = d3.geo.mercator()
.center([103.8,1.33])
.scale(100000)
.rotate([0,0]);
var path = d3.geo.path()
.projection(proj);
// for map
var zoom = d3.behavior.zoom()
.translate(proj.translate())
.scale(proj.scale())
.scaleExtent([100000,Infinity]) //.scaleExtent([height*.33, 4 * height])
.on("zoom", zoom);
var svg = d3.select("#map").append("svg")
.attr("width", width)
.attr("height", height)
.call(zoom);
function zoom() {
proj.translate(d3.event.translate).scale(d3.event.scale);
svg.selectAll("path").attr("d", path);
circles
.attr("cx", function(d){return proj([d.long, d.lat])[0];})
.attr("cy", function(d){return proj([d.long, d.lat])[1];});
}
var borders = svg.append("g");
var impacts = svg.append("g");
// colours and scales for the corresponding values in map
var metorScale = d3.scale.pow().exponent(.5).domain([0, 100, 1000, 2000, 3000, 5000, 8000]);
var colorScale = d3.scale.linear().domain([1980, 1888, 1996, 2004, 2014]);
var tooltip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 1e-6)
.style("background", "rgba(250,250,250,.7)");
tooltip.append("img")
.attr("id", "tooltipImg")
.attr("height", 200)
.attr("width", 200)
.style("opacity", "1");
// change the fell file to our rainfall
// file has to be at aggregated level for each year
// one station one value for one year
// change the json file to our map
queue()
.defer(d3.json, "Planning_Area_Census2010_WGS84.json")
.defer(d3.csv, "yearlyrainfall.csv")
/*.defer(d3.json, "pics.json")*/
.await(ready);
var metors;
// for the rest of the code
// removed pics in the inputs
function ready(error, topology, csv){
borders.selectAll("path")
.data(topojson.object(topology, topology.objects.Planning_Area_Census2010_WGS84)
.geometries)
.enter()
.append("path")
.attr("d", path)
.attr("class", "border")
rawMetors = csv;
// change mass_g to rainfall
// cartodb_id is a key for our station
metors = [];
rawMetors.forEach(function(d){
d.rainfall = +d.rainfall;
d.year = +d.year;
d.id = +d.cartodb_id;
d.name = d.name;
d.region = d.region;
metors.push(d);
});
metors.sort(function(a, b){return a.id - b.id;})
// size tag to rainfall
//colour tag to year
metorScale
.range([1.5, 2, 3, 4, 5, 8, 10]);
colorScale
.range(["#FFFF66", "#FFFF00", "#E68000", "#D94000", "#CC0000"]);
circles = impacts.selectAll("circle")
.data(metors).enter()
.append("svg:a")
.attr("xlink:href", function(d) { return d.database; })
.attr("xlink:show", "new")
.append("circle")
.attr("cx", function(d){return proj([d.long, d.lat])[0];})
.attr("cy", function(d){return proj([d.long, d.lat])[1];})
.attr("r", function(d){return metorScale(d.rainfall);})
.attr("id", function(d){return "id" + d.id;})
.style("fill", function(d){return colorScale(d.year); })
.on("mouseover", function(d){
d3.select(this)
.attr("stroke", "black")
.attr("stroke-width", 1)
.attr("fill-opacity", 1);
tooltip
.style("left", (d3.event.pageX + 5) + "px")
.style("top", (d3.event.pageY - 5) + "px")
.transition().duration(300)
.style("opacity", 1)
.style("display", "block")
updateDetails(d);
})
.on("mouseout", function(d){
d3.select(this)
.attr("stroke", "")
.attr("fill-opacity", function(d){return 1;})
tooltip.transition().duration(700).style("opacity", 0);
});
metorsCF = crossfilter(metors),
all = metorsCF.groupAll(),
year = metorsCF.dimension(function(d){return d.year;}), /*creating a type dimension*/
years = year.group(function(d){return Math.floor(d);}),
rainfall = metorsCF.dimension(function(d){return d.rainfall }), /*creating a type dimension*/
rainfalls = rainfall.group(function(d){return Math.floor(d/10)*10;}),
// for grouping at var charts
// group by type, change to region
region = metorsCF.dimension(function(d){return d.region;}), /*creating a type dimension*/
regions = region.group();
// create group of ids
cartoDbId = metorsCF.dimension(function(d){return d.id;}); /*creating a type dimension*/
cartoDbIds = cartoDbId.group()
// create all the bar charts
// first one draw by group of years
// change the domain relate to the format tick in barchart.js
var charts = [
barChart()
.dimension(year)
.group(years)
.x(d3.scale.linear()
.domain([1970,2020])
.rangeRound([-1, 20*24-5])),
// change the domain relate to the format tickvalues in barchart.js
barChart()
.dimension(rainfall)
.group(rainfalls)
.x(d3.scale.linear()
.domain([1,10000])
.rangeRound([0,20*24]))
];
var chart = d3.selectAll(".chart")
.data(charts)
.each(function(chart){chart.on("brush", renderAll).on("brushend", renderAll)});
d3.selectAll("#total")
.text(metorsCF.size());
function render(method){
d3.select(this).call(method);
}
lastFilterArray = [];
metors.forEach(function(d, i){
lastFilterArray[i] = 1;
});
function renderAll(){
chart.each(render);
var filterArray = cartoDbIds.all();
filterArray.forEach(function(d, i){
if (d.value != lastFilterArray[i]){
lastFilterArray[i] = d.value;
d3.select("#id" + d.key).transition().duration(500)
.attr("r", d.value == 1 ? 2*metorScale(metors[i].rainfall) : 0)
.transition().delay(550).duration(500)
.attr("r", d.value == 1 ? metorScale(metors[i].rainfall) : 0);
}
})
d3.select("#active").text(all.value());
}
window.reset = function(i){
charts[i].filter(null);
renderAll();
}
renderAll();
}
// to show the labels on what to display on map
var printDetails = [
{'var': 'name', 'print': 'Station'},
{'var': 'region', 'print': 'Region'},
{'var': 'rainfall', 'print': 'Rainfall(mm)'},
{'var': 'year', 'print': 'Year'}];
function updateDetails(metorsCF){
// var image = new Image();
// image.onload = function(){
// document.getElementById("tooltipImg").src = 'pictures/' + metor.cartodb_id + '.jpg';}
// image.src = 'pictures/' + metor.cartodb_id + '.jpg';
tooltip.selectAll("div").remove();
tooltip.selectAll("div").data(printDetails).enter()
.append("div")
.append('span')
.text(function(d){return d.print + ": ";})
.attr("class", "boldDetail")
.insert('span')
.text(function(d){return metorsCF[d.var];})
.attr("class", "normalDetail");
}
[1]: http://roadtolarissa.com/meteors/