d3 draggable object example #7 – parametric + tangent line + quadratic
Table of Contents
1. Introduction
2. Demo
The div element #frame
will appear below this line:
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*/