Can't move annotation on an Android chart (Xamarin bindings)


#1

Hi,

I am trying to reproduce the range selector from tutorial serie https://www.shinobicontrols.com/blog/posts/2013/02/20/building-a-range-selector-with-shinobicharts-part-i

Every time I try to move a vertical annotation, nothing happen on the chart (even if forcing the chart to redraw after editing the annotation XValue).
The only working solution is to remove every annotation then recreating them every time I need to move the range selector.

Is this an expected behavior for the Android ShinobiChart?

Regards,

Guillaume.


#2

Hi Guillaume,

This isn’t the expected behaviour - changing the xValue or the yValue and then calling chart.redrawChart() should cause the annotation to visibly move (I’ve just tried doing that very thing on a Nexus 10 and it works fine).

It’s also possible to move annotations based on a touch gesture. The Drag an Object section of https://developer.android.com/training/gestures/scale.html should be quite helpful in this respect. While it’s extending a View, you can instead add an OnTouchListener to an existing View but it’s very similar - it does seem like the example they give however miisses out the step to actually change the position of the View i.e. setX() and setY(). You also might find getRawX() and getRawY() more helpful.

Hopefully that will point you in the right direction!

Kind regards,

Patrick


#3

I should add that I was using native Android but I don’t see any reason why doing this with Xamarin would be any different.

Cheers,

Patrick


#4

Hi Patrick,

Please find in my dropbox a sample to reproduce the issue http://1drv.ms/1G363u1

Concerning how to handle the gesture, as I currently have to remove/add the annotations each time, I can’t associate a gesture listener to them.
Instead, I am using your IShinobiChartOnGestureListener to handle user interaction with the chart. Then I am able to compute gesture position based on expected annotation positions and also neew annotation positions.

Thanks,

Guillaume.


#5

This is becoming problematic on low resources devices as GC has to run more frequently and for a longer time… resulting in several seconds where the app is not responding, resulting in an ANR notification  smiley cry


#6

Hi Guillaume,

Apologies I’ve not been able to look at your sample app sooner but I’ve just downloaded it now (MoveAnnotations).

For me, when I run it, the black vertical bar jumps around when I pan/zoom the chart (so its position is being updated by the RedrawChart() call). However, I would probably not take the Timer approach you have done but instead look to adding an IOnTouchListener to the View from the created Annotation. I know you said that wouldn’t work because you’re having to remove and readd annotations but this way I don’t think you will need to do that.

Have a look at that Drag an Object link I put in my previous reply and see if that helps you move the annotation around with the user gesture.

Kind regards,

Patrick


#7

Hi Patrick,

I expect the vertical bar to move without any user interaction… The RedrawChart is called by the code which update the annotation position.

RunOnUiThread(() => {
                m_MyAnnotation.XValue = DateUtils.ConvertToJavaDate(newPostition);
                chart.RedrawChart();

                Console.WriteLine("The line should now be at {0}", newPostition);
            });

Why would the user have to interact with the chart in order to effectively redraw it…? I need to be able to edit annotations without waiting for user interaction to properly render them.

Is there any other way to achieve it?

Concerning the timer approach, it was for the sample purpose only. In real life situation, I am relying on IShinobiChartOnAxisRangeChangeListener and IShinobiChartOnGestureListener. But updates can also happen due to some Model changes…

Thanks for your help.

Guillaume.


#8

Hello Guillaume.

Thank you for your response.

As my colleague Patrick is away from the office I am going to pick this up. 

I see from running your application that the line annotation maintains its x position during pinch and pan gestures, which is the expected behaviour.

I appreciate that your issue relates to the programmatic setting of the x position of the annotation. Whilst I am not experienced in C#, I gather from looking at your code that you set a timer, which at a 1 second interval updates the X position of the annotation and asks to redraw the chart. As such I am making the assumption that when running your application, the expected behaviour is to see the line annotation move, without needing to make any user gestures on the device. If my understanding of this is incorrect please let me know!

As my colleague Patrick has mentioned, you should be able to set the position of an annotation programmatically, in a similar way to how you have done in your code. This morning I wrote a quick application which simply takes our ‘Quickstart’ application and adds a vertical line annotation. I also added a button which when clicked sets the X value of the annotation and asks the chart to redraw. I observed the line annotation moving along the x axis to the new position.

Whilst I performed this task on a native Android application, I see no reason why this should not also work on Xamarin.

You ask in your question if there is another way to achieve this (programmatically moving the x position of the annotation). I would say that you seem to be already using the correct approach and as such I would try to (temporarily, for testing purposes) simplify the invocation of the x position setting code to rule out any other issues. 

Would it be possible for you to try a simple approach, possibly using a button to set a new x value on your annotation?  We currently are not aware of any issues with the setting of x or y positions of our annotations. Having said that, if you strongly feel that this may be a bug, please contact us an info@shinobicontrols.com and we will certainly look into this further for you.

Thanks and kind regards,

Kai.


#9

Kai,

Again, my sample demonstrate that in a Xamarin.Android app this DOES NOT WORK.

I have updated my sample as you requested to simplify it to a simple action on a button.
It is available here https://onedrive.live.com/redir?resid=3ab57e9b12d17188!2914&authkey=!AE6Pg9B8p4IUw3s&ithint=file%2czip

Am I missing anything obvious?

Thanks,

Guillaume.


#10

Hello Guillaume,

Thank you for your updated application. I have spent some more time looking into this matter, and finally I have been able to reproduce the issue which you are facing. At this stage I think that there may be an issue with our library, but more work is needed by us to accurately pinpoint the issue. Once we have confirmed the exact cause of the issue we will be able to estimate and prioritise any potential fix. 
If you wish us to directly contact you when a fix may become available, please contact us directly at info@shinobicontrols.com and we will add you to our ‘awaiting component release’ list. 

In the meantime I apologise for any issue this may cause you.

Thanks and kind regards,

Kai.


#11

While a fix for this issue has not yet made it into the library, a simple workaround for this problem should be to call requestLayout() on the Annotation’s View after the X and/or Y value has been updated.

Setting the X or Y value of the Annotation won’t in itself kick off a redraw - it was intended that the user call shinobiChart.redrawChart() afterwards (enabling the X and Y values to be updated in one go). However, it seems in some later API versions optimisations to the measure/layout/draw code mean that the (internal) ViewGroup holding the Annotations’ Views is not being re-laid out as it was before. Requesting a layout on the Annotation’s View itself should filter up the View hierarchy to this ViewGroup causing the Annotation’s position to be updated on screen.