Create a Vertical Line in Column Chart

1 Answer 142 Views
Chart
Chevron Phillips Chemical Co
Top achievements
Rank 1
Chevron Phillips Chemical Co asked on 19 Jun 2022, 05:31 PM

I have a user requirement to plot a chart as shown in the attached image (VerticalLine.JPG).

@(Html.Kendo().Chart<MyProject.WebAPI.MyChart.MyModel()>()
                    .Name("statistics")
                    .Title("User Interaction (Days)")
                    .Legend(legend => legend
                    .Position(ChartLegendPosition.Top)
                    )
                    .DataSource(ds => ds.Read(read => read.Url("/api/GetUserStats").Type(HttpVerbs.Get)))
                    .Series(series =>
                    {
                        series.Column(model => model.UserCount).Name("Total").Gap(.2).Color("#4169e1");
                    })
                    .CategoryAxis(axis => axis
                        .Categories(a => a.UserScore)
                        .Title("Days")
                    )
                    .ValueAxis(axis => axis.Numeric()
                        .Labels(labels => labels.Format("{0:N0}"))
                        .MajorUnit(1)
                    )
                    .AxisDefaults(a => a
                        .Labels(l => l.Font("12px Verdana"))
                    )
                    .Tooltip(tooltip => tooltip
                    .Visible(true)
                    .Shared(true)
                    .Format("{0:N0}")
                    )
                    .Zoomable(zoomable => zoomable
                    .Mousewheel(mousewheel => mousewheel.Lock(ChartAxisLock.Y))
                    .Selection(selection => selection.Lock(ChartAxisLock.Y))
                    )
                    )

 

namespace MyProject.WebAPI.MyChart
{
    public class MyModel
    {       
        public int UserCount { get; set; }

        public int UserScore { get; set; }

        public int UserGoal { get; set; }
    }
}

ResponseFromWebApi GetUserStats:

[{"UserCount":33,"UserScore":0,"UserGoal":7},{"UserCount":46,"UserScore":1,"UserGoal":7},
{"UserCount":46,"UserScore":2,"UserGoal":7},{"UserCount":32,"UserScore":3,"UserGoal":7},{"UserCount":29,"UserScore":4,"UserGoal":7},{"UserCount":40,"UserScore":5,"UserGoal":7},{"UserCount":45,"UserScore":6,"UserGoal":7},{"UserCount":54,"UserScore":7,"UserGoal":7},{"UserCount":42,"UserScore":8,"UserGoal":7},{"UserCount":31,"UserScore":9,"UserGoal":7},{"UserCount":22,"UserScore":10,"UserGoal":7},{"UserCount":29,"UserScore":11,"UserGoal":7},{"UserCount":25,"UserScore":12,"UserGoal":7},{"UserCount":35,"UserScore":13,"UserGoal":7},{"UserCount":42,"UserScore":14,"UserGoal":7},{"UserCount":28,"UserScore":15,"UserGoal":7},{"UserCount":13,"UserScore":16,"UserGoal":7},{"UserCount":12,"UserScore":17,"UserGoal":7},{"UserCount":10,"UserScore":18,"UserGoal":7},{"UserCount":16,"UserScore":19,"UserGoal":7},{"UserCount":23,"UserScore":20,"UserGoal":7},{"UserCount":24,"UserScore":21,"UserGoal":7},{"UserCount":20,"UserScore":22,"UserGoal":7},{"UserCount":12,"UserScore":23,"UserGoal":7},{"UserCount":17,"UserScore":24,"UserGoal":7},{"UserCount":4,"UserScore":25,"UserGoal":7},{"UserCount":14,"UserScore":26,"UserGoal":7},{"UserCount":5,"UserScore":27,"UserGoal":7},{"UserCount":20,"UserScore":28,"UserGoal":7},{"UserCount":16,"UserScore":29,"UserGoal":7},{"UserCount":16,"UserScore":30,"UserGoal":7},{"UserCount":3,"UserScore":31,"UserGoal":7},{"UserCount":7,"UserScore":32,"UserGoal":7},{"UserCount":10,"UserScore":33,"UserGoal":7},{"UserCount":5,"UserScore":34,"UserGoal":7},{"UserCount":14,"UserScore":35,"UserGoal":7},{"UserCount":9,"UserScore":36,"UserGoal":7},{"UserCount":4,"UserScore":37,"UserGoal":7},{"UserCount":3,"UserScore":39,"UserGoal":7},{"UserCount":7,"UserScore":40,"UserGoal":7}]

 

The vertical line should be plotted at the value of UserGoal which always will be the same number for all rows, like 7 in above exampe. I tried using PlotBand with hardcoded value (just for testing) but it doesn't plot at value 7. It probably plots at 7th position. If I use Vertical Chart, it plots from position 0 to 7, a diagonal line.

I can get the value of UserGoal via JQuery instead of getting through WebApi but how can I draw the vertical line on existing graph ?

  

1 Answer, 1 is accepted

Sort by
0
Aleksandar
Telerik team
answered on 22 Jun 2022, 08:25 AM

Hello,

I have provided a response to the support ticket on the same matter and am also posting it here, for the benefit of the community:

The Plot band will position the band on the set index of the category axis. 

I have modified the example to demonstrate how to render a custom plot band, as demonstrated in the knowledgebase article, based on the value of the category, obtained from the model. Here is the updated REPL example.

@functions{
    public class MyModel
    {       
        public int UserCount { get; set; }

        public int UserScore { get; set; }

        public int UserGoal { get; set; }
    }
}

@{
    var desiredCategory = 7;
}

@(Html.Kendo().Chart<MyModel>()
                    .Name("statistics")
                    .Title("User Interaction (Days)")
                    .Legend(legend => legend
                        .Position(ChartLegendPosition.Top)
                    )
                    //.DataSource(ds => ds.Read(read => read.Url("https://run.mocky.io/v3/c6c6267f-18cc-4140-b5a4-37eb766ca35e").Type(HttpVerbs.Get)))
                    .DataSource(ds => ds.Read(read => read.Url("https://run.mocky.io/v3/0c108282-a605-4411-96f3-ee7645432218").Type(HttpVerbs.Get)))
                    .Series(series =>
                    {
                        series.Column(model => model.UserCount).Name("Total").Gap(.2).Color("#4169e1");
                    })
                    .CategoryAxis(axis => axis
                        .Name("categoryAxis")
                        .Categories(a => a.UserScore)
                        .Title("Days")
                    )
                    .ValueAxis(axis => axis.Numeric()
                        .Name("valueAxis")
                        .Labels(labels => labels.Format("{0:N0}"))
                        .MajorUnit(1)
                    )
                    .AxisDefaults(a => a
                        .Labels(l => l.Font("12px Verdana"))
                    )
                    .Tooltip(tooltip => tooltip
                    .Visible(true)
                    .Shared(true)
                    .Format("{0:N0}")
                    )
                    .Zoomable(zoomable => zoomable
                    .Mousewheel(mousewheel => mousewheel.Lock(ChartAxisLock.Y))
                    .Selection(selection => selection.Lock(ChartAxisLock.Y))
                    )
                    .Events(ev=>ev.Render("onRender"))
                    )
<script>
    function onRender(e){

        // Locate value slot
          //
          // https://docs.telerik.com/kendo-ui/api/javascript/dataviz/chart/chart_axis/methods/slot
          var valueAxis = e.sender.getAxis("valueAxis");
          var valueSlot = valueAxis.slot(60);

          // Locate right-most category slot
          //
          var categoryAxis = e.sender.getAxis("categoryAxis");
          var lastCategoryIndex = Math.max(1, categoryAxis.range().max);
          var minCategorySlot = categoryAxis.slot(0);
          var maxCategorySlot = categoryAxis.slot(lastCategoryIndex);
          
          var desiredCategoryPoition = categoryAxis.options.srcCategories.indexOf(@desiredCategory); //pass desired category from model
          var categoryAxisSlot = categoryAxis.slot(desiredCategoryPoition);
          

          // Render a line element
          //
          // https://docs.telerik.com/kendo-ui/api/javascript/dataviz/drawing/text
          var line = new kendo.drawing.Path({
            stroke: {
              color: "red",
              width: 3
            }
          });
          line.moveTo(categoryAxisSlot.origin).lineTo([categoryAxisSlot.origin.x, valueSlot.origin.y]);

          // Render a text element
          //
          // https://docs.telerik.com/kendo-ui/api/javascript/dataviz/drawing/text
          var labelPos = [categoryAxisSlot.origin.x - 50, valueSlot.origin.y - 20];
          var label = new kendo.drawing.Text("UserGoal", labelPos, {
            fill: {
              color: "red"
            },
            font: "14px sans"
          });

          var group = new kendo.drawing.Group();
          group.append(line, label);

          // Draw on chart surface
          //
          // https://docs.telerik.com/kendo-ui/framework/drawing/overview
          e.sender.surface.draw(group);
    }
</script>

Add a render event handler and set the name configuration for both axis. Find the index of the category based on a model value and use it to position the custom band and it's label.

Regards,
Aleksandar
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Tags
Chart
Asked by
Chevron Phillips Chemical Co
Top achievements
Rank 1
Answers by
Aleksandar
Telerik team
Share this question
or