123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 |
- using System;
- using System.ComponentModel;
- using System.Collections.Generic;
- using System.Text;
- using System.Globalization;
- using FastReport.Utils;
- namespace FastReport.Map
- {
- /// <summary>
- /// Represents a set of size ranges used to draw points based on analytical value.
- /// </summary>
- [TypeConverter(typeof(FastReport.TypeConverters.FRExpandableObjectConverter))]
- public class SizeRanges
- {
- #region Fields
- private List<SizeRange> ranges;
- private float startSize;
- private float endSize;
- #endregion // Fields
- #region Properties
- /// <summary>
- /// Gets the list of ranges.
- /// </summary>
- public List<SizeRange> Ranges
- {
- get { return ranges; }
- }
- /// <summary>
- /// Gets or sets the number of ranges.
- /// </summary>
- public int RangeCount
- {
- get { return Ranges.Count; }
- set
- {
- if (Ranges.Count < value)
- {
- while (Ranges.Count < value)
- Ranges.Add(new SizeRange());
- }
- else if (Ranges.Count > value)
- {
- while (Ranges.Count > value)
- Ranges.RemoveAt(Ranges.Count - 1);
- }
- }
- }
- /// <summary>
- /// Gets or sets the start size.
- /// </summary>
- public float StartSize
- {
- get { return startSize; }
- set { startSize = value; }
- }
- /// <summary>
- /// Gets or sets the end size.
- /// </summary>
- public float EndSize
- {
- get { return endSize; }
- set { endSize = value; }
- }
- /// <summary>
- /// Gets or sets ranges as a string.
- /// </summary>
- [Browsable(false)]
- public string RangesAsString
- {
- get { return GetRangesAsString(); }
- set { SetRangesAsString(value); }
- }
- #endregion // Properties
- #region Private Methods
- private string GetRangesAsString()
- {
- StringBuilder result = new StringBuilder();
- foreach (SizeRange range in Ranges)
- {
- result.Append(range.GetAsString()).Append("\r\n");
- }
- if (result.Length > 2)
- result.Remove(result.Length - 2, 2);
- return result.ToString();
- }
- private void SetRangesAsString(string value)
- {
- Ranges.Clear();
- if (String.IsNullOrEmpty(value))
- return;
- string[] values = value.Split(new string[] { "\r\n" }, StringSplitOptions.None);
- foreach (string val in values)
- {
- SizeRange range = new SizeRange();
- range.SetAsString(val);
- Ranges.Add(range);
- }
- }
- #endregion // Private Methods
- #region Public Methods
- /// <summary>
- /// Copies the contents of another SizeRanges.
- /// </summary>
- /// <param name="src">The SizeRanges instance to copy the contents from.</param>
- public void Assign(SizeRanges src)
- {
- StartSize = src.StartSize;
- EndSize = src.EndSize;
- RangeCount = src.RangeCount;
- for (int i = 0; i < RangeCount; i++)
- Ranges[i].Assign(src.Ranges[i]);
- }
- /// <summary>
- /// Gets a size associated with given analytical value.
- /// </summary>
- /// <param name="value">The analytical value.</param>
- /// <returns>The size associated with this value, or 0 if no association found.</returns>
- public float GetSize(double value)
- {
- foreach (SizeRange range in Ranges)
- {
- if (value >= range.StartValue && value < range.EndValue)
- return range.Size;
- }
- return 0;
- }
- internal void Fill(double min, double max)
- {
- double delta = (max - min) / RangeCount;
- float sizeDelta = (EndSize - StartSize) / RangeCount;
- for (int i = 0; i < RangeCount; i++)
- {
- SizeRange range = Ranges[i];
- if (range.IsSizeEmpty)
- range.Size = StartSize + sizeDelta * i;
- if (range.IsStartValueEmpty)
- range.StartValue = min + delta * i;
- // make last EndValue bigger to fit largest data value in this range
- if (range.IsEndValueEmpty)
- range.EndValue = min + delta * (i + 1) + (i == RangeCount - 1 ? 0.1 : 0);
- }
- }
- internal void SaveState()
- {
- foreach (SizeRange range in Ranges)
- {
- range.SaveState();
- }
- }
- internal void RestoreState()
- {
- foreach (SizeRange range in Ranges)
- {
- range.RestoreState();
- }
- }
- internal void Serialize(FRWriter writer, string prefix)
- {
- writer.WriteFloat(prefix + ".StartSize", StartSize);
- writer.WriteFloat(prefix + ".EndSize", EndSize);
- writer.WriteStr(prefix + ".RangesAsString", RangesAsString);
- }
- #endregion // Public Methods
- /// <summary>
- /// Initializes a new instance of the <see cref="SizeRanges"/> class.
- /// </summary>
- public SizeRanges()
- {
- ranges = new List<SizeRange>();
- startSize = 4;
- endSize = 20;
- }
- }
- /// <summary>
- /// Represents a single size range.
- /// </summary>
- public class SizeRange
- {
- #region Fields
- private float size;
- private double startValue;
- private double endValue;
- private SizeRange state;
- #endregion // Fields
- #region Properties
- /// <summary>
- /// Gets or sets size of the range.
- /// </summary>
- public float Size
- {
- get { return size; }
- set { size = value; }
- }
- /// <summary>
- /// Gets or sets start value of the range.
- /// </summary>
- public double StartValue
- {
- get { return startValue; }
- set { startValue = value; }
- }
- /// <summary>
- /// Gets or sets end value of the range.
- /// </summary>
- public double EndValue
- {
- get { return endValue; }
- set { endValue = value; }
- }
- internal bool IsSizeEmpty
- {
- get { return float.IsNaN(Size); }
- }
- internal bool IsStartValueEmpty
- {
- get { return double.IsNaN(StartValue); }
- }
- internal bool IsEndValueEmpty
- {
- get { return double.IsNaN(EndValue); }
- }
- #endregion // Properties
- #region Public Methods
- /// <summary>
- /// Copies the contents of another SizeRange.
- /// </summary>
- /// <param name="src">The SizeRange instance to copy the contents from.</param>
- public void Assign(SizeRange src)
- {
- Size = src.Size;
- StartValue = src.StartValue;
- EndValue = src.EndValue;
- }
- internal void SaveState()
- {
- if (state == null)
- state = new SizeRange();
- state.Assign(this);
- }
- internal void RestoreState()
- {
- if (state != null)
- Assign(state);
- }
- internal string GetAsString()
- {
- return Size.ToString(CultureInfo.InvariantCulture.NumberFormat) + ";" +
- StartValue.ToString(CultureInfo.InvariantCulture.NumberFormat) + ";" +
- EndValue.ToString(CultureInfo.InvariantCulture.NumberFormat);
- }
- internal void SetAsString(string value)
- {
- Reset();
- if (String.IsNullOrEmpty(value))
- return;
- string[] val = value.Split(';');
- if (val.Length != 3)
- return;
- Size = float.Parse(val[0], CultureInfo.InvariantCulture.NumberFormat);
- StartValue = double.Parse(val[1], CultureInfo.InvariantCulture.NumberFormat);
- EndValue = double.Parse(val[2], CultureInfo.InvariantCulture.NumberFormat);
- }
- internal void Reset()
- {
- size = float.NaN;
- startValue = double.NaN;
- endValue = double.NaN;
- }
- #endregion
- /// <summary>
- /// Initializes a new instance of the <see cref="SizeRange"/> class.
- /// </summary>
- public SizeRange()
- {
- Reset();
- }
- /// <summary>
- /// Initializes a new instance of the <see cref="SizeRange"/> class with a specified parameters.
- /// </summary>
- /// <param name="size">The size of the range.</param>
- /// <param name="startValue">The start value of the range.</param>
- /// <param name="endValue">The end value of the range.</param>
- public SizeRange(float size, double startValue, double endValue)
- {
- this.size = size;
- this.startValue = startValue;
- this.endValue = endValue;
- }
- }
- }
|