Динамическое создание приложений Silverlight RadChart SeriesMappings на основе данных, возвращаемых службой - PullRequest
0 голосов
/ 20 марта 2012

У меня есть служба, которая будет возвращать 0 или более наборов данных. Структура данных выглядит следующим образом:

public class ReportData
{
    public List<SeriesSet> SeriesSet {get;set;}
}

public class SeriesSet
{
    public DateTime ItemDate {get;set;}
    public List<SeriesItem> SeriesItem {get;set;}
}

public class SeriesItem
{
    public string ItemType {get;set;}
    public double ItemValue {get;set;}
}

Мой сервис вернет ReportData, который содержит список SeriesSets. Данные SeriesSet содержат список SeriesItems. Каждый SeriesItem в SeriesSet должен быть элементом данных в соответствующей серии на моей диаграмме (то есть отдельной строкой или столбцом) для конкретной даты этого SeriesSet. Я хочу динамически создавать ряды в диаграмме на основе того, что возвращается из сервиса.

Я думаю, что мне нужно сначала определить различные возвращаемые типы элементов, а затем на основе этого создать сопоставления серии.

Одна из проблем, с которыми я сталкиваюсь, заключается в том, что данные поступают из асинхронного веб-сервиса. Как создать сопоставления серии с правильными привязками в моем представлении, когда данные поступают в мою модель представления?

Из-за того, как я создавал диаграммы, кажется, что мне нужно определить сопоставления серий, прежде чем я получу данные из моей модели представления?

Есть указатели?

1 Ответ

1 голос
/ 20 марта 2012

Я недавно сделал нечто похожее на это.Источники ItemMappings были привязаны, хотя сами SeriesMappings и привязки были созданы в программном коде.

Моя модель представления инициировала событие, когда все его данные были загружены.Представление обработало событие и добавило новые объекты SeriesMapping на диаграмму.Вот некоторый код для создания объектов SeriesMapping.

void AddBarSeriesMapping(string itemsSourceBindingPath, string legendLabel, string itemFieldName = null)
{
    this.AddSeriesMapping(itemsSourceBindingPath, legendLabel, CreateBarSeriesDefinition(), itemFieldName);
}

void AddLineSeriesMapping(string itemsSourceBindingPath, string legendLabel, string itemFieldName = null)
{
    this.AddSeriesMapping(itemsSourceBindingPath, legendLabel, CreateLineSeriesDefinition(), itemFieldName);
}

void AddSeriesMapping(string itemsSourceBindingPath, string legendLabel, ISeriesDefinition seriesDefinition, string itemFieldName)
{
    //
    // Set label and type (bar/line/etc).
    //
    SeriesMapping seriesMapping = new SeriesMapping
    {
        ChartArea = this.Chart.DefaultView.ChartArea,
        LegendLabel = legendLabel,
        SeriesDefinition = seriesDefinition
    };

    //
    // Bind to items source.
    //
    BindingOperations.SetBinding(seriesMapping, SeriesMapping.ItemsSourceProperty, new Binding(itemsSourceBindingPath));

    //
    // Map items to the Y value, and set field name if the items source is not a list of numeric values.
    //
    var itemMapping = new ItemMapping { DataPointMember = DataPointMember.YValue };
    if (itemFieldName != null)
    {
        itemMapping.FieldName = itemFieldName;
    }
    seriesMapping.ItemMappings.Add(itemMapping);

    this.Chart.SeriesMappings.Add(seriesMapping);
}

private static ISeriesDefinition CreateBarSeriesDefinition()
{
    return new BarSeriesDefinition
    {
        ShowItemLabels = false,
        ShowItemToolTips = true,
        ItemToolTipFormat = "#Y",
        InteractivitySettings = DefaultInteractivitySettings
    };
}

private static ISeriesDefinition CreateLineSeriesDefinition()
{
    return new LineSeriesDefinition
    {
        ShowItemLabels = false,
        ShowItemToolTips = true,
        ItemToolTipFormat = "#Y",
        InteractivitySettings = DefaultInteractivitySettings
    };
}

private static InteractivitySettings DefaultInteractivitySettings;

static ChartSummaryView()
{
    DefaultInteractivitySettings = new InteractivitySettings
    {
        HoverScope = InteractivityScope.Series,
        SelectionScope = InteractivityScope.Item
    };
}

ОБНОВЛЕНИЕ:

Чтобы модель представления передавала данные и отображала информацию в представлении, возможно, вы могли бы сделать что-то вродеэто.

public class SeriesMappingInfo
{
    public int DataSourceIndex { get; set; } // Index in ViewModel.DataSources
    public string LegendLabel { get; set; }
    // Other properties to tell the view how to create the mapping...
}

public class ViewModel
{
    public event EventHandler DataLoaded;
    public double?[][] DataSources { get; private set; }
    public SeriesMappingInfo[] Mappings { get; private set; }

    private void OnDataRetrievedFromServer(ReportData data)
    {
        // TODO: Translate data into something SeriesMappings can bind to, and set DataSources property.
        // TODO: Assemble info for creating SeriesMappings, and set Mappings property.

        // Tell the view everything is ready.
        if (this.DataLoaded != null)
        {
            this.DataLoaded(this, EventArgs.Empty);
        }
    }
}

public class View : UserControl
{
    public View()
    {
        this.DataContextChanged += new DependencyPropertyChangedEventHandler(View_DataContextChanged);
        // InitializeComponent, etc.
    }

    private void View_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        var viewModel = e.NewValue as ViewModel;
        if (viewModel != null)
        {     
            this.CreateSeriesMappings(viewModel.Mappings);
            viewModel.DataLoaded += new EventHandler(ViewModel_DataLoaded);
        }
    }

    private void ViewModel_DataLoaded(object sender, EventArgs e)
    {
        var viewModel = sender as ViewModel;
        if (viewModel != null)
        {
            this.CreateSeriesMappings(viewModel.Mappings);
        }
    }

    private void CreateSeriesMappings(SeriesMappingInfo[] seriesMappingInfo)
    {
        var chartSeriesMappings = seriesMappingInfo.Select(m =>
        {
            // TODO: Create mapping. The binding would look something like this:
            var seriesMapping = new SeriesMapping();
            BindingOperations.SetBinding(seriesMapping, SeriesMapping.ItemsSourceProperty, new Binding(String.Format("DataSources[{0}]", m.DataSourceIndex)));
            return seriesMapping;
        });

        // TODO: Give these mappings to the chart control.
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...