ChartRow height doesn't update

Hi, this issue is sort of a continuation of this thread I created:

https://www.syncfusion.com/forums/138304/negative-series-based-on-positive-source-values

where the goal is to display two column series filling the entire vertical space in correct proportion to each other. That aspect has been solved.

The issue I'm having here is that sometimes the row height is not immediately updated visually. Please run the sample. There are two column series: buy volume and sell volume. The max height for buy volume is 80, and for sell volume it's 200. However upon startup, the two chart rows have the same height, which is wrong. Since the max sell volume is greater than for the buy volume, the sell volume chart row should be bigger. Now, click the normal window state button to reduce the window from maximized to normal state. Now, the chart rows appear correctly, with the correct Y axis labels. Next, maximize the window again, and click the 1 day zoom button. The max buy volume y axis label is displayed as 80, but this is wrong, it should be 50. Also, the chart row heights are wrong. Now, slowly drag the scrollbar to the right. Now the y axis label displays 50, and the chart row heights are correct.

From this it seems like there is an issue with the visual updating of the chart row heights, as well as the y axis labels (which is less important as they won't be displayed). As you can see in the two text boxes, the chart row heights are correctly set (the total value of the chart row heights is always 2).

How can this update issue be solved? Also, I'm not sure the way I set the chart row heights (SetChartRowHeights sub) the most efficient or correct way.

Thank you.

Attachment: sfChartNegativeChart4_ca9ad91f.rar

5 Replies

MK Muneesh Kumar G Syncfusion Team August 6, 2018 11:29 AM UTC

Hi Tom, 
 
Greetings from Syncfusion. We have analyzed your requirement and provided sample. We would like to inform you that chart row height calculation done before the axis range visible range calculation, so that the calculated height value has not reflected in chart. We have resolved this problem by setting row height while creating chart as per the below code snippet.  
 
Code snippet [MainWindow .vb]: 
Private Sub chart_Loaded(sender As Object, e As RoutedEventArgs) Handles chart.Loaded 
 
        scrollBar = CType(chart.PrimaryAxis.GetType.GetField("sfChartResizableBar", BindingFlags.NonPublic Or BindingFlags.GetField Or BindingFlags.Instance).GetValue(chart.PrimaryAxis), SfChartResizableBar) 
 
 
        chart.RowDefinitions.Clear() 
 
        AddChartAreas() 
 
        SetChartRowHeights(chart) 
    End Sub 
 
    Sub SetChartRowHeights(inChart As SfChart) 
 
        Dim maxBuyVolume As Double = BaseTicker.Minutes.Max(Function(buy) buy.BuyVolume) 
        Dim maxSellVolume As Double = BaseTicker.Minutes.Max(Function(buy) buy.SellVolume) 
 
        inChart.RowDefinitions(1).Height = (2 * maxBuyVolume) / (maxBuyVolume + maxSellVolume) 'buy row 
        inChart.RowDefinitions(0).Height = (2 * maxSellVolume) / (maxBuyVolume + maxSellVolume) 'sell row 
 
        WinMainInstance.tbRowHeight0.Text = "ChartRow 0 height: " & inChart.RowDefinitions(0).Height 
        WinMainInstance.tbRowHeight1.Text = "ChartRow 1 height: " & inChart.RowDefinitions(1).Height 
 
    End Sub 
 
Note : We have removed the row height value calculation in CustomDateTimeCategoryXAxis class CalculateVisibleRange method. Please find the modified sample from the following location.  
 
 
Please let us know if you have any queries.  
 
Thanks, 
Muneesh Kumar G. 
 



TO Tom August 6, 2018 04:02 PM UTC

Hi Muneesh, I checked your sample, and you've solved the chartrow height issue at the application startup. But now, when pressing the 1 day zoom button the chartrow heights don't update. And they don't update when scrolling the chart, either. In the first section of the chart the row height ratios are 80/40, and in the last section the height ratios are 50/200. So, when viewing only the last section of the chart using for example the 1 day zoom, the sell volume row should be bigger than the buy row, and when viewing only the first section, the buy row should be bigger than the sell row. Therefore, there should be code which sets the chart row heights as the visiblerange of the x axis changes. How to implement this?


MK Muneesh Kumar G Syncfusion Team August 7, 2018 10:47 AM UTC

Hi Tom,  
 
We have resolved the runtime update problem by calling UpdateArea method in dispatcher to refresh the chart again. Here, we have checked the current visible range values to avoid calling this UpdateArea method multiple times. Please find the code snippet below.  
 
Code snippet [ChartExtension.vb] :  
 
Class CustomDateTimeCategoryXAxis 
    Inherits DateTimeCategoryAxis 
 
    Dim previousVisibleRange As DoubleRange 
 
    .. 
 
    'We need to update the secondary axis visible range after the primary axis actual range is updated. 
    Protected Overrides Sub CalculateVisibleRange(avalableSize As Size) 
 
        previousVisibleRange = VisibleRange 
 
        MyBase.CalculateVisibleRange(avalableSize) 
 
        .. 
 
        If (VisibleRange.Start <> previousVisibleRange.Start OrElse VisibleRange.End <> previousVisibleRange.End) Then 
            SetChartRowHeights(sfChart) 
            Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, Sub() UpdateArea()) 
        End If 
 
    End Sub 
 
    Private Sub UpdateArea() 
 
        If (sfChart IsNot Nothing) Then 
            sfChart.GetType().GetMethod("UpdateArea", 
                     BindingFlags.InvokeMethod Or BindingFlags.NonPublic Or BindingFlags.Instance, Nothing, 
                     New Type() {GetType(System.Boolean)}, 
                     Nothing).Invoke(sfChart, New Object() {True}) 
        End If 
 
    End Sub 
 
    Sub SetChartRowHeights(inChart As SfChart) 
 
        Dim maxBuyVolume As Double = WinMainInstance.YAxisVolumeBuy.VisibleRange.End 
        Dim maxSellVolume As Double = WinMainInstance.YAxisVolumeSell.VisibleRange.End 
 
        inChart.RowDefinitions(1).Height = (2 * maxBuyVolume) / (maxBuyVolume + maxSellVolume) 'buy row 
        inChart.RowDefinitions(0).Height = (2 * maxSellVolume) / (maxBuyVolume + maxSellVolume) 'sell row 
 
        WinMainInstance.tbRowHeight0.Text = "ChartRow 0 height: " & inChart.RowDefinitions(0).Height 
        WinMainInstance.tbRowHeight1.Text = "ChartRow 1 height: " & inChart.RowDefinitions(1).Height 
 
    End Sub 
 
End Class 
 
We have modified our sample based on this, please find the sample from the following location.  
 
 
Hope this helps.  
 
Thanks, 
Muneesh Kumar G. 
 



TO Tom August 8, 2018 07:42 PM UTC

Hi Muneesh, unfortunately this line 

Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, Sub() UpdateArea())

causes the chart to become very slow during scrolling with large amount of data.

However, I've solved this issue by having a single row for both buy and sell series and having an extension series for the sell series which converts all values into negative:

Public Class FastColumnBitmapSeriesNegative
    Inherits FastColumnBitmapSeries
    Protected Overrides Sub OnDataSourceChanged(oldValue As IEnumerable, newValue As IEnumerable)
        MyBase.OnDataSourceChanged(oldValue, newValue)

        For i = 0 To YValues.Count - 1 Step 1
            YValues(i) = -YValues(i)
        Next

    End Sub
    Protected Overrides Sub SetIndividualPoint(index As Integer, obj As Object, replace As Boolean)
        MyBase.SetIndividualPoint(index, obj, replace)
        CType(Me.YAxis, Object).IsUpdateNeeded = True

        YValues(index) = -YValues(index)

    End Sub
End Class

Now the regular Y zoom method can be performed. So, with this the issue has been resolved.



PR Padmini Ramamurthy Syncfusion Team August 9, 2018 04:48 AM UTC

Hi Tom, 
  
Glad that the issue has been resolved and please get back to us if you need any other assistance. 
  
Regards, 
Padmini R 


Loader.
Up arrow icon