Draw a column graph with no space between columns

I am using a WPF toolkit and trying to display a graph that looks like a histogram. In particular, I want each column to be directly opposite each other. There should be no spaces between columns.

There are a number of components that you use when creating a column. (See XAML Example below). Does anyone know if there is a property that you can set on one of the elements that refers to the width of the space between the columns?

<charting:Chart Height="600" Width="Auto" HorizontalAlignment="Stretch" Name="MyChart" Title="Column Graph" LegendTitle="Legend"> <charting:ColumnSeries Name="theColumnSeries" Title="Series A" IndependentValueBinding="{Binding Path=Name}" DependentValueBinding="{Binding Path=Population}" Margin="0" > </charting:ColumnSeries> <charting:Chart.Axes> <charting:LinearAxis Orientation="Y" Minimum="200000" Maximum="2500000" ShowGridLines="True" /> <charting:CategoryAxis Name="chartCategoryAxis" /> </charting:Chart.Axes> </charting:Chart> 
+4
source share
2 answers

In the absence of magic answers, I downloaded wpftoolkit code from codeplex.

After reading the code, I see in the ColumnSeries.UpdateDataPoint method, there is this line of code:

  double segmentWidth = coordinateRangeWidth * 0.8; 

So, for a pretty definitive no, you cannot change the spacing between columns by setting a public property.

The solution I'm going to try is to write a new class that inherits from ColumnSeries and override UpdateDataPoint .


Edit later

Ok, I earned it. In case anyone is interested, I added the complete code for the HistogramSeries class.

 public class HistogramSeries : ColumnSeries, ISeries { protected override void UpdateDataPoint(DataPoint dataPoint) { // That set the height and width. base.UpdateDataPoint(dataPoint); // Now we override the part about setting the width object category = dataPoint.ActualIndependentValue; var coordinateRange = GetCategoryRange(category); double minimum = (double)coordinateRange.Minimum.Value; double maximum = (double)coordinateRange.Maximum.Value; double coordinateRangeWidth = (maximum - minimum); const int WIDTH_MULTIPLIER = 1; // Harcoded to 0.8 in the parent. Could make this a dependency property double segmentWidth = coordinateRangeWidth * WIDTH_MULTIPLIER; var columnSeries = SeriesHost.Series.OfType<ColumnSeries>().Where(series => series.ActualIndependentAxis == ActualIndependentAxis); int numberOfSeries = columnSeries.Count(); double columnWidth = segmentWidth / numberOfSeries; int seriesIndex = columnSeries.IndexOf(this); double offset = seriesIndex * Math.Round(columnWidth) + coordinateRangeWidth * 0.1; double dataPointX = minimum + offset; double left = Math.Round(dataPointX); double width = Math.Round(columnWidth); Canvas.SetLeft(dataPoint, left); dataPoint.Width = width; } #region ISeries Members System.Collections.ObjectModel.ObservableCollection<object> ISeries.LegendItems { get { return base.LegendItems; } } #endregion #region IRequireSeriesHost Members ISeriesHost IRequireSeriesHost.SeriesHost { get { return base.SeriesHost;} set { base.SeriesHost = value; } } #endregion } // Copied from the DataVisualization library // (It was an internal class) static class MyEnumerableFunctions { public static int IndexOf(this IEnumerable that, object value) { int index = 0; foreach (object item in that) { if (object.ReferenceEquals(value, item) || value.Equals(item)) { return index; } index++; } return -1; } } 
+7
source

Thanks for the sample code. That was almost what I needed. I translated it into VB.Net and deleted the minor parts.

 Imports System.Windows.Controls.DataVisualization.Charting Public Class HistogramSeries Inherits ColumnSeries Protected Overrides Sub UpdateDataPoint(dataPoint As DataPoint) MyBase.UpdateDataPoint(dataPoint) ' Now we override the part about setting the width Dim category As Object = dataPoint.ActualIndependentValue Dim coordinateRange = GetCategoryRange(category) Dim minimum As Double = CDbl(coordinateRange.Minimum.Value) Dim maximum As Double = CDbl(coordinateRange.Maximum.Value) Dim coordinateRangeWidth As Double = (maximum - minimum) Const WIDTH_MULTIPLIER As Integer = 1 ' Harcoded to 0.8 in the parent. Could make this a dependency property Dim segmentWidth As Double = coordinateRangeWidth * WIDTH_MULTIPLIER Dim columnS As System.Collections.Generic.IEnumerable(Of ColumnSeries) = SeriesHost.Series.OfType(Of ColumnSeries)().Where(Function(series) series.ActualIndependentAxis Is ActualIndependentAxis) Dim numberOfSeries As Integer = columnS.Count Dim columnWidth As Double = segmentWidth / numberOfSeries Dim seriesIndex As Integer = columnS.ToList.IndexOf(Me) Dim offset As Double = seriesIndex * Math.Round(columnWidth) + coordinateRangeWidth * 0.1 Dim dataPointX As Double = minimum + offset Dim left As Double = Math.Round(dataPointX) Dim width As Double = Math.Round(columnWidth) Canvas.SetLeft(dataPoint, left) dataPoint.Width = width End Sub End Class 
0
source

Source: https://habr.com/ru/post/1308634/


All Articles