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


Reply via email to