Barchart issue with aligning the bars with the custom ticks

A forum dedicated to WinForms version of LightningChart Ultimate.

Moderator: Arction_LasseP

Post Reply
mahendran_epg
Posts: 2
Joined: Fri Sep 21, 2018 9:05 pm

Barchart issue with aligning the bars with the custom ticks

Post by mahendran_epg » Fri Sep 21, 2018 9:51 pm

Hi Team,

I am currently working on bar chart with custom ticks. I have an issue in aligning the bars with the custom ticks. If you could help me out with that it would be great.

Please find the image attached to get a clear picture of the issue.

I am using the below function to find the x-axis width. I have set the x-axis min as 0 and maximum as 1000 using setRange() function.

private double GetXAixsWidth(LightningChartUltimate _chart)
{
var min = _chart.ViewXY.XAxes[0].ValueToCoordD(_chart.ViewXY.XAxes[0].Minimum);
var max = _chart.ViewXY.XAxes[0].ValueToCoordD(_chart.ViewXY.XAxes[0].Maximum);
return max - min;
}

I am using the below function to set the width of the bar in the bar series.

private void SetBarsWidth(List<double> xValues)
{
List<double> xValues = new List<double> xValues{0,150,300,400,500,700,850,900,1000};
var xAxisWidth = GetXAixsWidth(_chart);
var denom = (double)(xValues.Last() - xValues.First());
var propWidth = xAxisWidth / denom;
for (int index = 0; index < _chart.ViewXY.BarSeries.Count; index++)
{
double cVal = xValues[index + 1] - xValues[index];
var bWid = (double)(cVal * propWidth);
_chart.ViewXY.BarSeries[index].BarThickness = (int)Math.Ceiling(bWid);
}
}

In the above code I am trying to find the total width of the X-axis and find the range of value by subtracting the last first value in the XValues with the last values in the XValues. On dividing the total width by range we are getting the proportional width which is being multiplied with the difference between adjacent values in the XValues to find the appropriate width of the bar based upon the difference in the adjacent values. Please find the below example to understand the approach used to fix the width of the bar.

Example:
XAxisWidth =1200
denom =1000
propWidth = 1200/1000= 1.2

First Bar Width = ((150-100)*1.2) = 60
Second Bar Width = ((300-150)*1.2) = 180

With the above approach I am getting little deviation in the alignment of the bar with the custom ticks, which is highlighted using red box in the attached image file. BarThickness in BarSeries is expecting the width in pixels (integer value) and the ValueToCoordD is returning the coordinate value (float value). On converting float value to integer we are getting a slight variation in the value which makes the alignment of the bar slightly before or after the custom ticks.

Kindly help me out to getting the exact pixel value of the custom ticks or guide me if there is any other approach to fix this issue.
Attachments
Histogram_Allignment_Issue.jpg
Histogram_Allignment_Issue.jpg (49.79 KiB) Viewed 2439 times

ArctionKestutis
Posts: 366
Joined: Mon Mar 14, 2016 9:22 am

Re: Barchart issue with aligning the bars with the custom ti

Post by ArctionKestutis » Mon Sep 24, 2018 2:44 pm

Hi,

What are the settings for BarViewOptions (especially Grouping)?
Could you send whole project to Arction's support account for testing?

All the best.

mahendran_epg
Posts: 2
Joined: Fri Sep 21, 2018 9:05 pm

Re: Barchart issue with aligning the bars with the custom ti

Post by mahendran_epg » Mon Sep 24, 2018 9:12 pm

I am not using any BarViewOptions in the application.

As suggested
1. Sent the sample application to arction's support account(support@arction.com).
2. Attached screenshot of the sample application.
Barcharissue.png
Barcharissue.png (116.16 KiB) Viewed 2433 times
Question: Since the BarThickness is expecting value in pixel, I would like to know if there is any way to find the width of the x-axis (from 0 to 1000 as in attachment) in pixel?
Attachments
BarChart_CustomTicks_Issue.zip
(71.85 KiB) Downloaded 192 times

ArctionKestutis
Posts: 366
Joined: Mon Mar 14, 2016 9:22 am

Re: Barchart issue with aligning the bars with the custom ti

Post by ArctionKestutis » Tue Sep 25, 2018 12:18 pm

Hi,

If you want place Bars at particular value of XAxis, you should set
lightningchart.ViewXY.BarViewOptions.Grouping = BarsGrouping.ByLocation;

The default option ‘ByIndex’ and another option ‘ByIndexFitWidth’ will not rely XAxis. Instead Bars are drawn in the center of the chart without any binding to XAxis. Note, you can pan (drag) Xaxis to any direction and bars will stay at the same place.
Therefore, you need to set Grouping as ByLocation, and only then compare CustomTick and Bar’s location.
Bars_ByLocation.jpg
Bars_ByLocation.jpg (200.16 KiB) Viewed 2429 times
That option alone will basically fix your problem. However, there are several issues in your application I would like to mention.

First, you are using WindowsFormsHost to place Arction Windows Forms controls in WPF. It is allowed, but there are pros and cons for doing that. You can read about those in our User’s Manual. In any case, just to remind you that we have 3 WPF editions, which in most cases better than using WinForm edition through WindowsFormsHost.

Second, you should use axisX.ValueToCoordD(value, FALSE). Please note 2nd argument is set to false, so you can get output as screen pixels not DIP units. In WinForms it is not important, but for WPF it will be a problem in systems with scaling >100%.

Third, your handler of lightningchart.SizeChanged event is not using BeginUpdate-EndUpdate calls. This will be a problem when you will have hundreds or thousands of bar series. Just to remind you that each property change (here BarThickness) will lead to chart rendering. To change properties as a batch use BeginUpdate-EndUpdate call.

Fourth, control Resize event come before Chart is actually rendered. And until chart is not rendered some of properties are not updated yet. This may lead to some unexpected results. I would recommend in SizeChanged event handler subscribe to _chart.AfterRendering event. And only in AfterRendering event handler update bar thickness (please unsubscribe from AfterRendering first). For example,

Code: Select all

            lightningchart.SizeChanged += (sender, val) =>
            {
                lightningchart.AfterRendering += Lightningchart_AfterRendering;
            };

        private void Lightningchart_AfterRendering(object sender, AfterRenderingEventArgs e)
        {
            lightningchart.AfterRendering -= Lightningchart_AfterRendering;
            UpdateBarThickness();
        }
Fifth, although it is not wrong, but good replacement for your GetXAixsWidth method would be
axisX.GetActiveAxisArea().Width

Hope this helps.

Post Reply