4

私は WPF ツールキットを使用しており、ヒストグラムのようなグラフをレンダリングしようとしています。特に、各列を他の列と正対させたいと考えています。列間に隙間があってはなりません。

縦棒グラフを作成するときに適用するコンポーネントは多数あります。(以下の XAML の例を参照してください)。列間の空白の幅を参照する要素の 1 つに設定できるプロパティがあるかどうかは誰にもわかりませんか?

                <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

2 に答える 2

7

魔法のように見える答えがないので、codeplex から wpftoolkit コードをダウンロードしました。

コードを読むと、メソッドColumnSeries.UpdateDataPointに次のコード行があることがわかります。

    double segmentWidth = coordinateRangeWidth * 0.8;

これはかなり決定的な「いいえ」です。パブリック プロパティを設定して列間のギャップを変更することはできません。

私が試みる解決策は、ColumnSeriesから継承する新しいクラスを作成し、 UpdateDataPointをオーバーライドすることです。


後で編集

OK、私はそれを働かせました。興味のある方のために、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;
    }
}
于 2010-05-03T05:29:31.797 に答える