I guess my first question in formulating a reply would be:
Why are you building these constraints manually? Is there something
in particular about this code that prevents you from just saying:
<attribute name="x" value="${this.barlink.x +
(this.barlink.width / 2) - (this.width / 2)}" />
...
I see there are some conditionals before the constraint, but I can't
tell if these are conditions that happen once at init time, or if it
is expected that they may change at runtime so the constraints have to
be applied and removed?
If the latter, this is what states are for. You can say:
<state applied="${this.charttype == 'bar' && this.drawaxis == 'x'">
<attribute name="x" value="${this.barlink.x +
(this.barlink.width / 2) - (this.width / 2)}" />
...
If you really feel you've got to do it the dynamic way, the trick is
getting those dependencies right. The dependencies are a list of the
objects and slot names that could possibly change the outcome of your
constraint. They are the things whose events the constraint will be
registered to handle. The nifty thing about doing it all in LZX is
that the compiler computes the dependencies (and usually gets them
right). So, one trick you could use is to make a simple test case,
writing your constraints in LZX, then compile to DHTML and look at the
output JS.
Ok, this is not completely trivial. I compiled this:
<canvas>
<attribute name="x" value="${this.barlink.x +
(this.barlink.width / 2) - (this.width / 2)}" />
</canvas>
And got this:
var $backtrace=false;var $dhtml=true;var $as3=false;var
$js1=true;var $swf7=false;var $swf8=false;var $svg=false;var
$as2=false;var $swf9=false;var $profile=false;var
$runtime="dhtml";var $debug=false;var $j2me=false;Class.make("$lzc
$class_$m3",LzCanvas,["$m1",function($1){
this.setAttribute("x",this.barlink.x+this.barlink.width/2-this.width/
2)
},"$m2",function(){
return [this.barlink,"x",this.barlink,"width",this,"width"]
}],["tagname","canvas","attributes",new
LzInheritedHash(LzCanvas.attributes)]);canvas=new $lzc$class_
$m3(null,
{__LZproxied:"true",appbuilddate:"2008-11-03T23:29:51Z",bgcolor:
16777215,embedfonts:true,fontname:"Verdana,Vera,sans-serif",fontsize:
11,fontstyle:"plain",height:"100%",lpsbuild:"11685 /Users/ptw/
OpenLaszlo/
trunk
-2
",lpsbuilddate
:"2008
-11
-03T20
:
03
:
20Z
",lpsrelease
:"Latest",lpsversion:"4.2.x",runtime:"dhtml",width:"100%",x:new
LzAlwaysExpr("$m1","$m2")});canvas.initDone();
I happen to know the `x:new LzAlwaysExpr("$m1","$m2")` is the
constraint (x is initialized to an 'always' expression, the first
method is the computation of the value, and the second, $m2, computes
the dependencies for the constraint, so I can see the dependencies are:
[this.barlink,"x",this.barlink,"width",this,"width"]
so, perhaps you see where you went wrong:
this.applyConstraintMethod("constrainBarDrawXX", [this.barlink, x,
this, x]);
I guess I am surprised you did not get an error or warning from the
debugger when it tried to apply your constraint method, because the
dependencies did not name valid events?
The correct dependencies for your `y` constraint are:
[this.barlink,"y",this,"height"]
Now, maybe you know that some of those variables involved in your
constraints aren't really going to change, so they don't need to be
listed as dependencies, but you _really_ have to know what you are
doing then.
Suffice it to say, dynamically creating constraints by hand is pretty
much of a black art and should be avoided if at all possible!
On 2008-11-03, at 18:05EST, J Crowley wrote:
So, I'm working on bringing all the charting stuff up to speed so
that we can finally get that checked in appropriately, and I have a
bunch of instances of applyConstraint() that need to be changed. So
what I did was, I took the functions and made methods out of them,
but I'm not sure exactly what to feed into applyConstraintMethod()
to get it to work the same way. For instance, part of my code block
looks like:
if(this.charttype == "bar"){
if(this.drawaxis == 'x'){
var f = function(ignore=null)
{ this.setAttribute("x", this.barlink.x +
(this.barlink.width / 2) -
(this.width / 2)); }
var d = [this.barlink, "x"];
this.applyConstraint("x", f, d);
var ff = function(ignore=null){
this.setAttribute("y", this.barlink.y -
this.height - 4);
}
var dd = [this.barlink, "y"];
this.applyConstraint("y", ff, dd);
if(this.fadein == true){
this.fader.doStart();
}
}
So what I did was, I made methods for these:
<method name="constrainBarDrawXX" args="ignore=null">
this.setAttribute('x', this.barlink.x +
(this.barlink.width / 2) - (this.width / 2));
</method>
<method name="constrainBarDrawXY" args="ignore=null">
this.setAttribute('y', this.barlink.y - this.height - 4);
</method>
...and changed the script to:
if(this.charttype == "bar"){
if(this.drawaxis == 'x'){
this.applyConstraintMethod("constrainBarDrawXX",
[this.barlink, x, this, x]);
this.applyConstraintMethod("constrainBarDrawXY",
[this.barlink, y, this, y]);
if(this.fadein == true){
this.fader.doStart();
}
However, the labels now don't exhibit the same behavior as when they
were using applyConstraint(). What am I doing wrong?
Thanks!
Josh