/// <summary> /// Get value from custom attribute BubbleMaxSize /// </summary> /// <param name="area">Chart Area</param> /// <returns>Bubble Max size</returns> static internal double GetBubbleMaxSize(ChartArea area) { double maxPossibleBubbleSize = 15; // Try to find bubble size scale in the custom series properties foreach (Series ser in area.Common.DataManager.Series) { if (string.Compare(ser.ChartTypeName, ChartTypeNames.Bubble, StringComparison.OrdinalIgnoreCase) == 0 && ser.ChartArea == area.Name && ser.IsVisible() && ser.IsCustomPropertySet(CustomPropertyName.BubbleMaxSize)) { maxPossibleBubbleSize = CommonElements.ParseDouble(ser[CustomPropertyName.BubbleMaxSize]); if (maxPossibleBubbleSize < 0 || maxPossibleBubbleSize > 100) { throw (new ArgumentException(SR.ExceptionCustomAttributeIsNotInRange0to100("BubbleMaxSize"))); } } } return(maxPossibleBubbleSize / 100); }
/// <summary> /// Scales the value used to determine the size of the Bubble. /// </summary> /// <param name="common">The Common elements object</param> /// <param name="area">Chart area for this chart</param> /// <param name="value">Value to scale.</param> /// <param name="yValue">True if Y value is calculated, false if X.</param> /// <returns>Scaled values.</returns> static internal double AxisScaleBubbleSize(CommonElements common, ChartArea area, double value, bool yValue) { // Try to find bubble size scale in the custom series properties double minAll = double.MaxValue; double maxAll = double.MinValue; double maxPossibleBubbleSize = 15F; double minPossibleBubbleSize = 3F; float maxBubleSize; float minBubleSize; double valueScale; double valueDiff; foreach (Series ser in common.DataManager.Series) { if (String.Compare(ser.ChartTypeName, ChartTypeNames.Bubble, StringComparison.OrdinalIgnoreCase) == 0 && ser.ChartArea == area.Name && ser.IsVisible()) { // Check if custom properties are set to specify scale if (ser.IsCustomPropertySet(CustomPropertyName.BubbleScaleMin)) { minAll = Math.Min(minAll, CommonElements.ParseDouble(ser[CustomPropertyName.BubbleScaleMin])); } if (ser.IsCustomPropertySet(CustomPropertyName.BubbleScaleMax)) { maxAll = Math.Max(maxAll, CommonElements.ParseDouble(ser[CustomPropertyName.BubbleScaleMax])); } // Check if attribute for max. size is set if (ser.IsCustomPropertySet(CustomPropertyName.BubbleMaxSize)) { maxPossibleBubbleSize = CommonElements.ParseDouble(ser[CustomPropertyName.BubbleMaxSize]); if (maxPossibleBubbleSize < 0 || maxPossibleBubbleSize > 100) { throw(new ArgumentException(SR.ExceptionCustomAttributeIsNotInRange0to100("BubbleMaxSize"))); } } // Check if custom properties set to use second Y value (bubble size) as label text if (ser.IsCustomPropertySet(CustomPropertyName.BubbleUseSKSizeorLabel) && String.Compare(ser[CustomPropertyName.BubbleUseSKSizeorLabel], "true", StringComparison.OrdinalIgnoreCase) == 0) { break; } } } // Scale values are not specified - auto detect double minimum = double.MaxValue; double maximum = double.MinValue; double minSer = double.MaxValue; double maxSer = double.MinValue; foreach (Series ser in common.DataManager.Series) { if (String.Compare(ser.ChartTypeName, ChartTypeNames.Bubble, StringComparison.OrdinalIgnoreCase) == 0 && ser.ChartArea == area.Name && ser.IsVisible()) { foreach (DataPoint point in ser.Points) { if (!point.IsEmpty) { minSer = Math.Min(minSer, point.YValues[1]); maxSer = Math.Max(maxSer, point.YValues[1]); if (yValue) { minimum = Math.Min(minimum, point.YValues[0]); maximum = Math.Max(maximum, point.YValues[0]); } else { minimum = Math.Min(minimum, point.XValue); maximum = Math.Max(maximum, point.XValue); } } } } } if (minAll == double.MaxValue) { minAll = minSer; } if (maxAll == double.MinValue) { maxAll = maxSer; } // Calculate maximum bubble size maxBubleSize = (float)((maximum - minimum) / (100.0 / maxPossibleBubbleSize)); minBubleSize = (float)((maximum - minimum) / (100.0 / minPossibleBubbleSize)); // Calculate scaling variables depending on the Min/Max values if (maxAll == minAll) { valueScale = 1; valueDiff = minAll - (maxBubleSize - minBubleSize) / 2f; } else { valueScale = (maxBubleSize - minBubleSize) / (maxAll - minAll); valueDiff = minAll; } // Check if value do not exceed Min&Max if (value > maxAll) { return(0F); } if (value < minAll) { return(0F); } // Return scaled value return((float)((value - valueDiff) * valueScale) + minBubleSize); }
/// <summary> /// Scales the value used to determine the size of the Bubble. /// </summary> /// <param name="graph">The Chart Graphics object</param> /// <param name="common">The Common elements object</param> /// <param name="area">Chart area for this chart</param> /// <param name="value">Value to scale.</param> /// <returns>Scaled values.</returns> private float ScaleBubbleSize(ChartGraphics graph, CommonElements common, ChartArea area, double value) { // Check if scaling numbers are detected if (!_scaleDetected) { // Try to find bubble size scale in the custom series properties _minAll = double.MaxValue; _maxAll = double.MinValue; foreach (Series ser in common.DataManager.Series) { if (String.Compare(ser.ChartTypeName, Name, true, System.Globalization.CultureInfo.CurrentCulture) == 0 && ser.ChartArea == area.Name && ser.IsVisible()) { // Check if custom properties are set to specify scale if (ser.IsCustomPropertySet(CustomPropertyName.BubbleScaleMin)) { _minAll = Math.Min(_minAll, CommonElements.ParseDouble(ser[CustomPropertyName.BubbleScaleMin])); } if (ser.IsCustomPropertySet(CustomPropertyName.BubbleScaleMax)) { _maxAll = Math.Max(_maxAll, CommonElements.ParseDouble(ser[CustomPropertyName.BubbleScaleMax])); } // Check if attribute for max. size is set if (ser.IsCustomPropertySet(CustomPropertyName.BubbleMaxSize)) { _maxPossibleBubbleSize = CommonElements.ParseDouble(ser[CustomPropertyName.BubbleMaxSize]); if (_maxPossibleBubbleSize < 0 || _maxPossibleBubbleSize > 100) { throw(new ArgumentException(SR.ExceptionCustomAttributeIsNotInRange0to100("BubbleMaxSize"))); } } // Check if attribute for min. size is set if (ser.IsCustomPropertySet(CustomPropertyName.BubbleMinSize)) { _minPossibleBubbleSize = CommonElements.ParseDouble(ser[CustomPropertyName.BubbleMinSize]); if (_minPossibleBubbleSize < 0 || _minPossibleBubbleSize > 100) { throw(new ArgumentException(SR.ExceptionCustomAttributeIsNotInRange0to100("BubbleMinSize"))); } } // Check if custom properties set to use second Y value (bubble size) as label text labelYValueIndex = 0; if (ser.IsCustomPropertySet(CustomPropertyName.BubbleUseSKSizeorLabel) && String.Compare(ser[CustomPropertyName.BubbleUseSKSizeorLabel], "true", StringComparison.OrdinalIgnoreCase) == 0) { labelYValueIndex = 1; break; } } } // Scale values are not specified - auto detect if (_minAll == double.MaxValue || _maxAll == double.MinValue) { double minSer = double.MaxValue; double maxSer = double.MinValue; foreach (Series ser in common.DataManager.Series) { if (ser.ChartTypeName == Name && ser.ChartArea == area.Name && ser.IsVisible()) { foreach (DataPoint point in ser.Points) { if (!point.IsEmpty) { // Check required Y values number if (point.YValues.Length < YValuesPerPoint) { throw (new InvalidOperationException(SR.ExceptionChartTypeRequiresYValues(Name, YValuesPerPoint.ToString(CultureInfo.InvariantCulture)))); } minSer = Math.Min(minSer, point.YValues[1]); maxSer = Math.Max(maxSer, point.YValues[1]); } } } } if (_minAll == double.MaxValue) { _minAll = minSer; } if (_maxAll == double.MinValue) { _maxAll = maxSer; } } // Calculate maximum bubble size SKSize areaSize = graph.GetAbsoluteSize(area.PlotAreaPosition.Size); _maxBubleSize = (float)(Math.Min(areaSize.Width, areaSize.Height) / (100.0 / _maxPossibleBubbleSize)); _minBubleSize = (float)(Math.Min(areaSize.Width, areaSize.Height) / (100.0 / _minPossibleBubbleSize)); // Calculate scaling variables depending on the Min/Max values if (_maxAll == _minAll) { _valueScale = 1; _valueDiff = _minAll - (_maxBubleSize - _minBubleSize) / 2f; } else { _valueScale = (_maxBubleSize - _minBubleSize) / (_maxAll - _minAll); _valueDiff = _minAll; } _scaleDetected = true; } // Check if value do not exceed Min&Max if (value > _maxAll) { return(0F); } if (value < _minAll) { return(0F); } // Return scaled value return((float)((value - _valueDiff) * _valueScale) + _minBubleSize); }