1+ ( function ( $ ) {
2+
3+ // Class: $.jqplot.LinDifferentColorMarkerLineRenderereRenderer
4+ // Line renderer for jqPlot, this class has one
5+ // markerColors: []
6+ // Draws series as a line.
7+ $ . jqplot . DifferentColorMarkerLineRenderer = function ( options ) {
8+ this . markerColors = [ ] ;
9+ this . shapeRenderer = new $ . jqplot . ShapeRenderer ( ) ;
10+ this . shadowRenderer = new $ . jqplot . ShadowRenderer ( ) ;
11+ $ . extend ( true , this , options ) ;
12+ } ;
13+
14+ // called with scope of series.
15+ $ . jqplot . DifferentColorMarkerLineRenderer . prototype . init = function ( options ) {
16+ //$.extend(true, this, options);
17+ // set the shape renderer options
18+ this . markerColors = options . markerColors || this . markerColors ;
19+ var opts = {
20+ lineJoin :'round' ,
21+ lineCap :'round' ,
22+ fill :this . fill ,
23+ isarc :false ,
24+ strokeStyle :this . color ,
25+ fillStyle :this . fillColor ,
26+ lineWidth :this . lineWidth ,
27+ closePath :this . fill
28+
29+ } ;
30+ this . renderer . shapeRenderer . init ( opts ) ;
31+ // set the shadow renderer options
32+ // scale the shadowOffset to the width of the line.
33+ if ( this . lineWidth > 2.5 ) {
34+ var shadow_offset = this . shadowOffset * ( 1 + ( Math . atan ( ( this . lineWidth / 2.5 ) ) / 0.785398163 - 1 ) * 0.6 ) ;
35+ // var shadow_offset = this.shadowOffset;
36+ }
37+ // for skinny lines, don't make such a big shadow.
38+ else {
39+ var shadow_offset = this . shadowOffset * Math . atan ( ( this . lineWidth / 2.5 ) ) / 0.785398163 ;
40+ }
41+ var sopts = {
42+ lineJoin :'round' ,
43+ lineCap :'round' ,
44+ fill :this . fill ,
45+ isarc :false ,
46+ angle :this . shadowAngle ,
47+ offset :shadow_offset ,
48+ alpha :this . shadowAlpha ,
49+ depth :this . shadowDepth ,
50+ lineWidth :this . lineWidth ,
51+ closePath :this . fill
52+ } ;
53+ this . renderer . shadowRenderer . init ( sopts ) ;
54+ } ;
55+
56+ // Method: setGridData
57+ // converts the user data values to grid coordinates and stores them
58+ // in the gridData array.
59+ // Called with scope of a series.
60+ $ . jqplot . DifferentColorMarkerLineRenderer . prototype . setGridData = function ( plot ) {
61+ // recalculate the grid data
62+ var xp = this . _xaxis . series_u2p ;
63+ var yp = this . _yaxis . series_u2p ;
64+ var data = this . _plotData ;
65+ var pdata = this . _prevPlotData ;
66+ this . gridData = [ ] ;
67+ this . _prevGridData = [ ] ;
68+ for ( var i = 0 ; i < this . data . length ; i ++ ) {
69+ if ( data [ i ] != null ) {
70+ this . gridData . push ( [ xp . call ( this . _xaxis , data [ i ] [ 0 ] ) , yp . call ( this . _yaxis , data [ i ] [ 1 ] ) ] ) ;
71+ }
72+ if ( pdata [ i ] != null ) {
73+ this . _prevGridData . push ( [ xp . call ( this . _xaxis , pdata [ i ] [ 0 ] ) , yp . call ( this . _yaxis , pdata [ i ] [ 1 ] ) ] ) ;
74+ }
75+ }
76+ } ;
77+
78+ // Method: makeGridData
79+ // converts any arbitrary data values to grid coordinates and
80+ // returns them. This method exists so that plugins can use a series'
81+ // linerenderer to generate grid data points without overwriting the
82+ // grid data associated with that series.
83+ // Called with scope of a series.
84+ $ . jqplot . DifferentColorMarkerLineRenderer . prototype . makeGridData = function ( data , plot ) {
85+ // recalculate the grid data
86+ var xp = this . _xaxis . series_u2p ;
87+ var yp = this . _yaxis . series_u2p ;
88+ var gd = [ ] ;
89+ var pgd = [ ] ;
90+ for ( var i = 0 ; i < data . length ; i ++ ) {
91+ if ( data [ i ] != null ) {
92+ gd . push ( [ xp . call ( this . _xaxis , data [ i ] [ 0 ] ) , yp . call ( this . _yaxis , data [ i ] [ 1 ] ) ] ) ;
93+ }
94+ }
95+ return gd ;
96+ } ;
97+
98+
99+ // called within scope of series.
100+ $ . jqplot . DifferentColorMarkerLineRenderer . prototype . draw = function ( ctx , gd , options ) {
101+ var i ;
102+ var opts = ( options != undefined ) ? options : { } ;
103+ var shadow = ( opts . shadow != undefined ) ? opts . shadow : this . shadow ;
104+ var showLine = ( opts . showLine != undefined ) ? opts . showLine : this . showLine ;
105+ var fill = ( opts . fill != undefined ) ? opts . fill : this . fill ;
106+ var fillAndStroke = ( opts . fillAndStroke != undefined ) ? opts . fillAndStroke : this . fillAndStroke ;
107+ ctx . save ( ) ;
108+ if ( gd . length ) {
109+ if ( showLine ) {
110+ // if we fill, we'll have to add points to close the curve.
111+ if ( fill ) {
112+ if ( this . fillToZero ) {
113+ // have to break line up into shapes at axis crossings
114+ var negativeColors = new $ . jqplot . ColorGenerator ( this . negativeSeriesColors ) ;
115+ var negativeColor = negativeColors . get ( this . index ) ;
116+ if ( ! this . useNegativeColors ) {
117+ negativeColor = opts . fillStyle ;
118+ }
119+ var isnegative = false ;
120+ var posfs = opts . fillStyle ;
121+
122+ // if stoking line as well as filling, get a copy of line data.
123+ if ( fillAndStroke ) {
124+ var fasgd = gd . slice ( 0 ) ;
125+ }
126+ // if not stacked, fill down to axis
127+ if ( this . index == 0 || ! this . _stack ) {
128+
129+ var tempgd = [ ] ;
130+ var pyzero = this . _yaxis . series_u2p ( 0 ) ;
131+ var pxzero = this . _xaxis . series_u2p ( 0 ) ;
132+
133+ if ( this . fillAxis == 'y' ) {
134+ tempgd . push ( [ gd [ 0 ] [ 0 ] , pyzero ] ) ;
135+
136+ for ( var i = 0 ; i < gd . length - 1 ; i ++ ) {
137+ tempgd . push ( gd [ i ] ) ;
138+ // do we have an axis crossing?
139+ if ( this . _plotData [ i ] [ 1 ] * this . _plotData [ i + 1 ] [ 1 ] < 0 ) {
140+ if ( this . _plotData [ i ] [ 1 ] < 0 ) {
141+ isnegative = true ;
142+ opts . fillStyle = negativeColor ;
143+ }
144+ else {
145+ isnegative = false ;
146+ opts . fillStyle = posfs ;
147+ }
148+
149+ var xintercept = gd [ i ] [ 0 ] + ( gd [ i + 1 ] [ 0 ] - gd [ i ] [ 0 ] ) * ( pyzero - gd [ i ] [ 1 ] ) / ( gd [ i + 1 ] [ 1 ] - gd [ i ] [ 1 ] ) ;
150+ tempgd . push ( [ xintercept , pyzero ] ) ;
151+ // now draw this shape and shadow.
152+ if ( shadow ) {
153+ this . renderer . shadowRenderer . draw ( ctx , tempgd , opts ) ;
154+ }
155+ this . renderer . shapeRenderer . draw ( ctx , tempgd , opts ) ;
156+ // now empty temp array and continue
157+ tempgd = [ [ xintercept , pyzero ] ] ;
158+ }
159+ }
160+ if ( this . _plotData [ gd . length - 1 ] [ 1 ] < 0 ) {
161+ isnegative = true ;
162+ opts . fillStyle = negativeColor ;
163+ }
164+ else {
165+ isnegative = false ;
166+ opts . fillStyle = posfs ;
167+ }
168+ tempgd . push ( gd [ gd . length - 1 ] ) ;
169+ tempgd . push ( [ gd [ gd . length - 1 ] [ 0 ] , pyzero ] ) ;
170+ }
171+ // now draw this shape and shadow.
172+ if ( shadow ) {
173+ this . renderer . shadowRenderer . draw ( ctx , tempgd , opts ) ;
174+ }
175+ this . renderer . shapeRenderer . draw ( ctx , tempgd , opts ) ;
176+
177+
178+ // var gridymin = this._yaxis.series_u2p(0);
179+ // // IE doesn't return new length on unshift
180+ // gd.unshift([gd[0][0], gridymin]);
181+ // len = gd.length;
182+ // gd.push([gd[len - 1][0], gridymin]);
183+ }
184+ // if stacked, fill to line below
185+ else {
186+ var prev = this . _prevGridData ;
187+ for ( var i = prev . length ; i > 0 ; i -- ) {
188+ gd . push ( prev [ i - 1 ] ) ;
189+ }
190+ if ( shadow ) {
191+ this . renderer . shadowRenderer . draw ( ctx , gd , opts ) ;
192+ }
193+
194+ this . renderer . shapeRenderer . draw ( ctx , gd , opts ) ;
195+ }
196+ }
197+ else {
198+ // if stoking line as well as filling, get a copy of line data.
199+ if ( fillAndStroke ) {
200+ var fasgd = gd . slice ( 0 ) ;
201+ }
202+ // if not stacked, fill down to axis
203+ if ( this . index == 0 || ! this . _stack ) {
204+ // var gridymin = this._yaxis.series_u2p(this._yaxis.min) - this.gridBorderWidth / 2;
205+ var gridymin = ctx . canvas . height ;
206+ // IE doesn't return new length on unshift
207+ gd . unshift ( [ gd [ 0 ] [ 0 ] , gridymin ] ) ;
208+ len = gd . length ;
209+ gd . push ( [ gd [ len - 1 ] [ 0 ] , gridymin ] ) ;
210+ }
211+ // if stacked, fill to line below
212+ else {
213+ var prev = this . _prevGridData ;
214+ for ( var i = prev . length ; i > 0 ; i -- ) {
215+ gd . push ( prev [ i - 1 ] ) ;
216+ }
217+ }
218+ if ( shadow ) {
219+ this . renderer . shadowRenderer . draw ( ctx , gd , opts ) ;
220+ }
221+
222+ this . renderer . shapeRenderer . draw ( ctx , gd , opts ) ;
223+ }
224+ if ( fillAndStroke ) {
225+ var fasopts = $ . extend ( true , { } , opts , {
226+ fill :false ,
227+ closePath :false
228+ } ) ;
229+ this . renderer . shapeRenderer . draw ( ctx , fasgd , fasopts ) ;
230+ //////////
231+ // TODO: figure out some way to do shadows nicely
232+ // if (shadow) {
233+ // this.renderer.shadowRenderer.draw(ctx, fasgd, fasopts);
234+ // }
235+ // now draw the markers
236+ if ( this . markerRenderer . show ) {
237+ for ( i = 0 ; i < fasgd . length ; i ++ ) {
238+ this . markerRenderer . draw ( fasgd [ i ] [ 0 ] , fasgd [ i ] [ 1 ] , ctx , opts . markerOptions ) ;
239+ }
240+ }
241+ }
242+ }
243+ else {
244+ if ( shadow ) {
245+ this . renderer . shadowRenderer . draw ( ctx , gd , opts ) ;
246+ }
247+ this . renderer . shapeRenderer . draw ( ctx , gd , opts ) ;
248+ }
249+ }
250+
251+ // now draw the markers
252+ if ( this . markerRenderer . show && ! fill ) {
253+ for ( i = 0 ; i < gd . length ; i ++ ) {
254+ // Grab each color and send it to a new markerRenderer.
255+ opts . markerOptions = {
256+ color : this . markerColors [ i ] || this . color
257+ } ;
258+ this . markerRenderer = new $ . jqplot . MarkerRenderer ;
259+ this . markerRenderer . init ( opts . markerOptions ) ;
260+ this . markerRenderer . draw ( gd [ i ] [ 0 ] , gd [ i ] [ 1 ] , ctx , opts . markerOptions ) ;
261+ }
262+ }
263+ }
264+
265+ ctx . restore ( ) ;
266+ } ;
267+
268+ $ . jqplot . DifferentColorMarkerLineRenderer . prototype . drawShadow = function ( ctx , gd , options ) {
269+ // This is a no-op, shadows drawn with lines.
270+ } ;
271+
272+ } ) ( jQuery ) ;
0 commit comments