/// <summary> /// Calculates the length of the data points. /// </summary> protected void CalculateDataPointLength() { if (!(ActualIndependentAxis is ICategoryAxis)) { IEnumerable <UnitValue> values = ActiveDataPoints .Select(dataPoint => ActualIndependentAxis.GetPlotAreaCoordinate(dataPoint.ActualIndependentValue)) .Where(value => ValueHelper.CanGraph(value.Value)) .OrderBy(value => value.Value) .ToList(); _dataPointlength = EnumerableFunctions.Zip( values, values.Skip(1), (left, right) => new Range <double>(left.Value, right.Value)) .Select(range => range.Maximum - range.Minimum) .MinOrNullable(); } }
/// <summary> /// Gets the margin to use for an independent axis that does not implement ICategoryAxis. /// </summary> /// <param name="axis">Axis to get the margin for.</param> /// <returns>Margin for axis.</returns> private double GetMarginForNonCategoryAxis(IAxis axis) { Debug.Assert(!(axis is ICategoryAxis), "This method is unnecessary for ICategoryAxis."); // Find the smallest distance between two independent value plot area coordinates double smallestDistance = double.MaxValue; double lastCoordinate = double.NaN; foreach (double coordinate in IndependentValueGroupsOrderedByIndependentValue .Select(g => axis.GetPlotAreaCoordinate(g.IndependentValue).Value) .Where(v => ValueHelper.CanGraph(v))) { if (!double.IsNaN(lastCoordinate)) { double distance = coordinate - lastCoordinate; if (distance < smallestDistance) { smallestDistance = distance; } } lastCoordinate = coordinate; } // Return the margin if (double.MaxValue == smallestDistance) { // No smallest distance because <= 1 independent values to plot FrameworkElement element = axis as FrameworkElement; if (null != element) { // Use width of provided axis so single column scenario looks good return(element.GetMargin(axis)); } else { // No information to work with; no idea what margin to return throw new NotSupportedException(); } } else { // Found the smallest distance; margin is half of that return(smallestDistance / 2); } }
/// <summary> /// Gets the margin to use for an independent axis that does not implement ICategoryAxis. /// </summary> /// <param name="axis">Axis to get the margin for.</param> /// <returns>Margin for axis.</returns> private double GetMarginForNonCategoryAxis(IAxis axis) { Debug.Assert(!(axis is ICategoryAxis), "This method is unnecessary for ICategoryAxis."); // Find the smallest distance between two independent value plot area coordinates double smallestDistance = double.MaxValue; double lastCoordinate = double.NaN; foreach (double coordinate in IndependentValueGroupsOrderedByIndependentValue .Select(g => axis.GetPlotAreaCoordinate(g.IndependentValue).Value) .Where(v => ValueHelper.CanGraph(v))) { if (!double.IsNaN(lastCoordinate)) { double distance = coordinate - lastCoordinate; if (distance < smallestDistance) { smallestDistance = distance; } } lastCoordinate = coordinate; } // Return the margin if (double.MaxValue == smallestDistance) { // No smallest distance because <= 1 independent values to plot FrameworkElement element = axis as FrameworkElement; if (null != element) { // Use width of provided axis so single column scenario looks good return element.GetMargin(axis); } else { // No information to work with; no idea what margin to return throw new NotSupportedException(); } } else { // Found the smallest distance; margin is half of that return smallestDistance / 2; } }
protected override void UpdateDataItemPlacement(IEnumerable <DefinitionSeries.DataItem> dataItems) { IAxis actualIndependentAxis = ActualIndependentAxis; if ((null != ActualDependentAxis) && (null != actualIndependentAxis)) { double plotAreaMaximumDependentCoordinate = ActualDependentAxis.GetPlotAreaCoordinate(ActualDependentRangeAxis.Range.Maximum).Value; double zeroCoordinate = ActualDependentAxis.GetPlotAreaCoordinate(ActualDependentRangeAxis.Origin ?? 0.0).Value; ICategoryAxis actualIndependentCategoryAxis = actualIndependentAxis as ICategoryAxis; double nonCategoryAxisRangeMargin = (null != actualIndependentCategoryAxis) ? 0 : GetMarginForNonCategoryAxis(actualIndependentAxis); foreach (IndependentValueGroup group in IndependentValueGroups) { Range <UnitValue> categoryRange = new Range <UnitValue>(); if (null != actualIndependentCategoryAxis) { categoryRange = actualIndependentCategoryAxis.GetPlotAreaCoordinateRange(group.IndependentValue); } else { UnitValue independentValueCoordinate = actualIndependentAxis.GetPlotAreaCoordinate(group.IndependentValue); if (ValueHelper.CanGraph(independentValueCoordinate.Value)) { categoryRange = new Range <UnitValue>(new UnitValue(independentValueCoordinate.Value - nonCategoryAxisRangeMargin, independentValueCoordinate.Unit), new UnitValue(independentValueCoordinate.Value + nonCategoryAxisRangeMargin, independentValueCoordinate.Unit)); } } if (categoryRange.HasData) { double categoryMinimumCoordinate = categoryRange.Minimum.Value; double categoryMaximumCoordinate = categoryRange.Maximum.Value; double padding = 0.1 * (categoryMaximumCoordinate - categoryMinimumCoordinate); categoryMinimumCoordinate += padding; categoryMaximumCoordinate -= padding; double sum = IsStacked100 ? group.DataItems.Sum(di => Math.Abs(ValueHelper.ToDouble(di.DataPoint.ActualDependentValue))) : 1; if (0 == sum) { sum = 1; } double ceiling = 0; double floor = 0; foreach (DataItem dataItem in group.DataItems) { DataPoint dataPoint = dataItem.DataPoint; double value = IsStacked100 ? (ValueHelper.ToDouble(dataPoint.ActualDependentValue) * (100 / sum)) : ValueHelper.ToDouble(dataPoint.ActualDependentValue); if (ValueHelper.CanGraph(value)) { double valueCoordinate = ActualDependentAxis.GetPlotAreaCoordinate(value).Value; double fillerCoordinate = (0 <= value) ? ceiling : floor; double topCoordinate = 0, leftCoordinate = 0, height = 0, width = 0, deltaCoordinate = 0; if (AxisOrientation.Y == ActualDependentAxis.Orientation) { topCoordinate = plotAreaMaximumDependentCoordinate - Math.Max(valueCoordinate + fillerCoordinate, zeroCoordinate + fillerCoordinate); double bottomCoordinate = plotAreaMaximumDependentCoordinate - Math.Min(valueCoordinate + fillerCoordinate, zeroCoordinate + fillerCoordinate); deltaCoordinate = bottomCoordinate - topCoordinate; height = (0 < deltaCoordinate) ? deltaCoordinate + 1 : 0; leftCoordinate = categoryMinimumCoordinate; width = categoryMaximumCoordinate - categoryMinimumCoordinate + 1; } else { leftCoordinate = Math.Min(valueCoordinate + fillerCoordinate, zeroCoordinate + fillerCoordinate); double rightCoordinate = Math.Max(valueCoordinate + fillerCoordinate, zeroCoordinate + fillerCoordinate); deltaCoordinate = rightCoordinate - leftCoordinate; width = (0 < deltaCoordinate) ? deltaCoordinate + 1 : 0; topCoordinate = categoryMinimumCoordinate; height = categoryMaximumCoordinate - categoryMinimumCoordinate + 1; } double roundedTopCoordinate = Math.Round(topCoordinate); Canvas.SetTop(dataItem.Container, roundedTopCoordinate); dataPoint.Height = Math.Round(topCoordinate + height - roundedTopCoordinate); double roundedLeftCoordinate = Math.Round(leftCoordinate); Canvas.SetLeft(dataItem.Container, roundedLeftCoordinate); dataPoint.Width = Math.Round(leftCoordinate + width - roundedLeftCoordinate); dataPoint.Visibility = Visibility.Visible; if (0 <= value) { ceiling += deltaCoordinate; } else { floor -= deltaCoordinate; } } else { dataPoint.Visibility = Visibility.Collapsed; } } } else { foreach (DataPoint dataPoint in group.DataItems.Select(di => di.DataPoint)) { dataPoint.Visibility = Visibility.Collapsed; } } } } }