web-dev-qa-db-fra.com

Comment construire une interface de budgétisation (la somme des articles doit être égale à 100)?

J'essaie de créer une interface Web visuelle où les utilisateurs peuvent répartir un budget sur un certain nombre (variable) d'articles. Par exemple, si le budget est de 100 points, je pourrais allouer:

50 points to 'Apples'
50 points to 'Oranges' 

ou:

75 points to 'Apples'
25 points to 'Oranges' 

Si l'utilisateur souhaite ajouter une nouvelle catégorie, quelque chose comme ceci devrait se produire:

30 points to 'Pears' 
60 points to 'Apples'
10 points to 'Oranges'

mais sans le "saut", l'allocation ci-dessus donnerait si les points étaient simplement représentés sous forme de graphique à barres. J'imagine une sorte d'interface d'égaliseur audio où les utilisateurs peuvent simplement déplacer les curseurs pour chaque élément, mais je n'arrive pas à bien faire les "mathématiques" et j'ai l'impression de manquer quelque chose d'important. Voici les contraintes:

  • Je veux que tous les nombres soient compris entre 0 et 100
  • Je veux que le budget soit toujours satisfait (c'est-à-dire des sommes jusqu'à 100)
  • Je veux que les utilisateurs puissent ajouter/supprimer des articles à leur "panier"
  • Je ne veux pas que l'utilisateur doive faire des calculs
  • Je préférerais fortement que tous les mouvements du curseur soient continus (c'est-à-dire, pas de "sauts")

Mise à jour: J'ai quelques prototypes pour les gens à essayer/voter:

http://buger.github.com/skill_weight_ui/#

25
John Horton

Je pense que vous devriez éviter de régler automatiquement les autres variables pour maintenir le total de 100%. Il peut devenir extrêmement ennuyeux de devoir gérer cela chaque fois qu'il y a plus de 2 variables en jeu. Et si vous assouplissez un peu vos restrictions, je pense que vous pouvez en créer une interface plus conviviale.

Je suis venu avec une solution qui est en partie saisie de texte/représentation visuelle en partie qui, je pense, fonctionnera bien ... enter image description here

Intuitivement, les utilisateurs peuvent saisir des pourcentages directement dans les zones de texte. Mais pour aller plus loin, vous pouvez même créer une poignée sur chaque colonne et les rendre glissables. Par exemple, vous pouvez saisir la colonne "Oranges" et la faire glisser jusqu'à 30% pour satisfaire l'exigence totale de 100%.

15
Steve Wortham

(modifier) ​​Les autres réponses m'ont fait considérer qu'il y a en effet deux cas différents: faire une affectation relative, et remplir un conteneur limité.

Affectation relative


Une affectation relative consisterait à créer une recette de punch aux fruits, avec une quantité encore inconnue de punch aux fruits à créer à partir de celle-ci.

Je n'ai pas encore trouvé un curseur multi-tap qui se sent "bien". Les opérations typiques, telles que "extraire 5% de chacune pour faire de la place pour une nouvelle" sont un gâchis.

À condition que votre public cible puisse entrer des chiffres, voici ma suggestion:

1. supprimez la contrainte "somme à 100%" de l'entrée utilisateur

Ce que vous voulez, c'est une allocation relative .

Vous pouvez laisser l'utilisateur entrer n'importe quel nombre, puis mapper la somme à 100:

total = sum(input[1..N])
if (total == 0) 
  ShockUser();
percent[1..N] = 100* input[1..N] / total 

En ce moment, vous forcez l'utilisateur à suivre une contrainte qui n'est pas strictement nécessaire pour une entrée valide, juste pour la présentation. Vous auriez besoin de rejeter ou de modifier les entrées utilisateur uniquement pour préserver cette contrainte, mais la contrainte n'affecte pas les données elles-mêmes.

2. Fournir une rétroaction instantanée
Mettez à jour instantanément un graphique à secteurs, circulaire ou à barres A avec l'entrée. Exemple d'esquisse:

enter image description here

La rétroaction instantanée est importante pour que l'utilisateur puisse voir les effets.

. n'utilisez pas un camembert 3D (met l'accent sur la partie avant), autorisez les fractionnaires (rend les scientifiques heureux)


La seule faiblesse ici est que certaines personnes pourraient penser par exemple doubler toutes les valeurs augmentera en quelque sorte leur allocation - surtout si leur allocation est "en concurrence" avec quelqu'un d'autre.

L'idée est:

  • Je veux moins de bacon dans le mélange. Je réduis le nombre de "Bacon". La moitié du nombre = la moitié de la quantité de bacon.
  • Je jette quelques citrons. "24 citrons" signifie autant de citrons que d'oranges et deux fois plus de pommes.
  • Je peux toujours saisir des pourcentages et m'assurer que tout correspond bien à 100. Je n'ai pas à le faire, cependant
  • Ce qui est plus délicat dans cette interface (par exemple par rapport aux curseurs multi-tap) est la distribution entre deux éléments sans affecter le reste. Ce n'est pas plus compliqué qu'avec des entrées en pourcentage, cependant.

Conteneur limité


dans le scénario de conteneur limité, vous avez de la place pour exactement Max fruits, et le nombre absolu de pommes compte. (chaque fruit prenant la même taille, bien sûr ...)

Dans ce cas, la suggestion de Steve Wortham fonctionnerait en effet mieux. Vous pouvez l'étendre avec les éléments suivants:

  • un bouton "Remplir" pour chaque type, visible lorsque le Total < Max. Il remplit l'espace restant avec un type de fruit.

  • un bouton "Réduire" pour chaque type, visible lorsque Total > Max. Il réduit le type sélectionné pour ramener le total à Max (ou définit le type à zéro s'il n'y en a pas assez dans ce type).

  • un bouton "Remplir/Réduire proportionnel". (Je ne suis pas sûr de l'étiquette). Cela fonctionnerait de manière similaire à l'affectation relative recommandée ci-dessus.


Dans les deux cas, le calcul relatif peut conduire à des nombres étranges - par ex. passant de 50% à 41,666 ...% selon l'application, vous pouvez permettre un arrondi à une granularité plus conviviale.

9
peterchen

John,

Je pense que ce que vous cherchez est un curseur de plage (aka double curseur), comme celui-ci ici .

L'utilisateur aura un bouton disant "nouvelle catégorie" qui demandera le nom de la nouvelle catégorie et demandera à l'utilisateur de sélectionner un point sur la barre. Sur le point sélectionné, une nouvelle poignée apparaîtra, prenant le nombre approprié de points de la catégorie sur laquelle vous l'avez placée.

Il existe également un bouton "supprimer la catégorie", obligeant l'utilisateur à sélectionner l'une des poignées et à répartir ses points de manière égale entre ses voisins.

Cela fonctionnera probablement mieux avec une barre verticale, où il est un peu plus facile d'afficher les noms des catégories à côté de leurs poignées.

On dirait qu'il satisfait à toutes vos conditions, et la logique de la redistribution des points est très claire et graphique.

Fondamentalement, c'est identique à la création de dégradés avec ce contrôle:

enter image description here

6
Vitaly Mijiritsky

Si vous souhaitez modéliser votre interface utilisateur après un égaliseur audio, la clé est de laisser la position de chaque curseur représenter l'allocation de cette catégorie par rapport à toutes les autres catégories. N'essayez pas de mapper la position du curseur sur une valeur numérique absolue. Au lieu de cela, modifiez simplement l'échelle numérique de chaque curseur de manière dynamique afin que les nombres totalisent toujours jusqu'à 100. De cette façon, la position d'un curseur ne doit jamais changer à moins que l'utilisateur ne la touche. Par exemple:

1) L'utilisateur ajoute la première catégorie:


Apples  ---------------+--------------- 100%

2) L'utilisateur ajoute une deuxième catégorie:


Apples  ---------------+--------------- 50%
Oranges ---------------+--------------- 50%

3) L'utilisateur ajuste le curseur Oranges à environ 1/2 pomme:


Apples  ---------------+--------------- 67%
Oranges -------+----------------------- 33%

4) L'utilisateur ajoute une troisième catégorie:


Apples  ---------------+--------------- 40%
Oranges -------+----------------------- 20%
Pears   ---------------+--------------- 40%

Pour calculer la valeur d'allocation pour un curseur donné, vous feriez:

100 * slider_position/sum_of_all_slider_positions

5
cduhn

Il me semble que vous parlez d'équilibrer entre différentes ressources ou caractéristiques, un peu comme certains jeux de rôle.

Que se passe-t-il si vous venez d'afficher les allocations visuellement, sans aucun sens de l'échelle et en permettant à l'utilisateur de faire glisser les valeurs?

Vous pouvez faire le calcul vous-même, en arrière-plan.

Par exemple, vous pouvez afficher les pondérations sous forme de Spider Chart :

Spider Chart

Avec l'amélioration que les utilisateurs pouvaient faire glisser des valeurs le long de l'axe pour les rendre plus ou moins importantes. (Notez que vous ne voudriez pas utiliser une échelle numérique visible, car c'est l'équilibre visuel avec lequel l'utilisateur travaillerait.)

Pour illustrer, considérons que nous avons cinq catégories (intelligence, charisme, force, endurance, dextérité) à montrer sur la carte d'araignée. Pour commencer, les cinq ont un réglage de "milieu de gamme" de 25 (sur 50 possibles): (25, 25, 25, 25, 25). Leur mise à l'échelle pour s'adapter à un total de 100 donne: (20, 20, 20, 20, 20)

Ensuite, l'utilisateur commence à configurer la balance, en faisant glisser l'intelligence et la dextérité au maximum, et l'endurance jusqu'à 10. Les valeurs pour les cinq catégories sont maintenant: (50, 20, 20, 10, 50). Leur mise à l'échelle pour correspondre à un total de 100 donne (33,3, 13,3, 13,3, 6,7, 33,4)

Notez, cependant, que vous n'utiliseriez que ces valeurs mises à l'échelle comme sortie de l'écran, calculées une fois.

Faire glisser une valeur vers le haut diminue automatiquement l'allocation à tous les autres attributs, proportionnellement - et comme le calcul est effectué à la fin du processus, les erreurs d'arrondi ne provoquent pas de boucle de rétroaction dans les valeurs affichées.

4
Bevan

Juste un coup dans le noir, mais je pourrais suggérer de jeter un œil à l'outil Project Success Sliders proposé par Mountain Goat Software (Mike Cohn's Company). Cet outil fonctionne sous différentes contraintes, mais j'aime l'interface utilisateur et l'interface utilisateur qu'il propose.

http://www.mountaingoatsoftware.com/tools/project-success

3
sklein

Je ne pense pas que vous puissiez aborder le problème exactement comme vous semblez le vouloir. Vous ne pouvez vraiment pas ajuster d'autres catégories pour compenser la catégorie à laquelle l'utilisateur attribue actuellement des points.

Si vous le faisiez, l'utilisateur aurait du mal à obtenir les affectations exactes qu'il voulait car chaque ajustement déplacerait également les points dans toutes les autres catégories, modifiant les points qu'ils ont déjà attribués (j'espère que cela a du sens).

Ce que vous devriez probablement faire, c'est permettre à tous les curseurs de se déplacer entre 0 et 100, donner une visualisation claire à l'utilisateur du nombre de points qu'ils sont au-dessus ou au-dessous de 100, ainsi qu'indiquer clairement quand ils sont à 100 (tout est vert), et quand ils ne sont pas à 100 (tout est rouge).

Si nécessaire, empêchez-les de "sauvegarder" sauf s'ils ont utilisé exactement 100 points.

2
ThatSteveGuy

Peut-être pourriez-vous également ajouter l'élément "ce qui reste". Il montrerait ce qui reste, mais serait en lecture seule. L'ajout d'un élément pourrait récupérer le reste. Tant que le reste n'est pas 0, vous ne pouvez pas continuer/enregistrer/...

apples:  [ 20 ]
oranges: [ 30 ]

budget:    50 !!

ou visuellement comme l'a montré peterchen, mais la partie rouge étant le reste.

2
Peter Frings

J'ai travaillé sur quelque chose de similaire à cela. L'avantage que nous avions était qu'il y aurait une catégorie par défaut. Si vous pouvez en tirer parti, vous pouvez commencer avec quelque chose comme ceci:

  [100] Default
------------------
  + new

Vous pouvez ensuite ajouter des catégories supplémentaires. Saisie d'un qui soustrait de la valeur par défaut:

  [60 ] Default
------------------
- [20 ] food
- [20 ] rent
+ new

La suppression d'une catégorie ou la suppression du champ de valeur de catégorie remettra ce montant dans la valeur par défaut.

S'ils utilisent tout l'attribution avec de nouvelles catégories, les données sont enregistrées sans la valeur par défaut.

Ce qui est différent avec cette solution, cependant, c'est que vous auriez besoin d'une sorte de catégorie par défaut qui serait acceptable pour être enregistrée avec des données.

2
DA01

Je pense que la meilleure solution peut être une combinaison de Peter et Fring.

Pouvez-vous compter les points "non attribués"? La somme des points de chaque article plus le nombre de points non attribués doit toujours être égale à 100.

mockup

Dans l'exemple ci-dessus, si vous augmentiez le nombre de poires à 15, le nombre dans le compartiment non alloué tomberait à 5. Lorsque vous soumettez le formulaire, tous les points non alloués restants seront distribués en fonction des valeurs relatives de chaque élément. Le nombre de points attribués à chaque élément, y compris ceux qui seront attribués automatiquement à partir du compartiment "non alloué", est indiqué entre parenthèses.

Cette idée pourrait également être appliquée à un curseur de plage.

|=========================+===============++----------|
                          A               OP            

Les points non attribués sont représentés par un espace vide à la fin du curseur. Si vous déplacez l'un des contrôles pour (A) pples, (O) gammes ou (P) chacun, il déplacera tout vers la droite et modifiera la longueur de la portion non allouée.

2
Patrick McElhaney

John,

Je ne pense pas que l'ajout dans une nouvelle catégorie et l'ajout automatique de certains points et leur soustraction des autres soit la meilleure façon de procéder. Si l'utilisateur a délibérément sélectionné 75% par rapport aux oranges, il ne s'attendrait pas à ce que ce chiffre change automatiquement à une date ultérieure en ajoutant une nouvelle catégorie. (Le simple fait que vous-même ne puissiez pas ressentir correctement le fonctionnement des mathématiques est une indication que ce serait le cas pour vos utilisateurs).

Une meilleure option serait que l'OMI fournisse une indication visuelle quelconque lorsqu'elle ajoute dans une nouvelle catégorie que cette nouvelle catégorie a besoin de ressources qui lui sont allouées pour continuer. Pour l'accessibilité, nous ne pouvons pas vraiment utiliser la couleur ici, donc je suggère des graduations et des croix pour chaque catégorie. Si toutes les ressources sont allouées, toutes les catégories sont "cochées", mais si une catégorie est manquante, elle aura une "croix" contre elle.

OK, cela laisse un autre dilemme sur la façon dont vous sélectionnez "0" comme montant de ressource pour l'article, mais c'est un problème à explorer séparément si vous pensez que cette approche est ce que vous recherchez.

1
JonW

Une technique simple consiste à calculer les pourcentages des valeurs de curseur par rapport à la somme des valeurs de curseur, puis à réaffecter les valeurs de curseur aux pourcentages calculés respectifs. de cette façon, les valeurs du curseur seront réajustées, par exemple

slider1.value = (slider1.value / sumOfSliderValues) * 100 ;
slider2.value = (slider2.value / sumOfSliderValues) * 100 ;
slider3.value = (slider3.value / sumOfSliderValues) * 100 ;

Il y a une petite erreur d'arrondi mais elle peut être gérée au cas où nous aurions besoin que les valeurs des curseurs totalisent exactement et toujours jusqu'à 100.

J'ai installé un violon pour le démontrer en utilisant angularjs. Veuillez visiter démo

1
Ahmad Noor

C'est une question intéressante et il y a déjà beaucoup de bonnes solutions dans ce fil. Je pense que vous avez oublié une information importante dans votre description. La nature réelle de la tâche en cours d'exécution. Lorsque l'utilisateur modifie les nombres et les catégories, ce qui l'intéresse réellement, en attribuant des nombres absolus aux catégories ou en proposant une bonne distribution, entre les nombres.

La tâche consiste-t-elle à remplir un camion, c'est-à-dire (pour vous en tenir à vos exemples), il y a de la place pour 100 morceaux de fruits combien de chaque catégorie voulez-vous dans le camion. L'utilisateur peut généralement vouloir d'abord se débarrasser de toutes les pièces d'un même type, puis remplir le reste. Si tel est le cas, je pense que votre meilleur pari est une interface où l'entrée est contrainte au nombre total et ne peut pas être dépassée, lorsque l'utilisateur essaie d'augmenter un élément au-dessus dont il a besoin pour en réduire un autre.

Si en revanche le rapport entre vos articles est plus important par exemple peaufiner le mélange de tarte aux fruits industriels, nous le faisons toujours en lots de 100 livres, quelle est la meilleure allocation, puis je pense qu'une interface plus dynamique où tous les curseurs se déplacent lorsque quelque chose change serait plus approprié.

1
Harald Scheirich

Comment aurais-je pu le faire. Je vais demander quelle stratégie de distribution l'utilisateur veut-il utiliser (proportionnel, couper du premier ..., couper du plus grand ...). Par exemple:

Ajout du premier ("pommes"): 100%

100 points to 'Apples'

Ajout du second ('Oranges') -> saisie utilisateur: 30%

70 points to 'Apples'
30 points to 'Oranges'

Ajout du troisième ('Poires') -> entrée utilisateur: 20% ([x] proportionnel)

20 points to 'Pears'
56 points to 'Apples'
24 points to 'Oranges'

AJOUTÉ:

Je voudrais ajouter l'option de verrouillage [x] pour conserver certaines valeurs

0
igor

Il existe un site Web de finances personnelles, Buxfer .

Il a un composant IOU. Il existe une implémentation de base de ce dont vous avez besoin. Il y a plusieurs personnes, partage et dépenses. Si nous devons le diviser de manière inégale, il fournit une interface utilisateur simple avec des zones de texte pour fournir les différents montants.

enter image description here

Cela commence par un partage égal et lorsque vous apportez des modifications, les champs encore intacts sont automatiquement mis à jour.

enter image description here

Notez que lorsque vous effectuez une modification manuelle dans un champ, cela ne modifiera pas son contenu par programmation.

enter image description here

Si vous modifiez tout et si le total ne dépasse pas le montant, le système ne vous permet pas d'enregistrer. J'ai aimé certains aspects de cette interface utilisateur.

  • Il vous permet d'ajouter dynamiquement un partage.
  • Il s'assure que le montant totalise toujours le montant de la transaction.
  • Le système ne met à jour que les champs qui ne sont pas encore touchés par l'utilisateur . Il ne remplace pas les entrées de l'utilisateur.
  • Vous pouvez encore améliorer en donnant une bordure différente ou quelque chose aux champs que l'utilisateur a explicitement modifiés.
  • À tout moment, il offre aux utilisateurs des options de réinitialisation par une répartition égale.

Vous pouvez probablement l'augmenter avec un graphique qui se reflète dès que l'utilisateur fait des changements dans les champs. Vous pouvez avoir des valeurs réelles à la base de chaque barre et donner des gradients basés sur le pourcentage de votre budget total consommé par chaque barre. Vous pourriez probablement ajouter une superposition sur chaque barre indiquant le pourcentage.

La gestion de l'équilibrage est une partie essentielle de votre algorithme, mais je serais las de toucher les montants que l'utilisateur a explicitement saisis. Cela vous laisse moins de contrôle. Pendant que les utilisateurs manipulent les graphiques, vous pouvez virer les barres individuelles en rouge ou le graphique entier si vous pensez que le système ne peut pas prendre de décisions en fonction de l'état de l'utilisateur.

Fondamentalement, la partie mathématique va être compliquée. Lorsque vous essayez d'ajuster un chiffre, vous devriez probablement tenir compte des valeurs historiques, des valeurs de tendance, etc. La réaction de l'utilisateur lorsque vous prenez des décisions pour lui fait également beaucoup de différence.

Buxfer va de façon neutre, il divise également le montant restant, et s'il ne le peut pas, il désactive l'action d'enregistrement/soumission et indique à l'utilisateur que les choses ne s'additionnent pas. Si vous ne voulez pas cette route, vous auriez besoin de plus d'informations sur le comportement des utilisateurs en fonction des profils, quoi et comment ils utilisent le système, et vous courez toujours le risque de déranger un groupe qui ne voudrait pas de répartitions inégales avec condescendance faites par le système pour leur.

Il y a un problème de savoir comment ajouter dynamiquement une catégorie lorsque certains calculs sont en cours. Quel effet cela devrait-il avoir sur les mathématiques jusqu'à présent? Je suggérerais des répartitions égales uniquement si l'utilisateur n'a touché aucun montant, ou des répartitions égales entre des montants qui n'ont pas encore été touchés par l'utilisateur.

Dans tous les cas, il reste le choix entre être brutal et restreindre fortement les opérations de l'utilisateur, ou être libéral et forcer l'utilisateur à corriger les mauvaises entrées avant de sauvegarder. Ce choix peut être fait en fonction du contexte de votre application, du type de données budgétisées, de la quantité de méta-informations du système.

Je suggère également de considérer la durée de l'opération. Un utilisateur expérimenté s'attend à un moyen de saisir des données qui n'implique pas de manipulation de graphique.

De plus, je sais que votre exigence explicite dit qu'il n'y a pas de sauts, mais cela va entraîner des montants comme 63, 41, 39, etc. au multiple de 5, 2 ou 10 le plus proche, en fonction du type de données que je traite. C'est plus long et ennuyeux. ( Remettez cela car il s'agit d'une opinion personnelle et non appuyée par une recherche). Quand j'essaye de mettre des budgets sur quelque chose, je suis plus enclin aux ballparks qu'aux détails comme mentionné ci-dessus.

Faites-moi savoir si j'ai besoin d'ajouter quelque chose de plus.

0
Sol