Bagaimana cara membuat titik plot saya lancar di d3.js menggunakan proyeksi?

Saya dapat memplot beberapa data cuaca ke peta menggunakan kode berikut. Namun titik-titiknya berbentuk persegi panjang dan saya ingin membuatnya lebih halus.

Persegi Panjang Diplot,

Saya ingin memplotnya dengan lebih halus seperti sesuatu yang mirip dengan Ideal plot points

Saya yakin saya perlu mempelajari interpolasi, analisis spasial, dan/atau peta Choropleth. Saya pikir mereka adalah algoritma yang berbeda dalam melakukan ini. Saya merasa perlu mengisi lebih banyak poin di antara poin yang sudah ada? Dan dengan itu apakah mungkin membuat titik seperti gradien? Apakah ini bisa dilakukan di D3? Atau haruskah saya mempertimbangkan untuk menggunakan barang three.js atau WebGL?

var width = 960,
height = 960;

var map = {};
var projection = d3.geo.mercator()
.scale((width + 1) / 2 / Math.PI)
.translate([width / 2, height / 2])
.precision(.1);

var path = d3.geo.path()
.projection(projection);

var graticule = d3.geo.graticule();

var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);

svg.append("path")
.datum(graticule)
.attr("class", "graticule")
.attr("d", path);

d3.json("world-50m.json", function(error, world) {
 svg.insert("path", ".graticule")
  .datum(topojson.feature(world, world.objects.land))
  .attr("class", "land")
  .attr("d", path);

svg.insert("path", ".graticule")
  .datum(topojson.mesh(world, world.objects.countries, function(a, b) { return a !== b; }))
  .attr("class", "boundary")
  .attr("d", path);
});

map.plot_points = [];
map.max = 30;
map.min = -1;
var opacity = d3.scale.linear()
 .domain([map.min, map.max])
 .range([0,1]);  
var rainbow = ["#CE0C82", "#800CCE", "#1F0CCE", "#0C5BCE", "#0C99CE", "#2ECE0C", "#BAE806", "#FEFF00", "#FFCD00", "#FF9A00", "#FF6000", "#FF0000"];
zs.forEach(function(zv,zi){
    zv.forEach(function(zzv, zzi){
        if(zzv != 999)
            {
                map.plot_points.push({lat: ys[zi], long:xs[zzi],value:zzv});
            }

        })
});
console.log(map);
var points = svg.selectAll("rects.points")
 .data(map.plot_points)
 .enter()
 .append("rect")
 .attr("class", "points")
 .style("fill", function(d) {
   var scale = d3.scale.linear().domain([map.min, map.max]).range([1, rainbow.length]);
        return rainbow[Math.round(scale(d.value))]; 
}).attr("width", 8)
.attr("height", 8)
.style("fill-opacity", 1)
.attr("transform", function(d) {
        return "translate(" + projection([d.long, d.lat]) + ")";
})

person user176855    schedule 06.12.2013    source sumber


Jawaban (4)


Sepertinya masalah dalam kasus Anda adalah datanya. Yang perlu Anda lakukan adalah mengambil data asli dan menginterpolasinya ke bentuk yang lebih halus. Untuk ini, Anda dapat menggunakan program GIS seperti QGIS. Cara tepatnya melakukannya bergantung pada format data asli Anda.

Setelah Anda memiliki data yang lebih halus, Anda dapat memplotnya lagi di D3. Dugaan saya adalah hasil akhirnya akan serupa dengan apa yang saya lakukan di sini, di mana garis kontur digambar dengan efek yang hampir sama seperti yang Anda tuju.

person Lars Kotthoff    schedule 06.12.2013
comment
Algoritme seperti apa yang digunakan untuk membuat data lebih lancar? Saya sudah mencoba melakukan ini melalui javasacript saja. conrec adalah yang terdekat namun hanya berfungsi pada titik genap. - person user176855; 18.12.2013
comment
Saya tidak mengetahui apa pun dalam Javascript; Saya sangat merekomendasikan menggunakan program GIS untuk itu. - person Lars Kotthoff; 18.12.2013

Mungkin Anda bisa melihat peta panas js.

http://www.patrick-wied.at/static/heatmapjs/

Meskipun berdasarkan poin, ini mungkin memberi Anda petunjuk. Ini menggunakan kanvas, bukan svg.

person Xumo    schedule 06.12.2013

Jason Davies menulis implementasi algoritma conrec yang melakukan apa yang Anda perlukan:

https://github.com/jasondavies/conrec.js Ada contoh yang berfungsi di dalamnya

person Roger Veciana    schedule 06.12.2013
comment
Saya pikir conrec.js adalah cara yang tepat atau d3.geo.contour(), namun bagaimana cara menerjemahkan (bujur, lintang, nilai) atau (x,y,nilai) menjadi sesuatu untuk kontur? - person user176855; 10.12.2013
comment
Dalam contoh ini, Anda dapat melihat bahwa Anda memerlukan tiga array, dengan nilai x, y, dan nilai: github.com/jasondavies/conrec.js/blob/master/example/ Saya tidak tahu apakah ini pertanyaan Anda... - person Roger Veciana; 10.12.2013

Saya yakin garis putih tersebut terjadi karena proyeksi yang Anda gunakan; Faktanya, ketinggian setiap persegi panjang harus disesuaikan ke utara dan selatan dari Khatulistiwa, karena proyeksi Mercator mengubah jarak ke utara dan selatan.
Untuk mendapatkan tinggi persegi panjang yang tetap, Anda dapat mencoba proyeksi ini:< br> http://bl.ocks.org/mbostock/3757119
yang melestarikan dimensi menuju utara dan selatan

person tomtomtom    schedule 06.12.2013