Searching for a nice dashboard


(jmm) #22

Please bear in mind that the code I posted above doesn’t work properly as en edict in a prototype, contrary to what I wrote. It does count, but what it counts it escapes me.


(Paul Walters) #23

We don’t have your data, so it’s hard to parse what’s going on. If I break it down and write it out in pseudo-English, it looks like the calculations are:

MyNumber is words in all descendants

MyNumber_1 is words in descendants whose prototype is either pNote or pAnnotation

Subtitle line 1 is the number of descendants whose prototype is either pNote or pAnnotation, then a space, then MyNumber_1 (the count of all words in descendants with either of those prototypes), then a “W”, then MyNumber_1 divided by 250 (the number of pages in descendants with either of those prototypes), then a “P”, and then a new line

Subtitle line 2 is MyNumber (the sum of all words in all descendants), then a “W”, then MyNumber divided by 250 (the number of pages in all descendants), then a “P”

So, in short, your subtitle says you have 2 notes, containing 2,856 words and 11.4 pages, that have either of those prototypes, and overall you have 3 notes, containing 2,917 words and 11.7 pages.

Is that what you intended?


(jmm) #24

Back to TB. Thanks for taking your time to describe what I was meaning to achieve. The numbers displayed in subtitles do not correspond to the notes inside my containers nor to their word counts. My guess is that instead of a string, the above might be using numbers. I’ll just wait to have a better command of these operations.


(Andreas Grimm) #25

What do I have to add in order to get the $WordCount of words just created today?


(eastgate) #27

I sometimes like to know how many words I’ve added to a section, or to an entire document, today. There are several ways to do this. Here’s mine.

  1. Make a new note to serve as a container. This container will have prototype Dashboard and will hold notes on your progress,

  2. The container has an OnAdd action, something like this:

OnAdd: $StartDate=date(“today”);$MyNumber=sum(all,$WordCount);
Rule: $Subtitle=$MyNumber(lastChild)
Sort: by $StartDate

  1. When you finish working for the day, make a new note — name it “A” or anything you like — and drag it into the container.

  2. The container’s subtitle will now be the word count of the latest progress note. Exercises left to the reader:

  • Restrict the counting to a specific container /Drafts
  • Draw the subtitle more legibly, e.g. with a comma as a thousands separator

(Andreas Grimm) #28

It’s not working for me … which probably means: I don’t understand it.

My problems already start with my illiteracy of adding OnAdd actions to containers; for I only know how to achieve that for adornments.

@eastgate: A small video or gif really would help here.


(Paul Walters) #29

Select a container note. Open the inspector. Insert as shown:


(Mark Anderson) #30

@andreas, referencing the left-hand screen grab above, if the sub-pane label of ‘action’ (as opposed to ‘OnAdd’) is confusing you this is because that pane stores $OnAdd for containers and adornments but also $AgentAction for agents.

Although this might seem odd as these are two different attributes, even if an agent has an $OnAdd value set it is never evaluated (and not shown in the panel) - the reverse is true for containers/adornments. So, there is no actual conflict in two sources being served by a common input.

However, a label of ‘OnAdd/AgentAction’ would not necessarily be clearer and would be too long for the space available on the button.

TL;DR - the ‘Action’ sub-pane set $OnAdd or $AgentAction depending on the type of currently selected item(s).


(Mark Anderson) #31

I’m not sure I follow. A new note ‘A’ will have no $Text. Added to the container, the $MyNumber(lastChild) will be zero, surely?


(Andreas Grimm) #32

I understand. Thanks @mwra for your clarification.

And, indeed, I did already go the path you kindly clarified.

Where I definitely struggled was when a new (empty?) Note “A” was supposed to be added … in order to show … hmmm … what?


(Mark Anderson) #33

I’ve not got time to build a demo now, so I have not fully tested what follows, but I think I see a way to @andreas’s question thus…

Tinderbox doesn’t record the timing of changes within $Text. But we do something like:

  • predicated on all actions running on file open, or still running if file is left open
  • record and store $WordCount of relevant notes. At the very start we place this title in $OldCount and set $DateOfCount with the current date, and $DateNextCount to 23:59 of the same day.
  • test if the day of today’s Date is after day of the stored one (don’t use days()). If different, we are on a new day.
  • if today’s date is after $DateNextCount, we reset $OldCount to the current count (i.e total as at end of previous day (of use) and reset the two guard dates. This should happen once, at the start of the day
    *If on a new day but before date/time of $DateNextCount we compare we set $OldCount vs the current count to give $CurrentCount which gives the word count so far today(don’t calculate this on the fly in a DisplayExpression - use a stored count).

So you need two Number-type attribute $OldCount and $CurrentCount, and two Date-type attributes $DateOfCount and $DateNextCount.

I’ll assume all notes of interest are descended from a root level container ‘DATA’.

Make a stamp for applying/ initiating the process in container at path /Data:

$OldCount= sum(descendants,$WordCount);
$CurrentCount =;
$DateOfCount = date("today");
$DateNextCount = date("today 23:59");

Now the edict for the container (why an edict? See below):

if today’s date is after $DateNextCount, we reset $OldCount to the current count (i.e total as at end of previous day (of use) and reset the two guard dates. This should happen once, at the start of the day

if($DateOfCount & $DateOfCount < date("today") ){
   $OldCount = sum(descendants,$WordCount);
   $NewCount =;
   $DateOfCount = date("today");
   $DateNextCount = date("today 23:59");
};

That will only occur once per day and resets the base word count for start of day. Now we calculate the current word count:

$NewCount = sum(descendants,$WordCount)- $OldCount;
$Subtitle = $NewCount.format("l");

The latter gives a formatted number (format string is a _lowercase _L), e.g. ‘4,562’ not ‘4562’.

So, as one action:

if($DateOfCount & $DateOfCount < date("today") ){
   $OldCount = sum(descendants,$WordCount);
   $NewCount =;
   $DateOfCount = date("today");
   $DateNextCount = date("today 23:59");
};
$NewCount = sum(descendants,$WordCount)- $OldCount;
$Subtitle = $NewCount.format("l");

Why an edict? You probably don’t want a rule running all the time - especially is your actual sum() group designator is actually a complex find(). Edicts run on file open, then about once every hour but can be refresh on demand (i.e. once only, like a stamp action) via the edict Inspector or by menu File -> Update Agents Now (this update all edicts once, as well as all agents). This gives you easy access to your current word count without a rule running all the time. Or, use a rule if you prefer but be open to an edict if you start adding lots of actions. The code above remains unchanged - it’s simply a matter of whether you put it in the container’s $Edict or $Rule.


(Andreas Grimm) #34

@mwra wow, thank you for this. I just have to digest what you’ve suggested, then test and then come back here to report back.

Again, thank you very much. I guess this is really a major contribution; since a writing environment such as Tinderbox really could use a $Today'sWordcount Attribute. But maybe it’s just me – again.


(Mark Anderson) #35

That assumes it is easy to tell what is actual writing and what is back-of-house stuff. Having an infrastructure to ‘easily’ tell the app what that is - rather than configure it (as above) is actually a lot more work. Compare with a writing app like scrivener, where writing is the primary purpose; although you can add other notes, PDFs, images, etc., they are tangential to the main design. Thus, it doesn’t surprise me Tinderbox doesn’t have a built-in time-scoped word count. (which doesn’t mean it may not acquire one!)


(Mark Anderson) #36

One final polish. It may be that your TBX has more than one discrete project for which you are tracking word counts. If so, it may make sense to make a prototype ‘pCounts’ (or whatever name/style you prefer for prototypes). I’ll refer to an edict but use a rule if preferred (as discussed above). Set the edict/rule in the prototype to disabled (see the tick-box on the Inspector) and then past in this modified code - I’ll explain the changes below the code:

if($DateOfCount & $DateOfCount < date("today") ){
   $OldCount = sum(descendants($Name(this)),$WordCount);
   $NewCount =;
   $DateOfCount = date("today");
   $DateNextCount = date("today 23:59");
};
$NewCount = sum(descendants($Name(this)),$WordCount)- $OldCount;
$Subtitle = $NewCount.format("l");

We’ve change the sum() group argument from descendants to descendants($Name(this)). Now each container inheriting the edict/rule from the prototype will sum it’s own descendants.

Plus, importantly, if you’ve lots of these counters and find you ned to need to alter the action code - you do it once, in the prototype. :smile: