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

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

Related

How to show dimensions of objects - autocad

I have multi shapes.
I want to show all dimensions of each sides(the green lines).
I want to use vba.
I can show dimension a full square or rectangle shape.
for example to show a horizontal dimension I use this function:
Function createDimensionHorizental(x1, y1, x2, y2)
' This example creates an aligned dimension in model space and
' uses the TextHeight property to increase the height of the
' dimension text
Dim dimObj As AcadDimAligned
Dim point1(0 To 2) As Double, point2(0 To 2) As Double
Dim location(0 To 2) As Double
' Define the dimension
point1(0) = x1: point1(1) = y1: point1(2) = 0
point2(0) = x2: point2(1) = y1: point2(2) = 0
location(0) = x1: location(1) = y1 + 10: location(2) = 0
' Create an aligned dimension object in model space
Set dimObj = ThisDrawing.ModelSpace.AddDimAligned(point1, point2, location)
' Read and display current dimension text height
'MsgBox "The dimension text height for this object is currently set to: " & dimObj.TextHeight
' Increase the distance of the dimension gap
'Format the dimension object according to your needs.
With dimObj
.TextHeight = 30
.TextGap = 10 'The distance of the dimension text from the dimension line.
.Arrowhead1Type = 5 'acArrowOblique in early binding
.Arrowhead2Type = 5 'For the standard dimension arrow put 0 here.
.ArrowheadSize = 20
.ExtensionLineExtend = 10 'The amount to extend the extension line beyond the dimension line.
End With
ThisDrawing.Regen acAllViewports
End Function

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

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.

Excel VBA only show labels for each series' max value

I am trying to create a macro which loops through series in a chart and only shows the maximum / minimum label dependent on what the max / min value is.
Some of the series will only have negative values and in these cases I wish to only show the minimum datapoint label, and vice versa for series with 0 or greater values.
The code I have so far is:
Sheets("Curve").ChartObjects("Chart 14").Activate
For Each serie In ActiveChart.SeriesCollection
Dim pointCount As Integer
Dim pointValues As Variant
pointCount = serie.Points.Count
pointValues = serie.Values
For pointIndex = 1 To pointCount
If pointValues(pointIndex) < 1000 Then
serie.Points(pointIndex).HasDataLabel = True
End If
Next pointIndex
Next serie
End Sub
Which works fine when I manually enter the threshold, but I want to replace the '1000' with Max(series) value instead, so that each series in the chart has only one label visible.
The following modified routine includes MaxPoint, MaxPointIndex, MinPoint, and MinPointIndex variables which are calculated in the For loop on each serie's points. It then sets the label for the maximum point if the series has only positive value and minimum point otherwise.
Option Explicit
Sub chart()
Dim serie As Variant
Dim Pointindex As Long
Dim MaxPoint As Long
Dim MaxPointIndex As Long
Dim MinPoint As Long
Dim MinPointIndex As Long
Sheets("Curve").ChartObjects("Chart 14").Activate
For Each serie In ActiveChart.SeriesCollection
Dim pointCount As Integer
Dim pointValues As Variant
pointCount = serie.Points.Count
pointValues = serie.Values
MinPoint = 10000 'set to value greater than any point in any serie
MaxPoint = 0
For Pointindex = 1 To pointCount
If pointValues(Pointindex) > MaxPoint Then
MaxPoint = pointValues(Pointindex)
MaxPointIndex = Pointindex
ElseIf pointValues(Pointindex) < MinPoint Then
MinPoint = pointValues(Pointindex)
MinPointIndex = Pointindex
End If
Next Pointindex
If MinPoint >= 0 Then
serie.Points(MaxPointIndex).HasDataLabel = True
Else
serie.Points(MinPointIndex).HasDataLabel = True
End If
Next serie
End Sub
I have an alternative approach, which does not require VBA. It adds an extra series with an invisible data point at the max and this point has a data label. It also changes dynamically if the data changes and a different point is maximum, without having to rerun the VBA procedure.
For each series in the chart you'll need to use a range the same size as the Y values of the series.
Assume the original Y values for a given series is in D2:D10, and we'll use G2:G10 for our extra data. In G2 enter
=IF($D2=MAX($D$2:$D$10),$D2,NA())
and fill this down to G10. Modify this formula for the case where you might instead look for the minimum value if everything is negative.
Copy G2:G10 and hold CTRL while you select the X values for this series. Copy. Select the chart, use Paste Special, and select Add data as new Series, in Columns, Categories in First Column.
Select the added series, which is one point (unless there are two points at the maximum), format to have no lines and no markers. Add your data labels to this series.
Repeat for the other series in the chart.

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)