Got it.
The best (IMHO) answer is an intermediate table.
Charts can only take direct references, which is why you're having to update them every time your main table expands.
The trick is to create a separate table (can be on the same sheet or a different sheet, and hidden if you don't want to see it). This table is configured to capture the last 12 values from the main Credit Card table. Your chart then references this intermediate table rather than the main one.
In this setup, each time you add a new row (month) to your expenses sheet, the intermediate sheet updates with the last twelve values, and your chart follows suit.
To replicate this I created a simple 'Credit Card' table with two columns - Month, and Expense:
(your sheet may, of course, have additional columns)
Then I created a new table I called 'Rolling 12 Months' that extracts the last 12 items from the Credit Card table:
To do this, use the formula:
A2=INDEX(Credit Card::A,ROWS(Credit Card::$A)−11,1)
The INDEX() function takes three arguments - a range to search (in this case Column A in the Credit Card table), and a row and column index.
For the row I calculate the ROWS() in the Credit Card::$A table and subtract 11 (to get the eleventh-last entry).
For the column index I simply use 1
So if you have 4 years of credit card expenses (48 rows), the INDEX lookup the 37th entry (48 - 11) in that column.
As you add a new 49th month, the INDEX() will lookup the 38th entry (49-11)
Adjusting the numbers coming down, in cell A3 you subtract 10, A4 subtracts 9, etc.
The same principle is used for the Expense column, just substituting the column that has the expenses (Credit Card::B in my example).
Now you have a table that always shows the last 12 items on the main table.
From here it's simple to create your chart that references the Rolling 12 Months table, and it will always be up to date.