Ga naar hoofdinhoud

Kaarten verslepen op het bord

Het tweede idee dat na v0.8 is toegevoegd: kaarten met de muis verplaatsen — binnen een kwadrant én over de kwadrantgrens heen — waarbij het loslaten de belangrijkheid en de urgentie van de taak bijstelt, afgeleid van de kaarten eromheen.

Wat slepen moet opleveren

Scores invullen per factor (Ranking) is precies, maar het is de verkeerde vraag op het verkeerde moment. Je weet zelden of een taak een 7 of een 8 verdient; je weet wél dat hij belangrijker is dan die ene en minder dringend dan die andere. Vergelijken kunnen mensen goed, absolute cijfers geven niet.

Slepen maakt van het bord daarom een invoermiddel in plaats van alleen een weergave: je zet een kaart tussen twee andere en zegt daarmee "hier hoort hij, tussen deze twee". Het model leidt daar de getallen uit af, niet andersom.

Dat levert twee dingen op. Het bijstellen van een verkeerd ingeschatte taak kost één beweging in plaats van een formulier met zeven schuifjes. En het verschil tussen waar jij een kaart neerlegt en waar het model hem had staan is zelf informatie — zie Slepen als signaal over het model.

Het bord wordt een vlak

Vandaag staan kaarten binnen hun kwadrant in een lijst, gesorteerd op rangordescore (Visualisatie). Voor slepen is dat te weinig: een plek in een lijst is één getal, en er moeten er twee uit komen. Het bord wordt daarom een coördinatenvlak binnen dezelfde vier kwadranten: de horizontale positie van een kaart is haar urgentie, de verticale haar belangrijkheid. De assen, de richting en de kwadrantindeling blijven zoals in Visualisatie beschreven — urgent links, belangrijk boven.

Om te voorkomen dat kaarten met (bijna) dezelfde score elkaar volledig overlappen, ligt er een fijn rooster onder het vlak: elke cel is een tiende van een kwadrant breed en hoog. Kaarten in dezelfde cel worden licht gewaaierd, met een teller als het er meer dan drie zijn. Zo blijft het vlak leesbaar zonder dat de positie zijn betekenis verliest.

Van loslaatpunt naar doelscore: de buren beslissen

De doelscore wordt niet rechtstreeks uit de pixelpositie gelezen, maar afgeleid uit de kaarten waartussen je loslaat. Per dimensie afzonderlijk:

doel_urgentie = (urgentie buur links + urgentie buur rechts) / 2
doel_belangrijkheid = (belang buur boven + belang buur onder) / 2

Waarbij "buur" de dichtstbijzijnde zichtbare kaart in die richting is. De randgevallen:

SituatieDoelscore in die dimensie
Twee burenHet midden tussen beide
Eén buur, aan één kantDe score van die buur, één stap (0,5) opgeschoven in de richting waarin je loslaat
Geen buren in die richtingDe waarde die de asschaal op het loslaatpunt aangeeft
Precies op een andere kaartEen halve stap boven of onder die kaart, afhankelijk van waar je hem loslaat

Waarom via de buren en niet via de as: zo is de handeling een vergelijking en geen meting. Je hoeft niet te weten dat de kaart op 7,3 uitkomt — je ziet dat hij tussen deze twee hoort, en dat is het oordeel dat je werkelijk kunt maken. Bijkomend voordeel: de uitkomst hangt niet af van schermbreedte, zoomniveau of de precieze pixel waarop je losliet.

Over de kwadrantgrens slepen vraagt geen aparte regel. De grens tussen kwadranten ligt bij 5/6 op beide assen; een kaart die je aan de andere kant loslaat, krijgt buren met scores aan die kant en komt dus vanzelf in het andere kwadrant terecht. Slepen binnen een vak en slepen over vakken heen is technisch dezelfde handeling.

Van doelscore naar factoren: de bijstelfactor

Hier zit de kern van het probleem. Belangrijkheid en urgentie zijn geen velden maar uitkomsten: het gewogen gemiddelde van de factor-subscores (Principe). Een kaart verslepen zet dus niet zomaar een getal — het moet ergens in het model landen, anders wist de eerstvolgende herberekening (de deadline-factor loopt dagelijks, Wanneer er herberekend wordt) de verplaatsing weer uit.

De oplossing houdt het model intact: elke dimensie krijgt er één factor bij, Handmatige bijstelling. Die factor werkt als alle andere — een subscore van 1 t/m 10, een gewicht, meelopend in dezelfde formule — met als enige verschil dat je hem niet zelf invult. Hij wordt berekend uit de plek waar je de kaart loslaat:

benodigde_subscore = (doelscore × Σ alle gewichten
− Σ (gewicht_i × effectieve_subscore_i)) / gewicht_bijstelling

waarbij i over alle factoren behalve de bijstelling loopt. De uitkomst wordt begrensd tot 1–10, net als elke andere subscore.

Dat heeft drie prettige gevolgen. De formule uit Principe blijft ongewijzigd, dus de 1–10-garantie geldt nog steeds. De deadline-factor blijft zijn werk doen: een versleepte kaart schuift daarna nog steeds vanzelf op naarmate de datum nadert — je duw was een oordeel, de deadline is een feit, en die twee horen naast elkaar te bestaan. En de kaart houdt een uitlegbare score: in het detail staat gewoon dat er handmatig is bijgestuurd, en met hoeveel.

De kaart landt niet altijd precies waar je hem loslaat. Hoe ver je kunt duwen hangt af van het gewicht van de bijstelfactor: met een klein gewicht komt de kaart maar een eindje jouw kant op, met een groot gewicht overstemt één sleepbeweging de hele inhoudelijke beoordeling. Loopt de benodigde subscore buiten 1–10, dan gaat de kaart zo ver als het model toelaat en zegt het scherm dat erbij: "verder dan dit komt hij niet — pas de subscores aan of verhoog het gewicht van de bijstelling". Dat is geen gebrek maar het punt: het bord geeft tegengas wanneer je iets anders wilt dan je eigen model vindt. Welk gewicht daarbij past, is een open punt (Gewicht van de handmatige bijstelling).

Overwogen en afgevallen

De dimensiescore rechtstreeks overschrijven. Twee extra velden op de taak die, als ze gevuld zijn, de berekening buitenspel zetten. Simpel te bouwen, maar het maakt van elke versleepte taak een taak zonder onderbouwing: de factoren staan er nog, ze doen alleen niets meer. Bovendien zou de deadline-factor stilvallen precies bij de taken die je het meest in handen hebt gehad.

Alle subscores proportioneel meeschuiven. Terugrekenen van de doelscore naar de onderliggende factoren, elk in dezelfde verhouding. Dat houdt de factoren in beeld, maar de terugrekening is niet eenduidig (veel combinaties leveren dezelfde uitkomst) en ze liegt: door een kaart omhoog te slepen zou "toegevoegde waarde" stijgen, terwijl je over de toegevoegde waarde niets hebt gezegd. Een oordeel bewaar je bij de factor die het oordeel draagt.

Wat de gebruiker ziet

  • Tijdens het slepen licht de plek op waar de kaart terechtkomt, met de twee buurkaarten per richting gemarkeerd en een kleine uitlezing van de doelscores ("belangrijkheid 7,4 · urgentie 6,1"). Je ziet dus vóór het loslaten wat je aanricht.
  • Bij het loslaten animeert de kaart naar de positie die het model werkelijk berekent (Van doelscore naar factoren: de bijstelfactor). Wijkt die merkbaar af van het loslaatpunt, dan verschijnt de melding uit Van doelscore naar factoren: de bijstelfactor in plaats van dat de kaart zwijgend terugveert.
  • Ongedaan maken is één klik in dezelfde melding, en herstelt de vorige subscore van de bijstelfactor. Daarnaast staat elke wijziging in het scorelogboek dat Taakbeheer al noemt.
  • Zonder muis: een kaart is met het toetsenbord op te pakken en met de pijltjestoetsen per stap te verplaatsen, bevestigen met Enter en afbreken met Escape. Dezelfde regels, dezelfde meldingen.
  • Zonder JavaScript blijft het bord doen wat het deed: kaarten tonen op hun plek. Verplaatsen gebeurt dan via het taakformulier, zoals nu.

Slepen als signaal over het model

De bijstelfactor maakt zichtbaar hoe vaak en hoe ver je het model corrigeert, en dat is precies de informatie waar Urgentie is nog onderontwikkeld om vraagt. Een beheeroverzicht "grootste bijstellingen" toont de taken waar model en gevoel het meest uiteenlopen. Zit daar een patroon in — alle taken van één gebied structureel omhoog, alle taken met een hoge inzet structureel omlaag — dan klopt er iets aan de gewichten of ontbreekt er een factor, en is de conclusie niet "de kaart moet verschoven" maar "het model moet bijgesteld".

Om die reden legt task_factor_score.source bij deze factor drag vast, naast de bestaande waarden voor handmatig en AI (Vastgestelde ontwerpkeuzes). Slepen is daarmee niet alleen een gebaar maar ook een meting.

Randgevallen en afspraken

  • Een gefilterd bord. Buren worden bepaald over de zichtbare kaarten: je vergelijkt met wat je ziet, anders zou de uitkomst afhangen van iets wat niet op het scherm staat. Gevolg is wel dat een kaart kan verspringen zodra je het filter uitzet. Of dat acceptabel is, of dat slepen bij een actief filter beperkt moet worden, is een open punt (Slepen op een gefilterd bord).
  • Deadline blijft onaangeroerd. Net als in de agenda (Interactie) verandert slepen alleen een zacht gegeven. Op het bord is dat de bijstelling, in de agenda de geplande dag; de deadline verzet je in beide gevallen bewust, in het formulier.
  • Vastgezette kaarten (pin, Overige attributen) staan los van de score en zijn daarom niet sleepbaar zolang ze vastzitten.
  • Afgeronde en gearchiveerde taken worden op het bord niet getoond (Archivering en zichtbaarheid) en tellen dus ook niet mee als buur.

Gevolgen voor het datamodel

Geen nieuwe tabellen en geen nieuwe kolommen. De bijstelling is twee gewone rijen in factor — één voor importance, één voor urgency — met auto_calculated aan, zodat ze niet als invulveld in het taakformulier verschijnen. De waarde per taak is een gewone rij in task_factor_score, met source = 'drag' en het bestaande veld updated als tijdstempel.

Dat het model dit zonder wijziging aankan, is een aanwijzing dat het klopt: een handmatige duw is inhoudelijk gewoon een factor, en zo wordt hij ook opgeslagen. Wel moeten de twee rijen bij installatie worden aangemaakt, en krijgen bestaande taken op grond van de regel uit Vastgestelde ontwerpkeuzes een neutrale subscore (5) — die precies neerkomt op "niet bijgestuurd".

Eén aandachtspunt: een neutrale bijstelling van 5 trekt de dimensiescore naar het midden zodra de factor gewicht heeft. Bij het aanzetten van deze functie verschuiven alle kaarten dus een beetje. Dat is te vermijden door de bijstelfactor te laten rekenen met een neutrale waarde die géén invloed heeft (alleen meewegen zodra hij is aangeraakt) — een detail voor de bouw, maar wel één om vooraf te beslissen.

Bewust buiten scope

  • Meerdere kaarten tegelijk verslepen. Aantrekkelijk bij een grote opruimactie, maar de afleiding uit buren is per kaart gedefinieerd.
  • Slepen naar een ander project of gebied. Zou kunnen door op een filterknop of gebiedslabel te droppen, maar dat is een andere handeling met hetzelfde gebaar — verwarrend zolang slepen "score bijstellen" betekent.
  • Slepen in de agenda. Daar betekent hetzelfde gebaar iets anders (Interactie); de twee schermen blijven bewust gescheiden.

Plaats in de fasering

Slepen hoort in fase A en is toegevoegd als fase A5. Het vraagt geen Joomla en geen publiek endpoint, maar wel een bord met genoeg kaarten om tussen te vergelijken — met vijf taken op het scherm heeft de functie geen betekenis. A4 (agenda) en A5 (slepen) zijn onderling verwisselbaar: slepen raakt de kern van het bord en zou daarom ook eerst kunnen, de agenda levert sneller iets nieuws op.