Dynamic Chart Source Data
by Jon Peltier
Peltier Technical Services, Inc., Copyright © 2008. All rights reserved.
A dynamic chart can be constructed using dynamic ranges that change in size as data is added or removed. This technique is very powerful: you can define flexible ranges limited only by your ability to write an appropriate Refers To formula.
One imitation of this approach is that it can only account for dynamic numbers of points in a series, but not dynamic numbers of series in a chart. Using VBA you can work around this limitation.
Let’s start with a simple data range as shown below. Following best practices, the data is arranged with series in columns, the category labels (X values) are in the first column, the series names are in the first row, and the top left cell of the range is blank. Using the Define Names dialog, we can define a name using these parameters:
Name: ChtSourceData
Refers To: =OFFSET(Sheet1!$B$2,0,0,COUNTA(Sheet1!$B:$B)+1,COUNTA(Sheet1!$2:$2)+1)
When we click Add and then click in the Refers To box, the range defined by the Refers To formula is highlighted by the marching ants border.

When creating a chart, or editing its source data, we can enter a dynamic range name in the Data Range box.

Excel accepts this definition of the chart data, but it converts the dynamic range name to a static range address. This means that our chart does not update as the dynamic range changes in size.

Here is our chart created with the dynamic range ChtSourceData. When the plot area or chart area of the chart is selected, the source data is highlighted.

Add some data to enlarge the dynamic range. Open the Define Names dialog, select ChtSourceData, and click in the Refers To box: The highlighted range shows that the dynamic range has enlarged to include all the added data.

The chart has not changed, but with a simple VBA procedure we can change the chart’s source data range to reflect the new dimensions of our defined range:
Sub UpdateChartSourceData()
With ActiveSheet
.ChartObjects(1).Chart.SetSourceData _
Source:=.Range("ChtSourceData"), _
PlotBy:=xlColumns
End With
End Sub
This procedure should be placed into a regular code module, as described in How To Use Someone Else’s Macro.
Here is the updated chart:

To make this work more dynamically, you can include the SetSourceData command in a Worksheet_Change event. Right click on the sheet tab, choose View Code, and the VB Editor will appear with a code module representing the active sheet. Put this procedure into the module:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Me.Range("ChtSourceData")) Is Nothing Then
Me.ChartObjects(1).Chart.SetSourceData _
Source:=Me.Range("ChtSourceData"), _
PlotBy:=xlColumns
End If
End Sub
This procedure executes whenever there is a change to a cell on the worksheet (not a calculation, but a change in an entered value or formula). The If checks whether the change occurred within the dynamic range ChtSourceData; if so, it resets the chart’s source data range. It’s automagic.
Posted: Thursday, July 3rd, 2008 under Charting Principles, Dynamic Charts, VBA.
Comments: 6
Comments
Comment from sam
Time: Friday, July 4, 2008, 12:56 pm
Hi JP,
Dont use Offset - Its Volatile
Use ChrtArea = Index($1:$65536,Counta($A:$A)+1,Counta($1:$1)+1)
Assuming Data Stars from Cell A1
sam
Comment from Jon Peltier
Time: Friday, July 4, 2008, 2:43 pm
Sam - Thanks for the suggestion. Actually your formula links to the bottom right of the range, so this is the appropriate form of the Refers To formula:
=$A$1:INDEX($1:$65536,1+COUNTA($A:$A),1+COUNTA($1:$1))
or, since Excel inserts the sheet name:
=Sheet1!$A$1:INDEX(Sheet1!$1:$65536,1+COUNTA(Sheet1!$A:$A),1+COUNTA(Sheet1!$1:$1))
It’s a good point about volatility of functions. Since I usually have small worksheets, I usually don’t worry about the calculation impact of my range definitions.
Comment from Doug
Time: Saturday, September 27, 2008, 2:31 pm
This is a great tip. But I need help on one more step. I am setting up the dynamic update in the worksheet code. Your code works for 1 chart but I need to update 2 charts on the same page. How would I modify the VBA code to support 2 different charts on the worksheet?
Comment from Jon Peltier
Time: Saturday, September 27, 2008, 8:53 pm
Doug -
You need to define a range for each chart, and you should name each chart. To name a chart, hold Shift while selecting the cart, and type a distinctive name in the Name Box. Something like DynoChart1 and DynoChart2. If you have questions about this, see my tutorial Chart Names. Use ranges named DynoRange1 and DynoRange2. Then in the code:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Me.Range("DynoRange1")) Is Nothing Then
Me.ChartObjects("DynoChart1").Chart.SetSourceData _
Source:=Me.Range("DynoRange1"), _
PlotBy:=xlColumns
ElseIf Not Intersect(Target, Me.Range("DynoRange2")) Is Nothing Then
Me.ChartObjects("DynoChart2").Chart.SetSourceData _
Source:=Me.Range("DynoRange2"), _
PlotBy:=xlColumns
End If
End Sub
Comment from Nick
Time: Friday, October 3, 2008, 4:48 pm
Jon,
Cam across your website in need of excel guidance.
This is great and I have been playing with this and learning.
However, when I execute the code, it resets the labeling of the series in the chart.
Thinking about it, I could define a name for each series and then add an update into the macro to update the series using the definition but I think there must be a quicker way of doing this especially when there are several series.
Thanks,
Nick
Comment from Jon Peltier
Time: Friday, October 3, 2008, 4:56 pm
Nick -
In my example, the series names are in the first row of the range “ChtSourceData”. Keep the top left cell blank, put the series names in the rest of the top row of this range, and the X values or category labels in the rest of the first row.






Write a comment