MS chart zoom the chart to a region - core

I created a test project where I have a Chart on a .net core 3 winforms project. I also have a data grid that shows related data, I would like to click on the row in my grid and then Zoom into that region on the chart.
I have the DataPoint and know the duration however how to zoom into to that timespan without loosing the Hight of my YAxis?
This Zooms but also cuts of the YAxis work
DataPoint dp = LocationOnChart((double)td.Bar.Close, td.Date.AddSeconds(-5));
chart.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
chart.ChartAreas[0].AxisX.ScrollBar.IsPositionedInside = true;
chart.ChartAreas[0].AxisX.ScrollBar.ButtonStyle = System.Windows.Forms.DataVisualization.Charting.ScrollBarButtonStyles.SmallScroll;
chart.ChartAreas[0].AxisX.ScaleView.SmallScrollMinSize = 0;
chart.ChartAreas[0].CursorY.IsUserEnabled = false;
chart.ChartAreas[0].CursorY.IsUserSelectionEnabled = false;
chart.ChartAreas[0].AxisY.ScaleView.Zoomable = true;
chart.ChartAreas[0].AxisY.ScrollBar.IsPositionedInside = true;
chart.ChartAreas[0].AxisY.ScrollBar.ButtonStyle = System.Windows.Forms.DataVisualization.Charting.ScrollBarButtonStyles.SmallScroll;
chart.ChartAreas[0].AxisY.ScaleView.SmallScrollMinSize = 0;
chart.ChartAreas[0].AxisX.ScaleView.Position = dp.XValue;
chart.ChartAreas[0].AxisY.ScaleView.Position = dp.YValues[0];
chart.ChartAreas[0].AxisX.ScaleView.MinSize = (td.Ended.Value-td.Date).TotalSeconds+5;
chart.ChartAreas[0].AxisX.ScaleView.MinSizeType = DateTimeIntervalType.Seconds;
chart.ChartAreas[0].AxisX.ScaleView.Scroll(td.Date);
chart.ChartAreas[0].AxisX.ScaleView.Zoom(dp.XValue,chart.ChartAreas[0].AxisX.ScaleView.MinSize,DateTimeIntervalType.Seconds);
chart.ChartAreas[0].AxisY.ScaleView.MinSize = chart.ChartAreas[0].AxisY.ScaleView.ViewMaximum;
The method LocationOnChart is defined like this:
private DataPoint LocationOnChart(double price, DateTime time)
{
var y = TradeChart.ChartAreas[0].AxisY.ValueToPosition(price);
var x = TradeChart.ChartAreas[0].AxisX.ValueToPosition(time.ToOADate());
return new DataPoint(x, y);
}

Related

ListView with only 1 column is not filling the whole width

I have a list view that gets populated dynamically each time a new message comes in. I did not add a column to the collection in the designer since I only need 1 column. But when the new message comes in, the "listview" gets populated but the single column is not taking the whole width of the listview.
lvRfidMessages.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
lvRfidMessages.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
string[] rowData = { e };
var lvItem = new ListViewItem(rowData);
lvRfidMessages.Items.Add(lvItem);
The design
this.lvRfidMessages.ForeColor = System.Drawing.Color.DimGray;
this.lvRfidMessages.FullRowSelect = true;
this.lvRfidMessages.GridLines = true;
this.lvRfidMessages.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
this.lvRfidMessages.HideSelection = false;
this.lvRfidMessages.Location = new System.Drawing.Point(0, 64);
this.lvRfidMessages.Name = "lvRfidMessages";
this.lvRfidMessages.Size = new System.Drawing.Size(182, 185);
this.lvRfidMessages.TabIndex = 3;
this.lvRfidMessages.UseCompatibleStateImageBehavior = false;

Resizing of an AutoScroll Panel affects scrolled position

When I resize the following form with the right resize handle, the contained TableLayoutPanel gets decorated with scroll bars (as intended, panel1.AutoScroll = true) for smaller form sizes, but the TableLayoutPanel also gets displaced from its original position. See images below: after resizing the form with right resize handle only, the second one has its scroll bars not leftmost and the left border of the content is cut off.
It seems somehow that this behavior is tied to the existence of the nested RadioButtons because if I remove them (or replace them by another TextBox for example), the "normal" behavior is restored (TableLayoutPanel stays in place during resize).
What properties do I have to set in order to keep the content always stationary relative to the (top)left borders?
BTW: When I replace the panel1 by a TabControl + one TabPage, the "normal" behavior is also restored.
using System;
using System.Drawing;
using System.Windows.Forms;
namespace Test
{
/// <summary>
/// Description of Form3.
/// </summary>
public partial class Form3 : Form
{
const int textBoxNameWidth = 500;
TableLayoutPanel testControl1;
Panel panel1;
TextBox textBoxName;
RadioButton radioButtonNo;
RadioButton radioButtonYes;
TableLayoutPanel tableLayoutPanelDecision;
public Form3()
{
testControl1 = new TableLayoutPanel();
panel1 = new Panel();
textBoxName = new TextBox();
radioButtonNo = new RadioButton();
radioButtonYes = new RadioButton();
tableLayoutPanelDecision = new TableLayoutPanel();
testControl1.AutoSize = true;
testControl1.AutoSizeMode = AutoSizeMode.GrowAndShrink;
testControl1.Location = new Point(0, 0);
testControl1.Dock = DockStyle.None;
testControl1.ColumnCount = 2;
testControl1.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
testControl1.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
testControl1.RowCount = 2;
testControl1.RowStyles.Add(new RowStyle(SizeType.AutoSize));
testControl1.RowStyles.Add(new RowStyle(SizeType.AutoSize));
testControl1.Controls.Add(textBoxName, 1, 0);
testControl1.Controls.Add(tableLayoutPanelDecision, 1, 1);
textBoxName.Text = "New Boolean";
textBoxName.TextAlign = HorizontalAlignment.Center;
textBoxName.Anchor = (AnchorStyles.Left | AnchorStyles.Right);
textBoxName.TabStop = false;
textBoxName.Width = textBoxNameWidth;
tableLayoutPanelDecision.AutoSize = true;
tableLayoutPanelDecision.ColumnCount = 2;
tableLayoutPanelDecision.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50f));
tableLayoutPanelDecision.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50f));
tableLayoutPanelDecision.RowCount = 1;
tableLayoutPanelDecision.RowStyles.Add(new RowStyle(SizeType.AutoSize));
tableLayoutPanelDecision.Controls.Add(radioButtonYes, 0, 0);
tableLayoutPanelDecision.Controls.Add(radioButtonNo, 1, 0);
tableLayoutPanelDecision.Dock = DockStyle.Fill;
radioButtonNo.Checked = true;
radioButtonNo.AutoSize = true;
radioButtonNo.TabIndex = 1;
radioButtonNo.TabStop = true;
radioButtonNo.Text = "False";
radioButtonNo.UseVisualStyleBackColor = true;
radioButtonNo.Anchor = AnchorStyles.None;
radioButtonYes.AutoSize = true;
radioButtonYes.TabIndex = 0;
radioButtonYes.Text = "True";
radioButtonYes.UseVisualStyleBackColor = true;
radioButtonYes.Anchor = AnchorStyles.None;
panel1.AutoScroll = true;
panel1.Controls.Add(testControl1);
panel1.Dock = System.Windows.Forms.DockStyle.Fill;
panel1.Location = new System.Drawing.Point(0, 0);
panel1.Name = "panel1";
panel1.Size = new System.Drawing.Size(560, 219);
panel1.TabIndex = 1;
AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
ClientSize = new System.Drawing.Size(560, 219);
Controls.Add(panel1);
Name = "Form3";
Text = "Form3";
}
}
}
The panel is trying to keep focusable controls within view for the user. To change that, you would have to use your own panel:
public class PanelEx : Panel {
protected override Point ScrollToControl(Control activeControl) {
return this.DisplayRectangle.Location;
}
}

Scaling and moving an item at the same time

I'm trying to create a storyboard that scales and moves an element to a specific position. The basic idea is there are a row of 6 small cards, clicking on one will zoom into a more detailed image, starting from the position and size of the small card and ending up with a large centered card.
The card doesn't end up in the X,Y position I specify, I believe because the scaletransform is also moving it. I saw that a matrixtransform may work, but couldn't get it to work, at least in WP8. Here is my original code, card is the small card for starting location, item is the large detailed card to be scaled and moved
private void ZoomIn(UIElement item, UIElement card)
{
// setup
var _Scale = new ScaleTransform
{
ScaleX = 1,
ScaleY = 1,
CenterX = item.RenderSize.Width / 2,
CenterY = item.RenderSize.Height / 2,
};
var transform = card.TransformToVisual(Application.Current.RootVisual as FrameworkElement);
Point absolutePosition = transform.Transform(new Point(0, 0));
var _Translate = new TranslateTransform();
var _Group = new TransformGroup();
_Group.Children.Add(_Scale);
_Group.Children.Add(_Translate);
item.RenderTransform = _Group;
// animate
var _Storyboard = new Storyboard { };
// scale X
var _ScaleAnimateX = new DoubleAnimation
{
To = 1.0,
From=0.5,
Duration = TimeSpan.FromSeconds(.25)
};
_Storyboard.Children.Add(_ScaleAnimateX);
Storyboard.SetTarget(_ScaleAnimateX, _Scale);
Storyboard.SetTargetProperty(_ScaleAnimateX,
new PropertyPath(ScaleTransform.ScaleXProperty));
// scale Y
var _ScaleAnimateY = new DoubleAnimation
{
To = 1.0,
From = 0.5,
Duration = TimeSpan.FromSeconds(.25)
};
_Storyboard.Children.Add(_ScaleAnimateY);
Storyboard.SetTarget(_ScaleAnimateY, _Scale);
Storyboard.SetTargetProperty(_ScaleAnimateY,
new PropertyPath(ScaleTransform.ScaleYProperty));
// translate (location X)
var _TranslateAnimateX = new DoubleAnimation
{
From = absolutePosition.X,
To = 300,
Duration = TimeSpan.FromSeconds(.25)
};
_Storyboard.Children.Add(_TranslateAnimateX);
Storyboard.SetTarget(_TranslateAnimateX, _Translate);
Storyboard.SetTargetProperty(_TranslateAnimateX,
new PropertyPath(TranslateTransform.XProperty));
// translate (location Y)
var _TranslateAnimateY = new DoubleAnimation
{
From = absolutePosition.Y,
To = 40,
Duration = TimeSpan.FromSeconds(.25)
};
_Storyboard.Begin();
}
I found the solution, the panel with the zoomed card didn't have a horizontal/vertical alignment, I set it to left/top, used CenterX/CenterY of 0, and movements are now pixel perfect

List View doesn't render items in Details view

VariableBox = gcnew ListView();
VariableBox->Font = ScriptEditorOptions->FontSelection->Font;
VariableBox->Dock = DockStyle::Fill;
VariableBox->BorderStyle = BorderStyle::Fixed3D;
VariableBox->BackColor = ScriptEditorOptions->BCDialog->Color;
VariableBox->ForeColor = ScriptEditorOptions->FCDialog->Color;
VariableBox->DoubleClick += gcnew EventHandler(this, &ScriptEditor::VariableBox_DoubleClick);
VariableBox->View = View::Details;
VariableBox->MultiSelect = false;
VariableBox->CheckBoxes = false;
VariableBox->FullRowSelect = true;
VariableBox->HideSelection = false;
VariableBox->Tag = (int)1;
ColumnHeader^ VariableBoxName = gcnew ColumnHeader();
VariableBoxName->Text = "Variable Name";
VariableBoxName->Width = 70;
ColumnHeader^ VariableBoxType = gcnew ColumnHeader();
VariableBoxType->Text = "Type";
VariableBoxType->Width = 50;
ColumnHeader^ VariableBoxIndex = gcnew ColumnHeader();
VariableBoxIndex->Text = "Index";
VariableBoxIndex->Width = 50;
VariableBox->Columns->Add(VariableBoxName);
VariableBox->Columns->Add(VariableBoxType);
VariableBox->Columns->Add(VariableBoxIndex);
VariableBox->ColumnClick += gcnew ColumnClickEventHandler(this, &ScriptEditor::VariableBox_ColumnClick);
I have the above code in a WinForms application. The control is added to the main form directly. For some reason, it never renders any items or columns when the layout is set to Details - Only the scroll bars are visible. The following code is used to add items to its collection:
ListViewItem^ Item = gcnew ListViewItem("Qw");
Item->SubItems->Add("Int");
Item->SubItems->Add("10");
VariableBox->Items->Add(Item);
Switching to any other view (at either run-time or design-time) fixes the issue. Any ideas on why this is happening ?
EDIT: Bump! Or is that not allowed ?
Turns out that I was removing the column headers before the control was displayed.

WPF image thumbnail with the offset

I have an image 800x600 and I would show a thumbnail 90x30 with some offset x=12 and y 12.
I have created a brush but I am struggling to apply an offset.
var source = new ImageBrush(groundSource);
source.Stretch = Stretch.None;
source.AlignmentX = AlignmentX.Left;
source.AlignmentY = AlignmentY.Top;
source.RelativeTransform = new TranslateTransform(0.5, 0);
var grid = new Grid();
grid.ClipToBounds = true;
grid.Background = source;
grid.VerticalAlignment = System.Windows.VerticalAlignment.Top;
grid.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
grid.Margin = new System.Windows.Thickness(12, 12, 0, 0);
grid.Width = SpriteSize.SpriteWidht + 33;
grid.Height = SpriteSize.SpriteHeight;
grid.SnapsToDevicePixels = true;
I would appreciate any suggestions.
There is a hacky solution for this problem:
Add Image as a child to the Grid.
Set Grid attribute as ClipToBounds=true
Set Image margin to control thumbnail offset.

Resources