You have two options for saving the old data attached to an element in order to identify changes after a new data join.
The first option, as you suggested, is to use data attributes. This SO Q&A describes that approach.  Things to consider:
- all your data values will get coerced to strings
 
- you'll need a separate method call/attribute for each aspect of the data
 
- you're manipulating the DOM, so it could slow things down if you've got a lot of elements or lot of data for each
 
- the data is now part of the DOM, so can be saved with the image or accessed by other scripts
 
The second option is to store the data as a Javascript property of the DOM object for the element, in the same way that d3 stores the active data as the __data__ property.  I've discussed this method in this forum post.  
The general approach:
selection = selection.property(" __oldData__", function(d){ return d; } ); 
                        //store the old data as a property of the node
                    .data(newData, dataKeyFunction);  
                        //over-write the default data property with new data
                        //and store the new data-joined selection in your variable
selection.enter() /*etc*/;  
selection.attr("fill",  function(d) {
                 // Within any d3 callback function,
                 // you can now compare `d` (the new data object)
                 // with `this.__oldData__` (the old data object).
                 // Just remember to check whether `this.__oldData__` exists
                 // to account for the just-entered elements.
                if (this.__oldData__) { //old data exists
                  var dif = d.value - this.__oldData__.value; 
                  return (dif) ? //is dif non-zero?
                         ( (dif > 0)? "blue" : "red" ) :
                         "black" ; 
                } else {
                  return "green"; //value for new data
                }
            });
selection.property("__oldData__", null); 
          //delete the old data once it's no longer needed
          //(not required, but a good idea if it's using up a lot of memory)
You can of course use any name for the old data property, it's just convention to throw a lot of "_" characters around it to avoid messing up any of the browser's native DOM properties.