This is a migrated thread and some comments may be shown as answers.

Undesired automatic ZoomScroll selection with no user input

8 Answers 93 Views
Chart
This is a migrated thread and some comments may be shown as answers.
Jon
Top achievements
Rank 1
Jon asked on 20 Dec 2011, 05:16 PM

Hello,

This is a tough one to explain, and even tougher to demonstrate. I've tried to build a sample project to demonstrate this issue, but I'm unable to re-create it in my sample.

This only happens in our full-fledged implementation.

The basic setup is as follows:

When the chart is being rendered, it is receiving data from the server and being rendered like so (slightly obfuscated so that object names aren't specific to my project - anywhere you see "My" is a business object name, but other than that, this code is untouched):

private void buildChart(MyReport report)
{
    // Clear chart
    MyChart.ItemsSource = null;
    MyChart.SeriesMappings.Clear();
    MyChart.DefaultView.ChartTitle.Content = null;
    MyChart.DefaultView.ChartArea.Legend.Items.Clear();
    MyChart.DefaultView.ChartArea.DataSeries.Clear();
    // Set NoDataControl Text
    MyChart.DefaultView.ChartArea.NoDataString = report.NoDataLabel;
    // Axes titles
    MyChart.DefaultView.ChartArea.AxisX.Title = report.XAxisTitle;
    MyChart.DefaultView.ChartArea.AxisY.Title = report.YAxisTitle;
    // Axes setup
    MyChart.DefaultView.ChartArea.AxisY.MinValue = (double) report.YAxisMin;
    MyChart.DefaultView.ChartArea.AxisY.MaxValue = (double) report.YAxisMax;
    MyChart.DefaultView.ChartArea.AxisY.Step = (double) report.YAxisStep;
    // X-Axis Scrolling
    MyChart.DefaultView.ChartArea.ZoomScrollSettingsX.ScrollMode = ScrollMode.ScrollAndZoom;
    MyChart.DefaultView.ChartArea.ZoomScrollSettingsX.MinZoomRange = 0.1;
    MyChart.DefaultView.ChartArea.ZoomScrollSettingsX.RangeStart = (double)report.XAxisScrollRangeStart;
    MyChart.DefaultView.ChartArea.ZoomScrollSettingsX.RangeEnd = (double)report.XAxisScrollRangeEnd;
    // Disable scrolling if the entire chart fits in the render area
    if (report.XAxisScrollRangeStart == 0 && report.XAxisScrollRangeEnd == 1)
    {
        MyChart.DefaultView.ChartArea.ZoomScrollSettingsX.ScrollMode = ScrollMode.None;
    }
    // Show or hide legend based on chart type
    switch (report.ChartType)
    {
        case QasrChartType.Bar:
            MyChart.DefaultView.ChartArea.Legend.Visibility = Visibility.Collapsed;
            break;
        case QasrChartType.Line:
            MyChart.DefaultView.ChartArea.Legend.Visibility = Visibility.Visible;
            break;
        default:
            throw new EnumSwitchException(report.ChartType);
    }
    // If there is no data, hide the legend
    if (report.DataPoints.Count == 0)
    {
        MyChart.DefaultView.ChartArea.Legend.Visibility = Visibility.Collapsed;
    }
    // Create series data
    List<List<MyDataPoint>> seriesData = new List<List<MyDataPoint>>();
    // Create Series Mappings
    int collectionIndex = 0;
    foreach (string seriesName in report.DataPoints.Keys)
    {
        SeriesDefinition seriesDefinition = null;
        switch (report.ChartType)
        {
            case MyChartType.Bar:
                seriesDefinition = new BarSeriesDefinition();
                break;
            case MyChartType.Line:
                seriesDefinition = new LineSeriesDefinition();
                break;
            default:
                throw new EnumSwitchException(report.ChartType);
        }
        // Add series mappings
        SeriesMapping seriesMapping = createSeriesMapping(seriesName, seriesDefinition);
        seriesMapping.CollectionIndex = collectionIndex;
        MyChart.SeriesMappings.Add(seriesMapping);
        // Add series data
        seriesData.Add(new List<MyDataPoint>());
        seriesData[collectionIndex].AddRange(report.DataPoints[seriesName]);
        collectionIndex++;
    }
    // Set chart ItemsSource to the series data
    MyChart.ItemsSource = seriesData;
    if (report.ChartType == MyChartType.Line && report.DataPoints.Count > 0)
    {
        // Legend
        buildLegend();
    }
    // Initial load is complete
    _isInitialLoad = false;
}

Due to the highly dynamic nature of the data, I was forced to use codebehind to setup the chart.

Either way, the following odd behavior occurs:

This chart has clickable data points (the ItemClick event is wired up elsewhere). When any data point is clicked, whether it be a line or bar chart, a new report is retrieved from the server, and the chart is re-rendered.

When re-rendered, the chart automatically puts itself in "user has started zooming with their mouse mode", meaning that the zoom box (the draggable zoom selection area) is drawn. To make matters more odd, by clicking the selection it doesn't actually zoom. The highlight box just disappears.

I have tried everything imaginable to try to fix this issue. Since the only difference between my sample project and the real project is that the Telerik "Vista" theme is used, I'm thinking it may have something to do with that.

I'm at my wits end, however, as to how to workaround the issue.

I have tried the following:

1: Set MyChart.DefaultView.ChartArea.ZoomScrollSettingsX.ScrollMode to ScrollMode.None, then change it back to ScrollMode.ScrollAndZoom after the chart has rendered

2: Tried the above on another thread, where it is set to "None", waits 1 second, then gets set back to ScrollAndZoom. Amazingly, 1 second later, when ScrollAndZoom is turned back on, the highlight box *still* shows up without any user interaction.

 

3: Tried waiting until the DataBound event is fired before changing the ScrollMode back to ScrollAndZoom - same problem.
4: A host of other attempts which all lead to the same problem.

Whatever is happening, it appears that some flag is set after I clear my chart and either before or after I render the chart that says "the user has started zooming in the ChartArea with their mouse", although this isn't the case. Again, actually clicking to "zoom" does nothing - it seems that this flag just puts it in some kind of "draw the highlight area" mode.

I would even settle on a solution that requires me to use reflection to manually set this flag to false if you can point me towards some internal or private property that I can use to force it.

To confound matters even worse, this problem doesn't manifest itself on every chart render, and despite methodically trying to figure out exactly which sequence of events causes this happen, it seems to be completely random.

I know that this is a difficult one because I cannot produce a sample project. My main goal by posting this is in the hopes that you can point me towards some internal / private property that I can force using Reflection.

[Edit: I should mention that I was originally using Q1 2011 and tried upgrading to Q3 2011, but that didn't fix my problem. Issue still persists in Q3 2011]

[Edit 2: Upon further research and some testing, I've discovered that in Silverlight, it's impossible to set a private property (as opposed to full .NET where this isn't a problem). Using Reflector, I was able to determine that the ChartArea.DragZoomLayerControl has a property called "isDragging", which is private, which I have no way to change with these absurd security restrictions in Silverlight. Any other suggestions would be greatly appreciated.]

Thanks for your time on this difficult one,
Jon

 

8 Answers, 1 is accepted

Sort by
0
Peshito
Telerik team
answered on 23 Dec 2011, 01:34 PM
Hello,

Thank you for your detailed explanation about the core of this issue.

I tried to reproduce your issue in a scenario that is closest to yours, but I could not. For your convenience I have attached this project so you could refer to it. In order for us to assist you with a proper solution to the problem could you try to reproduce your issue in this sample, or send us a runnable project where the problem is reproducible(even though having in mind that it is hard to be reproduced, as you already said).

All the best,
Peshito
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Jon
Top achievements
Rank 1
answered on 23 Dec 2011, 04:02 PM
Peshito,

Thank you for your reply. Since this is a rather big issue that I need to fix, I've put considerable more time towards finding a solution.

I'm now convinced that this has something to do with some combination of the Vista theme and related style files that we have imported into our project.

I'm going to try to setup a sample project that includes the theme and all of these styles in the hopes that this will reproduce the issue.

I will post it ASAP.

Thanks again,
Jon
0
Jon
Top achievements
Rank 1
answered on 24 Dec 2011, 11:33 PM
Peshito,

I've gone through the process of importing all styles, etc., and believe it or not, the issue *still* will not reproduce in my sample project. I am now looking down other avenues to determine what it could possibly be.

My goal is to provide you with a sample project as soon as I possibly can.

If I'm not able to reproduce the issue in a sample project, however, would it be possible to setup a Webex (or similar remote viewing technology) to have support on this issue? We would of course considered this paid support. I was just wondering if you provided this type of support, and what the cost would be.

Thanks again for your help,
Jon
0
Giuseppe
Telerik team
answered on 28 Dec 2011, 04:41 PM
Hello Jon,

Generally we have a consulting service that is administered by our partners from Falafel Software, however, I am unsure that this will provide any helpful insight due to the specific nature of the described problem.

While we are still unable to reproduce the problem locally, we have prepared a sample application that demonstrates how you can force the DragZoomLayerControl (the one responsible for the zoom/scroll handling) to handle mouse input or not on demand. In theory this should ensure the correct operation in your scenario as well.

The key here is to toggle the DragZoomLayerControl.IsInteractive dependency property at the right time -- note that the proposed solution uses custom external DependencyPropertyHelper to register for notifications for this property as the property is manipulated internally by the chart control several times and this is the only way that would ensure the forced value (disabled) sticks as long as you need it.

So the workflow is as follows:
  • In ChartArea.ItemClick handler you need to retrieve the DragZoomLayerControl instance and register for change notifications for its DragZoomLayerControl.IsInteractive dependency property (let's say your property changed callback would be IsInteractivePropertyChanged.
  • In the IsInteractivePropertyChanged property changed callback you need to unconditionally force the IsInteractive property to false (this would ensure that the control cannot  enter "user has started zooming with their mouse" mode).
  • In RadChart.DataBound handler you need to undo the forced IsInteractive property value so zooming/scrolling can actually work once again (you do this in a Dispatcher.BeginInvoke(...) block to avoid potential timing issues).

Hope this helps.


All the best,
Giuseppe
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Jon
Top achievements
Rank 1
answered on 28 Dec 2011, 09:22 PM
Thank you for your in-depth response and this sample project. Using Reflector, I did in fact discover the DragZoomLayerControl, specifically the "isDragging" private property, which unfortunately I cannot change in Silverlight (Silverlight has restricted reflection access).

I won't get a chance to look at this in my development environment until at least 1/3/2011, but as soon as I do, I will let you know if I was able to come up with a satisfactory solution.

Thanks again for all your help with this,
Jon
0
Jon
Top achievements
Rank 1
answered on 03 Jan 2012, 09:53 PM
Giuseppe,

I have implemented your sample code in my project verbatim, and believe it or not, the behavior is even a little *more* bizarre. Keep in mind that I am still not able to reproduce any of this in my sample project, but I will try to explain:

With the new code toggling IsInteractive on the DragZoomLayerControl, not only does the "user clicked mouse to start zooming" behavior happen, but it's as if X and Y scrolling is enabled (the "zoom" box draws on the Y axis as well, which didn't happen before). This is odd because I don't have any Y-Axis scrolling (only X).

So basically, it went from "user clicked mouse, draw vertical box from top to bottom of chart, following the X location of the mouse" to "user clicked mouse, draw box with bounds of X and Y location of mouse". Note that as before, clicking does nothing - the box just hides, and if the user subsequently *really* clicks and drags the mouse, zooming works as expected.

This is hard to explain without seeing, so I hope you can understand what I'm trying to describe. If this explanation is confusing in any way, please let me know and I'll try to clarify.

At this point I'm beyond baffled by the behavior - I cannot recreate it nor can I pin down the exact difference between my sample and the real thing - they are nearly identical. If you have any other suggestions, they are of course welcomed. I understand if you can't think of anything else, however.

Thanks again,
Jon
0
Giuseppe
Telerik team
answered on 06 Jan 2012, 01:31 PM
Hello Jon,

This is indeed quite odd. I do understand what you are observing on your end but I really cannot get my head around how this could be happening (especially when forcing the interactive flag).

Should I come up with a new possible suggestion I will follow up here but unfortunately at this point I am really out of ideas as well.


Kind regards,
Giuseppe
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Jon
Top achievements
Rank 1
answered on 06 Jan 2012, 04:11 PM
Giuseppe,

I totally understand, and thank you for your dedicated support on this. I just wish I could re-create this in a sample project, as it is still an issue and will probably end up in production as a known issue on our first release.

Although I need to move on to other things, i will certainly be revisiting this at a point in the future, and should I come up with a demonstrable sample or an outright solution, I will be sure to post it to this thread.

Again, thank you for all your efforts on this. They haven't gone unappreciated.

Thanks again,
Jon
Tags
Chart
Asked by
Jon
Top achievements
Rank 1
Answers by
Peshito
Telerik team
Jon
Top achievements
Rank 1
Giuseppe
Telerik team
Share this question
or