Graph works fine for first set of data. Plotting and zooming is good. When we change the data set, the graph will be re-plotted correctly. But on zooming, the scales still remain the same(so high), that the plotted line will turn out to be really small.
I guess it's the problem with setting the domain and range.
Also the init graph method is called only once - which is responsible for the domain and range update.
Below is my code,
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' );
}
}
} );
Aucun commentaire:
Enregistrer un commentaire