Javascript D3图形在缩放动态数据时不更新范围和域
对于第一组数据,Graph运行良好。绘图和缩放效果很好。 当我们更改数据集时,图形将正确地重新绘制。但在缩放时,比例仍然保持不变(如此之高),以至于绘制的线将变得非常小 我想这是设置域和范围的问题 此外,init-graph方法只被调用一次,它负责域和范围的更新 下面是我的代码Javascript D3图形在缩放动态数据时不更新范围和域,javascript,ember.js,d3.js,Javascript,Ember.js,D3.js,对于第一组数据,Graph运行良好。绘图和缩放效果很好。 当我们更改数据集时,图形将正确地重新绘制。但在缩放时,比例仍然保持不变(如此之高),以至于绘制的线将变得非常小 我想这是设置域和范围的问题 此外,init-graph方法只被调用一次,它负责域和范围的更新 下面是我的代码 App.ReportsGraphView = Ember.View.extend( { //... global Variables... didInsertElement: function () {
App.ReportsGraphView = Ember.View.extend( {
//... global Variables...
didInsertElement: function () {
this.initGraph();
},
initGraph: function () {
var self = this,
title = this.get( 'title' ),
element = this.$().get( 0 ),
graph = {
margin: {
top: 40,
right: 80,
bottom: 50,
left: 50
},
bisectDate: d3.bisector( function ( d ) {
return d[ self.get( 'xField' ) ];
} ).left
};
graph.width = this.$().width() - graph.margin.left - graph.margin.right;
graph.height = 400 - graph.margin.top - graph.margin.bottom;
graph.x = d3.time.scale()
.domain(d3.extent(self.get( 'dataSource' ), function(d) { return d[ self.get( 'xField' ) ]; }))
.range( [0, graph.width] );
graph.y = d3.scale.linear()
.domain(d3.extent(self.get( 'dataSource' ), function(d) { return d[ self.get( 'yField' ) ]; }))
.range( [graph.height, 0] );
graph.xAxis = d3.svg.axis()
.scale( graph.x )
.tickSize(-graph.height, 0)
.tickPadding(10)
.tickSubdivide(true)
.orient( 'bottom' );
graph.yAxis = d3.svg.axis()
.scale( graph.y )
.ticks( 4 )
.tickSize( -graph.width )
.tickPadding(10)
.tickSubdivide(true)
.orient( 'left' );
graph.line = d3.svg.line()
.interpolate("linear")
.x( function ( d ) {
return graph.x( d[ self.get( 'xField' ) ] );
} )
.y( function ( d ) {
return graph.y( d[ self.get( 'yField' ) ] );
} );
var zoom = d3.behavior.zoom()
.x(graph.x)
.y(graph.y)
.on("zoom", zoomed);
var self = this;
function zoomed() {
//debugger;
graph.node.select("g.x.axis").transition().call(graph.xAxis);
graph.node.select("g.y.axis").transition().call(graph.yAxis);
graph.node.select('path.line')
.attr("d", graph.line(self.get( 'dataSource' )))
.attr("clip-path", "url(#clip)");
}
graph.node = d3.select( element ).append( 'svg' )
.attr( 'width', graph.width + graph.margin.left + graph.margin.right )
.attr( 'height', graph.height + graph.margin.top + graph.margin.bottom )
.append( 'g' )
.attr( 'transform', 'translate(' + graph.margin.left + ',' + graph.margin.top + ')' )
.classed( 'empty', true )
.call(zoom);
graph.node.append( 'g' )
.attr( 'class', 'x axis' )
.attr( 'transform', 'translate(0,' + graph.height + ')' )
.call( graph.xAxis );
graph.node.append( 'g' )
.attr( 'class', 'y axis' )
.call( graph.yAxis );
graph.title = graph.node.append( 'text' )
.attr( 'class', 'graph-title' )
.attr( 'x', graph.width / 2 )
.attr( 'y', graph.height + 40 )
.style( 'text-anchor', 'middle' )
.text( title );
graph.focus = graph.node.append( 'g' )
.attr( 'class', 'focus' )
.style( 'display', 'none' );
graph.overlay = graph.node.append( "rect" )
.attr( 'class', 'overlay' )
.attr( 'width', graph.width )
.attr( 'height', graph.height )
.style( 'display', 'none' )
.on( 'mouseover', function () {
graph.focus.style( 'display', null );
} )
.on( 'mouseout', function () {
var node = graph.overlay.node(),
pos = d3.mouse( node ),
nodeSize = node.getBBox();
if ( pos[0] < 0 || pos[0] > nodeSize.width || pos[1] < 0 || pos[1] > nodeSize.height ) {
graph.focus.style( 'display', 'none' );
}
} )
.on( 'mousemove', function () {
var x0 = graph.x.invert( d3.mouse( this )[ 0 ] ),
i = graph.bisectDate( graph.data, x0, 1 ),
d0 = graph.data[ i - 1 ],
d1 = graph.data[ i ],
xField = self.get( 'xField' ),
yField = self.get( 'yField' );
if(d0 && d1){
var d = x0 - d0[ xField ] > d1[ xField ] - x0 ? d1 : d0;
graph.focus.attr( 'transform', 'translate(' + graph.x( d[ xField ] ) + ',' + graph.y( d[ yField ] ) + ')' );
}
} );
this.set( '_graph', graph );
this.drawGraph( this.get( 'dataSource' ) );
},
drawGraph: function ( data ) {
var graph = this.get( '_graph' ),
xField = this.get( 'xField' ),
yField = this.get( 'yField' ),
title = this.get( 'title' );
if ( !this.get( 'canDrawGraph' ) ) {
graph.node
.classed( 'empty', true )
.select( '.line' )
.remove();
graph.overlay.style( 'display', 'none' );
this.drawEmptyAxes();
}
else {
graph.node.classed( 'empty', false );
if (this.get( 'from' ) && this.get( 'to' )) {
graph.x.domain([this.get( 'from' ), this.get( 'to' )]);
}
else {
graph.x.domain( d3.extent( data, function ( d ) {
return d[ xField ];
} ) );
}
graph.y.domain( [ 0, d3.max( data, function ( d ) {
return d[ yField ];
} ) ] );
graph.node.select( '.x.axis' )
.call( graph.xAxis );
graph.node.select( '.y.axis' )
.call( graph.yAxis );
var line = graph.node.select( '.line' );
if ( line.empty() ) {
line = graph.node.append( 'path' )
.attr( 'class', 'line' )
.attr( 'color', '#000' );
}
line.attr( 'd', graph.line( data ) );
graph.overlay.style( 'display', null );
}
graph.data = data;
this.set( '_graph', graph );
},
drawEmptyAxes: function() {
var graph = this.get( '_graph' );
graph.x.domain( [ moment().toDate(), moment().subtract( 'days', 1 ).toDate() ] );
graph.y.domain( [0, 1] );
graph.node.select( '.x.axis' )
.call( graph.xAxis );
graph.node.select( '.y.axis' )
.call( graph.yAxis );
this.set( '_graph', graph );
},
canDrawGraph: function () {
return !Ember.isEmpty( this.get( 'dataSource' ) ) && !Ember.isEmpty( this.get( 'xField' ) ) && !Ember.isEmpty( this.get( 'yField' ) );
}.property( 'xField', 'yField', 'dataSource' ),
didDataSourceChanged: function () {
this.drawGraph( this.get( 'dataSource' ) );
}.observes( 'dataSource' ),
didAxesChanged: function () {
this.drawGraph( this.get( 'dataSource' ) );
}.observes( 'xField', 'yField' ),
didTitleChanged: function () {
var graph = this.get( '_graph' );
var title = this.get( 'title' );
var yField = this.get( 'yField' );
var xField = this.get( 'xField' );
graph.title.text( title );
}.observes( 'title' ),
actions: {
onChoice: function ( checked ) {
this.toggleProperty( 'isHidden' );
}
}
} );
App.ReportsGraphView=Ember.View.extend({
//…全局变量。。。
didInsertElement:函数(){
this.initGraph();
},
initGraph:函数(){
var self=这个,
title=this.get('title'),
元素=此。$().get(0),
图={
保证金:{
前40名,
右:80,,
底数:50,
左:50
},
等分日期:d3.等分线(函数(d){
返回d[self.get('xField');
})。左
};
graph.width=this.$().width()-graph.margin.left-graph.margin.right;
graph.height=400-graph.margin.top-graph.margin.bottom;
graph.x=d3.time.scale()
.domain(d3.extent(self.get('dataSource'),函数(d){返回d[self.get('xField')];}))
.范围([0,图形宽度]);
graph.y=d3.scale.linear()
.domain(d3.extent(self.get('dataSource'),函数(d){返回d[self.get('yField')];}))
.范围([图形高度,0]);
graph.xAxis=d3.svg.axis()
.比例(图x)
.tickSize(-图形高度,0)
.1(10)
.tickSubdivide(真)
.定向(‘底部’);
graph.yAxis=d3.svg.axis()
.比例(图y)
.滴答声(4)
.tickSize(-图形宽度)
.1(10)
.tickSubdivide(真)
.东方(‘左’);
graph.line=d3.svg.line()
.插入(“线性”)
.x(功能(d){
返回图.x(d[self.get('xField'));
} )
.y(功能(d){
返回图y(d[self.get('yField'));
} );
var zoom=d3.behavior.zoom()
.x(图x)
.y(图.y)
。打开(“缩放”,缩放);
var self=这个;
函数缩放(){
//调试器;
graph.node.select(“g.x.axis”).transition().call(graph.xAxis);
graph.node.select(“g.y.axis”).transition().call(graph.yAxis);
graph.node.select('path.line')
.attr(“d”,graph.line(self.get('dataSource'))
.attr(“剪辑路径”、“url(#剪辑)”);
}
graph.node=d3.select(element).append('svg')
.attr('width',graph.width+graph.margin.left+graph.margin.right)
.attr('height',graph.height+graph.margin.top+graph.margin.bottom)
.append('g')
.attr('transform','translate('+graph.margin.left+','+graph.margin.top+'))
.classed('empty',true)
.呼叫(缩放);
graph.node.append('g')
.attr('class','x轴')
.attr('transform','translate(0',+graph.height+'))
.call(graph.xAxis);
graph.node.append('g')
.attr('class','y轴')
.call(graph.yAxis);
graph.title=graph.node.append('text')
.attr('class','graph title')
.attr('x',graph.width/2)
.attr('y',图形高度+40)
.style('文本定位','中间')
.文本(标题);
graph.focus=graph.node.append('g')
.attr('class','focus')
.style('display','none');
graph.overlay=graph.node.append(“rect”)
.attr('class','overlay')
.attr('width',graph.width)
.attr('height',graph.height)
.style('display','none')
.on('mouseover',函数(){
graph.focus.style('display',null);
} )
.on('mouseout',函数(){
var node=graph.overlay.node(),
位置=d3.鼠标(节点),
nodeSize=node.getBBox();
如果(位置[0]<0 | |位置[0]>节点尺寸.宽度| |位置[1]<0 | |位置[1]>节点尺寸.高度){
graph.focus.style('display','none');
}
} )
.on('mousemove',函数(){
var x0=graph.x.invert(d3.mouse(this)[0]),
i=图二等分日期(图数据,x0,1),
d0=图形数据[i-1],
d1=图表数据[i],
xField=self.get('xField'),
yField=self.get('yField');
如果(d0和d1){
变量d=x0-d0[xField]>d1[xField]-x0?d1:d0;
graph.focus.attr('transform','translate('+graph.x(d[xField])+','+graph.y(d[yField])+');
}
} );
这个.set(“_-graph”,graph);
this.drawGraph(this.get('dataSource'));
},
绘图图:函数(数据){
var-graph=this.get(“\u-graph”),
xField=this.get('xField'),
yField=this.get('yField'),
title=this.get('title');
如果(!this.get('canDrawGraph')){
graph.node
.classed('empty',true)
.选择(“.line”)
.remove();
graph.overlay.style('display','none');
这个.dramptyaxes();
}
否则{
graph.node.classed('empty',false);
if(this.get('from')&&this.get('to')){
graph.x.domain([this.get('from')、this.get('to')]);
}
否则{
图x.域(d3.范围(数据、函数(d)){
返回d[xField];
} ) );
}
图y.domain([0,d3.max(数据,函数(d)){
返回d[yField];
} ) ] );
graph.node.select('.x.axis'))
.call(graph.xAxis);
graph.node.select(“.y.axis”)
.call(graph.yAxis);
var line=graph.node.select('.line');
if(line.empty()){
line=graph.node.append('path')
.attr('class','line')
.attr('color','#000');
}
line.attr('d',graph.line(数据));
graph.overlay.style('display',null);
}
graph.data=数据;
这个.set(“_-graph”,graph);
},
paumptyaxes:function(){
var-graph=this.get('u-graph');
graph.x.domain([moment().toDate(),moment().subtract('days',1.toDate()]);
图y.域([0,1]);
graph.node.select('.x.axis'))
.call(graph.xAxis);
graph.node.select(“.y.axis”)
.call(graph.yAxis);
这个.set(“_-graph”,graph);
},
canDrawGraph:函数()