Great!
I've added all files to this gist for you to download the full code, as I'd like to focus on explaining the changes I made so that you can build on them accordingly.
capabilities.json - dataRoles
I've modified the dataRoles to the following:
This will modify the visual's data roles as follows:
Notethat your development visual will likely still have the now removed myMeasure role in there, so your best bet is to ensure everything is fully removed and re-applied when working with the new code I've provided.
capabilities.json - dataViewMappings
The dataViewMappings now look as follows:
This will group by myCategory and then bind both measures to each. For my test data, the visual table looks as follows:
Note that this is a public dataset and I'm treating Tip as actual and Total Bill as budget.
Let's take a look at the dataViewMapping in the developer visual for the data I've added:
The values array now has two entries - one for actual and one for budget. We can see this if we expand the source object for each and then roles - and this is how you can determine which entry is performing which role. The measure values for each are then in the associated values array (which will match the order of myCategory). For brevity, I've only expanded this for actual.
visual.ts - BarchartDataPoint interface
We need to change the interface spec to ensure that the 'shape' of each data point is correct. This now looks as follows:
(it's not essential, but good practice to use camelCase for properties, so I have modified all to suit)
This now means that our view model expects two numeric values for each category, which matches our dataViewMappings, so we need to map them into the view model next.
visual.ts - createViewModel function
If you're making the above changes incrementally, you'll now see errors in your code, because the BarchartDataPoint interface 'shape' does not match the object you're assigning in the createViewModel function. We need to update this.
With the above in mind, and how the dataViewMapping looks, we need to change the way we iterate over it.
- You were previously iterating over the measure values; I have modified this to iterate over the category values just to make the next bit easier.
- I'm going to do the simplest possible solution for the measures using array accessors of [0] for actual and [1] for budget.
- To make your code super-resilient, you would filter the values array by role to ensure the value is definitely provided, but we can worry about that waaaaay later 😉
The portion of the function code to map the view model now looks as follows:
You have a sort lower down, so that's been modified to use the actual value:
visual.ts - update function
It's now a case or binding everything from the view model correctly to your chart logic.
The first fix is your maxValueY assignment - we just get this to match the highest value now that you have two measures:
Now, the actual shape! barSelectionMerged gets updated to now use the actual property from the data point:
...and barSelectionMerged2 gets the budget property as part of its yScale:
Verifying
We can now test in the developer visual! Here's how it looks for my data above:
And hopefully, this is where you need to be 🙂
Good luck!
Daniel
If my post solves your challenge, then please consider accepting as a solution to help other forum members find the answer more quickly 🙂