Cocoa Control: Horizontal Graph View
I have been struggling for years trying to get NSRect to play nicely and draw a cool looking responsive graph in a Cocoa application. I was trying to create a controller that could be used with iOS and Mac OSX and I found that the two had too many internal differences for one controller class to make sense.
As a novice Cocoa Programmer I turned to HTML & CSS. I created the Animal Age program as a test, and included some static data and it worked. The premise is simple. Create a responsive CSS3 graph. Pass its width variable via Cocoa to a Javascript Function. Then display the graph.
After months of perfecting I finally had something that worked, that was cross platform compatible and was easy to style. Below are the steps that you need to take my GitHub project and up and running in your app quickly and easily.
First import all the HTML files into your project, these are located in the /GraphFiles directory. The index.html file is the file that is used to generate the graph. The file has inline CSS that you can alter to change the style of the graph. The CSS3 transform components make the graph animate as its called into view.
The next step is to get the Sum of each column of data, I created an Array Controller that does just that. If you look at the array controller it controls the data going into each column that is bound to the Shared User Defaults Controller and each sum field is also connected to the Graph Controller.
ArrayController.m : Subclass of NSArrayController
As you can see this controller handles the sum values of the different columns in the project. These are outputted to the connected text fields in the info panel. The values are being fed into these fields and summed by their programatic binding to the arrangedObjects keyPath which is where the data is stored.
Now that we have the sum values of each column we can pass that data into our WebView or GraphController. The graph controller is a subclass of WebView so you need to change the class in the Xcode Info Panel. This is not an object the outputs for this will live right on the web view itself. We need to connect the ArrayController to the Web View. Lastly the WebView must be setup as a delegate of App Delegate.
GraphController : Subclass of WebView
Now that you have everything hooked up when you change the data in the NSTableView and then refresh the data it will re-draw the graph. The data is sent from the GraphController through a Javascript call, this sends the sum value to the web view and to the specific javascript function that takes that value and then passes it on to set the width of the DIV item.
Because of the CSS3 transform on the DIV the bar animates into view!