Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Javascript (http://www.velocityreviews.com/forums/f68-javascript.html)
-   -   Timeline API (http://www.velocityreviews.com/forums/t924426-timeline-api.html)

jshanman 04-24-2006 09:00 PM

Timeline API
 
I am working on a timeline API that devevelopers can use to add a
dynamic timeline to their sites.

Here is a *working* demo of the basic interface. (it works for me
anyway on ie6 & firefox 1.5)

http://www.endeavorpub.com/wiki/timeline.html

Please tear apart my code and tell me what I'm doing wrong so far...

Eventually, I would like this to be cross-browser compatible, give the
deveoper the ability to set colors, ranges, sizes, positions, and set
markers & event ranges.

- JS
http://www.endeavorpub.com


jshanman 04-25-2006 12:46 PM

Re: Timeline API
 
jshanman wrote:
> I am working on a timeline API that devevelopers can use to add a
> dynamic timeline to their sites.
>
> Here is a *working* demo of the basic interface. (it works for me
> anyway on ie6 & firefox 1.5)
>
> http://www.endeavorpub.com/wiki/timeline.html
>
> Please tear apart my code and tell me what I'm doing wrong so far...
>
> Eventually, I would like this to be cross-browser compatible, give the
> deveoper the ability to set colors, ranges, sizes, positions, and set
> markers & event ranges.
>
> - JS
> http://www.endeavorpub.com


You mean to tell me all the experts in this group found absolutly no
problems in my code!

I found a problem : In firefox, I get this message : Error: Error in
parsing value for property 'left'. Declaration dropped.

In IE (when the try catch is removed), I get "Object Error".

Here is the code:

if (document.getElementById("marker"+IconName)) {
document.getElementById("marker"+IconName).style.v isibility =
"visible";
var p = (typeof
document.getElementById("marker"+IconName).style.l eft) ? "px":0;
try {
document.getElementById("marker"+IconName).style.l eft =
XPos+p;
} catch(e) {}
} else {
this["Markers"]["marker"+IconName] =
this.document.createElement("DIV");
this["Markers"]["marker"+IconName].className =
"MarkerClass";
this["Markers"]["marker"+IconName].title = LabelText;
this["Markers"]["marker"+IconName].id = "marker"+IconName;
var p = (typeof
this["Markers"]["marker"+IconName].style.left == 'string') ? "px":0;
try {
this["Markers"]["marker"+IconName].style.left = XPos+p;
} catch(e) {}
this["Markers"]["marker"+IconName].style.top =
parseInt(this.height/2,10)-(h-AnchorY))+p;
this["Markers"]["marker"+IconName].style.width = w+p;
this["Markers"]["marker"+IconName].style.height = h+p;
document.getElementById(Target.id+"LabelDiv").appe ndChild(this["Markers"]["marker"+IconName]);
}

I used the recommended ?"px":0; trick that I discovered while searching
the group, but why is it causing errors? Note: All the markers are
still drawn in their correct positions, these errors just fill up the
console as I drag the map.

- JS


Thomas 'PointedEars' Lahn 04-25-2006 01:53 PM

Re: Timeline API
 
jshanman wrote:

> jshanman wrote:
>> I am working on a timeline API that devevelopers can use to add a
>> dynamic timeline to their sites.
>>
>> Here is a *working* demo of the basic interface. (it works for me
>> anyway on ie6 & firefox 1.5)
>>
>> http://www.endeavorpub.com/wiki/timeline.html
>>
>> Please tear apart my code and tell me what I'm doing wrong so far...
>>
>> Eventually, I would like this to be cross-browser compatible, give the
>> deveoper the ability to set colors, ranges, sizes, positions, and set
>> markers & event ranges.
>>
>> - JS
>> http://www.endeavorpub.com

>
> You mean to tell me all the experts in this group found absolutly no
> problems in my code!


| This is Usenet. It is a discussion group, not a helpdesk. You post
| something, we discuss it. If you have a question and that happens to get
| answered in the course of the discussion, then great. If not, you can
| have a full refund of your membership fees. -- Mark Parnell in alt.html

> I found a problem : In firefox, I get this message : Error: Error in
> parsing value for property 'left'. Declaration dropped.


That is a CSS (layout engine) error, not a script (engine) error. Install
Console^2, FireBug, or both, to filter console messages (since Firefox
1.5/Gecko 1.8b1).

> In IE (when the try catch is removed), I get "Object Error".


Probably it says in which line of the code.

<URL:http://jibbering.com/faq/#FAQ4_43>

> Here is the code:
>
> if (document.getElementById("marker"+IconName)) {

^
Identifiers should start uppercase only if they refer to constructors.

> document.getElementById("marker"+IconName).style.v isibility =
> "visible";
> var p = (typeof
> document.getElementById("marker"+IconName).style.l eft) ? "px":0;
> try {
> document.getElementById("marker"+IconName).style.l eft =
> XPos+p;
> } catch(e) {}


OMG. You definitely want to optimize here:

var marker = document.getElementById("marker" + IconName);
if (marker)
{
marker.style.visibility = "visible";

// `typeof something' always evaluates to a non-empty string,
// therefore `true' in a boolean expression; you want to compare
// it against a string. And still there would be no point in this.
var p = (typeof marker.style.left) ? "px": 0;
try
{
marker.style.left = XPos+p;
}
catch(e) {}
}

Now that redundancy has been removed and thereby efficiency has been
increased, you want to reconsider your approach: Not risking the error and
attempting to handle it later, but attempting to prevent it in the first
place instead, by doing feature tests prior to access.

<URL:http://pointedears.de/scripts/test/whatami#inference>

// from types.js
function isMethod(a)
{
var t;
return (a && ((t = typeof a) == "function" || t == "object"));
}

// from dhtml.js
function setStyleProperty(o, s, v)
{
if (typeof o.style != "undefined"
&& typeof o.style[s] != "undefined")
{
o.style[s] = v;
return (o.style[s] == v);
}

return false;
}

if (typeof document != "undefined"
&& isMethod(document.getElementById))
{
var marker = document.getElementById("marker" + iconName);
if (marker)
{
setStyleProperty(marker, "visibility", "visible");
setStyleProperty(marker, "left", XPos + "px");

> } else {
> this["Markers"]["marker"+IconName] =
> this.document.createElement("DIV");


The W3C DOM Level 2 HTML Specification states that element type identifiers
passed to DOM methods should be lowercase.

> this["Markers"]["marker"+IconName].className =
> "MarkerClass";
> this["Markers"]["marker"+IconName].title = LabelText;
> this["Markers"]["marker"+IconName].id = "marker"+IconName;
> var p = (typeof
> this["Markers"]["marker"+IconName].style.left == 'string') ? "px":0;


That's a workaround for old buggy Geckos -- do you really want to support
them? Furthermore in the following you assume that if `left' is a number,
the rest must be a number, too. Reasoning?

> try {
> this["Markers"]["marker"+IconName].style.left = XPos+p;
> } catch(e) {}
> this["Markers"]["marker"+IconName].style.top =
> parseInt(this.height/2,10)-(h-AnchorY))+p;

^^^^^^^^^^^^^^^^^^^^^^^^^^
If this.height is a string, you cannot divide it by 2 without a NaN result.
First convert, then calculate, not vice-versa.

> this["Markers"]["marker"+IconName].style.width = w+p;
> this["Markers"]["marker"+IconName].style.height = h+p;
> document.getElementById(Target.id+"LabelDiv").appe ndChild(this["Markers"

["marker"+IconName]);
> }


Same here. Can it possibly be more inefficient and ugly than the above?

}
else
{
// Are you sure you want this.document.createElement() here,
// and not simply document.createElement() instead?
if ((marker = this["Markers"]["marker" + iconName]
= this.document.createElement("div")))
{
// you may also want to do feature tests for those
marker.className = "MarkerClass";
marker.title = labelText;
marker.id = "marker" + iconName;

// As I said above, this is considered obsolete
var p = (typeof marker.style.left == 'string') ? "px" : 0;

setStyleProperty(marker, "left", xPos + p);
setStyleProperty(marker, "top",
parseInt(this.height, 10) / 2 - (h - anchorY)) + p);
setStyleProperty(marker, "width", w + p);
setStyleProperty(marker, "height", h + p);

var oTarget = document.getElementById(target.id + "LabelDiv");
if (oTarget && isMethod(oTarget.appendChild))
{
oTarget.appendChild(marker);
}
}
}

> I used the recommended ?"px":0; trick that I discovered while searching
> the group,


Must be posted several years ago, I suppose.

> but why is it causing errors?


Probably because your first comparison and your calculation were wrong.

> Note: All the markers are still drawn in their correct positions, these
> errors just fill up the console as I drag the map.


Firefox 1.5 supports W3C DOM Level 2 Style, where non-zero lengths must have
a unit, as specified in CSS. Hence the _CSS_ error message if you attempt
to omit the unit.


HTH

PointedEars
--
But he had not that supreme gift of the
artist, the knowledge of when to stop.
-- Sherlock Holmes

jshanman 04-25-2006 04:09 PM

Re: Timeline API - setTimeout
 
Thomas 'PointedEars' Lahn wrote:
> > Note: All the markers are still drawn in their correct positions, these
> > errors just fill up the console as I drag the map.

>
> Firefox 1.5 supports W3C DOM Level 2 Style, where non-zero lengths must have
> a unit, as specified in CSS. Hence the _CSS_ error message if you attempt
> to omit the unit.
>
>
> HTH
>
> PointedEars
> --
> But he had not that supreme gift of the
> artist, the knowledge of when to stop.
> -- Sherlock Holmes


Thank you for your help!

I implemented your suggestions and I still ended up with the same
problem. It ended being because if a date was < 4000BC, xPos was
false, and therefore it was trying to add "falsepx" as the left
value... But your code is cleaner and more efficient anyway.

Another Question: Is there a better way of referencing a local object
(this) in a window.setTimeout ?

Code:
if (this.timeline.NextDraw)
window.clearTimeout(this.timeline.NextDraw);
this.timeline.NextDraw =
window.setTimeout("document.getElementById('"+this .id+"').timeline.DrawLabels()",50);

I read previous posts that state a setTimeout runs in the Global
Context. Is there a *better* way then my example above? I don't want
any global variables or functions.

- JS


Randy Webb 04-25-2006 07:17 PM

Re: Timeline API
 
Thomas 'PointedEars' Lahn said the following on 4/25/2006 9:53 AM:
> jshanman wrote:
>
>> jshanman wrote:
>>> I am working on a timeline API that devevelopers can use to add a
>>> dynamic timeline to their sites.
>>>
>>> Here is a *working* demo of the basic interface. (it works for me
>>> anyway on ie6 & firefox 1.5)
>>>
>>> http://www.endeavorpub.com/wiki/timeline.html
>>>
>>> Please tear apart my code and tell me what I'm doing wrong so far...
>>>
>>> Eventually, I would like this to be cross-browser compatible, give the
>>> deveoper the ability to set colors, ranges, sizes, positions, and set
>>> markers & event ranges.
>>>
>>> - JS
>>> http://www.endeavorpub.com

>> You mean to tell me all the experts in this group found absolutly no
>> problems in my code!

>
> | This is Usenet. It is a discussion group, not a helpdesk. You post
> | something, we discuss it. If you have a question and that happens to get
> | answered in the course of the discussion, then great. If not, you can
> | have a full refund of your membership fees. -- Mark Parnell in alt.html


When quoting something, specify it as a quote.

>> I found a problem : In firefox, I get this message : Error: Error in
>> parsing value for property 'left'. Declaration dropped.

>
> That is a CSS (layout engine) error, not a script (engine) error. Install
> Console^2, FireBug, or both, to filter console messages (since Firefox
> 1.5/Gecko 1.8b1).
>
>> In IE (when the try catch is removed), I get "Object Error".

>
> Probably it says in which line of the code.


And probably not. If you had any knowledge at all of IE error messages
you would know that. IE is very well known to spit out cryptic error
messages.

> <URL:http://jibbering.com/faq/#FAQ4_43>
>
>> Here is the code:
>>
>> if (document.getElementById("marker"+IconName)) {

> ^
> Identifiers should start uppercase only if they refer to constructors.


Pure 100% unadulterated bullshit. You can name a variable anything you
want as long as it isn't already reserved/used. Naming them lowercase
beginning is nothing more than a coding style.

<snipped more I don't feel like correcting>

> HTH


It doesn't. But that is typical of your posts here.

--
Randy
comp.lang.javascript FAQ - http://jibbering.com/faq & newsgroup weekly
Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/

Thomas 'PointedEars' Lahn 04-25-2006 07:54 PM

Re: Timeline API - setTimeout
 
jshanman wrote:

> Another Question: Is there a better way of referencing a local object
> (this) in a window.setTimeout ?
>
> Code:
> if (this.timeline.NextDraw)


This may not be sufficient. Unfortunately, it is not specified what value
window.setTimeout() returns, only that this value can be passed to
window.clearTimeout(); it could be 0, which would evaluate to `false' in a
boolean expression. It would be best if you initialized
this.timeline.NextDraw (note the capitalized identifier again) with a value
that is unlikely to be returned by window.setTimeout() to indicate that it
has not been assigned that. I have found `null' to be suitable for this.
You then could test for it with

if (this.timeline.NextDraw == null)

(0 != null).

> window.clearTimeout(this.timeline.NextDraw);
> this.timeline.NextDraw =
>

window.setTimeout("document.getElementById('"+this .id+"').timeline.DrawLabels()",50);
>
> I read previous posts that state a setTimeout runs in the Global
> Context. Is there a *better* way then my example above? I don't want
> any global variables or functions.


Certainly there is a better way. However, a globally available object is
required for that, as you need a method to be called in order to avoid
spaghetti code.

Please trim your quotes to the part(s) you are actually referring to.


PointedEars
--
Homer: I have changed the world. Now I know how it feels to be God!
Marge: Do you want turkey sausage or ham?
Homer: Thou shalt send me *two*, one of each kind.
(Santa's Little Helper [dog] and Snowball [cat] run away :))

RobG 04-26-2006 03:48 AM

Re: Timeline API
 
jshanman said on 25/04/2006 10:46 PM AEST:
> jshanman wrote:
>
>>I am working on a timeline API that devevelopers can use to add a
>>dynamic timeline to their sites.
>>
>>Here is a *working* demo of the basic interface. (it works for me
>>anyway on ie6 & firefox 1.5)
>>
>>http://www.endeavorpub.com/wiki/timeline.html
>>
>>Please tear apart my code and tell me what I'm doing wrong so far...
>>
>>Eventually, I would like this to be cross-browser compatible, give the
>>deveoper the ability to set colors, ranges, sizes, positions, and set
>>markers & event ranges.
>>
>>- JS
>>http://www.endeavorpub.com

>
>
> You mean to tell me all the experts in this group found absolutly no
> problems in my code!


No one has told you anything, you should not presume that no response
means there is nothing to respond about (noting that Thomas has
subsequently replied with some tips).

I looked briefly at your code - it is very inefficient, unnecessarily
complicated and lacks comments. No documentation is provided about what
it is supposed to do or how it is supposed to do it. For example, you
have arrays of month names and day numbers that don't appear on the
page. Is that an error or isn't that functionality implemented yet?

There are efficient ways of determining the number of days in the month
and adding the ordinal suffix (st, nd, rd, and so on) without creating
literal arrays with all of the values in them.

I don't have the time to wade through the code to find the answer or
provide useful assistance. These issues are obvious and hint that there
are many, many more.

e.g. (my wrapping)

this.labels.style.left =
String(
-1*this.GetPos(
DtObj.getFullYear(),
DtObj.getMonth(),
DtObj.getDate(),
DtObj.getHours()
) + 400
) + "px"

Seems silly, why not pass the date object to the function and have it
return the value? Why explicitly convert the returned value to a
number, then convert it back to a string? Appending 'px' to a number
will convert the value to a string without using a String object, so:

this.labels.style.left = '-' + (GetPos(DtObj) + 400) + 'px';


would be far simpler. Then the getPos() function can do its thing with
the date parts as required. Incidentally, getPos() seems far more
complex than it needs to be, for example:

with (D = new Date(0)) {
setFullYear(year, month, day);
setHours(hour);
}

Why not:

var D = new Date(year, month, day, hours);

Which just creates a copy of the date object above - DtObj. Since D
(which isn't declared anywhere and so is global) isn't modified, why not
just pass a reference to DtObj and use that directly?


As a general hint, if you ask a specific, clearly presented problem you
will usually get timely and worthwhile assistance - posting a page that
very likely has many basic design flaws (given that no design is
provided) and poor coding practices will likely deter everyone from
offering any help at all.

[...]


--
Rob
Group FAQ: <URL:http://www.jibbering.com/FAQ>

jshanman 04-26-2006 01:04 PM

Re: Timeline API
 
RobG wrote:
> jshanman said on 25/04/2006 10:46 PM AEST:
> > jshanman wrote:
> >
> >>I am working on a timeline API that devevelopers can use to add a
> >>dynamic timeline to their sites.
> >>
> >>Here is a *working* demo of the basic interface. (it works for me
> >>anyway on ie6 & firefox 1.5)
> >>
> >>http://www.endeavorpub.com/wiki/timeline.html
> >>
> >>Please tear apart my code and tell me what I'm doing wrong so far...
> >>
> >>Eventually, I would like this to be cross-browser compatible, give the
> >>deveoper the ability to set colors, ranges, sizes, positions, and set
> >>markers & event ranges.
> >>
> >>- JS
> >>http://www.endeavorpub.com

> >
> >
> > You mean to tell me all the experts in this group found absolutly no
> > problems in my code!

>
> No one has told you anything, you should not presume that no response
> means there is nothing to respond about (noting that Thomas has
> subsequently replied with some tips).
>


I know, that statement was meant to provoke a response. A harsh one
with a little helpful content is better then no response at all. I
don't mind being told my code is *wrong* or ineffecient. How else will
I learn?

> I looked briefly at your code - it is very inefficient, unnecessarily
> complicated and lacks comments. No documentation is provided about what
> it is supposed to do or how it is supposed to do it.


When it is completed, I will create a full set of documentation.

> For example, you
> have arrays of month names and day numbers that don't appear on the
> page. Is that an error or isn't that functionality implemented yet?
>


It will be used to display the text labels, which is now partially
implemented.

> There are efficient ways of determining the number of days in the month
> and adding the ordinal suffix (st, nd, rd, and so on) without creating
> literal arrays with all of the values in them.
>


Link or example? that would be very useful. I will probably end up
figuring out a differant way to do it.

> I don't have the time to wade through the code to find the answer or
> provide useful assistance. These issues are obvious and hint that there
> are many, many more.
>
> e.g. (my wrapping)
>
> this.labels.style.left =
> String(
> -1*this.GetPos(
> DtObj.getFullYear(),
> DtObj.getMonth(),
> DtObj.getDate(),
> DtObj.getHours()
> ) + 400
> ) + "px"
>
> Seems silly, why not pass the date object to the function and have it
> return the value?


That makes sense, the reason I didn't just send a date object is
because in other places, that function will be used to position dates
from a database that may be in julian or gregorian (as actual
year/month/date/hour, not # ms), so a direct date object would not
represent those properly.


> Why explicitly convert the returned value to a
> number, then convert it back to a string? Appending 'px' to a number
> will convert the value to a string without using a String object, so:
>
> this.labels.style.left = '-' + (GetPos(DtObj) + 400) + 'px';
>


I was getting desperate will a css error I was getting and was basicly
troubleshooting why it wasn't applying the values... I figured out it
was a differant reason and haven't bothered to remove the extra
functions yet.

>
> would be far simpler. Then the getPos() function can do its thing with
> the date parts as required. Incidentally, getPos() seems far more
> complex than it needs to be, for example:
>
> with (D = new Date(0)) {
> setFullYear(year, month, day);
> setHours(hour);
> }
>
> Why not:
>
> var D = new Date(year, month, day, hours);
>


Thise does not work for dates preceeding 100 AD, it would just return
the milliseconds for "1901" instead of "01"AD

> Which just creates a copy of the date object above - DtObj. Since D
> (which isn't declared anywhere and so is global) isn't modified, why not
> just pass a reference to DtObj and use that directly?
>
>
> As a general hint, if you ask a specific, clearly presented problem you
> will usually get timely and worthwhile assistance - posting a page that
> very likely has many basic design flaws (given that no design is
> provided) and poor coding practices will likely deter everyone from
> offering any help at all.
>
> [...]
>
>
> --
> Rob
> Group FAQ: <URL:http://www.jibbering.com/FAQ>


I am aware of that and will continue to do that as well.

Javascript is very fun to learn and I am all *ears*...

My next question involves disabling the drag and drop in IE. If you
try to drag the timeline in IE, if you move your mouse to fast, it will
turn into the "no can do" cursor and will not continue to move the
timeline until the mouse is released. How can I cause IE to ignore the
drag > drop events ?

Also in IE, when you are able to move the timeline successfully (from
one end to the other very quickly, every other text label ends up being
highlighted... wierd.

Thanks again,

- JS


Richard Cornford 04-26-2006 04:55 PM

Re: Timeline API
 
jshanman wrote:
> RobG wrote:
>> jshanman said on 25/04/2006 10:46 PM AEST:

<snip>
>>> You mean to tell me all the experts in this group found
>>> absolutly no problems in my code!

>>
>> No one has told you anything, you should not presume that
>> no response means there is nothing to respond about (noting
>> that Thomas has subsequently replied with some tips).

>
> I know, that statement was meant to provoke a response.

<snip>

Couldn't you have waited at least 24 hours before trying to provoke a
response (the questionable wisdom of which not withstanding)? This is an
international group and it would take at least 24 hours for everyone in
the world just to get an opportunity to see your first post.

Richard.



Matt Kruse 04-26-2006 05:59 PM

Re: Timeline API
 
jshanman wrote:
> When it is completed, I will create a full set of documentation.


Just my opinion - In order for something to be evaluated, a person needs to
have some overview of what it's supposed to do and what problem it is
intended to solve. Then, they need to know what features it is trying to
implement to solve those problems and how they should attempt to use it.

You don't need to write detailed API documentation at the beginning. But you
should at least write some introductory text if you want to get any useful
feedback from people.

I visited your page, had no idea what I was looking at, and closed my
browser. Thus, no response here :)

--
Matt Kruse
http://www.JavascriptToolbox.com
http://www.AjaxToolbox.com




All times are GMT. The time now is 03:49 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.