I have just started looking at potentially using the MSChart control for .Net 3.5 for a project that will be starting shortly. One of the requirements of the project is that the users be able to zoom into the charts to see small data points more clearly when necessary.
I have looked at a number of tutorials and the either do not mention zooming, or just give a brief bit of information about how to enable it and seem to assume that using it is so obvious that it requires no explanation.
I created a quick test project, added the control to the form, and then added a few Points to the default Series. I then went into the ChartAreas collection and made sure that in the default ChartArea, the Zoomable property was set to True in the ScaleView property of all of the Axis members.
When I run the application my chart shows all correctly, but I cannot fathom any way to zoom into it. I have tried clicking on it, double clicking, the scroll wheel, ctrl-scroll wheel, ctrl-+, and many other things.
I am obviously missing something. Could someone please tell me what I am doing wrong, how I enable the zooming UI, and how I actually use the zooming UI?
I am on Windows 7, using VS2012.
Thank you.
[edit: fixed idiotic spelling error in title]
Doing something like the following should allow you to Zoom using the Mouse Left Click and Drag:
private void ZoomToggle(bool Enabled)
{
// Enable range selection and zooming end user interface
this.cwSubplot.ChartAreas(0).CursorX.IsUserEnabled = Enabled;
this.cwSubplot.ChartAreas(0).CursorX.IsUserSelectionEnabled = Enabled;
this.cwSubplot.ChartAreas(0).CursorX.Interval = 0;
this.cwSubplot.ChartAreas(0).AxisX.ScaleView.Zoomable = Enabled;
this.cwSubplot.ChartAreas(0).AxisX.ScrollBar.IsPositionedInside = true;
this.cwSubplot.ChartAreas(0).AxisX.ScrollBar.ButtonStyle = System.Windows.Forms.DataVisualization.Charting.ScrollBarButtonStyles.SmallScroll;
this.cwSubplot.ChartAreas(0).AxisX.ScaleView.SmallScrollMinSize = 0;
this.cwSubplot.ChartAreas(0).CursorY.IsUserEnabled = Enabled;
this.cwSubplot.ChartAreas(0).CursorY.IsUserSelectionEnabled = Enabled;
this.cwSubplot.ChartAreas(0).CursorY.Interval = 0;
this.cwSubplot.ChartAreas(0).AxisY.ScaleView.Zoomable = Enabled;
this.cwSubplot.ChartAreas(0).AxisY.ScrollBar.IsPositionedInside = true;
this.cwSubplot.ChartAreas(0).AxisY.ScrollBar.ButtonStyle = System.Windows.Forms.DataVisualization.Charting.ScrollBarButtonStyles.SmallScroll;
this.cwSubplot.ChartAreas(0).AxisY.ScaleView.SmallScrollMinSize = 0;
if (Enabled == false) {
//Remove the cursor lines
this.cwSubplot.ChartAreas(0).CursorX.SetCursorPosition(double.NaN);
this.cwSubplot.ChartAreas(0).CursorY.SetCursorPosition(double.NaN);
}
}
Where this.cwSubplot is the Chart object you want zooming to work on.
Related
I am building a game for Windows PCs and I need to change the cursor icon when the user is over clickable UI elements. I have found this command Cursor.SetCursor(texture2d, vector2) but it has some lag.
When the mouse is over the UI elements it changes but it has some delay which is really annoying (This is what other users said about that anyway).
After some reading, I learned that Unity basically just changes the cursor icon in the software level. i.e. Hides the cursor and displays my image, and make it follow the cursor position.
My question is: How can I change the icon in hardware level, again, in windows builds only.
When I searched "Changing mouse cursor in C#", I have found the windows.forms option (which doesn't work in unity) and a c++ code but it wasn't full (Only methods' names), and I don't know how to run it in C#…
The SetCursor not work very good on all Windows app, but is the right way to do it.
Cursor.SetCursor(cursorTexture, hotSpot, cursorMode);
Another way is to make a Little fake hidding the mouse cursor and making a GUI cursor for your desire case. You can add more conditions for each event you like to customize.
var OnMouseEnterCursor:Texture2D;
var cursorSizeX: int = 32; // your cursor width
var cursorSizeY: int = 32; // your cursor height
var MouseEnterCond = false;
function OnMouseEnter()
{
MouseEnterCond = true;
Screen.showCursor = false;
}
function OnMouseExit()
{
MouseEnterCond = false;
Screen.showCursor = true;
}
function OnGUI()
{
if(MouseEnterCond )
{
GUI.DrawTexture (Rect(Input.mousePosition.x-cursorSizeX/2 + cursorSizeX/2, (Screen.height-Input.mousePosition.y)-cursorSizeY/2 + cursorSizeY/2, cursorSizeX, cursorSizeY),OnMouseEnterCursor);
}
}
If there is a way to enforce hardware cursors in Unity the world has not found it yet.
Unity's own documentation explains it pretty well:
A hardware cursor is preferred on supported platforms through the function which you have yourself found (remember to set the cursor-mode to auto), but it will automatically, and uncontrollably, fall back on software for unsupported platforms and resolutions.
An important thing to note is that there is a special field (which the reference only peripherally mentioned) in the project settings/player settings menu called the "Default Cursor".
This is the only supported hardware cursor on e.g. windows store apps.
And remember to set your textures to type "cursor" in their configurations,.
Finally, keep in mind that windows only supports the 32x32px size. This may force Unity's hand when selecting the render type.
The default cursor settings in the player settings worked in the editor but it did not show up in a build. Also limiting the texture size to 32x32. I resolved this issue by using Cursor.SetCursor method in a script to change the cursor.
[SerializeField] Texture2D cursor;
void Start() {
Cursor.SetCursor(cursor, Vector3.zero, CursorMode.ForceSoftware);
}
I have two UWP apps and after testing them out with Continuum I noticed the app bar of the OS (the bar with the Start button) at the bottom of the screen (it can be at each of the 4 edges of the screen, of course) was covering part of my app.
Now, I'm already using ApplicationView.GetForCurrentView().SetDesiredBoundsMode(ApplicationViewBoundsMode.UseVisible) before calling Window.Current.Activate(), but that doesn't seem to solve the issue.
1) Why is it that setting the DesiredBoundsMode property doesn't seem to work here? Shouldn't that automatically resize the window
content to the visible bounds (ie. excluding system overlays like the
navigation bar or the app bar)?
The workaround I'm using for now on Windows 10 Mobile devices is to subscribe to the VisibleBoundsChanged event and then manually adjust the margins of my Window.Current.Content item to make sure it doesn't show anything behind covered areas of the screen.
Basically, I use the Window.Current.Bounds property and the ApplicationView.VisibleBounds property to calculate the occluded areas on the different edges of the app window, and increase the margins from there.
2) Is there a proper/better way to do this?
I mean, I'm quite sure there's another method that should be used to avoid this issue (considering there are tons of different situations like Continuum, navigation bar etc... that I don't think are supposed to be manually handled one by one).
Thank you for your help!
Use the subscription to the event VisibleBoundsChanged. This is the best solution that I found.
var curr = ApplicationView.GetForCurrentView();
if (curr.IsFullScreenMode == true)
{
ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.FullScreen;
curr.FullScreenSystemOverlayMode = FullScreenSystemOverlayMode.Minimal;
}
else
{
ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.Auto;
curr.FullScreenSystemOverlayMode = FullScreenSystemOverlayMode.Standard;
}
I have created a chart in the image below and I need to insert in addition to the existing labels, the end labels on the extreme left and right of the x-axis. There are numerous datapoints and therefore I cannot set the interval to 1 for the labels as they'll clutter the axis. I have already tried setting the property
chartHistory.ChartAreas[0].AxisX.LabelStyle.IsEndLabelVisible = true;
but it doesn't seem to work. How can I achieve this?
You may try:
chartHistory.ChartAreas[0].AxisX.IsMarginVisible = true;
chartHistory.ChartAreas[0].AxisX.LabelStyle.IsEndLabelVisible = true;
Or probably you will have to add the labels yourself,
you can either use DataPoint.AxisLabel:
chartHistory.Series[0].Points[0].AxisLabel = "5/4/2010";
or more flexibly:
chartHistory.Series[0].Points[0].AxisLabel =
System.DateTime.FromOADate(chartHistory.Series[0].Points[0].XValue).ToShortDateString();
(and the same for the last point in series)
or you can add a custom label to the AxisX control:
chartHistory.ChartAreas[0].AxisX.CustomLabels.Add(0, 20, "5/4/2010");
See also this answer and this answer.
I am working on a Windows Store App using C#.
I am trying to change the cursor when the user hover over a rectangle but it is causing me problems.
Here is my code:
Rectangle item = sender as Rectangle;
item.Cursor = Cursors.AppStarting;
mouseVerticalPosition = e.GetCurrentPoint(null).Position.Y;
mouseHorizontalPosition = e.GetCurrentPoint(null).Position.X;
isMouseCaptured = true;
item.CapturePointer(e.Pointer);
It says 'Windows.UI.Xaml.Shapes.Rectangle' does not contain a definition for 'Cursor'.
You're confusing WPF with WinRT/XAML. These are both XAML-based UI technologies, but although superficially similar when looking at some basic controls and properties - these are completely separate implementations that have many differences once you start looking at the details. One of these is the Cursor property missing in the Windows Runtime.
You can use Window.Current.CoreWindow.PointerCursor property to get or set the cursor on the current window.
You can also use some attached behaviors I wrote in WinRT XAML Toolkit here to get an API similar to the WPF one where you set a cursor per element. There's a sample you can check here that shows how you can set a cursor on an element like this:
Extensions:FrameworkElementExtensions.SystemCursor="Arrow"
I have a question about zooming and scrolling. My scroll function doesn't work perfectly, but close enough. Instead of the Maximum value I want to change the ActualMaximum, but that one was protected.
plotBSITotalA.Model.Axes[0].Maximum = hScrollBarA.Value +
(plotBSITotalA.Model.Axes[0].ActualMaximum - plotBSITotalA.Model.Axes[0].ActualMinimum);
plotBSITotalA.Model.Axes[0].Minimum = hScrollBarA.Value;
Ok, here comes the real problem: When I have zoomed in or out, the scroll function won't work anymore in that specific plot Area, where it have been zoomed. Other plotArea's that weren't zoomed, will work perfectly.
Does somebody know, how I can scroll when I zoomed in??
May be, It can be done by connecting two enevts with two methods:
1. event emitted when scrollbar changed with method of changing axes range
2. event emitted when axes range changed with method of changing the scrollbar position
Quite a few views, so maybe still a problem.
As I understand it, your saying the auto scroll stops when you have zoomed back out and subsequently add new values to the series?
Can't find a formal solution, but this works for me
add this to your axis:
xAxis.AxisChanged += OnXAxisChange;
add the method
bool doAxisReset = false;
private void OnXAxisChange(object sender, AxisChangedEventArgs e)
{
//if zoomed fully out, then enable auto scroll
//
if ((e.DeltaMaximum == 0) && (e.DeltaMinimum == 0))
{
doAxisReset = true;
}
}
In the rendering code (ie when you get a new element that triggers autoscrolling) and before InvalidatePlot
if (doAxisReset)
{
xAxis.Reset();
doAxisReset = false;
}