org-howto/d3/drag7/index.org

5.5 KiB
Raw Permalink Blame History

d3 draggable object example #7 parametric + tangent line + quadratic

#

#

#

Introduction

This page extends example #6, adding a quadratic approximation using 1st & 2nd derivatives

source
org-mode source for this page is here

Demo

The div element #frame will appear below this line:

Prerequisites

As for examples #1, #2, #3, #4, #5

Procedure

Start with example #5: we will arrive at the following:

index.org
this file
drag6.css
new .css file with axis styling
point.js
procedures for working with 2d coordinate points (unchanged from #5)
fx.js
specifies target function and derivative (unchanged from #5)
fx_view.js
visualization code (edited as shown below)
parametric-drag-example.js
setup code (unchanged from #5)

provide axis styling

Edit css/drag6.css:

 .axis path,
 .axis line {
 fill: none;
 stroke: black;
 }

 .axis text {
 font-family: sans-serif;
 font-size: 11px;
 }

add stylesheet link to index.org (this .org file)

  ..
  #+html_head: <link rel="stylesheet" type="text/css" href="drag6.css" />
  ..

extend fxview.js

Add functions fx_view.draw_x_axis, fx_view.draw_y_axis

 /* box :: Svg
  * xyscale :: Xyscale
  */
 fx_view.draw_x_axis = function(box_pt, box, xyscale)
 {
 var x_axis = (d3.svg.axis()
           .scale(xyscale.xscale)
           .orient("bottom"));

 fx_view.box.append("svg:g")
     .attr("class", "axis")
     .attr("transform", "translate(0," + (0.5 * box_pt.y) + ")")
     .call(x_axis);

 return x_axis;
 } /*draw_x_axis*/
 /* box :: Svg
  * xyscale :: Xyscale
  */
 fx_view.draw_y_axis = function(box_pt, box, xyscale)
 {
 var y_axis = (d3.svg.axis()
           .scale(xyscale.yscale)
           .orient("left"));

 box.append("svg:g")
     .attr("class", "axis")
     .attr("transform", "translate(" + (0.5 * box_pt.x) + ",0)")
     .call(y_axis);

 return y_axis
 } /*draw_y_axis*/

Call the new axis-creating functions from fx_view.draw:

 /* parent_id :: string.  pass this to d3.select() to get selection for parent
  *   at which to attach svg box
  * box_pt :: Point.  size of svg bounding box
  * xyscale :: Xyscale
  */
 fx_view.draw = function(parent_id, box_pt, target_pt_v, xyscale)
 {
 /* create an svg bounding box, to contain interactive drawing area */
 fx_view.box = fx_view.draw_bounding_box(parent_id, box_pt);

 /* border, so bounding box is visible */
 fx_view.border = fx_view.draw_border(box_pt, fx_view.box);

 /* create axes.. */
 fx_view.draw_x_axis(box_pt, fx_view.box, xyscale);
 fx_view.draw_y_axis(box_pt, fx_view.box, xyscale);

 /* create path representing our target function f(x) */
 fx_view.fx_path = fx_view.draw_fx_path(fx_view.box, target_pt_v);

 fx_view.fx_update_tangent_fn(xyscale.xscale.invert(0.5 * box_pt.x),
                  box_pt, xyscale);

 fx_view.fx_update_select_circle(pt.find_closest(pt.scale_pt(0.5, box_pt),
                         target_pt_v));
 } /*draw*/

Insert html fragment to invoke our interactive javascript code

This also follows the same model we used in examples #3, #4, #5.

 #+begin_html
 <div id="frame"></div>
 <script type="text/javascript">
   window.onload = function() { ex.start(this); }
 </script>
 #+end_html