My goal is to use the d3 force layout to display two different networks that share the same nodes. For example, among four people, you could define a social network and a ge
Javascript is notorious for obfuscating whether state is shared or not. Your minimal example is no longer available, but when I encountered the same problem, my conclusion was that I was only making shallow copies where I needed complete clones. (I'm talking about the links and nodes that D3 takes as input.)
Without a true copy, the resulting behavior will be a bit random, as you discovered, depending on whether D3 code choses to modify any shared data "in situ" or not. In general, D3 tries not to create copies, for performance reasons.
This is why the json call workaround works: by completely stringifying all the data, you are de facto forcing a clone operation.