d3.slider和日期在时间轴上过滤 [英] d3.slider and dates filtered on a timeline

查看:1411
本文介绍了d3.slider和日期在时间轴上过滤的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个



1 )显示热点应该从头到尾绘制
2)显示何时是实际drage /点击时间线到结束
3)显示我立即点击结束(不拖动)



日期在此函数中被过滤,它应该在我的理解中工作。示例和我的版本都使用underscore.js,我的知识是非常有限的。是什么原因导致这个问题,它不能正确过滤到最后如果我拖动滑块手柄?

  var dateParser = d3。 time.format(%d。%m。%Y)。 
var minDate = dateParser(01.01.2015);
var maxDate = dateParser(02.12.2015);
console.log(minDate);
var secondsInDay = 60 * 60 * 24;

d3.select('#slider3')。call(d3.slider()
.axis(true)
.min(minDate)
.max max date)
// .min(function(d){
// var date = dateParser(d.properties.date);
// return date;
//} )
// .max(function(d){
// var date = dateParser(d.properties.date);
// return date;
//})
.step(1)
.on(slide,function(evt,value){

newData = site_data.features.filter(function(d){
//console.log(new Date(value));
return dateParser(d.properties.date)< new Date(value);
});
console.log (New set size,newData.length);

displaySites(newData);
})

我的全部html现在看起来像这样



 <!DOCTYPE html>< head> < title> D3 Mapping Timeline< / title>< meta charset =utf-8>< link rel =stylesheethref =d3.slider.css/>< style& : 没有;中风:#333; stroke-width:.5px;}。land-boundary {stroke-width:1px;}。county-boundary {stroke:#ddd;}。site {opacity:0.2; fill:#9cf;}#slider3 {margin:20px 0 10px 20px; width:900px;} svg {background:#eee;}。sphere {fill:rgb(92,136,255)}。land {fill:rgb(255,239,204)}。incident {fill:#07f5e7; opacity:0.5;}。boundary {fill:none;中风:rgb(224,91,49); stroke-linejoin:round; stroke-linecap:round;向量效果:非缩放笔画;}。状态{fill:#000;}。city {fill:#de1ae8;}。 pointer-events:all;}< / style>< script src =http://d3js.org/d3.v3.min.js>< / script>< script src =http:/ /d3js.org/topojson.v1.min.js\"> ;<script><script src =https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore- min.js>< / script>< script src =d3.slider.js>< / script>< / head>< body>< div id =slider3> ; / div>< script> var width = 1240,height = 720; var projection = d3.geo.mercator().translate([width / 2,height / 2]).scale((width  -  1)/ 2 / Math.PI); var zoom = d3.behavior.zoom().scaleExtent([3,77]).on(zoom,zoomed); var path = d3.geo.path ; var svg = d3.select(body)。append(svg).attr(width,width).attr(height,height).append(g); var g = svg。 append(g); var sites = svg.append(g); svg.call(zoom).call(zoom.event); d3.json(countries.topo.json,function ){if(error)throw error; g.append(path).datum({type:Sphere}).attr(class,sphere).attr(d,path); g.append(path).datum(topojson.merge(world,world.objects.countries.geometries)).attr(class,land).attr(d,path); g.append(path).datum(topojson.mesh(world,world.objects.countries,function(a,b){return a!== b;})).attr(class,boundary ).attr(d,path); // _______________________________________________________________________________________________________________________________________________________________________________________________________________________________________ // ________________________________________________________________________________________________________________________________________________________________________________________ d3.json(germany.topo.json,function(error,ger){if(error)throw error; var states = topojson.feature ger.objects.states),cities = topojson.feature(ger,ger.objects.cities); g.selectAll(。states).data(states.features).enter().append(path ).attr(class,state).attr(class,function(d){returnstate+ d.id;}).attr(d,path); g.append路径).datum(cities).attr(d,path.pointRadius('0.05')).attr(class,city);});}); function zoomed(){g.attr (transform,translate(+ d3.event.translate +)scale(+ d3.event.scale +)); sites.attr(transform,translate(+ d3.event.translate +)scale(+ d3.event.scale +));} d3.select(self.frameElement).style ,height +px); d3.json(https://raw.githubusercontent.com/RitterLean/Slider-geojson-testing/master/vorfaelle.json,function(error,data){console.log data.features [1] .geometry.coordinates,sad); window.site_data = data;}); var displaySites = function(data){//console.log(data)sites.selectAll .data(data).enter().append(circle).attr(class,site).attr(cx,function(d){var p = projection(d.geometry.coordinates) ; return p [0];}).attr(cy,function(d){var p = projection(d.geometry.coordinates); return p [1]}).attr(r,0)。 transition()。duration(400).attr(r,0.25); //。.attrsites.selectAll(。site).data(data).exit()//删除要从数据集中删除的选择.transition()。duration(200).attr r,0).remove();}; var dateParser = d3.time.format(%d。%m。%Y)parse; var minDate = dateParser(01.01.2015); var maxDate = dateParser(02.12.2015); console.log(minDate); var secondsInDay = 60 * 60 * 24; d3.select('#slider3')。call(d3.slider().axis (minDate).max(maxDate)// .min(function(d){// var date = dateParser(d.properties.date); // return date; //})// .max {// var date = dateParser(d.properties.date); // return date; //}).step(1).on(slide,function(evt,value){newData = site_data.features.filter (function(d){//console.log(new Date(value)); return dateParser(d.properties.date)< new Date(value);}); console.log(New set size,newData .length); displaySites(newData);}));< / script>< / body>  

b
$ b

ann所有其他文件可以在我的 repo < a>因为我不知道如何在stackoverflow上正确分享。



我有三个想法从哪里开始。也许它是与主要html中的滑块函数的最小值和最大值有关,但更改它只是使轴的刻度消失。它也可以是在d3.slider.js(也许underscore.js?)过滤的东西。数据只有条目到今年12月2日,所以一些兴趣点不显示,因为日期,所以连接到.min .max可能?



提前感谢你

解决方案

滑块正常工作,并正确过滤。



看起来像退出标识更多的数据比它需要删除,不可见。

  sites.selectAll(。site)
.data(data).exit()/ /删除要从数据集中删除的选择
.transition()。duration(200)
.attr(r,0)
.remove

所以我改变了 displaySite

  var displaySites = function(data){
//删除所有点
sites.selectAll (.site)
.remove();
//添加所有过滤的点
sites.selectAll(。site)
.data(data)
.enter()
.append )
.attr(class,site)
.attr(cx,function(d){
var p = projection(d.geometry.coordinates);
return p [0];
})
.attr(cy,function(d){
var p = projection(d.geometry.coordinates);
return p [1]
})
.attr(r,0)
.transition()。duration(40)
.attr );
};

工作代码此处



另一种方法



在数据传递中,唯一标识符用于唯一标识对象。
下面假设每个点都有一个唯一的描述请改变它

  var displaySites = function(data){
var sitedata = sites.selectAll(。site)
.data(data,function(d){return d.properties.description});唯一标识每个数据集点

sitedata
.enter()
.append(circle)
.attr(class,site)
.attr(cx,function(d){
var p = projection(d.geometry.coordinates);
return p [0];
})
.attr(cy,function(d){
var p = projection(d.geometry.coordinates);
return p [1]
})
.attr r,0)
.transition()。duration(40)
.attr(r,0.23)

sitedata.exit()//删除要从数据集中删除的选择
.transition()。duration(200)
.attr(r,0 )
.remove();

};

工作代码此处



希望这有助于


I have this example where some points get spawned over time with a slider. My version is almost working but something that I cant get my head around is this problem:

1) Shows hot is should be plotted from the beginning to end 2) Shows when is actual drage/click on the timeline to the end 3) Shows when I click to the end at once (no dragging)

the date is filtered in this function and it should work in my understanding. The example and my version are both using underscore.js where my knowledge is very limited. What is causing this problem that it does not filter properly to the end if i drag the slider handle?

var dateParser = d3.time.format("%d.%m.%Y").parse;
var minDate = dateParser("01.01.2015");
var maxDate = dateParser("02.12.2015");
console.log(minDate);
var secondsInDay = 60 * 60 * 24;

d3.select('#slider3').call(d3.slider()
    .axis(true)
    .min(minDate)
    .max(maxDate)
    // .min(function(d){
    //   var date = dateParser(d.properties.date);
    //   return date;
    // })
    // .max(function(d){
    //   var date = dateParser(d.properties.date);
    //   return date;
    // })
    .step(1)
    .on("slide", function(evt, value) {

    newData = site_data.features.filter(function(d){
      //console.log(new Date(value));
      return dateParser(d.properties.date) < new Date(value);
    });
        console.log("New set size ", newData.length);

    displaySites(newData);
  })

My full html looks something like this now

<!DOCTYPE html>
<head>
    <title>D3 Mapping Timeline</title>
<meta charset="utf-8">
<link rel="stylesheet" href="d3.slider.css" />
<style>

path {
  fill: none;
  stroke: #333;
  stroke-width: .5px;
}

.land-boundary {
  stroke-width: 1px;
}

.county-boundary {
  stroke: #ddd;
}

.site {
  opacity: 0.2;
  fill: #9cf;
}

#slider3 {
  margin: 20px 0 10px 20px;
  width: 900px;
}

svg {
  background: #eee;
}

.sphere {
  fill: rgb(92, 136, 255)
}

.land {
  fill: rgb(255, 239, 204)
}

.incident{
  fill:#07f5e7;
  opacity: 0.5;
}

.boundary {
  fill: none;
  stroke: rgb(224, 91, 49);
  stroke-linejoin: round;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}

.state {
  fill: #000;
}
.city{
  fill: #de1ae8;
}

.overlay {
  fill: none;
  pointer-events: all;
}
</style>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="d3.slider.js"></script>
</head>
<body>
<div id="slider3"></div>

<script>

var width = 1240,
  height = 720;
var projection = d3.geo.mercator()
    .translate([width / 2, height / 2])
    .scale((width - 1) / 2 / Math.PI);

var zoom = d3.behavior.zoom()
    .scaleExtent([3, 77])
    .on("zoom", zoomed);

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

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

var g = svg.append("g");
var sites = svg.append("g");

svg.call(zoom)
    .call(zoom.event);

d3.json("countries.topo.json", function(error, world) {
	if (error) throw error;

  g.append("path")
      .datum({type: "Sphere"})
      .attr("class", "sphere")
      .attr("d", path);

  g.append("path")
      .datum(topojson.merge(world, world.objects.countries.geometries))
      .attr("class", "land")
      .attr("d", path);

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

//_______________________________________________________________________________________________________________________________________
//________________________________________________________________________________________________________________________________________


  d3.json("germany.topo.json", function(error, ger){
    if (error) throw error;
    var states = topojson.feature(ger, ger.objects.states),
        cities = topojson.feature(ger, ger.objects.cities );

    g.selectAll(".states")
        .data(states.features)
        .enter()
        .append("path")
        .attr("class", "state")
        .attr("class", function(d) { return "state " + d.id; })
        .attr("d", path);
    g.append("path")
        .datum(cities)
        .attr("d", path.pointRadius('0.05'))
        .attr("class", "city");
  });
});

function zoomed() {
  g.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
  sites.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}

d3.select(self.frameElement).style("height", height + "px");

d3.json("https://raw.githubusercontent.com/RitterLean/Slider-geojson-testing/master/vorfaelle.json", function(error, data){
    console.log(data.features[1].geometry.coordinates, "sad");
    window.site_data = data;

});


var displaySites = function(data) {
  //console.log(data)
  sites.selectAll(".site")
      .data(data)
      .enter()
      .append("circle")
      .attr("class", "site")
      .attr("cx", function(d) {
        var p = projection(d.geometry.coordinates);
        return p[0];
      })
      .attr("cy", function(d) {
        var p = projection(d.geometry.coordinates);
        return p[1]
      })
      .attr("r", 0)
      .transition().duration(400)
      .attr("r", 0.25);
    //  "".attr""

  sites.selectAll(".site")
        .data(data).exit()//remove the selection which are to be removed from dataset
      .transition().duration(200)
        .attr("r",0)
        .remove();

};


var dateParser = d3.time.format("%d.%m.%Y").parse;
var minDate = dateParser("01.01.2015");
var maxDate = dateParser("02.12.2015");
console.log(minDate);
var secondsInDay = 60 * 60 * 24;

d3.select('#slider3').call(d3.slider()
    .axis(true)
    .min(minDate)
    .max(maxDate)
    // .min(function(d){
    //   var date = dateParser(d.properties.date);
    //   return date;
    // })
    // .max(function(d){
    //   var date = dateParser(d.properties.date);
    //   return date;
    // })
    .step(1)
    .on("slide", function(evt, value) {

    newData = site_data.features.filter(function(d){
      //console.log(new Date(value));
      return dateParser(d.properties.date) < new Date(value);
    });
		console.log("New set size ", newData.length);

    displaySites(newData);
  })
);

</script>
</body>

ann all other files can be found on my repo because I don't know yet how to share it properly on stackoverflow.

I have three ideas where to begin. Maybe it is something to do with the min and max of the slider function in the main html but changing it just made the ticks of the axis disappear. It could also be something with the filtering inside the d3.slider.js (maybe underscore.js?). The data has only entries to the 2nd of december of this year so some points of interests wont' show because of the date so something connected to the .min .max maybe? So why is it not filtering like it is sopposed to?

Thank you in advance

解决方案

The slider is working perfectly and filtering it correctly.

Seems like the exit is identifying more data than it needs to remove., thus more points are not visible.

 sites.selectAll(".site")
        .data(data).exit()//remove the selection which are to be removed from dataset
      .transition().duration(200)
        .attr("r",0)
        .remove();

So I changed the displaySite function like this:

var displaySites = function(data) {
  //remove all the points 
  sites.selectAll(".site")
      .remove();
  //add all the filtered points    
  sites.selectAll(".site")
      .data(data)
      .enter()
      .append("circle")
      .attr("class", "site")
      .attr("cx", function(d) {
        var p = projection(d.geometry.coordinates);
        return p[0];
      })
      .attr("cy", function(d) {
        var p = projection(d.geometry.coordinates);
        return p[1]
      })
      .attr("r", 0)
      .transition().duration(40)
      .attr("r", 0.23);
};

Working code here

Another Way:

In the data pass the unique identifier for uniquely identifying object. Here below i am assuming each point will have a unique description please change it accordingly

var displaySites = function(data) {
  var sitedata = sites.selectAll(".site")
      .data(data, function(d){return d.properties.description});//uniquely identify each dataset point

  sitedata
      .enter()
      .append("circle")
      .attr("class", "site")
      .attr("cx", function(d) {
        var p = projection(d.geometry.coordinates);
        return p[0];
      })
      .attr("cy", function(d) {
        var p = projection(d.geometry.coordinates);
        return p[1]
      })
      .attr("r", 0)
      .transition().duration(40)
      .attr("r", 0.23);

    sitedata.exit()//remove the selection which are to be removed from dataset
      .transition().duration(200)
        .attr("r",0)
        .remove();

};

Working code here

Hope this helps

这篇关于d3.slider和日期在时间轴上过滤的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆