Show mouse's position on a logarithmic axis on a chart in vb.net - vb.net

I'm working with a MSchart and I'm trying to figure out how to show the x-axis value based on the mouse's position in the graph. It only shows when the mouse is on a datapoint. The y-axis is scaled linearly and works as it should.
The x-axis however doesn't since it is logarithmic and gives me results this:
(0 = 0, 10 = 1, 100 = 2, 1000 = 3)
Where x = 10, it gives me a returned value of 1, where x = 100, it gives me a returned value of 2, and etc.
dim position = e.Location
dim result = myChart.hitTest(position.x, position.y)
etoolTip.active = true
if(result.ChartElementType = DataVisualization.Charting.ChartElementType.datapoint)
dim x = result.ChartArea.AxisX.PixelPositionToValue(position.x)
dim y = result.chartarea.axisy.pixelPositionToValue(position.y)
etoolTip.SetToolTip(phaseNoiseChart, "X:"&x &"Y:"&y)
else
etoolTip.active = false
End If
How do I get the x-axis's true position based on the mouse's position for an axis that is logarithmic?

since the code belongs to mouse move event
e.X will give you the x co-ordinate
e.Y will give you the y co-ordinate

I clearly didn't understand what those numbers meant until I realized what the answer was telling me. The way I turn it back into actual coordinates is by 10^x.
dim x = result.ChartArea.AxisX.PixelPositionToValue(position.x)
x = 10^x
dim y = result.chartarea.axisy.pixelPositionToValue(position.y)
etoolTip.SetToolTip(phaseNoiseChart, "X:"&x & "Y:"&y)

Related

How to change Hole Table axis orientation via SolidWorks API?

Is there a way to change orientation (direction) of Hole Table axes with SolidWorks API?
I can do it manually by dragging the handles but recorded VBA macro does not contain actual changes.
This is what I would like to achieve:
Before
After
I don't have Visual Studio Tools on this PC so I cannot record a C# or VB macro and see if it contains more code. If somebody could check that on their PC I would be grateful.
I have figured it out. This time digging through SolidWorks API Help was useful.
By using HoleTable.DatumOrigin.SetAxisPoints() method it is possible to change points that define the Hole Table axes.
Important to notice is that SetAxisPoints() changes only the end points of the axis arrows (tips of the arrowheads). Start points get updated automatically.
You can get current point values with HoleTable.DatumOrigin.GetAxisPoints2() method.
Another thing to notice is that values in the hole table do not get updated automatically. They did update after I manually dragged a an axis point.
To get them update by the code set HoleTable.EnableUpdate property to False before and back to True after the call to SetAxisPoints().
Here is the code excerpt that does what I needed:
Dim ht As SldWorks.HoleTable
Dim htdo As SldWorks.DatumOrigin
Dim htdaxpts() As Double
Dim htdaxptsnew(0 To 3) As Double
Dim ystarty As Double
Dim yendx As Double
Dim yendy As Double
Dim xstartx As Double
Dim xendx As Double
Dim xendy As Double
'...
'here comes code to prepare for Hole Table insertion
'...
'insert the Hole Table
Set htann = theView.InsertHoleTable2(False, anchorx, anchory, swBOMConfigurationAnchor_BottomLeft, "A", holetemplatepath)
If Not htann Is Nothing Then
Set ht = htann.HoleTable
Set htdo = ht.DatumOrigin
'disable hole table update to get it refresh when done
ht.EnableUpdate = False
'get coordinates of the axis arrows (4 pairs of (x,y) doubles: X start(0,1), X end(2,3), Y start(4,5), Y end(6,7))
htdaxpts = htdo.GetAxisPoints2()
'take the values we use
xstartx = htdaxpts(0)
xendx = htdaxpts(2)
xendy = htdaxpts(3)
ystarty = htdaxpts(5)
yendx = htdaxpts(6)
yendy = htdaxpts(7)
'change direction only if Y arrow points up
If ystarty < yendy Then
yendy = ystarty - (yendy - ystarty)
End If
'change direction only if X arrow points left
If xstartx > xendx Then
xendx = xstartx - (xendx - xstartx)
End If
'change position only if X arrow is below Y arrow
If xendy < ystarty Then
'we can change end point only so change X end y only
xendy = xendy + (ystarty - xendy) * 2
End If
'prepare new axis points (2 pairs of (x,y) doubles: X end(0,1), Y end(2,3))
htdaxptsnew(0) = xendx
htdaxptsnew(1) = xendy
htdaxptsnew(2) = yendx
htdaxptsnew(3) = yendy
'set new axis end points
htdo.SetAxisPoints htdaxptsnew
'enable hole table update to refresh the values
ht.EnableUpdate = True
End If

Is there a way to plot a line graph with integer x values but label each point on the x axis with a string?

I'm producing a line graph and I'm plotting points according to x and y values using points.addxy(X, Y). However the xvalues are plotted through regular intervals which I want to have labeled below the axis. My code is below:
Dim AllRaceArray() As String = GetAllRaceArray() 'Array of The race names in date order
Dim RaceIDs() As Integer = GetAllRaceID() 'Array Of The Race IDs Paralell to the above array
Dim Xnum As Integer = AllRaceArray.Length
Dim Interval As Integer = Math.Floor(Chart1.Size.Width / Xnum)
Chart1.Series.Clear()
For i = 0 To 3
If CompareSlotEmpty(i) = False Then
Chart1.Series.Add(i & CompPaddler(i).Name)
Chart1.Series(i).ChartType = SeriesChartType.Line
Chart1.Series(i).XValueType = ChartValueType.String
Chart1.Series(i).BorderWidth = 2
Chart1.Series(i).MarkerStyle = DataVisualization.Charting.MarkerStyle.Circle
Chart1.Series(i).MarkerSize = 8
For p = 0 To Xnum - 1
For q = 0 To CompPaddler(i).RacePoints.Length - 1
If CompPaddler(i).RacePoints(q).RaceID = RaceIDs(p) Then
Chart1.Series(i).Points.AddXY(Interval * p, CompPaddler(i).RacePoints(q).Points) ' this point plot creates the correct ordering
Chart1.Series(i).Points.AddXY(AllRaceArray(p), CompPaddler(i).RacePoints(q).Points) ' this point plot creates the correct labels
End If
Next
Next
End If
' EDIT
' This below Section has now been added but nothing appears below the axis at all now
For t = 0 To Chart1.Series(i).Points.Count - 1
Chart1.Series(i).Points(t).AxisLabel = AllRaceArray(t)
Next
'EDIT
Next
As annotated above One chart series creates the correct looking graph (http://tinypic.com/r/sobwbc/9) but x axis labels. Then the second plotter plots the correct labels but the ordering and scale gets messed up (http://tinypic.com/r/2w2g5s4/9).
TLDR: How to I change the xAxis Labels to strings that line up with regularly interval points?
Edit: I have added a loop to change the .axislabel but now nothing shows below the axis

How can I automate the coloring of the dots(series) in a Scatter Plot?

http://s3.dosya.tc/server11/yvuh7e/v7m_Quadrant.zip.html
Attached you can find the table that I need help with. In "M Quadrant" sheet I have a graph and a pivot table. There's also a combobox which switches between some names and changes the pivot table therefore the graphic.
What I need is somehow automate the color of the series. When I change to a new name the series remain with their old color, i would like to have the colors via below criterias
X axis positive, Y axis positive = Green
X axis positive, Y axis negative = Orange
X axis negative, Y axis positive = Blue
X axis negative, Y axis negative = Red
or
this information is also recorded in "M Grafik" sheet, which is the resource of the pivot table, at N Column . Here are some translations :
Yeşil = Green, Kırmızı = Red, Mavi = Blue, Turuncu = Orange
I would like to add the solution below my button and combobox macros. So everytime I change the graphic, colorin should re-run.
Also a screenshot here :
Best Regards
You can use a method like this to get the X- and Y-Values from the Series objects, and then conditionally apply the R/G/B color to each Point's Fill.ForeColor and Fill.BackColor:
Sub foo()
Dim cht As Chart
Dim srs As Series
Dim pt As Excel.Point
Dim x, y
Dim s As Long
Dim p As Long
Set cht = ActiveSheet.ChartObjects(1).Chart '## Modify if needed
'Loop all series in this chart
For s = 1 To cht.SeriesCollection.Count
Set srs = cht.SeriesCollection(s)
'Loop all point in this series
For p = 1 To srs.Points.Count
'Get the x and y value of this point
x = srs.XValues(p)
y = srs.Values(p)
Set pt = srs.Points(p)
pt.Select
'assign color based on x and y value
'## NOTE: YOU NEED TO SPECIFY THE R/G/B PARAMETERS FOR EACH.
Select Case True
Case x >= 0 And y >= 0 'Green
pt.Format.Fill.ForeColor.RGB = RGB(0, 255, 0)
pt.Format.Fill.BackColor.RGB = RGB(0, 255, 0)
Case x >= 0 And y < 0 'Orange
'pt.Format.Fill.ForeColor.RGB = RGB(,,)
'pt.Format.Fill.BackColor.RGB = RGB(,,)
Case x < 0 And y >= 0 'Blue
'pt.Format.Fill.ForeColor.RGB = RGB(0,0,255)
'pt.Format.Fill.BackColor.RGB = RGB(0,0,255)
Case x < 0 And y < 0 'Red
'pt.Format.Fill.ForeColor.RGB = RGB(255,0,0)
'pt.Format.Fill.BackColor.RGB = RGB(255,0,0)
End Select
Next
Next
End Sub
Add four columns to your source data for green, orange, blue, red. Use formulas to pull the data from the original data column, according to the conditions you listed above.
Add the four new columns to the scatter chart as new series. Format each series to its respective marker color. Remove the original data series.

Smaller margin on VB.NET Chart

Is there a way to customize the margin between the first bar chart and the Y-Axis?
I'm aware that there is the possibility to set IsMarginVisible to False:
.AxisX.IsMarginVisible = False
But I don't want to remove the margin completely, I just would like to adjust it a bit. In âddition, I would like to adjust the margin between the "ticks" and the label text. Here is an example:
Here is how the chart looks right now
And how it should look like (space in front and after the "ticks")
Do you have an idea how to solve this problem?
Unfortunately, it looks like that there is no margin property in the way I would have liked one. But I stumbled upon this article today: http://support2.dundas.com/Default.aspx?article=869
My workaround was to set the MajorTickMark to the size of the ticks I wanted to have + the margin. Then I set the color to transparent.
Chart1.ChartAreas(0).AxisY.MajorTickMark.Size = size
Chart1.ChartAreas(0).AxisY.MajorTickMark.LineColor = Color.FromArgb(0, 0, 0, 0)
After that, I just added a HorizontalLineAnnotation for every row in the size and place I wanted.
Dim minValue As Double = Chart1.ChartAreas("ChartArea").AxisY.Minimum
Dim maxValue As Double = Chart1.ChartAreas("ChartArea").AxisY.Maximum
Dim iteration As Integer = CInt((Math.Abs(minValue) + Math.Abs(maxValue )) / interval)
For i As Integer = 0 To iteration
Dim line As New HorizontalLineAnnotation()
With line
.AxisX = Chart1.ChartAreas("ChartArea").AxisX
.AxisY = Chart1.ChartAreas("ChartArea").AxisY
.AnchorX = 0
.Y = i * interval - Math.Abs(minValue)
.AnchorOffsetX = offset
.Height = 0
.LineWidth = 1
.Width = (5 / Chart1.Width.Value * 1240)
.LineColor = Color.FromArgb(128, 128, 128)
End With
Chart1.Annotations.Add(line)
Next
With this workaround, I got the result I wanted.
With Chart1.Series(0)
.BackGradientStyle = GradientStyle.TopBottom
.Color = Color.Magenta
.BackSecondaryColor = Color.Purple
.IsValueShownAsLabel = True
.Points.DataBind(dtTest.DefaultView, "Month", "Bought", Nothing)
*****The pixel point width******.CustomProperties = "DrawingStyle = Cylinder ,PixelPointWidth = 26"
End With
Is this what you are looking for?
try this:
chart1.ChartAreas("Default").AxisY.ScaleBreakStyle.Spacing = 2
Why don't you add manually some "blank spaces" into each Y value, converting them to a string like "50,000 "?

Calculate angle of two points on Line chart

I want to get the angle of two points on a Line chart.
I know how to calculate an angle, the problem is that I need the x and y of the seriescollection.point and I have no idea how to get it.
Can someone help me with it?
EDIT:
Jean-François Corbett showed me how to get the points, I meant from top and left, and not point on the graph (on X scale and Y scale) though it can work.
I calculate it wrong. how can I calculate the angles in the picture below?
You ask how to get the (x,y) coordinates of points in a chart series. Here is how:
Dim c As Chart
Dim s As Series
Dim x As Variant
Dim y As Variant
Set c = ActiveChart
Set s = c.SeriesCollection.Item(1)
x = s.XValues
y = s.Values
EDIT As far as I can tell from the edited question, OP now wants the pixel coordinates of each point, with origin at the top left of the plot. To do so, you just need to scale by the axis width and span. The x axis is a bit tricky in the case of line plots (which I hate), because there is no min or max scale property; have to use the number of "categories" instead. The following code does this scaling:
Dim c As Chart
Dim s As Series
Dim xa As Axis
Dim ya As Axis
Dim x As Variant
Dim y As Variant
Dim i As Long
Set c = ActiveChart
Set s = c.SeriesCollection.Item(1)
Set xa = c.Axes(xlCategory)
Set ya = c.Axes(xlValue)
x = s.XValues
y = s.Values
For i = LBound(x) To UBound(x)
' Scale x by number of categories, equal to UBound(x) - LBound(x) + 1
x(i) = (i - LBound(x) + 0.5) / (UBound(x) - LBound(x) + 1) * xa.Width
' Scale y by axis span
y(i) = ya.Height - y(i) / (ya.MaximumScale - ya.MinimumScale) * ya.Height
Next i
Note that y increases along the negative y direction on the plot, since you want the origin to be at the top left.
Using this x and y, you can calculate your angle as seen on the screen.
The X and Y values are not directly accessible from the Point object, (as best as I can tell), but they represent actual values passed to the graph. Try accessing them from the worksheet where they are stored.
If that is unavailable, try Series.values, which returns an array of Y-values, and Series.XValues, which returns an array of X-values. (See MSDN Reference)