What's the best way to let users adjust values that must sum to a certain number?

I have four values that are a percentage of a whole, and I want the user to be able to edit these values. These four numbers must sum to 100.00 (any precision after that is unimportant) and the values the user submits can be to any precision. Is it better to let the user do the math on their own, and report an error when the sum is incorrect, or is it better to maintain a sum of 100 throughout the number editing process by coercing their values (one goes up the other goes down etc.)? I'm still debating about whether the input methods should be a slider bar (which matches the other inputs I'm using) or a numeric textbox input which might be more suited to this input.

Is it better to let the user do the math on their own, and report an error when the sum is incorrect

No. Maths is hard and letting users do hard things is a crime. Even if the maths is trivial, it is still an extra cognitive load.

Try for yourself, does this sum to a 100:

12.344 + 80.001 + 5.6 + 3.229?

Not fun.

There is a constraint (it has to sum up) so you better provide an interface that ensures the constraint is met.

or is it better to maintain a sum of 100 throughout the number editing process by coercing their values

That's more like it, but still can be done in various ways, some are better than others.

If you are fortunate enough to have used Photoshop, you've seen this before in its curve editor:

You can drag each control point, and set its values in a text field.

But the editor above is for 2D data, whereas yours in 1D. So something like this, often termed a multi-slider, is more appropriate:

Perhaps most important to note is that the user edits the breakpoints, not the ranges.

I'm still debating about whether the input methods should be a slider bar ... or a numeric textbox

Sliders are quick but coarse; textboxes are slow but fine. Seeing as you said 'precision', I guess providing both would be the way to go.

Consider:

• Vertical vs horizontal multi-slider (the former gives you more space if each control point has a text entry).
• Text box for each control point, or only for the selected one (the latter is harder to implement as it involves selection).
• Although this solution is my preferred solution (and something I hadn't even thought of!), I'm working in the RShiny framework and it doesn't appear that this sort of slider is possible. I'll probably need to do something closer to what Michael Lai is suggesting, but I'll keep your comment about maths in mind and make sure the UI is doing all the math for the user. I do have a question, I don't understand your comment about breakpoints and ranges, how would it work if I wanted to remove 10 euro from channel 1, and distribute 2 euro to channel 3, 5 euro to channel 4, and 3 euro to channel 5?
– zach
Commented Mar 28, 2017 at 15:57
• @zach, you drag breakpoint 1-2 (bp12) left by 10, that will put c1 on 100 and c2 on 120. Pull bp23 left by 10 (c2 = 110, c3 = 138 ), pull bp34 8 left (c3 = 130, c4 = 63), pull bp45 3 left (c4 = 60, c5 = 100). Commented Mar 28, 2017 at 16:10

The general rule of thumb is that the more you can reduce the amount of work the user has to do, the less likely it is for them to make errors. It will also lead to a better overall user experience since the tasks are easier. Having said that, if you adjust values in the slider so that they add up to 100, it means that previous inputs the user provides will also change, therefore it makes the interaction and the rules around how the values should be adjusted more complicated than it needs to be.

The general approach is to provide clear instructions and micro-interactions at the point of need to ensure that the users understand the input, and knows the right actions to take.

You could start by setting all the slider values (if you use this UI element, or equivalent for spinners and input fields) to zero, and when the next input exceeds 100 then provide a message where the input has taken place for them to adjust it. The other approach is to start with the values already at the sum of 100 and ask the user to reduce one or more values first so they are aware of the ceiling value.

You can then add a custom UI component that allows you to track and/or allocate amounts to each specific category, so that you track the total amount remaining.

I have actually worked on a project exactly like this for budget allocation, and have provided a screenshot to show you the implementation of the third concept. There was also a requirement that you can exceed the maximum value allowed (to show a budget deficit), but a physical limit was still set so that the chart can display sensible values.