Any plans for BarSeries with x axis of LinearAxis?

6 posts, 0 answers
  1. Mitchell
    Mitchell avatar
    45 posts
    Member since:
    Mar 2013

    Posted 29 Oct 2014 Link to this post

    I currently provide columns and bar charts with a LinearAxis using a ScatterPointSeries with a custom PointTemplate and SmartLabelStrategy (as suggested in this forum). However, now I need to add functionality for Stacked and Stacked100 bars/columns that are supported by BarSeries.  I would prefer to have less, not more, code just to draw the bars/columns for a LinearAxis.  Are there any plans to support a BarSeries for LinearAxis?  Thanks - Mitch
  2. Petar Marchev
    Admin
    Petar Marchev avatar
    968 posts

    Posted 30 Oct 2014 Link to this post

    Hello Mitch,

    We do not have current plans to introduce a scatter bar series.

    The problem is mainly that a continuous scenario is undefined for categorical entities like bars. Just a quick example - it is easy to draw a bar chart for the categories Banana, Cactus, Orange. Simply, a bar should occupy the whole Banana slot, and slots are easily and uniquely defined.

    On the other hand, we are unsure how to plot nicely bars on a continuous (linear) axis. Say that we have an axis with a range (0, 100) and a step of 20. If we have points with values 10, 86 and 87, how would the bar chart look like?

    Perhaps you can propose a correct and easily comprehensible visualization and if so, please attach snapshot (drawings of some sort) of how you think a scatter bar chart should look like in certain cases. Thank you for understanding.

    Regards,
    Petar Marchev
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  3. UI for WPF is Visual Studio 2017 Ready
  4. Mitchell
    Mitchell avatar
    45 posts
    Member since:
    Mar 2013

    Posted 30 Oct 2014 Link to this post

    I can certainly tell you what I am doing. Whether you think it is a "correct and easily comprehensible visualization" is a matter of opinion :). I am providing a point template in a style for a ScatterPointSeries when using a LinearAxis for the x axis (See below). Because this is a ScatterPointSeries, we are given a point to start our work from. There are 3 value converters in the DataTemplate that do all the work for us:

    columWidgetForLinearAxisConverter - This converter determines how wide the column should be. One of the params for that converter is a property called MinDeltaXForAllSeries. While all the plot data for all the series is being fetched, we calculate what the minimum delta is between any 2 x values in all the series. The requires a dictionary of unique x values & calculating the differences between adjacent values & taking the miminum.  Two other parameters to this converter are the axis ActualVisibleRange min and max.  With that info & the series info, we now know how many pixels correspond to the minimum difference between x values. There are then some decisions made like the bar is at least 1 px wide but no more than .75 times the min delta x. If multiple series are at this x value, then that available space has to be divided accordingly

    scatterBarTranslateTransformConverter - You could have multiple series that occupy the same x value(clustered mode. It's stacked I have yet to implement). The bars need to be ordered based on series order and moved within the calculated space.

    scatterBarHeightConverter - simple calculation for column height using layout slot.

    PointTemplate for the ScatterPointSeries:

    <Setter Property="PointTemplate">
                        <Setter.Value>
                            <DataTemplate>
      
                                <Canvas Height="0" x:Name="OuterCanvas">
                                    <Canvas.Width>
                                        <MultiBinding Converter="{StaticResource columnWidthForLinearAxisConverter}">
                                            <Binding ElementName="TelerikChart" Path="PlotAreaClip"/>
                                            <Binding ElementName="TelerikChart" Path="HorizontalAxis.ActualVisibleRange.Minimum"/>
                                            <Binding ElementName="TelerikChart" Path="HorizontalAxis.ActualVisibleRange.Maximum"/>
                                            <Binding ElementName="TelerikChart" Path="VerticalAxis.ActualVisibleRange.Minimum"/>
                                            <Binding ElementName="TelerikChart" Path="VerticalAxis.ActualVisibleRange.Maximum"/>
                                            <Binding Path="DataItem"/>
                                            <Binding Path="DataContext.MinDeltaXForAllSeries" RelativeSource="{RelativeSource AncestorType={x:Type local:ChartCartesianFlatWidgetViewWPF}}"/>
                                            <Binding Path="DataContext.ChartSeries" RelativeSource="{RelativeSource AncestorType={x:Type local:ChartCartesianFlatWidgetViewWPF}}"/>
                                        </MultiBinding>
                                    </Canvas.Width>
     
                                     <!--Need to shift point because left edge is AT the x value (it's just a point, after all). Different translation values depending on number of series-->
                                    <Canvas.RenderTransform>
                                        <TranslateTransform>
                                            <TranslateTransform.X>
                                                <MultiBinding Converter="{StaticResource scatterBarTranslateTransformConverter}">
                                                    <Binding Path="DataContext.ChartSeries" RelativeSource="{RelativeSource AncestorType={x:Type local:ChartCartesianFlatWidgetViewWPF}}"/>
                                                    <Binding Path="DataItem"/>
                                                    <Binding ElementName="OuterCanvas" Path="ActualWidth"/>
                                                    <Binding ElementName="OuterCanvas" Path="ActualHeight"/>
                                                </MultiBinding>
                                            </TranslateTransform.X>
                                        </TranslateTransform>
                                    </Canvas.RenderTransform>
     
                                    <Border x:Name="ParentBorder" >
                                        <Border.Height>
                                            <MultiBinding Converter="{StaticResource scatterBarHeightConverter}">
                                                <Binding ElementName="TelerikChart"/>
                                                <Binding Path="LayoutSlot"/>
                                                <Binding Path="DataItem"/>
                                                <Binding RelativeSource="{RelativeSource TemplatedParent}" Path="(Canvas.Left)"/>
                                            </MultiBinding>
                                        </Border.Height>
                                        <Border x:Name="MyAnimatedRectangle" Loaded="BarSeriesBorder_Loaded" Width="{Binding ElementName=OuterCanvas, Path=ActualWidth}">
                                            <Border.Background>
                                                <MultiBinding Converter="{StaticResource chartPointColorConverter}">
                                                    <Binding Path="DataContext.TopLevelThemeId" RelativeSource="{RelativeSource AncestorType={x:Type local:ChartCartesianFlatWidgetViewWPF}}"/>
                                                    <Binding Path="DataItem.Color"/>
                                                </MultiBinding>
                                            </Border.Background>
                                        </Border>
                                    </Border>
     
                                </Canvas>
                            </DataTemplate>
                        </Setter.Value>
                    </Setter>


    You end up with results like the attached screenshot (a couple of trivial series, but you get the idea).  Basically the bar width is dependent on the data. If there are 2 points very close to each other relative to the x axis min/max, you get very thin bars.  If the data is more equally spread, you'll get wider bars.

     

  5. Petar Marchev
    Admin
    Petar Marchev avatar
    968 posts

    Posted 30 Oct 2014 Link to this post

    Hi Mitch,

    I am unsure as to why you decided to use a linear horizontal axis. Please see the attached project and snapshot. I have used a categorical series and I pretty much get the same output.

    Do try out the project and see if it makes sense to switch to a categorical mode.

    Regards,
    Petar Marchev
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  6. Mitchell
    Mitchell avatar
    45 posts
    Member since:
    Mar 2013

    Posted 30 Oct 2014 Link to this post

    Ah, my simple example was so simple it was misleading. Imagine sparse data where there are not necessarily points at every integral value. Some something like 1, 4.56, 10.3, 55.3, 57.4, etc.  We need an actual Linear axis because the numbers are significant, not just categories. It's same difference as plotting on a DateTimeCategorical axis vs. a DateTimeContinuous axis.
  7. Petar Marchev
    Admin
    Petar Marchev avatar
    968 posts

    Posted 31 Oct 2014 Link to this post

    Hi Mitchell,

    We would love to see how you think these values should be rendered 1, 4.56, 10.3, 55.3, 57.4.

    Perhaps you will propose a nice and readable display, but may be bars will confuse the reader as the bar has a left and right corner and one may think that it is not a singular value being represented, but a range. From what we know about data viz, continuous and categorical representation do not mix.

    I have also attached a drawing with two very basic charts. The first one has three point denoting where the values are, and the second one has two points. Can you please draw bars in a way you think that is correct?

    I hope you understand why we are asking you let us know how you think these values should be drawn. Thank you for your cooperation.

    Regards,
    Petar Marchev
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
Back to Top
UI for WPF is Visual Studio 2017 Ready