During the preview, the custom parser tag <graph> needs to generate different HTML than during the save. It seems that the $parser->getOptions()->getIsPreview() is almost meaningless, as parser reuses previous parsing result even if it was done in preview mode. Is there an option to indicate that preview parsing is not valid for the final result?
Hmm, not entirely sure how this works, but with ParserOutput's recordOption, you should be able to introduce additional cache variance. includes/content/MessageContent.php does this for instance.
ParserOutput->mAccessedOptions has been added by https://www.mediawiki.org/wiki/Special:Code/MediaWiki/70783
I haven't played with the Parser in ages but varying output based on preview would do it, though you would only want to vary when the graph tag got used.
The vary-revision flag would probably also force the behaviour you want, although using it for this case is kind of hacky.
The parser should probably keep track of if isPreview is called, and if it is not reuse that particular paserOutput if is.