适用于Android的OxyPlot Mono(又名Xamarin.Android)Misplaced Draw。 (堆叠柱系列)

时间:2013-10-30 15:25:05

标签: c# android mono xamarin oxyplot

我正在使用OxyPlot库,我正在尝试显示堆积柱形图,但它被渲染错误。

这是图表应该如何的模型:

Expected Stacked Bar Chart

以下是我创建PlotModel的方法:

private void InitWidget ()
{

    _goalsPlotModel = new PlotModel ("Metas") {
        LegendPlacement = LegendPlacement.Outside,
        LegendPosition = LegendPosition.BottomCenter,
        LegendOrientation = LegendOrientation.Horizontal,
        LegendBorderThickness = 0
    };

    SelectedChannel = new ListOfValue ();
    SelectedProduct = new Product ();

    SelectedChannel.Code = string.Empty;
    SelectedProduct.ProductCode = string.Empty;

    LoadFilters ();
    Refresh ();
}

以下是我添加系列的方法:

private void FillGoalsPlotModel ()
{
    _goalsPlotModel.Series.Clear ();
    _goalsPlotModel.Axes.Clear ();

    var goals = new ColumnSeries {
        Title = "Goals",
        FillColor = OxyColors.Orange,
        IsStacked = true,
        StrokeColor = OxyColors.Black,
        StrokeThickness = 1
    };

    var sales = new ColumnSeries {
        Title = "Sales",
        FillColor = OxyColors.LightGreen,
        IsStacked = true,
        StrokeColor = OxyColors.White,
        StrokeThickness = 1
    };

    var surplus = new ColumnSeries {
        Title = "Surplus",
        FillColor = OxyColors.Cyan,
        IsStacked = true,
        StrokeColor = OxyColors.Black,
        StrokeThickness = 1
    };

    var categoryAxisForMonths = new CategoryAxis { 
        Position = AxisPosition.Bottom 
    };

    var valueAxis = new LinearAxis (AxisPosition.Left) { 
        MinimumPadding = 0, 
        MaximumPadding = 0.06, 
        AbsoluteMinimum = 0 
    };


    foreach (IGoal goal in _goals) {

        if (goal.GetSales () > goal.GetGoalValue ()) {
            sales.Items.Add (new ColumnItem { Value = goal.GetGoalValue () });
            surplus.Items.Add (new ColumnItem { Value = goal.GetSurplus () });
        } else {
            sales.Items.Add (new ColumnItem { Value = goal.GetSales () });
            goals.Items.Add (new ColumnItem { 
                Value = goal.GetGoalValue() - goal.GetSales ()  
            });
        }
    }

    foreach (var month in GetMonths()) {
        categoryAxisForMonths.Labels.Add (month);
    }


    _goalsPlotModel.Series.Add (sales);
    _goalsPlotModel.Series.Add (goals);
    _goalsPlotModel.Series.Add (surplus);

    _goalsPlotModel.Axes.Add (categoryAxisForMonths);
    _goalsPlotModel.Axes.Add (valueAxis);


    RaisePropertyChanged (() => GoalsPlotModel);
}

以下是它的呈现方式:

Misplaced Stacked Column Series

如果我将IsStacked设置为false,则只会绘制一个垂直BarChart,但每个条形底部都按预期位于y = 0,但如果IsStacked设置为{{} 1}}每个条形底部的值都不同true

对于Android Renderer,Mono的Oxyplot中是否存在错误? 或者只是我做错了什么? (如果是的话,我做错了什么?)

1 个答案:

答案 0 :(得分:1)

嗯,以下适用于我。 我会在代码后附上一些截图,但我认为你的问题就是你将这些点添加到堆栈中的方式。

您在每种情况下都添加了2个点(或列),但您需要将值分配给3(第三个值为零)。否则结果将保持堆叠,直到你得到3,似乎没有什么是正确的。

我的Xaml很直接:

<oxy:Plot Model="{Binding MyPlotModel}" />

然后我从构造函数中调用此方法,以创建和设置模型:

private void SetPlot()
{
    var model = new PlotModel("Metas")
    {
        LegendPlacement = LegendPlacement.Outside,
        LegendPosition = LegendPosition.BottomCenter,
        LegendOrientation = LegendOrientation.Horizontal,
        LegendBorderThickness = 0
    };

    var goals = new ColumnSeries {
        Title = "Goals",
        FillColor = OxyColors.Orange,
        IsStacked = true,
        StrokeColor = OxyColors.Black,
        StrokeThickness = 1
    };

    var sales = new ColumnSeries {
        Title = "Sales",
        FillColor = OxyColors.LightGreen,
        IsStacked = true,
        StrokeColor = OxyColors.White,
        StrokeThickness = 1
    };

    var surplus = new ColumnSeries {
        Title = "Surplus",
        FillColor = OxyColors.Cyan,
        IsStacked = true,
        StrokeColor = OxyColors.Black,
        StrokeThickness = 1
    };

    var categoryAxisForMonths = new CategoryAxis { 
        Position = AxisPosition.Bottom 
    };

    var valueAxis = new LinearAxis (AxisPosition.Left) { 
        MinimumPadding = 0, 
        MaximumPadding = 0.06, 
        AbsoluteMinimum = 0 
    };

    // Creating random data for 12 months
    for (int i = 0; i < 12; i++)
    {
        //var goal = 10;   // if you want a set goal, use this
        var goal = RandomHelper.RandomInt(8, 11); // otherwise use this
        var actualsales = RandomHelper.RandomInt(5, 15);

        if (actualsales > goal)
        {
            sales.Items.Add  (new ColumnItem( goal               ));
            surplus.Items.Add(new ColumnItem( actualsales-goal   ));
            goals.Items.Add  (new ColumnItem( 0                  ));
        }
        else
        {
            sales.Items.Add  (new ColumnItem( actualsales        ));
            goals.Items.Add  (new ColumnItem( goal - actualsales ));
            surplus.Items.Add(new ColumnItem( 0                  ));
        }

        // Next will create jan - dec in the labels
        categoryAxisForMonths.Labels.Add(CultureInfo.CurrentUICulture.DateTimeFormat.MonthNames[i]);

    }

    model.Series.Add (sales);
    model.Series.Add (goals);
    model.Series.Add (surplus);

    model.Axes.Add (categoryAxisForMonths);
    model.Axes.Add (valueAxis);

    MyPlotModel = model;
}
public PlotModel MyPlotModel { get; set; }

RandomHelper是一个帮助获取random的简单类:

public static class RandomHelper
{
    private static readonly Random RandomSeed = new Random();

    public static int RandomInt(int min, int max)
    {
        return RandomSeed.Next(min, max);
    }
}

以下是结果:

Fixed goal

Random goal

有趣的线条是空列边框的结果,但你可以弄明白:)