wpf - studio - graficar en c# en tiempo real
Dibuja un gráfico de columna sin espacio entre columnas (2)
En ausencia de respuestas aparentemente mágicas, descargué el código wpftoolkit de codeplex.
Al leer el código, puedo ver en el método ColumnSeries.UpdateDataPoint , existe esta línea de código:
double segmentWidth = coordinateRangeWidth * 0.8;
Entonces ese es un "no" muy definitivo, no puedes cambiar la brecha entre las columnas estableciendo una propiedad pública.
La solución que voy a intentar es escribir una nueva clase que herede de ColumnSeries y anular UpdateDataPoint .
Más tarde Editar
OK, lo tengo para trabajar. En caso de que alguien esté interesado, he adjuntado el código completo para la clase HistogramSeries.
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;
}
}
Estoy usando el kit de herramientas WPF, y estoy tratando de hacer un gráfico que se parece a un histograma. En particular, quiero que cada columna esté alineada entre sí. No debe haber espacios entre columnas.
Hay una serie de componentes que aplica al crear un gráfico de columna. (Ver el ejemplo XAML a continuación). ¿Alguien sabe si hay una propiedad que puede establecer en uno de los elementos que se refiere al ancho del espacio en blanco entre las columnas?
<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>
Thx para el ejemplo de código. Era casi exactamente lo que necesitaba. Lo traduje a VB.Net y borré las partes menores.
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