Painting a chart in Excel: conditional labels - excel

I create a pie chart in Excel 2013 using VBA. Everything works like expected: The chart is painted and each segment of that chart has its percentage value attached to it.
Now I have the problem that I got a lot of parts that are below 1% of the data making that chart very ugly with all that "0%" parts and its labels.
Now I still want all pies (otherwise I would just have filtered the source data) but I do only want lables on segments that are at least 2% of the data.
Is that possible?
Set DataSource = CreatePivotTableCurrFy
If Not (DataSource Is Nothing) Then
' Create chart object
Call ThisWorkbook.Worksheets("META").Shapes.AddChart(xlPie, 600, 200, 504, 360)
Set Co = ThisWorkbook.Worksheets("META").ChartObjects(2)
Co.chart.SetSourceData Source:=DataSource
Co.chart.ChartTitle.Text = "Sales by Brand"
Co.chart.SeriesCollection(1).ApplyDataLabels ShowPercentage:=True, ShowValue:=False
End If

You can try this not really very neat solution.
Dim d As Datalabel, Dim v As Long
For Each d In Co.chart.SeriesCollection(1).DataLabels
'v = CLng(Mid(d.Caption, 1, Len(d.Caption) - 1))
v = CLng(Split(d.Caption, "%")(0)) '~~> just thought this is better
If v < 2 Then d.Delete
Next

it is possible, just a bit complicated :) I take you want to hide the portion under 2% and you need to it for the slice as well as the legend and so on.
Naturally you start by selecting the slices of the pie that doesn't reach 2% (that is quite easy and it depends on how you give that % to your slices).
Then you can look here for a full procedure to follow. This link shows some code to do what I explained.

Related

When I add a chart into excel using VBA sometimes it becomes a pivot chart and causes errors

I have a pivot table with 3 values in it. Volume Processed, Volume Billed, and Billed Revenue. VB is always a subset of VP, and BR is often in the 100,000s compared to VB and VP which are usually less than 1,000. Additionally, there are over 1000 data points in my test data. I've only loaded in 2 months, and when it's done it has to be able to quickly handle an entire year. So Pivot Charts won't work. BR is a currency and VB and VP are just numbers. The chart I want is to show (VP-VB) stacked on top of VB where the height of VB = BR and the height of (VP-VB)+VB = (VP*BR)/VB. I also try to use a smaller amount of data points. If all the IDs are showing, that's over 1000 columns on the graph, it's much easier to see them group by buildings until you use a slicer to bring down the number of IDs to something more manageable.
My solution is to use VBA to make my own graph, scrape the data from the pivot table, figure out what graph the user wants to see, and then build it from scratch.
The problem is that sometimes the chart preloads with a pivot chart and then when I try to add in my data it throws a Run-time error. I am having trouble even creating the error because it doesn't always happen.
Dim MyChart as Object
Dim chtrng as Range
Dim srs as Series
Dim arrayvalues() as Double
Dim areayXvalues() as Variant
Set chtrng = Sheets("Pivot").Range("H30:T50")
Set MyChart = ThisWorkbook.Sheets("Pivot").ChartObjects.Add(Left:=chtrng.left,Width:=chtrng.width,Top:=chtrng.Top,Height:=chrrng.Height)
With MyChart.Chart
.ChartType = xlColumnStacked
.Has title = True
.ChartTitle.text = GraphName(0)
For j = 1 to 2
For I = 1 to GraphList.Count
Arrayvalues(i-1) = GraphList(I)(j)
Next I
Set srs = .Series collection.NewSeries
With srs
.Xvalues = areayXvalues
.Values = areayvalues
.Name = GraphName(j)
End With
Next j
End With
"Set srs" is where the error comes in. This is also the first pass of j. When I step through the code, the times that it works, at "Set MyChart" the graph is empty, but the times it doesn't work, the graph has a pivot chart inside. At the beginning of the actual code I delete all charts on the sheet.
Every scenario I try, with different data displayed in the pivot table has done both. I can't figure out what is even causing the issue.
I've tried making sure MyChart is set to nothing. I have code that calls the makegraph sub when the pivot table updates, I created a on/off switch for that. I've tried to disconnect all of my data scraping from the pivot table so that by the time I start on the graph none of my variables are attached to the table.
Most of the time the graph works exactly as expected, but every now and then it gives me a Run-time error '1004' on "Set srs"

Need VBA code to plot up series of linear data in Excel, create regression eq's for each series, then write the regression eq's in the Excel sheet

I have a fairly simple VBA code which is doing 75% of what I need it to do, I just can't get the last step to work properly.
In an Excel sheet, I have two sets of data (X data and Y data). The x data is the same two data values for every single case. Then I have two columns of data which comprise the Y data. I need to create an Excel scatter plot with a whole bunch of data series. Series 1 is the two constant x values with the first y value from the first column and the first y value from the second column. The 2nd series is the same two constant x values with the second y value from the first column and the second y value from the second column, and so on. The columns have about 300+ rows (hence > 300 series total). I realize that a scatter plot can only do up to about 256 series in one plot so I won't be able to fit them all in one plot. That's not the point. I've tried just plotting like, say, 50 of the series and I have that part working fine. Next, because all the series are straight lines, I need the slope/regression information from each series, so I create a linear trendline and plot the equation on the chart. I have this part automated and working correctly in Excel as well. Here's where I'm stuck though. The last step is, after I've had VBA create the, say, 50 series in the single plot and generate all of the regression equations, I then need for Excel to take those equations and paste them into a column in the main worksheet (where the plotting data resides). I found something on Google that is supposed to do this (grabbing trendline.datalabel.text and pasting it into the sheet), but it isn't working right, and I can't figure out what I'm doing wrong. I've tried 20 different things and am still beating my head against a wall. Any help with the last half of the code would be greatly appreciated. THANK YOU.
Sub Plot_slopes()
Dim i As Integer
Dim ChtOb As ChartObject
Dim objTrendline As Trendline
Dim strEquation As String
Set ChtOb = ActiveSheet.ChartObjects.Add(Left:=20, Width:=800, Top:=20, Height:=250)
ChtOb.Chart.ChartType = xlXYScatterSmoothNoMarkers
ChtOb.Activate
i = 9
For i = 9 To 59
With ActiveChart.SeriesCollection.NewSeries
.Name = "FS" & i
.XValues = Worksheets("summary").Range(Worksheets("summary").Cells(3, 7), Worksheets("summary").Cells(4, 7))
.Values = Worksheets("summary").Range(Worksheets("summary").Cells(i, 13), Worksheets("summary").Cells(i, 14))
.Trendlines.Add
End With
With ActiveSheet.ChartObjects(1).Chart
Set objTrendline = .Trendlines(1)
With objTrendline
.DisplayRSquared = False
Trendlines(1).DisplayEquation = True
strEquation = .DataLabel.Text
Range("Q9").Offset(i, 0) = strEquation
End With
End With
Next i
End Sub
I mainly need help with the code after the first With Block and where it starts with a new "with"..."with activesheet.chartobjects(1).chart", etc), although, I'm also having trouble with the .name part in the first With block as well. Goal is to get the last block so that VBA writes out the regression equations for each created series into the main "summary" worksheet

Various transparent step in a line in a chart

I am using VBA with Excel 2013. I am developing a Macro with a chart, inside the chart there is a line made with a serie if points. I need apply a transparency shape to the steps between 2 point.
example
1 to 2 solid
2 to 3 transparent
3 to 4 solid
With .transparency = 0 and 1 the shape is applied to the whole line. I tryed to apply .trasnparency various time but it is applied to the whole line.
How do I apply transparency to have the behauvior described above?
The easiest way to get a gap is to insert a blank row between segments you want to be visible. In the top view below the data range is continuous, and so is the chart. In the bottom view, I've inserted blank rows between the X-Y values for the horizontal segments, and the chart rewards me with gaps in the plot, so the verticals don't show up.
You can't get these gaps if your code is inserting arrays into the chart series source data, but you can use code like this to make them disappear (by using No Line instead of Transparency, personal preference):
Sub TransparentVerticals()
Dim srs As Series
Dim iPt As Long
Set srs = ActiveChart.SeriesCollection(1)
For iPt = 1 To srs.Points.Count Step 2
With srs.Points(iPt)
.Format.Line.Visible = msoFalse
End With
Next
End Sub

Colouring an Excel stacked bar chart's points in relation to a value assigned in a table

I am trying to create a roadmap/timeline in Excel 2010 using a stacked bar chart. I have provided a link below to an image which should explain my intentions with the chart. I wish to present different events in the chart and they should be drawn in relation to their duration. The longer the event is, the longer its respective bar is.
I have managed to build a macro that creates a chart of my liking. However, I wish to add another functionality to it. As it can be seen from the picture below, there is a column called 'Type' in the original table. It stands for the status of the event, whether it is completed, canceled or being planned. My aim is to have the chart represent this data by coloring the bars either red (if canceled), green(if completed) or blue (if planned) depending on what value the particular event in question has in its Type row.
Below is the code behind the macro that the button 'Create a New Event View' uses. I would like to know how to implement the coloring, preferably in this very same macro so that the user only needs to click the button.
Sub CreateEventTable()
Dim timespan_start As Date
Dim timespan_end As Date
timespan_start = Application.InputBox("Type start date:")
timespan_end = Application.InputBox("Type end date:")
ActiveSheet.Shapes.AddChart(xlBarStacked, Range("E2").Left, Range("E2").Top).Select
With ActiveChart
.SetSourceData Source:=Range("$A$1:$B$12, $D$1:$D$12"), PlotBy:=xlColumns
.SeriesCollection(1).Values = Range("B2:B12")
.SeriesCollection(1).XValues = Range("A2:A12")
.SetElement msoElementLegendNone
.ChartGroups(1).GapWidth = 31
.SeriesCollection(2).ApplyDataLabels
.SeriesCollection(2).DataLabels.ShowCategoryName = True
.SeriesCollection(2).DataLabels.ShowValue = False
.SeriesCollection(1).Format.Fill.Visible = msoFalse
.Axes(xlValue).MinimumScale = timespan_start
.Axes(xlValue).MaximumScale = timespan_end
End With
End Sub
Here is the link to the image which hopefully explains the overall structure:
http://i.imgur.com/XzPoMiY.jpg
I appreciate your invaluable help! I am happy to provide more details if deemed necessary.
Best solution here is not VBA. You'll need to create multiple series for your chart, have them overlapped, and use formulas to populate if they meet the criteria. Changes automatically, and very easy to maintain.
As Skip Intro said, Jon Peltier is the chart master.
This link will get you started in the right direction.
http://peltiertech.com/WordPress/conditional-formatting-of-excel-charts/

How to plot chart values outside axis maximum?

In previous versions of Excel there was a registry entry that you could create to allow Excel to display values/labels that would be positioned outside the axis min/max using QFE_Bonn dword=1. This is what I have used for Excel 2003: Plot lines that contain labels disappear ...)
I have not been able to find a similar patch or native functionality in Excel 2010 (Office Pro Plus). Any ideas how this can be accomplished, or did MS remove this functionality altogether?
Here are screenshots of examples in Excel 2003. I create a series of data which uniformly exceeds the y-axis maximum. This series' color fill has been removed already
To finish the look, remove the series' border so that it appears invisible. Then replace the series' value labels with the relevant data.
There is a workaround using the DataLabels.Left property which positions the DataLabel relative to the ChartArea.
Here is an example VB solution:
sub FakeLabels()
Dim sF As Double
Dim lOff As Double
Dim p As Double
ActiveSheet.ChartObjects(1).Activate
With ActiveChart
For sF = 1 To .SeriesCollection.Count
If .SeriesCollection(sF).Name = "FakeSeries" Then
'Define the lOff variable by adding 100, or some other value
lOff = .SeriesCollection(sF).Points(1).DataLabel.Left + 100
For p = 1 To .SeriesCollection(sF).Points.Count
.SeriesCollection(sF).Points(p).DataLabel.Left = lOff
Next p
End If
Next sF
End With
It yields the same results, the only new requirement is to keep the values for the "dummy" series within the axis min/max values for the chart.
A pleasant surprise is that re-sizing the chart doesn’t appear to affect the relative placement of the labels.
UPDATED 9-25-2013
I have used the "textbox" approach since first asking this question. But it is extremely clunky to manage the interplay between the labels' position and the textbox positions, their relative position of the PlotArea i.e., when to use .InsideWidth vs. .Width or .InsideLeft vs. .Left and whether there needs to be any sort of hedonic "adjustments" to the points values, as always seem to be the case, they are never quite perfectly aligned.
While perusing the PPT object model reference for some other chart-related inquiries, I stumbled upon this property which appears to replicate the functionality of the previous hotfix/registry hack.
.ShowDataLabelsOverMaximum

Resources