123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898 |
- // Licensed to the .NET Foundation under one or more agreements.
- // The .NET Foundation licenses this file to you under the MIT license.
- // See the LICENSE file in the project root for more information.
- //
- // Purpose: Base class for the Axis class which defines axis
- // labels related properties and methods.
- //
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Drawing.Design;
- using FastReport.DataVisualization.Charting.ChartTypes;
- using FastReport.DataVisualization.Charting.Utilities;
- namespace FastReport.DataVisualization.Charting
- {
- /// <summary>
- /// The Axis class provides functionality for
- /// drawing axis labels.
- /// </summary>
- public partial class Axis
- {
- #region Fields
- // Custom Labels collection
- private CustomLabelsCollection _customLabels = null;
- #endregion
- #region Axis labels properties
- /// <summary>
- /// Gets or sets the style of the label.
- /// </summary>
- [
- SRCategory("CategoryAttributeLabels"),
- Bindable(true),
- NotifyParentPropertyAttribute(true),
- SRDescription("DescriptionAttributeLabelStyle"),
- DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
- TypeConverter(typeof(NoNameExpandableObjectConverter))
- ]
- public LabelStyle LabelStyle
- {
- get
- {
- return labelStyle;
- }
- set
- {
- labelStyle = value;
- labelStyle.Axis = (Axis)this;
- this.Invalidate();
- }
- }
- /// <summary>
- /// Gets a collection of custom labels.
- /// </summary>
- [
- SRCategory("CategoryAttributeLabels"),
- Bindable(true),
- SRDescription("DescriptionAttributeCustomLabels"),
- DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
- #if DESIGNER
- Editor(typeof(ChartCollectionEditor), typeof(UITypeEditor))
- #endif
- ]
- public CustomLabelsCollection CustomLabels
- {
- get
- {
- return _customLabels;
- }
- }
- #endregion
- #region Axis labels methods
- /// <summary>
- /// Indicates that custom grid lines should be painted.
- /// </summary>
- /// <returns>Indicates that custom grid lines should be painted.</returns>
- internal bool IsCustomGridLines()
- {
- if(this.CustomLabels.Count > 0)
- {
- // Check if at least one custom label has a flag set
- foreach(CustomLabel label in this.CustomLabels)
- {
- if((label.GridTicks & GridTickTypes.Gridline) == GridTickTypes.Gridline)
- {
- return true;
- }
- }
- }
- return false;
- }
- /// <summary>
- /// Indicates that custom tick marks should be painted.
- /// </summary>
- /// <returns>Indicates that custom tick marks should be painted.</returns>
- internal bool IsCustomTickMarks()
- {
- if(this.CustomLabels.Count > 0)
- {
- // Check if at least one custom label has a flag set
- foreach(CustomLabel label in this.CustomLabels)
- {
- if((label.GridTicks & GridTickTypes.TickMark) == GridTickTypes.TickMark)
- {
- return true;
- }
- }
- }
- return false;
- }
- /// <summary>
- /// Gets the type of the axis.
- /// </summary>
- /// <value>The type of the axis.</value>
- internal AxisType GetAxisType()
- {
- if (this.axisType == AxisName.X || this.axisType == AxisName.Y)
- {
- return AxisType.Primary;
- }
- else
- {
- return AxisType.Secondary;
- }
- }
- /// <summary>
- /// Gets the axis series.
- /// </summary>
- /// <returns></returns>
- internal ArrayList GetAxisSeries()
- {
- ArrayList dataSeries = new ArrayList();
- // check for attached series.
- foreach (string seriesName in this.ChartArea.Series)
- {
- Series series = this.Common.DataManager.Series[seriesName];
- if (this.axisType == AxisName.X || this.axisType == AxisName.X2)
- {
- if (series.XAxisType == this.GetAxisType())
- {
- dataSeries.Add(series);
- }
- }
- else
- {
- if (series.YAxisType == this.GetAxisType())
- {
- dataSeries.Add(series);
- }
- }
- }
- return dataSeries;
- }
- /// <summary>
- /// Gets the other (primary/secondary) axis.
- /// </summary>
- /// <returns></returns>
- internal Axis GetOtherTypeAxis()
- {
- return ChartArea.GetAxis(
- this.axisType,
- this.GetAxisType() == AxisType.Primary ? AxisType.Secondary : AxisType.Primary,
- String.Empty
- );
- }
- /// <summary>
- /// Checks if the other (primary/secondary) axis has custom labels labels.
- /// These labels will be added if this axis has no series attached and no custom labels.
- /// This works only on category axes.
- /// </summary>
- internal void PostFillLabels()
- {
- foreach (CustomLabel label in this.CustomLabels)
- {
- if (label.customLabel)
- {
- return;
- }
- }
- // Labels are disabled for this axis
- if (
- !this.LabelStyle.Enabled ||
- !this.enabled ||
- !String.IsNullOrEmpty(((Axis)this).SubAxisName) ||
- this.axisType == AxisName.Y ||
- this.axisType == AxisName.Y2
- )
- {
- return;
- }
-
- // check if no series attached.
- if (this.GetAxisSeries().Count > 0)
- {
- return;
- }
- this.CustomLabels.Clear();
- foreach (CustomLabel label in this.GetOtherTypeAxis().CustomLabels)
- {
- this.CustomLabels.Add(label.Clone());
- }
- }
- /// <summary>
- /// Fill labels from data from data manager or
- /// from axis scale.
- /// </summary>
- /// <param name="removeFirstRow">True if first row of auto generated labels must be removed.</param>
- internal void FillLabels(bool removeFirstRow)
- {
- #if SUBAXES
- // Process all sub-axis
- foreach(SubAxis subAxis in ((Axis)this).SubAxes)
- {
- subAxis.FillLabels(true);
- }
- #endif // SUBAXES
- // Labels are disabled for this axis
- if( !this.LabelStyle.Enabled || !this.enabled )
- {
- return;
- }
- // For circular chart area fill only Y axis labels
- if(this.ChartArea != null && this.ChartArea.chartAreaIsCurcular)
- {
- if(this.axisType != AxisName.Y)
- {
- ICircularChartType type = this.ChartArea.GetCircularChartType();
- if(type == null || !type.XAxisLabelsSupported())
- {
- return;
- }
- }
- }
- // Check if the custom labels exist
- bool customLabelsFlag = false;
- foreach( CustomLabel lab in CustomLabels )
- {
- if( lab.customLabel )
- {
- if( lab.RowIndex == 0 ||
- this.ChartArea.chartAreaIsCurcular)
- {
- customLabelsFlag = true;
- }
- }
- }
- // Remove the first row of labels if custom labels not exist
- if(removeFirstRow)
- {
- if( customLabelsFlag == false )
- {
- for( int index = 0; index < CustomLabels.Count; index++ )
- {
- if( CustomLabels[index].RowIndex == 0 )
- {
- CustomLabels.RemoveAt( index );
- index = -1;
- }
- }
- }
- else
- {
- return;
- }
- }
- // Get data series for this axis.
- List<string> dataSeries = null;
- switch( axisType )
- {
- case AxisName.X:
- dataSeries = ChartArea.GetXAxesSeries( AxisType.Primary, ((Axis)this).SubAxisName );
- break;
- case AxisName.Y:
- dataSeries = ChartArea.GetYAxesSeries( AxisType.Primary, ((Axis)this).SubAxisName );
- break;
- case AxisName.X2:
- dataSeries = ChartArea.GetXAxesSeries( AxisType.Secondary, ((Axis)this).SubAxisName );
- break;
- case AxisName.Y2:
- dataSeries = ChartArea.GetYAxesSeries( AxisType.Secondary, ((Axis)this).SubAxisName );
- break;
- }
- // There aren't data series connected with this axis.
- if( dataSeries.Count == 0 )
- {
- return;
- }
- //Let's convert the ArrayList of the series names into to string[]
- string[] dataSeriesNames = new string[dataSeries.Count];
- for (int i = 0; i < dataSeries.Count; i++)
- dataSeriesNames[i] = (string)dataSeries[i];
- // Check if series X values all set to zeros
- bool seriesXValuesZeros = ChartHelper.SeriesXValuesZeros(this.Common, dataSeriesNames);
- // Check if series is indexed (All X values zeros or IsXValueIndexed flag set)
- bool indexedSeries = true;
- if (!seriesXValuesZeros)
- {
- indexedSeries = ChartHelper.IndexedSeries(this.Common, dataSeriesNames);
- }
- // Show End Labels
- int endLabels = 0;
- if( labelStyle.IsEndLabelVisible )
- {
- endLabels = 1;
- }
- // Get chart type of the first series
- IChartType chartType = Common.ChartTypeRegistry.GetChartType( ChartArea.GetFirstSeries().ChartTypeName );
- bool fromSeries = false;
- if( !chartType.RequireAxes )
- {
- return;
- }
- else if( axisType == AxisName.Y || axisType == AxisName.Y2 )
- {
- fromSeries = false;
- }
- else
- {
- fromSeries = true;
- }
- // X values from data points are not 0.
- if (fromSeries && !ChartHelper.SeriesXValuesZeros(this.Common, dataSeries.ToArray()))
- {
- fromSeries = false;
- }
- // X values from data points are not 0.
- if( fromSeries && ( labelStyle.GetIntervalOffset() != 0 || labelStyle.GetInterval() != 0 ) )
- {
- fromSeries = false;
- }
- // Get value type
- ChartValueType valueType;
- if( axisType == AxisName.X || axisType == AxisName.X2 )
- {
- // If X value is indexed the type is always String. So we use indexed type instead
- valueType = Common.DataManager.Series[dataSeries[0]].indexedXValueType;
- }
- else
- {
- valueType = Common.DataManager.Series[dataSeries[0]].YValueType;
- }
- if( labelStyle.GetIntervalType() != DateTimeIntervalType.Auto &&
- labelStyle.GetIntervalType() != DateTimeIntervalType.Number )
- {
- if (valueType != ChartValueType.Time &&
- valueType != ChartValueType.Date &&
- valueType != ChartValueType.DateTimeOffset)
- {
- valueType = ChartValueType.DateTime;
- }
- }
- // ***********************************
- // Pre calculate some values
- // ***********************************
- double viewMaximum = this.ViewMaximum;
- double viewMinimum = this.ViewMinimum;
- // ***********************************
- // Labels are filled from data series.
- // ***********************************
- if( fromSeries )
- {
- int numOfPoints;
- numOfPoints = Common.DataManager.GetNumberOfPoints( dataSeries.ToArray() );
- // Show end labels
- if( endLabels == 1 )
- {
- // min position
- CustomLabels.Add( - 0.5, 0.5, ValueConverter.FormatValue(
- this.Common.Chart,
- this,
- null,
- 0.0,
- this.LabelStyle.Format,
- valueType,
- ChartElementType.AxisLabels),
- false);
- }
- // Labels from point position
- for( int point = 0; point < numOfPoints; point++ )
- {
- CustomLabels.Add( ((double)point)+ 0.5, ((double)point)+ 1.5,
- ValueConverter.FormatValue(
- this.Common.Chart,
- this,
- null,
- point + 1,
- this.LabelStyle.Format,
- valueType,
- ChartElementType.AxisLabels),
- false);
- }
- // Show end labels
- if( endLabels == 1 )
- {
- // max position
- CustomLabels.Add( ((double)numOfPoints)+ 0.5, ((double)numOfPoints)+ 1.5,
- ValueConverter.FormatValue(
- this.Common.Chart,
- this,
- null,
- numOfPoints + 1,
- this.LabelStyle.Format,
- valueType,
- ChartElementType.AxisLabels),
- false);
- }
- int pointIndx;
- foreach( string seriesIndx in dataSeries )
- {
- // End labels enabled
- if( endLabels == 1 )
- pointIndx = 1;
- else
- pointIndx = 0;
- // Set labels from data points labels
- foreach( DataPoint dataPoint in Common.DataManager.Series[ seriesIndx ].Points )
- {
- // Find first row of labels
- while( CustomLabels[pointIndx].RowIndex > 0 )
- {
- pointIndx++;
- }
- // Add X labels
- if( axisType == AxisName.X || axisType == AxisName.X2 )
- {
- if( dataPoint.AxisLabel.Length > 0 )
- {
- CustomLabels[pointIndx].Text = dataPoint.AxisLabel;
- }
- }
-
- pointIndx++;
- }
- }
- }
- // ***********************************
- // Labels are filled from axis scale.
- // ***********************************
- else
- {
- if( viewMinimum == viewMaximum )
- return;
- double labValue; // Value, which will be converted to text and used for, labels.
- double beginPosition; // Begin position for a label
- double endPosition; // End position for a label
- double start; // Start position for all labels
- // Get first series attached to this axis
- Series axisSeries = null;
- if(axisType == AxisName.X || axisType == AxisName.X2)
- {
- List<string> seriesArray = ChartArea.GetXAxesSeries((axisType == AxisName.X) ? AxisType.Primary : AxisType.Secondary, ((Axis)this).SubAxisName);
- if(seriesArray.Count > 0)
- {
- axisSeries = Common.DataManager.Series[seriesArray[0]];
- if(axisSeries != null && !axisSeries.IsXValueIndexed)
- {
- axisSeries = null;
- }
- }
- }
- // ***********************************
- // Check if the AJAX zooming and scrolling mode is enabled.
- // Labels are filled slightly different in this case.
- // ***********************************
- DateTimeIntervalType offsetType = (labelStyle.GetIntervalOffsetType() == DateTimeIntervalType.Auto) ? labelStyle.GetIntervalType() : labelStyle.GetIntervalOffsetType();
- // By default start is equal to minimum
- start = viewMinimum;
- // Adjust start position depending on the interval type
- if(!this.ChartArea.chartAreaIsCurcular ||
- this.axisType == AxisName.Y ||
- this.axisType == AxisName.Y2 )
- {
- start = ChartHelper.AlignIntervalStart(start, labelStyle.GetInterval(), labelStyle.GetIntervalType(), axisSeries);
- }
-
- // Move start if there is start position
- if( labelStyle.GetIntervalOffset() != 0 && axisSeries == null)
- {
- start += ChartHelper.GetIntervalSize(start, labelStyle.GetIntervalOffset(),
- offsetType, axisSeries, 0, DateTimeIntervalType.Number, true, false);
- }
- // ***************************************
- // Date type
- // ***************************************
- if( valueType == ChartValueType.DateTime ||
- valueType == ChartValueType.Date ||
- valueType == ChartValueType.Time ||
- valueType == ChartValueType.DateTimeOffset ||
- axisSeries != null)
- {
- double position = start;
- double dateInterval;
- // Too many labels
- if ((viewMaximum - start) / ChartHelper.GetIntervalSize(start, labelStyle.GetInterval(), labelStyle.GetIntervalType(), axisSeries, 0, DateTimeIntervalType.Number, true) > ChartHelper.MaxNumOfGridlines)
- return;
- int counter = 0;
- double endLabelMaxPosition = viewMaximum - ChartHelper.GetIntervalSize(viewMaximum, labelStyle.GetInterval(), labelStyle.GetIntervalType(), axisSeries, labelStyle.GetIntervalOffset(), offsetType, true) / 2f;
- double endLabelMinPosition = viewMinimum + ChartHelper.GetIntervalSize(viewMinimum, labelStyle.GetInterval(), labelStyle.GetIntervalType(), axisSeries, labelStyle.GetIntervalOffset(), offsetType, true) / 2f;
- while( (decimal)position <= (decimal)viewMaximum )
- {
- dateInterval = ChartHelper.GetIntervalSize(position, labelStyle.GetInterval(), labelStyle.GetIntervalType(), axisSeries, labelStyle.GetIntervalOffset(), offsetType, true);
- labValue = position;
- // For IsLogarithmic axes
- if( this.IsLogarithmic )
- {
- labValue = Math.Pow( this.logarithmBase, labValue );
- }
- // Check if we do not exceed max number of elements
- if (counter++ > ChartHelper.MaxNumOfGridlines)
- {
- break;
- }
- if (endLabels == 0 && position >= endLabelMaxPosition)
- {
- break;
- }
- beginPosition = position - dateInterval * 0.5;
- endPosition = position + dateInterval * 0.5;
- if(endLabels == 0 && position <= endLabelMinPosition)
- {
- position += dateInterval;
- continue;
- }
-
- if( (decimal)beginPosition > (decimal)viewMaximum )
- {
- position += dateInterval;
- continue;
- }
- // NOTE: Fixes issue #6466
- // Following code is removed due to the issues caused by the rounding error
- //if( (((decimal)beginPosition + (decimal)endPosition) / 2.0m) < (decimal)viewMinimum )
- //{
- // position += dateInterval;
- // continue;
- //}
- //if ((decimal)viewMaximum < (((decimal)beginPosition + (decimal)endPosition) / 2m))
- //{
- // position += dateInterval;
- // continue;
- //}
- string pointLabel = GetPointLabel( dataSeries, labValue, !seriesXValuesZeros, indexedSeries );
- if( pointLabel.Length == 0 )
- {
- // Do not draw last label for indexed series
- if( position <= this.maximum )
- {
- // Add a label to the collection
- if( position != this.maximum || !Common.DataManager.Series[ dataSeries[0] ].IsXValueIndexed )
- {
- CustomLabels.Add( beginPosition,
- endPosition,
- ValueConverter.FormatValue(
- this.Common.Chart,
- this,
- null,
- labValue,
- this.LabelStyle.Format,
- valueType,
- ChartElementType.AxisLabels),
- false);
- }
- }
- }
- else
- {
- // Add a label to the collection
- CustomLabels.Add( beginPosition,
- endPosition,
- pointLabel,
- false);
- }
- position += dateInterval;
- }
- }
- else
- {
- // ***************************************
- // Scale value type
- // ***************************************
- // Show First label if Start Label position is used
- if( start != viewMinimum )
- endLabels = 1;
- // Set labels
- int labelCounter = 0;
- for (double position = start - endLabels * labelStyle.GetInterval(); position < viewMaximum - 1.5 * labelStyle.GetInterval() * (1 - endLabels); position = (double)((decimal)position + (decimal)labelStyle.GetInterval()))
- {
- // Prevent endless loop that may be caused by very small interval
- // and double/decimal rounding errors
- ++labelCounter;
- if(labelCounter > ChartHelper.MaxNumOfGridlines)
- {
- break;
- }
- labValue = (double)((decimal)position + (decimal)labelStyle.GetInterval());
- // This line is introduce because sometimes 0 value will appear as
- // very small value close to zero.
- double inter = Math.Log(labelStyle.GetInterval());
- double valu = Math.Log(Math.Abs(labValue));
- int digits = (int)Math.Abs(inter)+5;
- if( digits > 15 )
- {
- digits = 15;
- }
- if( Math.Abs(inter) < Math.Abs(valu)-5 )
- {
- labValue = Math.Round(labValue,digits);
- }
- // Too many labels
- if( ( viewMaximum - start ) / labelStyle.GetInterval() > ChartHelper.MaxNumOfGridlines )
- {
- return;
- }
- // For IsLogarithmic axes
- if( this.IsLogarithmic )
- labValue = Math.Pow( this.logarithmBase, labValue );
- beginPosition = (double)((decimal)position + (decimal)labelStyle.GetInterval() * 0.5m);
- endPosition = (double)((decimal)position + (decimal)labelStyle.GetInterval() * 1.5m);
-
- if( (decimal)beginPosition > (decimal)viewMaximum )
- {
- continue;
- }
- // Show End label if Start Label position is used
- // Use decimal type to solve rounding issues
- if( (decimal)(( beginPosition + endPosition )/2.0) > (decimal)viewMaximum )
- {
- continue;
- }
- string pointLabel = GetPointLabel( dataSeries, labValue, !seriesXValuesZeros, indexedSeries );
- if( pointLabel.Length > 15 && labValue < 0.000001)
- {
- labValue = 0.0;
- }
- if( pointLabel.Length == 0 )
- {
- // Do not draw last label for indexed series
- if( !(Common.DataManager.Series[ dataSeries[0] ].IsXValueIndexed && position > this.maximum) )
- {
- // Add a label to the collection
- CustomLabels.Add( beginPosition,
- endPosition,
- ValueConverter.FormatValue(
- this.Common.Chart,
- this,
- null,
- labValue,
- this.LabelStyle.Format,
- valueType,
- ChartElementType.AxisLabels),
- false);
- }
- }
- else
- {
- // Add a label to the collection
- CustomLabels.Add( beginPosition,
- endPosition,
- pointLabel,
- false);
- }
- }
- }
- }
- }
- /// <summary>
- /// This method checks if there is a data point which has value X equal
- /// to valuePosition, and returns label from data point if such value exist.
- /// If data point with this value not exists empty string will be returned.
- /// If all data points have X value zero, index is used instead of X value.
- /// </summary>
- /// <param name="series">Data series</param>
- /// <param name="valuePosition">A value which should be found in data points x values</param>
- /// <param name="nonZeroXValues">Series X values are not zeros.</param>
- /// <param name="indexedSeries">Series is indexed. All X values are zeros or IsXValueIndexed flag set.</param>
- /// <returns>LabelStyle</returns>
- private string GetPointLabel(
- List<string> series,
- double valuePosition,
- bool nonZeroXValues,
- bool indexedSeries
- )
- {
- // Get max number of data points in the series
- int maxPointCount = 0;
- foreach (string seriesName in series)
- {
- Series ser = Common.DataManager.Series[seriesName];
- maxPointCount = Math.Max(maxPointCount, ser.Points.Count);
- }
- // Check if axis only contains axis abels
- bool allEmpty = true;
- foreach( string seriesName in series )
- {
- // Get series by name
- Series ser = Common.DataManager.Series[ seriesName ];
- // Check if series has axis labels set
- if ((axisType == AxisName.X || axisType == AxisName.X2) && (margin != 0 || maxPointCount == 1 || !this._autoMinimum) && !ser.IsXValueIndexed)
- {
- if( ser.Points[ 0 ].AxisLabel.Length > 0 && ser.Points[ ser.Points.Count - 1 ].AxisLabel.Length > 0 )
- {
- allEmpty = false;
- }
- }
- // Try getting label from the point
- if(!ser.noLabelsInPoints || (nonZeroXValues && indexedSeries))
- {
- string result = GetPointLabel( ser, valuePosition, nonZeroXValues, indexedSeries );
- if(!String.IsNullOrEmpty(result))
- {
- return result;
- }
- }
- // VSTS 140676: Serach for IndexedSeriesLabelsSourceAttr attribute
- // to find if we have indexed series as source of formula generated nonindexed series.
- String labelSeriesName = ser[DataFormula.IndexedSeriesLabelsSourceAttr];
- if (!String.IsNullOrEmpty(labelSeriesName))
- {
- Series labelsSeries = Common.DataManager.Series[labelSeriesName];
- if (labelsSeries != null)
- {
- string result = GetPointLabel(labelsSeries, valuePosition, nonZeroXValues, true);
- if (!String.IsNullOrEmpty(result))
- {
- return result;
- }
- }
- }
- }
- if( !allEmpty )
- {
- return " ";
- }
- else
- {
- return "";
- }
- }
-
- /// <summary>
- /// This method checks if there is a data point which has value X equal
- /// to valuePosition, and returns label from data point if such value exist.
- /// If data point with this value not exists empty string will be returned.
- /// If all data points have X value zero, index is used instead of X value.
- /// </summary>
- /// <param name="series">Data series</param>
- /// <param name="valuePosition">A value which should be found in data points x values</param>
- /// <param name="nonZeroXValues">Series X values are not zeros.</param>
- /// <param name="indexedSeries">Series is indexed. All X values are zeros or IsXValueIndexed flag set.</param>
- /// <returns>LabelStyle</returns>
- private string GetPointLabel(
- Series series,
- double valuePosition,
- bool nonZeroXValues,
- bool indexedSeries)
- {
- int pointIndx = 1;
- if( axisType == AxisName.Y || axisType == AxisName.Y2 )
- {
- return "";
- }
- if( !(( axisType == AxisName.X && series.XAxisType == AxisType.Primary ) || ( axisType == AxisName.X2 && series.XAxisType == AxisType.Secondary )) )
- {
- #if SUBAXES
- if(series.XSubAxisName != ((Axis)this).SubAxisName)
- {
- return "";
- }
- #endif // SUBAXES
- return "";
- }
- // Loop through all series data points
- foreach( DataPoint point in series.Points )
- {
- // If series is indexed (all X values are zeros or IsXValueIndexed flag set)
- if( indexedSeries )
- {
- // If axis label position matches point index
- if( valuePosition == pointIndx )
- {
- // Use X value if axis label is not set and X values in series are not zeros
- if(point.AxisLabel.Length == 0 && nonZeroXValues)
- {
- return ValueConverter.FormatValue(
- this.Common.Chart,
- this,
- null,
- point.XValue,
- this.LabelStyle.Format,
- series.XValueType,
- ChartElementType.AxisLabels);
- }
- // Return axis label from data point
- return point.ReplaceKeywords(point.AxisLabel);
- }
- }
- else
- {
- // Find x value using Data point X values
- if( point.XValue == valuePosition )
- {
- // Return label
- return point.ReplaceKeywords(point.AxisLabel);
- }
- }
- pointIndx++;
- }
- return "";
- }
- #endregion
- }
- }
|