WHAT ARE HISTOGRAMS
|
|
Plus a function to keep track of the amount of chars inserted in a field
|
[ best viewed listening to Mr. Bojangle, Robbie Williams' version ]
A Jose Garcia Ramos painting, Going out of the theater, Paris.
A few unrelated observations on certain things that accrue, and on others that shine forth - for, «you know me, Al...»: some like it hot!
«They despise one another, yet they fawn one another; they want to climb over one another, yet they grovel to one another.
(...) and see what sort of people they are. You will then see that there is no need for you to tear yourself apart so that they will come to form this or that opinion of you. Nevertheless, you must show goodwill to them. And the Gods themselves lend them every aid, through dreams and oracles, if only to gain the things on which their hearts are set.
(...) Human life is such little a thing, and little too the corner of the earth on which it is lived, and little too even the fame that endures for the longest, and even that is passed on from one poor mortal to another, all of whom will die in no great while, and who have no knowledge even of themselves, let alone of one who has died many years before, in an ancient time.
(...) The same calamity happens to another, and either because he obtusely fails to realize that it has happened, or because he wants to display strength of mind, he stands firm or does not even really notice. Is it not extraordinary that ignorance and self-conceit should prove more efficacious than wisdom?
(...) and if it comes up against something else instead, it converts it into material for itself, much as with a fire when it masters the things which fall into it. These would have extinguished a little lamp, but a blazing fire appropriates in an instant all that is heaped on to it, and devours it, making use of this very material to leap ever higher.» [Marcus Aurelius, Meditations]
«No man, when he hath lighted a candle, putteth it in a secret place, neither under a bushel, but on a candlestick, that they which come in may see.» (KJV, Gospels, Luke)
«And he said unto them, Is a candle brought to be put under a bushel, or under a bed? and not to be set on a candlestick?» (KJV, Gospels, Mark)
« Neither do men light a candle, and put it under a bushel, but on a candlestick; and it giveth light unto all that [roam by] the house.» (KJV, Gospels, Matthew)
A nice gadget always comes with a price.
And since what you want is a nice gadget indeed, namely dynamic bar histograms that jump upward or downward or rightward or leftward or whatever your exigent caprice may devise so to symbolize the different degrees of accomplishment achieved by third ongoing processes (for this is the somewhat " ambitious" thing I am after here), then you have to pay a price; and since my website donates scripts and you never have to pay a penny for raiding them and using them wantonly at your discretion and whim, what you have to pay me is this: attention; and I mean yours.
Because you can have it for free, but you cannot have what you want for free and also without attention. Too convenient, Jim...! Life ain't that easy on this mortal resort, so far east of Eden!
So you want histograms. So you want a bar that moves forward to represent visually at what point some other process on the page is at.
Very well.
The first thing you must know is this: what I named " third processes" can be basically only two things:
- Time: time passes by all the while, when you're on a page - or wherever else as a matter of fact!
So you may want a bar that represents visually this elapsing time, towards a time limit you may have set? And maybe you want to decide whether this bar must move upward or downward or rightward or leftward, and then maybe you even want even to decide whether this bar must show the progress by increasingly revealing itself or by increasingly hide itself?
You can have all you want here.
- Events: on a web document there can occur events, such as, for instance, on clicks, on mouse downs, on change (of form text fields values) etc...
Each of such event describes a third ongoing process, for there are circumstances where you may want to count up how many times such an event has occurred - and yeah, have an histogram that represents the count of the times such an event has occurred.
Yeah, an example. Sure. And then tell me where else you find a guy who writes documentations like these!
An example is this: an user enters text within a form field, yet that form field allows only for a maximum amount of entered letters: there you go, whenever a key is pressed down, unless it is a delete key, it is one step more towards the final line; and as such this process is suitable to be also represented by an histogram.
For now without the histogram, to be sure you understand and appreciate, here is a form field where you can add a maximum of 20 chars. You will see it is possible to keep track of how many chars you've inserted - by the way a feature I many times have wished a website requiring for such limits would have implemented, rather than having to guess myself if I was close already to that maximum of say 400 allowed chars limit...
ON DIFFERENT SHORES |
|
Enter chars and see appearing a number revealing how many they are: max 20 chars allowed. Don't be shy now, type in:
0
|
|
As you may sense, that is a process suitable to be represented by an histogram too.
By the way if you're interested to know how it is achieved, first copy this function, whose name is typerCount, in your page:
To invoke it, it takes in these arguments:
- from: this must be the object value which you want to read for the amount of currently inserted chars; as such it can be either a form field, or even a layer for that matter.
If a form field, add the value keyword, if a layer add the innerHTML keyword:
document.formName.fieldName.value
if a layer, you can pass it by:
document.getElementById("anIdHere").innerHTML
though the latter would count in also possible html tags - which by the way you could strip by something more sophisticated like:
document.getElementById("anIdHere").innerHTML.replace(/<.*?>/g,"")
- to: it is just the object upon which you want to print the outcome of that calculation.
For this latter object reference, omit either value or innerHTML (the reason it has now to be omitted is, for those who love technicalities, that we're about to write on this latest object, and inserting such keyword now would read rather than write; so we have to add it in a second moment so to spare the script this "misunderstanding").
So:
document.formName.anotherFieldName
if a layer, you can pass it by:
document.getElementById("anId2Here")
- append: must be a string and defaults to "value". I suggest to you to pass it. If your second (previous) argument was a layer (namely you mean to print the outcome on a layer), pass this argument in between quotes as "innerHTML" and beware: innerHTML is a case sensitive keyword!
Otherwise pass it as "value".
Then you add on the form field (or layer) mentioned as first argument ( from) namely the element you want to count from the chars typed within, two event handlers ( both of them please!):
onKeyPress
onkeyUp
and in both of them you insert the same invocation to the typerCount function, say for instance:
< input type="text" name="FIELDNAME" maxlength="20"
>
<
div
id="IDhere"
></div>
|
The last thing you need to keep in mind is this: once decided whether what your third process is, whether elapsing time or events, you have to set a limit. When you have this all, a third process whose proceedings can be read via script and you set a limit for it, you can have your histograms too.
FIRST STEPS: ARRANGING YOUR LAYER(s)
|
|
How to draft the layer which will include your histogram
|
Since the function that creates the histograms is a class and therefore you can initialize as many active instances of the template such class represents, you can consequently have on your page as many histograms as you want, even whole full and spinning charts of them, just depending on how many instances of that same class you initialize in the page.
What you need, anyway, is that for every histogram you craft a layer. Here are the instructions on how you must build this layer.
All histograms will be background images set onto a layer, and the position of this layer background will be dynamically updated so to make it move in order to represent the progression of some external third task.
Thus you need to have:
- An image you want to use as layer background: this will perform as the scrolling histogram bar.
- You know the width and height of this image.
- If you need to crop subsection of an image or resize images, a completely freeware utility which is among the very best and at the same time simple in the world for it is Irfan View.
You can download it from that link, and once installed (requires very little) you can open an image with it. You can find in the menu voice image the option resize/resample, or if you draw with your mouse a rectangle onto the image, you can otherwise select from the menu voice edit the option crop.
Once you have that, you draft a layer for that image, a layer which of course must have an id.
In this layer you will declare a style property and in it you have to add as compulsory at least these properties:
- width: must be the same width as the background image.
- height: must be the same height as the background image.
- background-image: url(pathHere/imagename.gif)
- These properties must be set inline the tag via a style property
<span ...>
You could have set them also by, say, an external css, but if you do the function won't work: just and uniquely in order to simplify the code of this script and spare it the necessity to locate too where these necessary style properties might be declared in their prevailing definition (for style sheets allow a cascading set of precedence rules), you're mandatorily required to declare the three properties above inline the tag, or the function will not work.
So, assuming that the name of your image inclusive of extension is, say, myImage.jpg and resides in the same directory of your html file where you're inserting this layer, and its width is say 200 and its height say 400:
<div
id="anIdHere"
style=": 200; : 400; : myImage.jpg";
>
</div>
Please always use the <div> tag for making a layer: Netscape, even version 7, can fail to set right the width and height of a layer if it is not built up with a div tag but, say, with a <span> tag.
Also, note that adding features or paddings to the layer destined to host the scrolling background is not a good idea: the only surely safe css features you can add to it, are background-color and color, whereas all other features involve some risk of subtracting small slices of visibility to the scrolling background. So if for instance you want to give your layer a visible border, better to nest it within another layer, and give such additional features -like a border- to this outermost layer.
Once you'll run the script on the designed layer (you'll soon see how) the script will make sure that the background of the layer is set in the no-repeat mode too (setting it so automatically!) and accordingly to the kind of histogram you have chosen (say one that slowly appears from left to right, or say one that slowly disappears from top to bottom, or many others in the wide pool of methods this class offers) the script will also set by itself the position of the background in a consistent way upon execution, so that the background image position will start with the most consistent spacial arrangement with the direction it is meant to flow along.
Next section: the code of your function and how to initialize the layers.
CODE AND INITIALIZATIONS
|
|
The histogram codex and how to initialize instances for your layers
|
The code which follows is that of the histogram function, conveniently enough and perhaps not too imaginatively named exactly histogram.
This function (class) contains as many as 16 ( sixteen!) functions to account for whatever type of scrolling histogram you may want.
If you think you need only one of these various internal methods you could choose from, you can even edit the code so to shorten it to a few lines (this only if the codes, hosting so many methods, appears too long to your eyes), by locating the instances of the inner methods you don't need and deleting them: all deleteable methods start with a comment saying:
/*method*/
and ending by a comment saying:
/*method end*/
so they are conveniently enveloped by those strings.
The names assigned to these methods contained within this big class is as follows:
- First either the term appear or disappear: the former notation characterizes all those methods whose behaviour implies the gradual appearance of the background of the layer.
The latter notation characterizes all those methods whose behaviour implies the gradual disappearance of the background of the layer.
- The string "appear/disappear" is then followed by a set of two or four letters picked among:
- T means Top
- B means Bottom
- L means Left
- R means Right
thus a notation like RL would hint at the fact that the background of the layer will move from the Right towards the Left.
Consequently, an expression so apparently complex like disappearBTLR means that: the background will be visible at start, and to represent the progression it will slowly disappear. It will disappear following these coordinates: from Bottom towards the Top and from Left towards the Right.
Yeah. Like a sidelong forward slash climbing upward : /
Here is the code; let me insist, its length is due to the fact it is a class which includes as many as 16 functions (so called methods) itself!
To initialize one histogram thus, provided you have a layer with an id and whose style property is set to have its background, and whose style width and height are the same than its background, all you have to do is this: choose a variable name and then initialize it as a new instance of histogram, passing to the function its only two arguments:
Function Arguments |
|
varName
|
This must be a string, namely in between quotes, and must be the string name of the very same variable initialized as a new histogram.
So if for instance the name of your variable is foo, also the first argument passed must be:
"foo"
|
|
id
|
A String, namely in between quotes, and it must be the id of the layer that is to perform as histogram.
|
You can therefore initialize as follows: assuming the placeholder name for a variable to initialize as a new instance of this class is foo and the placeholder id of the related layer is anId:
var foo=new histogram("foo", "anId");
Though you can insert the histogram function codex in whatever point of the document you prefer, yet do not confound the code of this class function with the initialization of a new instance of that class. The code of the class can go wherever (though of course not after the initializations) in the page, but the initializations themselves can never go before the html layer code. Do not -never- issue that initialization before your layer has been declared: always initialize in some document location after, also soon after, the location of your layer html code, but never before such layer declaration:
<div id="anId" style="width: 200; height: 350; background-image: url(anImage.jpg)"></div>
<script>
var foo=new histogram("foo", "anId");
</script>
Additionally, if you have chosen for your layer id the same name as your chosen variable, you can even omit the second argument!
That's truly all to initialize, and don't say it is difficult. Only thing, upon performing such initialization, don't forget the keyword var.
RUN YOUR HISTOGRAM: AVAILABLE METHODS
|
|
How to run your histogram: available methods and how to trigger them, or how to run them as timeouts
|
Here I describe the available methods. The idea with every method is the following: upon running an histogram, you want it to represent by the increase (or decrease for that matter) of the dynamic bar (background image, in our case, as you learned), the increase/decrease in some external process which is affecting some other object whose values and properties are accessible via script: the histogram must in fact act as a mere graphical mirror and representation of this "alien" ("third") process.
Thus the progression of the bar of the histogram will have to be proportional with this external process; to achieve this you have to monitor the "third" process, and to do this each time you call (you'll soon see how) an histogram method, you'll have to pass to it two parameters:
- The maximum (a Number), being this the value reached which the external third process is considered concluded.
- The current (a Number) value of the external process, being this the value such property heading to arrive at the maximum is assuming in the current instant.
An example of this is typing in a form field (thence the example of the typerCount function above) which allows for a limit of chars that you can type in: if such limit is, say, 20 chars, then this as a whole represents a third process described as follows:
- What triggers it is any update of the field, which event handlers such as onChange and the alike capture.
- Its maximum is 20 (max amount of chars you can insert).
- Its current amount is the amount of chars inserted thus far.
Each histogram method will make a proportion devising the percentage that such current incarnates against the declared maximum, and then it will devise the related ratio between the overall width (or height, or both) of the layer and the amount of background which must be shown (or hidden) in order to reproduce a graphical representation of the former ratio.
In other words the proportion appears as follows:
maximum current layer_overall_width_or_height X
Here are now your histogram built in methods: you'll understand better what the arguments maxim and current in their signatures stand for now, I guess!
An Auguste Renoir painting, Jeune fille coiffant ses cheveux, 1894
|
Available Methods |
|
appearTB( maxim, current )
|
Example:
foo.appearTB(Number, Number)
Both Numerical arguments could be drawn by form fields or other javascript elements suitable to return Numerical values. Ideally, the maxim parameter is a hard coded number (such as say 300) and the current parameter is more directly drawn from some page element namely as references such as say document.formName.FormField.value and the alike.
|
|
disappearTB( maxim, current )
|
Example:
foo.disappearTB(Number, Number)
Both Numerical arguments could be drawn by form fields or other javascript elements suitable to return Numerical values. Ideally, the maxim parameter is a hard coded number (such as say 300) and the current parameter is more directly drawn from some page element namely as references such as say document.formName.FormField.value and the alike.
|
|
appearBT( maxim, current )
|
Example:
foo.appearBT(Number, Number)
Both Numerical arguments could be drawn by form fields or other javascript elements suitable to return Numerical values. Ideally, the maxim parameter is a hard coded number (such as say 300) and the current parameter is more directly drawn from some page element namely as references such as say document.formName.FormField.value and the alike.
|
|
disappearBT( maxim, current )
|
Example:
foo.disappearBT(Number, Number)
Both Numerical arguments could be drawn by form fields or other javascript elements suitable to return Numerical values. Ideally, the maxim parameter is a hard coded number (such as say 300) and the current parameter is more directly drawn from some page element namely as references such as say document.formName.FormField.value and the alike.
|
|
appearLR( maxim, current )
|
Example:
foo.appearLR(Number, Number)
Both Numerical arguments could be drawn by form fields or other javascript elements suitable to return Numerical values. Ideally, the maxim parameter is a hard coded number (such as say 300) and the current parameter is more directly drawn from some page element namely as references such as say document.formName.FormField.value and the alike.
|
|
disappearLR( maxim, current )
|
Example:
foo.disappearLR(Number, Number)
Both Numerical arguments could be drawn by form fields or other javascript elements suitable to return Numerical values. Ideally, the maxim parameter is a hard coded number (such as say 300) and the current parameter is more directly drawn from some page element namely as references such as say document.formName.FormField.value and the alike.
|
|
appearRL( maxim, current )
|
Example:
foo.appearRL(Number, Number)
Both Numerical arguments could be drawn by form fields or other javascript elements suitable to return Numerical values. Ideally, the maxim parameter is a hard coded number (such as say 300) and the current parameter is more directly drawn from some page element namely as references such as say document.formName.FormField.value and the alike.
|
|
disappearRL( maxim, current )
|
Example:
foo.disappearRL(Number, Number)
Both Numerical arguments could be drawn by form fields or other javascript elements suitable to return Numerical values. Ideally, the maxim parameter is a hard coded number (such as say 300) and the current parameter is more directly drawn from some page element namely as references such as say document.formName.FormField.value and the alike.
|
|
appearTBLR( maxim, current )
|
Example:
foo.appearTBLR(Number, Number)
Both Numerical arguments could be drawn by form fields or other javascript elements suitable to return Numerical values. Ideally, the maxim parameter is a hard coded number (such as say 300) and the current parameter is more directly drawn from some page element namely as references such as say document.formName.FormField.value and the alike.
|
|
disappearTBLR( maxim, current )
|
Example:
foo.disappearTBLR(Number, Number)
Both Numerical arguments could be drawn by form fields or other javascript elements suitable to return Numerical values. Ideally, the maxim parameter is a hard coded number (such as say 300) and the current parameter is more directly drawn from some page element namely as references such as say document.formName.FormField.value and the alike.
|
|
appearTBRL( maxim, current )
|
Example:
foo.appearTBRL(Number, Number)
Both Numerical arguments could be drawn by form fields or other javascript elements suitable to return Numerical values. Ideally, the maxim parameter is a hard coded number (such as say 300) and the current parameter is more directly drawn from some page element namely as references such as say document.formName.FormField.value and the alike.
|
|
disappearTBRL( maxim, current )
|
Example:
foo.disappearTBRL(Number, Number)
Both Numerical arguments could be drawn by form fields or other javascript elements suitable to return Numerical values. Ideally, the maxim parameter is a hard coded number (such as say 300) and the current parameter is more directly drawn from some page element namely as references such as say document.formName.FormField.value and the alike.
|
|
appearBTLR( maxim, current )
|
Example:
foo.appearBTLR(Number, Number)
Both Numerical arguments could be drawn by form fields or other javascript elements suitable to return Numerical values. Ideally, the maxim parameter is a hard coded number (such as say 300) and the current parameter is more directly drawn from some page element namely as references such as say document.formName.FormField.value and the alike.
|
|
disappearBTLR( maxim, current )
|
Example:
foo.disappearBTLR(Number, Number)
Both Numerical arguments could be drawn by form fields or other javascript elements suitable to return Numerical values. Ideally, the maxim parameter is a hard coded number (such as say 300) and the current parameter is more directly drawn from some page element namely as references such as say document.formName.FormField.value and the alike.
|
|
appearBTRL( maxim, current )
|
Example:
foo.appearBTRL(Number, Number)
Both Numerical arguments could be drawn by form fields or other javascript elements suitable to return Numerical values. Ideally, the maxim parameter is a hard coded number (such as say 300) and the current parameter is more directly drawn from some page element namely as references such as say document.formName.FormField.value and the alike.
|
|
disappearBTRL( maxim, current )
|
Example:
foo.disappearBTRL(Number, Number)
Both Numerical arguments could be drawn by form fields or other javascript elements suitable to return Numerical values. Ideally, the maxim parameter is a hard coded number (such as say 300) and the current parameter is more directly drawn from some page element namely as references such as say document.formName.FormField.value and the alike.
|
|
execute( functionName, maxim, current )
|
Example:
foo.execute("disappearLR", Number, Number)
Just an alternative way to run any of these methods: pass as first argument the name of the method, in between strings, that you want to execute.
|
|
run( functionName, maxTime, speed )
|
Example:
foo.run("disappearLR", Number, Number)
This is for the scrolling bar histograms that must run under a merely temporal input, namely it is time itself what is considered the "third process"
The numerical arguments must be milliseconds, namely 1000=1 second so 1000*60=60.000 is one minute, and so on.
The second argument maxTime must therefore be the amount of milliseconds after which the process is considered concluded: for one hour it is 3.600.000 for one day it is 86.400.000
The last argument speed is the interval after which you must check for an increase in the bar: it defaults to 100 milliseconds, which is a very fast: the higher it gets (say 1000) the bigger the leaps of the bar at each such recurrent check.
Each call to run performs a call to the method named reset() too (see below).
|
|
reset( functionName )
|
Example:
foo.reset("disappearLR")
You run this to reset a layer to the values it had at the beginning, so that it is set (positioned) in the most suited way to start performing as an histogram for the given functionName.
If you omit functionName, the script will reset the layer after the resetting values best suited for the lastly called in method, which is stored as a string name in a property named lastCalled.
|
|
stop()
|
Example:
foo.stop()
If a histogram has been triggered by run(etc...), a call to stop interrupts the histogram. A subsequent call to run would reset the layer too.
My suggestion is to issue a call to stop() always and as first in any event handler statement meant to hold a call to some histogram instance methods: it makes all just safer.
|
Thus once you have initialized your foo instance, you could set an event or more, such as onKeyPress or onkeyUp to check the values that some element gets any time such an event occurs. In the case of a form field which allows only for a maximum of 20 chars:
<div id="anId" style="width: 200; height: 350; background-image: url(anImage.jpg)"></div>
<script>
var foo=new histogram("foo", "anId");
</script>
<input maxlenght="20"
name="typeField"
>
The reason above we issue twice the same command on two different event handlers has nothing to do with the histogram function, but only with the way key strokes are detected as events: if we'd omit one of those event handlers, we'd most likely fail to detect deletions of chars.
Feel free to run a test below on such a typing event. I have intentionally chose as a dynamic "bar" an ample rectangle: you are more likely to choose something that is much thinner and looks much more like a bar.
|