我正在使用d3.js构建一种时间轴工具,可以在设定的时间段内向前和向后缩放和分页。我的轴完美转换,但我似乎无法重新加载我的数据。想法是缩放级别定义移动窗口,例如用户在几天的时间内向后和向前移动的1小时。每次他们这样做时,都会打电话来获取该小时的数据。
对于大代码块的抱歉,处理新数据获取的方法是最底层的。如果它有任何不同,该工具是angular.js的指令。
// routes.php
$route['(:any)'] = "PublicController/index/$1";
// PublicController.php
public function index()
{
var_dump(func_get_args());
}
更新#1
我已经能够在line console.log(data.items.length)
之后使用Articles.get回调中的以下代码来显示要显示的新数据和旧数据。 scope.zoomLevels = [
{
value: 1,
unit: 'minutes',
tickFormat: $window.d3.time.format('%S')
},
{
value: 30,
unit: 'minutes',
tickFormat: $window.d3.time.format('%H:%M')
},
{
value: 1,
unit: 'hours',
tickFormat: $window.d3.time.format('%H:%M')
},
{
value: 3,
unit: 'hours',
tickFormat: $window.d3.time.format('%H:%M')
},
{
value: 6,
unit: 'hours',
tickFormat: $window.d3.time.format('%H:%M')
},
{
value: 12,
unit: 'hours',
tickFormat: $window.d3.time.format('%H:%M')
},
{
value: 1,
unit: 'days',
tickFormat: $window.d3.time.format('%H:%M')
}
];
var margin = {top: 0, right: 0, bottom: 0, left: 0},
width = $window.innerWidth,
height = $window.innerHeight - margin.top - margin.bottom,
xAxisHeight = $window.innerHeight - margin.top - ($window.innerHeight/2);
var start = $window.moment(Datasets.current.dates[0], 'DD/MM/YYYY'),
end = $window.moment(Datasets.current.dates[Datasets.current.dates.length - 1], 'DD/MM/YYYY'),
duration = $window.moment.duration(end.diff(start));
scope.zoomLevel = 3;
scope.page = 0;
scope.maxPage = duration.asMinutes()/scope.zoomLevels[scope.zoomLevel].value;
//$scope.tweets = Tweets.getTweets(start.format('x'), end.format('x'));
var rows = Math.floor(height/ 60);
console.log(rows + ' Rows');
var x = $window.d3.time.scale()
.domain([start.toDate(), start.clone().add(scope.zoomLevels[scope.zoomLevel].value, scope.zoomLevels[scope.zoomLevel].unit).toDate()])
.range([0, width]);
var y = $window.d3.scale.linear()
.domain([(rows/2) * -1,(rows/2)])
.range([height, 0]);
var xAxis = $window.d3.svg.axis()
.scale(x);
var yAxis = $window.d3.svg.axis()
.scale(y)
.tickSize(5)
.orient('right');
var svg = $window.d3.select('#timeline').append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height)
.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
svg.append('g')
.attr('class', 'x axis')
.attr('transform', 'translate(0,' + xAxisHeight + ')')
.call(xAxis)
.selectAll('text')
.attr('y', 15)
.attr('x', 0)
.attr('dy', '.35em');
svg.append('g')
.attr('class', 'y axis')
.call(yAxis);
Articles.get({startDate: start.format(), endDate: start.clone().add(scope.zoomLevels[scope.zoomLevel].value, scope.zoomLevels[scope.zoomLevel].unit).format(), limit: 20}, function(data){
var bar = svg.selectAll('.news')
.data(data.items)
.enter()
.append('g')
.attr('class', 'news')
.on('mouseover', function(d) {
console.log(d);
})
.on('mouseout', function(d) {
});
bar.append('rect')
.attr('width', 250)
.attr('height', 60)
.attr('x', function(d){return x($window.moment(d.date, 'YYYY-MM-DDTHH:mm:ss.000Z').format('x'));})
.attr('y', function(d){return y(2);})
bar.append('foreignObject')
.attr('width', 250)
.attr('height', 60)
.attr('x', function(d){return x($window.moment(d.date, 'YYYY-MM-DDTHH:mm:ss.000Z').format('x'));})
.attr('y', function(d){return y(2);})
.append('xhtml:p')
.attr("class","statement")
.text(function(d) { return d.title; });
});
scope.movePage = function(direction){
if(!(direction === 1 && scope.page === scope.maxPage) || !(direction === -1 && scope.page === 0)){
console.log('Paging allowed');
if(direction === 1){
start = start.add(scope.zoomLevels[scope.zoomLevel].value, scope.zoomLevels[scope.zoomLevel].unit);
x.domain([start.toDate(), start.clone().add(scope.zoomLevels[scope.zoomLevel].value, scope.zoomLevels[scope.zoomLevel].unit).toDate()]);
Articles.get({startDate: start.format(), endDate: start.clone().add(scope.zoomLevels[scope.zoomLevel].value, scope.zoomLevels[scope.zoomLevel].unit).format(), limit: 20}, function(data) {
console.log(data.items.length);
svg.selectAll('.news').data(data.items).transition().duration(1500).ease('sin-in-out');
svg.selectAll('g.axis.x').transition().duration(1500).ease('sin-in-out').call(xAxis);
});
scope.page++;
}
if(direction === -1){
start = start.subtract(scope.zoomLevels[scope.zoomLevel].value, scope.zoomLevels[scope.zoomLevel].unit);
x.domain([start.toDate(), start.clone().add(scope.zoomLevels[scope.zoomLevel].value, scope.zoomLevels[scope.zoomLevel].unit).toDate()]);
svg.selectAll('g.axis.x').transition().duration(1500).ease('sin-in-out').call(xAxis);
scope.page--;
}
}
};
scope.toggleZoom = function(direction){
if(!(direction === 1 && scope.zoomLevel === 6) || !(direction === -1 && scope.zoomLevel === 0)){
duration = $window.moment.duration(end.diff(start));
scope.zoomLevel = scope.zoomLevel + direction;
console.log(scope.zoomLevels[scope.zoomLevel].unit);
switch (scope.zoomLevels[scope.zoomLevel].unit){
case 'minutes':
scope.maxPage = duration.asMinutes()/scope.zoomLevels[scope.zoomLevel].value;
console.log(duration.asMinutes() + ' Minutes');
console.log((duration.asMinutes()/scope.zoomLevels[scope.zoomLevel].value) + ' Pages');
break;
case 'hours':
scope.maxPage = duration.asHours()/scope.zoomLevels[scope.zoomLevel].value;
console.log(duration.asHours() + ' Hours');
console.log((duration.asHours()/scope.zoomLevels[scope.zoomLevel].value) + ' Pages');
break;
case 'days':
scope.maxPage = duration.asDays()/scope.zoomLevels[scope.zoomLevel].value;
console.log(duration.asDays() + ' Days');
console.log((duration.asDays()/scope.zoomLevels[scope.zoomLevel].value) + ' Pages');
break;
}
x.domain([start.toDate(), start.clone().add(scope.zoomLevels[scope.zoomLevel].value, scope.zoomLevels[scope.zoomLevel].unit).toDate()]);
svg.selectAll('g.axis').transition().duration(1500).ease('sin-in-out').call(xAxis);
}
};
然而,动画并没有真正起作用。最终,如果用户点击下一页,我希望代表每个新闻项目的svg元素以与轴相同的速度向左移动。目前,当用户点击前进和后退按钮时,它们会立即显示/消失。
答案 0 :(得分:0)
if(!(direction === 1 && scope.page === scope.maxPage) || !(direction === -1 && scope.page === 0)){
if(direction === 1){ ... }
if(direction === -1){ .. }
这不容易解析,你确定在给定这些条件的情况下,任何一个内部代码块都可以执行吗?