@@ -46,6 +46,9 @@ public LinearBarSeries()
4646 this . TrackerFormatString = XYAxisSeries . DefaultTrackerFormatString ;
4747 this . NegativeFillColor = OxyColors . Undefined ;
4848 this . NegativeStrokeColor = OxyColors . Undefined ;
49+ this . BaseValue = 0 ;
50+ this . BaseLine = double . NaN ;
51+ this . ActualBaseLine = double . NaN ;
4952 }
5053
5154 /// <summary>
@@ -97,10 +100,22 @@ public OxyColor ActualColor
97100 }
98101
99102 /// <summary>
100- /// Gets or sets the base line. This value is used for plotting to determine
101- /// the start of the plot. A suitable value is selected automatically if it is NaN.
103+ /// Gets or sets the base value. Default value is 0.
102104 /// </summary>
103- public double BaseLine { get ; set ; } = double . NaN ;
105+ /// <value>The base value.</value>
106+ public double BaseValue { get ; set ; }
107+
108+ /// <summary>
109+ /// Gets or sets the base value.
110+ /// </summary>
111+ /// <value>The base value.</value>
112+ public double BaseLine { get ; set ; }
113+
114+ /// <summary>
115+ /// Gets or sets the actual base line.
116+ /// </summary>
117+ /// <returns>The actual base line.</returns>
118+ public double ActualBaseLine { get ; protected set ; }
104119
105120 /// <summary>
106121 /// Gets the nearest point.
@@ -162,7 +177,6 @@ public override void Render(IRenderContext rc)
162177 }
163178
164179 this . VerifyAxes ( ) ;
165-
166180 this . RenderBars ( rc , actualPoints ) ;
167181 }
168182
@@ -204,27 +218,31 @@ protected internal override void UpdateAxisMaxMin()
204218 {
205219 base . UpdateAxisMaxMin ( ) ;
206220
207- this . YAxis . Include ( this . GetBaseLineOrAutomaticValue ( this . YAxis ) ) ;
221+ this . ComputeActualBaseLine ( ) ;
222+ this . YAxis . Include ( this . ActualBaseLine ) ;
208223 }
209224
210225 /// <summary>
211- /// Gets the base line value. If the value of the property is NaN, a sensible value is returned .
226+ /// Computes the actual base value..
212227 /// </summary>
213- /// <param name="axis">The axis for which to return a sensible value for.</param>
214- /// <returns>The base line property or a sensible default.</returns>
215- protected double GetBaseLineOrAutomaticValue ( Axis axis )
228+ protected void ComputeActualBaseLine ( )
216229 {
217230 if ( double . IsNaN ( this . BaseLine ) )
218231 {
219- if ( axis . IsLogarithmic ( ) )
232+ if ( this . YAxis . IsLogarithmic ( ) )
233+ {
234+ var lowestPositiveY = this . ActualPoints == null ? 1 : this . ActualPoints . Select ( p => p . Y ) . Where ( y => y > 0 ) . MinOrDefault ( 1 ) ;
235+ this . ActualBaseLine = Math . Max ( lowestPositiveY / 10.0 , this . BaseValue ) ;
236+ }
237+ else
220238 {
221- var lowestPostiveY = this . ActualPoints == null ? 1 : this . ActualPoints . Select ( p => p . Y ) . Where ( y => y > 0 ) . Min ( ) ;
222- return Math . Sqrt ( lowestPostiveY ) ;
239+ this . ActualBaseLine = 0 ;
223240 }
224- return 0 ;
225241 }
226-
227- return this . BaseLine ;
242+ else
243+ {
244+ this . ActualBaseLine = this . BaseLine ;
245+ }
228246 }
229247
230248 /// <summary>
@@ -282,6 +300,8 @@ private int FindRectangleIndex(ScreenPoint point)
282300 /// <param name="actualPoints">The list of points that should be rendered.</param>
283301 private void RenderBars ( IRenderContext rc , List < DataPoint > actualPoints )
284302 {
303+ bool clampBase = this . YAxis . IsLogarithmic ( ) && ! this . YAxis . IsValidValue ( this . BaseValue ) ;
304+
285305 var widthOffset = this . GetBarWidth ( actualPoints ) / 2 ;
286306 var widthVector = this . Orientate ( new ScreenVector ( widthOffset , 0 ) ) ;
287307
@@ -294,7 +314,7 @@ private void RenderBars(IRenderContext rc, List<DataPoint> actualPoints)
294314 }
295315
296316 var screenPoint = this . Transform ( actualPoint ) - widthVector ;
297- var basePoint = this . Transform ( new DataPoint ( actualPoint . X , this . GetBasePointY ( ) ) ) + widthVector ;
317+ var basePoint = this . Transform ( new DataPoint ( actualPoint . X , clampBase ? this . YAxis . ClipMinimum : this . BaseValue ) ) + widthVector ;
298318 var rectangle = new OxyRect ( basePoint , screenPoint ) ;
299319 this . rectangles . Add ( rectangle ) ;
300320 this . rectanglesPointIndexes . Add ( pointIndex ) ;
@@ -310,13 +330,6 @@ private void RenderBars(IRenderContext rc, List<DataPoint> actualPoints)
310330 }
311331 }
312332
313- private double GetBasePointY ( )
314- {
315- if ( this . YAxis . IsLogarithmic ( ) )
316- return LogarithmicAxis . LowestValidRoundtripValue ;
317- return 0 ;
318- }
319-
320333 /// <summary>
321334 /// Computes the bars width.
322335 /// </summary>
@@ -344,7 +357,7 @@ private double GetBarWidth(List<DataPoint> actualPoints)
344357 /// <returns>The bar colors</returns>
345358 private BarColors GetBarColors ( double y )
346359 {
347- var positive = y >= 0.0 ;
360+ var positive = y >= this . BaseValue ;
348361 var fillColor = ( positive || this . NegativeFillColor . IsUndefined ( ) ) ? this . GetSelectableFillColor ( this . ActualColor ) : this . NegativeFillColor ;
349362 var strokeColor = ( positive || this . NegativeStrokeColor . IsUndefined ( ) ) ? this . StrokeColor : this . NegativeStrokeColor ;
350363
0 commit comments