Stacked Bar with Remote Data

2 posts, 0 answers
  1. Lee
    Lee avatar
    20 posts
    Member since:
    Jun 2014

    Posted 03 Mar Link to this post

    My Model looks Like this:

    public class ForecastChartViewModel
    {
    public int ID { get; set; }
    public String PeriodName { get; set; }
    public String EstimateDesc { get; set; }
    public Decimal EstimateValue { get; set; }
    public String ChartColor { get; set; }
    public Boolean IsBenchmark { get; set; }

    }

    I want the periodName to be the values across the X-Axis and each EstimateDesc to be stack on top of each other for that period if IsBenchmark is false, if IsBenchmark is true I'd like to use a line instead of a stack.  EstimateValue is the charted Value.  I want to be able to set the color for the series to the value of the ChartColor as well.

    @(Html.Kendo().Chart<ManpowerForecast.Web.ViewModels.ForecastChartViewModel>()
    .Name("chart")
    .Legend(legend => legend
    .Visible(true)
    )
    .DataSource(ds => ds
    .Read(read => read.Action("ReadManpowerReportForecast", "Manpower"))
    .Group(group => group.Add(model => model.EstimateDesc))
    .Sort(sort => sort.Add(model => model.PeriodName))
    )
    .SeriesDefaults(seriesDefaults =>
    seriesDefaults.Bar().Stack(true)
    )
    .Series(series =>
    {
    series
    .Column(model => model.EstimateValue)
    .Name("#= group.value #")
    .Visible(true);
    })
    .CategoryAxis(axis => axis
    .Categories(model => model.PeriodName)
    .MajorGridLines(lines => lines.Visible(false))
    .Line(line => line.Visible(false))
    )
    .ValueAxis(axis => axis.Numeric()
    .Max(60)
    .MajorGridLines(lines => lines.Visible(false))
    .Visible(false)
    )
    )

     

    In my Controller "ReadManpowerReportForecast"  I'm just throwing in some junk data for right now to make sure I can get this chart to function before I go through the complexity of forcing my data into the model in this format.  so I could change my model if need be.  The code to load the viewmodel looks liket this:

    IList<ForecastChartViewModel> vCharts = new List<ForecastChartViewModel>();
    ForecastChartViewModel vChart = new ForecastChartViewModel()
    {
    PeriodName = "Period1",
    EstimateDesc = "Project1",
    EstimateValue = 20,
    IsBenchmark = false,
    ChartColor = "#cc00cc"
    };
    vCharts.Add(vChart);
    vChart = new ForecastChartViewModel()
    {
    PeriodName = "Period1",
    EstimateDesc = "Project2",
    EstimateValue = 20,
    IsBenchmark = false,
    ChartColor = "#aa0033"
    };
    vCharts.Add(vChart);
    vChart = new ForecastChartViewModel()
    {
    PeriodName = "Period1",
    EstimateDesc = "Project3",
    EstimateValue = 10,
    IsBenchmark = true,
    ChartColor = "#110011"
    };
    vCharts.Add(vChart);
    vChart = new ForecastChartViewModel()
    {
    PeriodName = "Period2",
    EstimateDesc = "Project1",
    EstimateValue = 30,
    IsBenchmark = false,
    ChartColor = "#cc00cc"
    };
    vCharts.Add(vChart);
    vChart = new ForecastChartViewModel()
    {
    PeriodName = "Period2",
    EstimateDesc = "Project2",
    EstimateValue = 12,
    IsBenchmark = false,
    ChartColor = "#aa0033"
    };
    vCharts.Add(vChart);
    vChart = new ForecastChartViewModel()
    {
    PeriodName = "Period2",
    EstimateDesc = "Project3",
    EstimateValue = 5,
    IsBenchmark = true,
    ChartColor = "#110011"
    };
    vCharts.Add(vChart);

  2. T. Tsonev
    Admin
    T. Tsonev avatar
    2772 posts

    Posted 07 Mar Link to this post

    Hello,

    Building the required chart directly from the definition will require a bit of work.

    We need to have separate series for each EstimateDesc and IsBenchmark combination. The Grouping feature of the chart allows us to do this at runtime by specifying an unique field to differentiate on.
    So for example in your model you can have:
        public GroupId
        {
            get
            {
                 return EstimateDesc + IsBenchmark;
            }
        }

    And then group on it:
        .Group(group => group.Add(model => model.GroupId))

    Then in the client-side dataBound handler you can iterate over the series and change their configuration appropriately.
        .Events(e => e.DataBound("dataBound"))
        ...

        <script>
        function dataBound(e) {
            var series = e.sender.options.series;
            for (var i = 0; i < series.length; i++) {
                if (series[i].data[0].IsBenchmark) {
                    series[i].type = "line";
                }
            }
        }
        </script>

    A similar scenario is covered in Create Stacked and Grouped Series Bound to Remote Data.

    The alternative is to build "flat" series and data in advance that maps directly to the chart definition.
    I hope this helps.

    Regards,
    T. Tsonev
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  3. UI for ASP.NET MVC is VS 2017 Ready
Back to Top