--- loncom/homework/functionplotresponse.pm 2012/02/29 01:24:47 1.94 +++ loncom/homework/functionplotresponse.pm 2015/01/19 15:35:53 1.107 @@ -1,7 +1,7 @@ # LearningOnline Network with CAPA # Functionplot responses # -# $Id: functionplotresponse.pm,v 1.94 2012/02/29 01:24:47 www Exp $ +# $Id: functionplotresponse.pm,v 1.107 2015/01/19 15:35:53 goltermann Exp $ # # Copyright Michigan State University Board of Trustees # @@ -45,47 +45,145 @@ BEGIN { } # +# Use old Java or HTML5/Javascript for GeoGebra? Depends on browser! +# Return a true value if HTML5 should be used. + +sub useHTML5 { + if ($env{'browser.type'} eq 'chrome') { + if ($env{'browser.version'} >= 14) { + return 1; + } + } elsif ($env{'browser.type'} eq 'safari') { + if ($env{'browser.os'} eq 'mac') { + my ($prefix,$version) = ($env{'browser.version'} =~ /^(\d*)(\d{3})\./); + if ((!$env{'browser.mobile'}) || + (($env{'browser.mobile'}) && length($prefix))) { + if ($version >= 536) { + return 1; + } + } + } + } elsif ($env{'browser.type'} eq 'mozilla') { + if ($env{'browser.info'} =~ /^firefox\-(\d+)/) { + my $firefox = $1; + if ((($env{'browser.os'} eq 'mac') && ($firefox >= 20)) || + (($env{'browser.os'} eq 'unix') && ($firefox >= 17)) || + (($env{'browser.os'} eq 'win') && ($firefox >= 14))) { + return 1; + } + } + } elsif ($env{'browser.type'} eq 'explorer') { + if (($env{'browser.os'} eq 'win') && ($env{'browser.version'} == 10)) { + return 1; + } + } + return 0; +} + +# +# HTML5 version does not understand "_" in IDs +# +sub appid { + my ($id)=@_; + $id=~s/\_/rid/gs; + $id=~s/\W//gs; + return $id; +} + +# +# Routines to start the applet (Java) or the HTML5/JavaScript +# # There can be a number of applets on a page, each called ggbApplet_$id, # where $id is the "_"-concatenated part and responseid # sub geogebra_startcode { my ($id,$width,$height)=@_; + if (&useHTML5()) { + return &html5_geogebra_startcode(@_); + } else { + return &java_geogebra_startcode(@_). + &java_geogebra_code_param(); + } +} + +sub geogebra_endcode { + if (&useHTML5()) { + return ''; + } else { + return &java_geogebra_endcode(); + } +} + +sub geogebra_default_parameters { + my ($id)=@_; + if (&useHTML5()) { + return ''; + } else { + return &java_geogebra_default_parameters($id); + } +} +# === Java code + +sub java_geogebra_startcode { + my ($id,$width,$height)=@_; + my $appid=&appid($id); $width=int(1.*$width); $height=int(1.*$height); unless ($width) { $width=700; } unless ($height) { $height=400; } return (<<ENDSTARTCODE); -<applet name="ggbApplet_$id" code="geogebra.GeoGebraApplet" archive="geogebra.jar" +<applet name="ggbApplet$appid" code="geogebra.GeoGebraApplet" archive="geogebra.jar" codebase="/adm/geogebra/" width="$width" height="$height" MAYSCRIPT> <param name="java_arguments" value="-Xmx512m -Djnlp.packEnabled=true"/> ENDSTARTCODE } -sub geogebra_endcode { +sub java_geogebra_endcode { return &Apache::lonhtmlcommon::java_not_enabled()."</applet>\n"; } +sub java_geogebra_code_param { + return '<param name="ggbBase64" value="'.&geogebra_internal_program().'" />'; +} + +# === HTML5 code + +sub html5_geogebra_startcode { + my ($id,$width,$height)=@_; + my $appid=&appid($id); + $width=int(1.*$width); + $height=int(1.*$height); + unless ($width) { $width=700; } + unless ($height) { $height=400; } + my $code=&geogebra_internal_program(); + return (<<ENDSTARTCODE); +<article class="geogebraweb" data-param-enableLabelDrags="false" data-param-enableShiftDragZoom="false" +data-param-width="$width" data-param-height="$height" data-param-id="ggbApplet$appid" +data-param-ggbbase64="$code"></article> +ENDSTARTCODE +} + # # This is the internal GeoGebra bytecode which defines the spline functions # -sub geogebra_spline_program { - return (<<ENDSPLINEPROGRAM); -<param name="ggbBase64" value="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"/> -ENDSPLINEPROGRAM +sub geogebra_internal_program { + return +'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'; } # # The standard set of parameters inside <applet> # -sub geogebra_default_parameters { +sub java_geogebra_default_parameters { my ($id)=@_; + my $appid=&appid($id); return(<<ENDDEFAULTPARAMETERS); <param name="image" value="/adm/lonIcons/lonanim.gif" /> <param name="boxborder" value="false" /> <param name="centerimage" value="true" /> <param name="cache_archive" value="geogebra.jar, geogebra_main.jar, geogebra_gui.jar, geogebra_cas.jar, geogebra_export.jar, geogebra_algos.jar, geogebra_javascript.jar, geogebra_properties.jar, jlatexmath.jar, jlm_cyrillic.jar, jlm_greek.jar" /> - <param name="cache_version" value="4.0.1.0,4.0.1.0,4.0.1.0,4.0.1.0,4.0.1.0,4.0.1.0,4.0.1.0,4.0.1.0,4.0.1.0,4.0.1.0,4.0.1.0" /> + <param name="cache_version" value="4.4.3.0,4.4.3.0,4.4.3.0,4.4.3.0,4.4.3.0,4.4.3.0,4.4.3.0,4.4.3.0,4.4.3.0,4.4.3.0,4.4.3.0" /> <param name="framePossible" value="false" /> <param name="showResetIcon" value="false" /> @@ -100,7 +198,7 @@ sub geogebra_default_parameters { <param name="enableShiftDragZoom" value="false" /> <param name="allowRescaling" value="false" /> <param name="enableLabelDrags" value="false" /> - <param name="ggbOnInitParam" value="applet_$id" /> + <param name="ggbOnInitParam" value="ggbApplet$appid" /> ENDDEFAULTPARAMETERS } @@ -115,12 +213,18 @@ sub init_script { if ($#Apache::functionplotresponse::callscripts>=0) { my $script=''; foreach my $id (@Apache::functionplotresponse::callscripts) { - $script.="if (param=='applet_$id') { loaded_$id=true; }\n"; + $script.="if (param=='ggbApplet".&appid($id)."') { loaded_$id=true; }\n"; } $script.="if (".join(' && ',map { "loaded_$_" } (@Apache::functionplotresponse::callscripts)). ") { setTimeout('ggbInitAll()',200) }"; my $calls=join("\n",map { "ggbInit_$_();" } (@Apache::functionplotresponse::callscripts)); + my $html5init=''; + if (&useHTML5()) { + $html5init= + '<script type="text/javascript" language="javascript" src="/adm/geogebra/web/web.nocache.js"></script>'; + } return (<<ENDGGBINIT); +$html5init <script type="text/javascript"> // <![CDATA[ // Function that each applet will call when loaded @@ -144,12 +248,13 @@ ENDGGBINIT # sub update_script { my ($id)=@_; + my $appid=&appid($id); return (<<ENDUPDATESCRIPT); <script type="text/javascript"> // <![CDATA[ function updatePointCoordinates_$id(coordinateName) { - var x = document.ggbApplet_$id.getXcoord(coordinateName); - var y = document.ggbApplet_$id.getYcoord(coordinateName); + var x = document.ggbApplet$appid.getXcoord(coordinateName); + var y = document.ggbApplet$appid.getYcoord(coordinateName); document.lonhomework.elements["HWVAL_$id\_" + coordinateName + "_x"].value = x; document.lonhomework.elements["HWVAL_$id\_" + coordinateName + "_y"].value = y; } @@ -164,7 +269,8 @@ ENDUPDATESCRIPT sub update_register { my ($id,$variable)=@_; - return "document.ggbApplet_$id.registerObjectUpdateListener('$variable','updatePointCoordinates_$id');\n"; + my $appid=&appid($id); + return "document.ggbApplet$appid.registerObjectUpdateListener('$variable','updatePointCoordinates_$id');\n"; } # @@ -172,6 +278,7 @@ sub update_register { # sub set_point_coordinate { my ($id,$variable,$x,$y,$fixed)=@_; + my $appid=&appid($id); my $mult=($fixed?'a*':''); # Get rid of wild exponents, make sure it's a number $x=1.*$x; @@ -182,9 +289,9 @@ sub set_point_coordinate { $y=~s/[e|E]/\*10\^/; $y=~s/\+//; return (<<ENDSETVARIABLE); -document.ggbApplet_$id.evalCommand("a=1"); -document.ggbApplet_$id.evalCommand("$variable=$mult($x,$y)"); -document.ggbApplet_$id.setLabelVisible("$variable",false); +document.ggbApplet$appid.evalCommand("a=1"); +document.ggbApplet$appid.evalCommand("$variable=$mult($x,$y)"); +document.ggbApplet$appid.setLabelVisible("$variable",false); ENDSETVARIABLE } @@ -193,6 +300,7 @@ ENDSETVARIABLE # sub set_slope_coordinate { my ($id,$variable,$xrel,$yrel,$xmin,$xmax,$ymin,$ymax,$pointname,$fixed)=@_; + my $appid=&appid($id); my $xvariable=$variable.'x'; my $yvariable=$variable.'y'; my $domain=$xmax-$xmin; @@ -201,15 +309,15 @@ sub set_slope_coordinate { my $yinterval=$range/200.; my $mult=($fixed?'a*':''); return (<<ENDSETSVARIABLE); -document.ggbApplet_$id.evalCommand("a=1"); -document.ggbApplet_$id.evalCommand("$xvariable=Slider[$xinterval,$domain,$xinterval]"); -document.ggbApplet_$id.setVisible("$xvariable", false); -document.ggbApplet_$id.evalCommand("$xvariable=$xrel"); -document.ggbApplet_$id.evalCommand("$yvariable=Slider[-$range,$range,$yinterval]"); -document.ggbApplet_$id.setVisible("$yvariable", false); -document.ggbApplet_$id.evalCommand("$yvariable=$yrel"); -document.ggbApplet_$id.evalCommand("$variable=$mult($xvariable+x($pointname),$yvariable+y($pointname))"); -document.ggbApplet_$id.setLabelVisible("$variable", false); +document.ggbApplet$appid.evalCommand("a=1"); +document.ggbApplet$appid.evalCommand("$xvariable=Slider[$xinterval,$domain,$xinterval]"); +document.ggbApplet$appid.setVisible("$xvariable", false); +document.ggbApplet$appid.evalCommand("$xvariable=$xrel"); +document.ggbApplet$appid.evalCommand("$yvariable=Slider[-$range,$range,$yinterval]"); +document.ggbApplet$appid.setVisible("$yvariable", false); +document.ggbApplet$appid.evalCommand("$yvariable=$yrel"); +document.ggbApplet$appid.evalCommand("$variable=$mult($xvariable+x($pointname),$yvariable+y($pointname))"); +document.ggbApplet$appid.setLabelVisible("$variable", false); ENDSETSVARIABLE } @@ -305,46 +413,48 @@ ENDSTARTINIT sub axes_script { my ($id,$xmin,$xmax,$ymin,$ymax,$xvisible,$yvisible,$gvisible)=@_; + my $appid=&appid($id); return (<<ENDAXESSCRIPT); // changes (xmin, xmax, ymin, ymax) - document.ggbApplet_$id.setCoordSystem($xmin,$xmax,$ymin,$ymax); + document.ggbApplet$appid.setCoordSystem($xmin,$xmax,$ymin,$ymax); // makes the (x,y) axis (in)visible - document.ggbApplet_$id.setAxesVisible($xvisible,$yvisible); + document.ggbApplet$appid.setAxesVisible($xvisible,$yvisible); // makes the grid (in)visible - document.ggbApplet_$id.setGridVisible($gvisible); + document.ggbApplet$appid.setGridVisible($gvisible); ENDAXESSCRIPT } sub axes_label { my ($id,$xmin,$xmax,$ymin,$ymax,$xlabel,$ylabel)=@_; + my $appid=&appid($id); unless ($xlabel || $ylabel) { return ''; } - my $return='document.ggbApplet_'.$id.'.evalCommand("topRight=Corner[3]");'; + my $return='document.ggbApplet'.$appid.'.evalCommand("topRight=Corner[3]");'; if ($xlabel) { if (($ymin<0) && ($ymax>0)) { $return.=(<<ENDXAXISLABELSCRIPT); -document.ggbApplet_$id.evalCommand("Xlabel=(x(topRight)-AxisStepX[],AxisStepY[]/6)"); -document.ggbApplet_$id.setVisible("Xlabel",false); -document.ggbApplet_$id.evalCommand("Text[\\"$xlabel\\", Xlabel]"); +document.ggbApplet$appid.evalCommand("Xlabel=(x(topRight)-AxisStepX[],AxisStepY[]/6)"); +document.ggbApplet$appid.setVisible("Xlabel",false); +document.ggbApplet$appid.evalCommand("Text[\\"$xlabel\\", Xlabel]"); ENDXAXISLABELSCRIPT } else { $return.=(<<ENDXOFFAXISLABEL); -document.ggbApplet_$id.evalCommand("LowerRight=Corner[2]"); -document.ggbApplet_$id.evalCommand("Text[\\"$xlabel\\", (x(LowerRight) - AxisStepX[], y(LowerRight) + AxisStepY[] / 2)]"); +document.ggbApplet$appid.evalCommand("LowerRight=Corner[2]"); +document.ggbApplet$appid.evalCommand("Text[\\"$xlabel\\", (x(LowerRight) - AxisStepX[], y(LowerRight) + AxisStepY[] / 2)]"); ENDXOFFAXISLABEL } } if ($ylabel) { if (($xmin<0) && ($xmax>0)) { $return.=(<<ENDYAXISLABELSCRIPT); -document.ggbApplet_$id.evalCommand("Ylabel=(AxisStepX[]/6,y(topRight)-AxisStepY[]/3)"); -document.ggbApplet_$id.setVisible("Ylabel",false); -document.ggbApplet_$id.evalCommand("Text[\\"$ylabel\\", Ylabel]"); +document.ggbApplet$appid.evalCommand("Ylabel=(AxisStepX[]/6,y(topRight)-AxisStepY[]/3)"); +document.ggbApplet$appid.setVisible("Ylabel",false); +document.ggbApplet$appid.evalCommand("Text[\\"$ylabel\\", Ylabel]"); ENDYAXISLABELSCRIPT } else { $return.=(<<ENDYOFFAXISLABEL); -document.ggbApplet_$id.evalCommand("UpperLeft=Corner[4]"); -document.ggbApplet_$id.evalCommand("Text[\\"$ylabel\\", (x(UpperLeft) + AxisStepX[] / 5, y(UpperLeft) - AxisStepY[] / 1.8)]"); +document.ggbApplet$appid.evalCommand("UpperLeft=Corner[4]"); +document.ggbApplet$appid.evalCommand("Text[\\"$ylabel\\", (x(UpperLeft) + AxisStepX[] / 5, y(UpperLeft) - AxisStepY[] / 1.8)]"); ENDYOFFAXISLABEL } } @@ -357,6 +467,7 @@ ENDYOFFAXISLABEL sub plot_script { my ($id,$function,$fixed,$label,$color,$xmin,$xmax,$thickness)=@_; + my $appid=&appid($id); $label=~s/\W//g; if (($label) && ($label!~/^[A-Za-z]/)) { $label='C'.$label; @@ -378,12 +489,12 @@ sub plot_script { $bc=hex($bh); } if ($fixed) { - return "document.ggbApplet_$id.evalCommand('$label=Function[$function,$xmin,$xmax]');\n". - ($visible?'':"document.ggbApplet_$id.setLabelVisible('$label', false);\n"). - ($color?"document.ggbApplet_$id.setColor('$label',$rc,$gc,$bc);\n":''). - ($thickness?"document.ggbApplet_$id.setLineThickness('$label',$thickness);\n":''); + return "document.ggbApplet$appid.evalCommand('$label=Function[$function,$xmin,$xmax]');\n". + ($visible?'':"document.ggbApplet$appid.setLabelVisible('$label', false);\n"). + ($color?"document.ggbApplet$appid.setColor('$label',$rc,$gc,$bc);\n":''). + ($thickness?"document.ggbApplet$appid.setLineThickness('$label',$thickness);\n":''); } else { - return "document.ggbApplet_$id.evalCommand('y=$function');\n"; + return "document.ggbApplet$appid.evalCommand('y=$function');\n"; } } @@ -393,17 +504,18 @@ sub plot_script { sub plotobject_script { my ($id,$label,$x,$y)=@_; + my $appid=&appid($id); unless ($label) { $Apache::functionplotresponse::counter++; $label='O'.$Apache::functionplotresponse::counter; } &generate_input_field($id,$label,$x,$y); - return "document.ggbApplet_$id.evalCommand('a=1');\n". - "document.ggbApplet_$id.setVisible('a', false);\n". - "document.ggbApplet_$id.setLabelVisible('a', false);\n". - "document.ggbApplet_$id.evalCommand('$label=a*($x,$y)');\n". - "document.ggbApplet_$id.setVisible('$label', true);\n". - "document.ggbApplet_$id.setLabelVisible('$label', true);\n"; + return "document.ggbApplet$appid.evalCommand('a=1');\n". + "document.ggbApplet$appid.setVisible('a', false);\n". + "document.ggbApplet$appid.setLabelVisible('a', false);\n". + "document.ggbApplet$appid.evalCommand('$label=a*($x,$y)');\n". + "document.ggbApplet$appid.setVisible('$label', true);\n". + "document.ggbApplet$appid.setLabelVisible('$label', true);\n"; } # @@ -412,6 +524,7 @@ sub plotobject_script { sub plotvector_script { my ($id,$label,$xs,$ys,$xe,$ye,$xmin,$xmax,$fixed)=@_; + my $appid=&appid($id); unless ($label) { $Apache::functionplotresponse::counter++; $label='V'.$Apache::functionplotresponse::counter; @@ -425,13 +538,13 @@ sub plotvector_script { &new_point_coordinate($id,$startlabel,$xs,$ys,$fixed). &new_point_coordinate($id,$endlabel,$xe,$ye,$fixed). (<<ENDVECTOR); -document.ggbApplet_$id.evalCommand("$label=Vector[$startlabel,$endlabel]"); -document.ggbApplet_$id.setLabelVisible("$label",true); -document.ggbApplet_$id.setLineThickness("$label",8); -document.ggbApplet_$id.evalCommand("$pointlabel=($pointx,y($startlabel))"); -document.ggbApplet_$id.evalCommand("$anglelabel=Angle[$pointlabel,$startlabel,$endlabel]"); -document.ggbApplet_$id.setLabelVisible("$anglelabel",true); -document.ggbApplet_$id.setLabelStyle("$anglelabel",VALUE=2); +document.ggbApplet$appid.evalCommand("$label=Vector[$startlabel,$endlabel]"); +document.ggbApplet$appid.setLabelVisible("$label",true); +document.ggbApplet$appid.setLineThickness("$label",8); +document.ggbApplet$appid.evalCommand("$pointlabel=($pointx,y($startlabel))"); +document.ggbApplet$appid.evalCommand("$anglelabel=Angle[$pointlabel,$startlabel,$endlabel]"); +document.ggbApplet$appid.setLabelVisible("$anglelabel",true); +document.ggbApplet$appid.setLabelStyle("$anglelabel",VALUE=2); ENDVECTOR } @@ -442,22 +555,23 @@ ENDVECTOR sub answer_spline_script { my ($id,@points)=@_; + my $appid=&appid($id); my $order=int(($#points+1)/4); if ($order<2) { $order=2; } if ($order>8) { $order=8; } $Apache::functionplotresponse::counter++; my $label='CSpline'.$Apache::functionplotresponse::counter; - my $output='document.ggbApplet_'.$id.'.evalCommand("'.$label.'=Spline'.$order.'['; + my $output='document.ggbApplet'.$appid.'.evalCommand("'.$label.'=Spline'.$order.'['; for (my $i=0;$i<=$#points;$i+=4) { $output.="($points[$i],$points[$i+1]),($points[$i+2],$points[$i+3]),"; } $output=~s/\,$//; $output.=']");'."\n"; for (my $i=2; $i<2*$order; $i+=2) { - $output.='document.ggbApplet_'.$id.'.setColor("'.$label.'_'.($i>=10?'{':'').$i.($i>=10?'}':'').'",0,170,0);'."\n"; + $output.='document.ggbApplet'.$appid.'.setColor("'.$label.'_'.($i>=10?'{':'').$i.($i>=10?'}':'').'",0,170,0);'."\n"; } for (my $i=1; $i<2*$order; $i+=2) { - $output.='document.ggbApplet_'.$id.'.setVisible("'.$label.'_'.($i>=10?'{':'').$i.($i>=10?'}':'').'",false);'."\n"; + $output.='document.ggbApplet'.$appid.'.setVisible("'.$label.'_'.($i>=10?'{':'').$i.($i>=10?'}':'').'",false);'."\n"; } return $output; @@ -469,6 +583,7 @@ sub answer_spline_script { sub generate_spline { my ($id,$label,$xmin,$xmax,$ymin,$ymax,$fixed)=@_; + my $appid=&appid($id); my $result=''; my $order=$Apache::functionplotresponse::splineorder{$label}; my $x=$Apache::functionplotresponse::splineinitx{$label}; @@ -485,7 +600,7 @@ sub generate_spline { $x+=$sx/(2.*($order-1)); push(@coords,$label.'S'.$i); } - $result.='document.ggbApplet_'.$id.'.evalCommand("Spline'.$order.'['.join(',',@coords).']");'."\n"; + $result.='document.ggbApplet'.$appid.'.evalCommand("Spline'.$order.'['.join(',',@coords).']");'."\n"; return $result; } @@ -551,6 +666,10 @@ sub start_plotvector { $label=~s/\W//gs; $label=ucfirst($label); unless ($label) { $label="NewVector"; } + if ($Apache::functionplotresponse::vectorlabels{$label}) { + &Apache::lonxml::warning(&mt('Vector labels must be unique: [_1]',$label)); + } + $Apache::functionplotresponse::vectorlabels{$label}=1; if ($target eq 'web') { my ($xmin,$xmax,$ymin,$ymax)=&boundaries($parstack,$safeeval,-3); unless (defined($tailx)) { $tailx=$xmin; } @@ -600,6 +719,7 @@ sub start_drawvectorsum { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result=''; my $internalid = $Apache::inputtags::part.'_'.$Apache::inputtags::response[-1]; + my $internalappid=&appid($internalid); my $tailx=&Apache::lonxml::get_param('tailx',$parstack,$safeeval); my $taily=&Apache::lonxml::get_param('taily',$parstack,$safeeval); my $showvalue=&Apache::lonxml::get_param('showvalue',$parstack,$safeeval); @@ -621,28 +741,32 @@ sub start_drawvectorsum { $thisvector=~s/\W//gs; $thisvector=ucfirst($thisvector); unless ($thisvector) { next; } + unless ($Apache::functionplotresponse::vectorlabels{$thisvector}) { + &Apache::lonxml::warning(&mt('Vectors must be defined before using them for drawing vector sums: [_1]',$thisvector)); + next; + } my $vectorx=$thisvector.'X'; my $vectory=$thisvector.'Y'; $result.=(<<ENDADDVEC); -document.ggbApplet_$internalid.evalCommand("$vectorx=x($thisvector)"); -document.ggbApplet_$internalid.evalCommand("$vectory=y($thisvector)"); -document.ggbApplet_$internalid.evalCommand("Include$thisvector$label=Checkbox[]"); +document.ggbApplet$internalappid.evalCommand("$vectorx=x($thisvector)"); +document.ggbApplet$internalappid.evalCommand("$vectory=y($thisvector)"); +document.ggbApplet$internalappid.evalCommand("Include$thisvector$label=Checkbox[]"); ENDADDVEC push(@sumx,"If[Include$thisvector$label,$vectorx,0]"); push(@sumy,"If[Include$thisvector$label,$vectory,0]"); } - $result.="document.ggbApplet_$internalid.evalCommand(".'"'."xTot$label=".join('+',@sumx).'");'."\n"; - $result.="document.ggbApplet_$internalid.evalCommand(".'"'."yTot$label=".join('+',@sumy).'");'."\n"; + $result.="document.ggbApplet$internalappid.evalCommand(".'"'."xTot$label=".join('+',@sumx).'");'."\n"; + $result.="document.ggbApplet$internalappid.evalCommand(".'"'."yTot$label=".join('+',@sumy).'");'."\n"; my $show=0; if ($showvalue=~/yes/i) { $show=1; } $result.=(<<ENDMAKEVECTOR); -document.ggbApplet_$internalid.evalCommand("$label=Vector[($tailx,$taily),($tailx+xTot$label,$taily+yTot$label)]"); -document.ggbApplet_$internalid.setLabelVisible("$label",true); -document.ggbApplet_$internalid.setLineThickness("$label",8); -document.ggbApplet_$internalid.setColor("$label",255,0,0); -document.ggbApplet_$internalid.setLabelStyle("$label",VALUE=$show); +document.ggbApplet$internalappid.evalCommand("$label=Vector[($tailx,$taily),($tailx+xTot$label,$taily+yTot$label)]"); +document.ggbApplet$internalappid.setLabelVisible("$label",true); +document.ggbApplet$internalappid.setLineThickness("$label",8); +document.ggbApplet$internalappid.setColor("$label",255,0,0); +document.ggbApplet$internalappid.setLabelStyle("$label",VALUE=$show); ENDMAKEVECTOR } } elsif ($target eq 'edit') { @@ -711,7 +835,7 @@ sub start_backgroundplot { &Apache::edit::text_arg('Label on Plot:','label', $token,'8'). &Apache::edit::text_arg('Color (hex code):','color', - $token,'8'). + $token,'8', 'colorchooser'). &Apache::edit::select_arg('Fixed location:','fixed', ['yes','no'],$token). &Apache::edit::end_row(); @@ -788,7 +912,7 @@ sub start_functionplotrule { $result=&Apache::edit::tag_start($target,$token,'Function Plot Graph Rule'). &Apache::edit::text_arg('Index/Name:','index', $token,'10').' '. - &Apache::edit::select_arg(&mt('Function:'),'derivativeorder', + &Apache::edit::select_arg('Function:','derivativeorder', [['0','Function itself'], ['1','First derivative'], ['2','Second derivative'], @@ -1304,6 +1428,8 @@ sub start_functionplotresponse { undef %Apache::functionplotresponse::previous; $Apache::functionplotresponse::inputfields=''; $Apache::functionplotresponse::counter=0; +# Remember vectors + undef %Apache::functionplotresponse::vectorlabels; # Remember rules undef @Apache::functionplotresponse::functionplotrules; undef @Apache::functionplotresponse::functionplotvectorrules; @@ -1330,7 +1456,7 @@ sub start_functionplotresponse { my $ylabel=&Apache::lonxml::get_param('ylabel',$parstack,$safeeval); if ($target eq 'edit') { $result.=&Apache::edit::start_table($token) - .'<tr><td><span class="LC_nobreak">'.&mt('Function Plot Question').'</span></td>' + .'<tr><td><span class="LC_nobreak">'.&Apache::loncommon::insert_folding_button().&mt('Function Plot Question').'</span></td>' .'<td><span class="LC_nobreak">'.&mt('Delete?').' ' .&Apache::edit::deletelist($target,$token).' ' .&Apache::edit::insertlist($target,$token).' ' @@ -1384,7 +1510,7 @@ sub start_functionplotresponse { $env{'form.counter'},$Apache::lonxml::curdepth); &Apache::lonxml::add_script_result( &Apache::loncommon::modal_adhoc_window($function_name,700,500, - '<pre>'.$Apache::functionplotresponse::ruleslog.'</pre>', + '<pre style="background-color:#ffffff;">'.$Apache::functionplotresponse::ruleslog.'</pre>', &mt('Rules Log'))."<br />"); } return $result; @@ -1917,7 +2043,7 @@ sub start_functionplotruleset { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; if ($target eq 'edit') { return &Apache::edit::start_table($token). - '<tr><td><span class="LC_nobreak">'.&mt('Function Plot Rule Set').'</span></td>' + '<tr><td><span class="LC_nobreak">'.&Apache::loncommon::insert_folding_button().&mt('Function Plot Rule Set').'</span></td>' .'<td><span class="LC_nobreak">'.&mt('Delete?').' ' .&Apache::edit::deletelist($target,$token).' '. &Apache::edit::insertlist($target,$token).' ' @@ -2074,8 +2200,6 @@ sub end_functionplotelements { $result.=&geogebra_startcode($internalid, &Apache::lonxml::get_param('width',$parstack,$safeeval,-2), &Apache::lonxml::get_param('height',$parstack,$safeeval,-2)); -# load the spline bytecode - $result.=&geogebra_spline_program(); # set default parameters $result.=&geogebra_default_parameters($internalid); # close the <applet>-tag @@ -2112,7 +2236,8 @@ sub start_functionplotelements { if ($target eq 'edit') { return &Apache::edit::start_table($token). - '<tr><td><span class="LC_nobreak">'.&mt('Function Plot Elements').'</span></td>' + '<tr><td><span class="LC_nobreak">'.&Apache::loncommon::insert_folding_button() + .&mt('Function Plot Elements').'</span></td>' .'<td><span class="LC_nobreak">'.&mt('Delete?').' ' .&Apache::edit::deletelist($target,$token).' '. &Apache::edit::insertlist($target,$token).' '