UP | HOME

d3 draggable object example #6 – parametric + tangent line + axes

Table of Contents

1. Introduction

This page extends example #5, adding d3 axes

source
org-mode source for this page is here

2. Demo

The div element #frame will appear below this line:

3. Prerequisites

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

4. 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)

4.1. provide axis styling

Edit css/drag6.css:

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

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

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

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

4.3. 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*/

4.4. 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

Author: Roland Conybeare

Created: 2024-09-08 Sun 18:01

Validate