Skip to content
This repository
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

file 369 lines (254 sloc) 14.753 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <base target="_top">
    <title>Tangle: Getting Started</title>

    <link href='http://fonts.googleapis.com/css?family=Lato' rel='stylesheet' type='text/css'>
    <link rel="stylesheet" href="Fonts/Insolent/stylesheet.css" type="text/css">
    <link rel="stylesheet" href="Fonts/BorisBlackBloxx/stylesheet.css" type="text/css">
    <link rel="stylesheet" href="style.css" type="text/css">

    <!-- Tangle -->
    <script type="text/javascript" src="Tangle.js"></script>

    <!-- TangleKit -->
    <link rel="stylesheet" href="TangleKit/TangleKit.css" type="text/css">
    <script type="text/javascript" src="TangleKit/mootools.js"></script>
    <script type="text/javascript" src="TangleKit/sprintf.js"></script>
    <script type="text/javascript" src="TangleKit/BVTouchable.js"></script>
    <script type="text/javascript" src="TangleKit/TangleKit.js"></script>

    <!-- examples -->
    <script type="text/javascript" src="Examples/CookieExample.js"></script>

</head>

<body>
<div id="everything">


<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- header -->

<div id="header">

<h1><a href="./">tangle</a></h1>
<h3>explorable explanations made easy</h3>

<div class="menu">
    <a href="guide.html">Getting Started</a> &nbsp; &nbsp;
    <a href="reference.html">API Reference</a> &nbsp; &nbsp;
    <a href="download.html">Download</a> &nbsp; &nbsp;
    <a href="https://groups.google.com/group/tangle-talk/topics">Discuss</a>
</div>

</div> <!-- header -->
    

<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- body -->

<div id="body" class="small">


<h2>Getting Started</h2>

<p>Tangle lets you write documents that change.</p>

<p>Let's say you're writing an article about dieting, and want to discuss the calorie content of various foods. You might write the following.</p>

<div class="example">
    <div class="exampleTop"></div>
    <div class="exampleCenter">
        <p>When you eat 3 cookies, you consume <b>150 calories</b>. That's 7% of your recommended daily calories.</p>
    </div>
    <div class="exampleBottom"></div>
</div>

<p>That's a true statement, but it only applies directly to those few readers who eat 3 cookies a day. Most of your readers eat more or less. What if the reader could adjust the statement to see information about their own situation? What if readers could explore alternative scenarios as well?</p>

<div id="cookieExample" class="example">
    <div class="exampleTop"></div>
    <div class="exampleCenter">
        <p>When you eat <span data-var="cookies" class="TKAdjustableNumber" data-min="2" data-max="100"> cookies</span>, you consume <b data-var="calories"> calories</b>. That's <span data-var="dailyPercent" data-format="%.0f">%</span> of your recommended daily calories.</p>
    </div>
    <div class="exampleBottom"></div>
</div>

<p>Let's see how to write this example.</p>


<h2>Variables</h2>

<p>We start by identifying the <strong>variables</strong> &mdash; those parts of the statement that need to change. In this case, there are three varying numbers in the statement, so we need three variables.</p>

<div class="example">
    <div class="exampleTop"></div>
    <div class="exampleCenter">
        <p>When you eat <strong>3 cookies</strong>, you consume <strong>150 calories</strong>. That's <strong>7%</strong> of your recommended daily calories.</p>
    </div>
    <div class="exampleBottom"></div>
</div>

<p>We'll call these variables <strong>cookies</strong>, <strong>calories</strong>, and <strong>dailyPercent</strong> respectively.</p>


<h2>HTML</h2>

<p>Now, let's look at the HTML for the statement.</p>

<pre>
&lt;p&gt;When you eat 3 cookies, you consume &lt;b&gt;150 calories&lt;/b&gt;.
   That's 7% of your recommended daily calories.&lt;/p&gt;
</pre>


<h6>data-var</h6>

<p>Let's start with the "150 calories" part. Notice that it's inside <code>&lt;b&gt;</code> tags, to make it bold. We'll make two simple changes:</p>

<pre>
&lt;p&gt;When you eat 3 cookies, you consume &lt;b <strong>data-var="calories"</strong>&gt; calories&lt;/b&gt;.
   That's 7% of your recommended daily calories.&lt;/p&gt;
</pre>

<p>First, we added the <code><b>data-var="calories"</b></code> attribute to the &lt;b&gt; tag. This tells Tangle to insert the value of the "calories" variable inside the tag. So, if the calories variable were 500, it would appear as "500 calories".</p>

<p>Second, we removed the "150" from inside the tag, because Tangle is going to insert the correct number itself.</p>


<h6>span</h6>

<p>Now, let's look at the "7%" part. It's not inside a tag, so we need to put it inside one. The <code>&lt;span&gt;</code> tag is typically used for this purpose. Unlike <code>&lt;b&gt;</code>, it has no intrinsic meaning of its own &mdash; it's simply a generic container that we can attach style and variable information to.</p>

<pre>
&lt;p&gt;When you eat 3 cookies, you consume &lt;b data-var="calories"&gt; calories&lt;/b&gt;.
   That's <strong>&lt;span data-var="dailyPercent"&gt;</strong>%<strong>&lt;/span&gt;</strong> of your recommended daily calories.&lt;/p&gt;
</pre>

<p>Tangle will insert the value of the "dailyPercent" variable at the start of the span.</p>


<h6>class</h6>

<p>Now, we'll look at the "3 cookies" part. This part isn't just dynamic &mdash; it's interactive. We want the reader to be able to adjust the variable by dragging on the number. For this, we use a class. A Tangle class can describe how the reader interacts with an HTML element, or how a variable should be displayed.</p>

<p>We'll use the class "<code>TKAdjustableNumber</code>", which comes with TangleKit. (The "TK" prefix refers to "TangleKit".) TangleKit is a collection of basic classes for you to use. Once you start tangling more heavily, you might want to start making your own classes.</p>

<pre>
&lt;p&gt;When you eat <strong>&lt;span class="TKAdjustableNumber" data-var="cookies"&gt;</strong> cookies<strong>&lt;/span&gt;</strong>,
   you consume &lt;b data-var="calories"&gt; calories&lt;/b&gt;. That's
   &lt;span data-var="dailyPercent"&gt;%&lt;/span&gt; of your recommended daily calories.&lt;/p&gt;
</pre>


<h6>id</h6>

<p>Finally, we need to make sure that we're able to find this statement from JavaScript. The easiest way to do so is to add an <code>id</code> attribute to the tag that contains it. In this case, our statement is inside a &lt;p&gt; paragraph tag, and we can name it like so:</p>

<pre>
&lt;p <strong>id="calorieCalculator"</strong>&gt;
  When you eat &lt;span class="TKAdjustableNumber" data-var="cookies"&gt; cookies&lt;/span&gt;,
  you consume &lt;b data-var="calories"&gt; calories&lt;/b&gt;. That's
  &lt;span data-var="dailyPercent"&gt;%&lt;/span&gt; of your recommended daily calories.&lt;/p&gt;
</pre>

<p>That's all we need to do with the HTML. Next, we'll tell Tangle how to calculate those variables.</p>

<h2>JavaScript</h2>

<p>In JavaScript, we need to "create a tangle" for all of the HTML elements and variables involved in this particular statement. We do so with <code><b>new Tangle</b></code>, like so:</p>

<pre>
var tangle = new Tangle(rootElement, model);
</pre>

<p>But first, we need the <code>rootElement</code> and the <code>model</code>.</p>


<h6>rootElement</h6>

<p>The <code>rootElement</code> refers to the element that contains our statement. In this case, we put an <code>id</code> attribute on the surrounding paragraph, so we can find it easily:</p>

<pre>
var rootElement = document.getElementById("calorieCalculator");
</pre>


<h6>model</h6>

<p>The <code>model</code> tells Tangle how to initialize and update the variables. It has this form:</p>

<pre>
var model = {
    initialize: function () { ... },
    update: function () { ... }
};
</pre>

<p>The <code>initialize</code> method runs when the tangle is first created. This is where you set the initial values of independent variables. We want the statement initially to read, "When you eat 3 cookies...", so we need the <code>cookies</code> variable to start at 3.</p>

<pre>
var model = {
    initialize: function () {
        <strong>this.cookies = 3;</strong>
    },
    update: function () { ... }
};
</pre>

<p>The <code>update</code> method runs whenever a variable changes. This is where you describe how to calculate "derived variables" &mdash; variables that depend on others. The <code>calories</code> variable can be calculated from <code>cookies</code>:

<pre>
var model = {
    initialize: function () {
        this.cookies = 3;
    },
    update: function () {
        <strong>this.calories = this.cookies * 50;</strong>
    }
};
</pre>

<p>and the <code>dailyPercent</code> variable can be calculated from <code>calories</code>.</p>

<pre>
var model = {
    initialize: function () {
        this.cookies = 3;
    },
    update: function () {
        this.calories = this.cookies * 50;
        <strong>this.dailyPercent = 100 * this.calories / 2100;</strong>
    }
};
</pre>

<p>This works fine, but it's a little hard to read. Someone perusing this code might not immediately understand what the "50" and "2100" are all about. Let's give them more descriptive names.</p>

<pre>
var model = {
    initialize: function () {
        this.cookies = 3;
        <strong>this.caloriesPerCookie = 50;</strong>
        <strong>this.dailyCalories = 2100;</strong>
    },
    update: function () {
        this.calories = this.cookies * <strong>this.caloriesPerCookie</strong>;
        this.dailyPercent = 100 * this.calories / <strong>this.dailyCalories</strong>;
    }
};
</pre>

<p>The code is now much easier to follow. And later, if we want <code>caloriesPerCookie</code> or <code>dailyCalories</code> to be adjustable, we can do so directly in the HTML, without touching the JavaScript.</p>


<h6>new Tangle</h6>

<p>We can now create the tangle. Instead of writing out the <code>rootElement</code> and <code>model</code> separately, we typically just define them inline, like so:</p>

<pre>
var tangle = new Tangle (document.getElementById("calorieCalculator"), {
    initialize: function () {
        this.cookies = 3;
        this.caloriesPerCookie = 50;
        this.dailyCalories = 2100;
    },
    update: function () {
        this.calories = this.cookies * this.caloriesPerCookie;
        this.dailyPercent = 100 * this.calories / this.dailyCalories;
    }
});
</pre>

<p>That's all there is to the JavaScript.</p>


<h2>Formats and Classes</h2>

<p>We're almost done. But when we try it out, we get this:</p>

<div id="cookieExample2" class="example">
    <div class="exampleTop"></div>
    <div class="exampleCenter">
        <p>When you eat <span data-var="cookies" class="TKAdjustableNumber" data-min="2" data-max="100"> cookies</span>, you consume <b data-var="calories"> calories</b>. That's <span data-var="dailyPercent">%</span> of your recommended daily calories.</p>
    </div>
    <div class="exampleBottom"></div>
</div>

<p>Our <code>dailyPercent</code> is perhaps a little more precise than necessary. To tell Tangle how to properly display that variable, we can specify a format.</p>


<h6>Formats</h6>

<p>In the HTML, we add a <code><b>data-format</b></code> attribute:</p>

<pre>
That's &lt;span data-var="dailyPercent" <strong>data-format="%.0f"</strong>&gt;%&lt;/span&gt;
of your recommended daily calories.
</pre>

<p><code>%.0f</code> is known as a <a href="http://bit.ly/lwIyZR">printf</a>-style format, which is a standard language for describing how numbers should be printed. Here, we specified that we wanted to round off the number, with no digits after the decimal point.</p>

<p>It's possible to create your own format functions and use those as well, but in this case, the printf format works fine.</p>

<div id="cookieExample3" class="example">
    <div class="exampleTop"></div>
    <div class="exampleCenter">
        <p>When you eat <span data-var="cookies" class="TKAdjustableNumber" data-min="2" data-max="100"> cookies</span>, you consume <b data-var="calories"> calories</b>. That's <span data-var="dailyPercent" data-format="%.0f">%</span> of your recommended daily calories.</p>
    </div>
    <div class="exampleBottom"></div>
</div>


<h6>Classes</h6>

<p>Currently, we can adjust the <code>cookies</code> variable by dragging it, thanks to the <code>TKAdjustableNumber</code> class that we specified:</p>

<pre>
&lt;span data-var="cookies" class="<b>TKAdjustableNumber</b>"&gt;
</pre>

<p>Perhaps you don't like dragging, and would rather let your readers type in a number instead. We can simply switch the class to <code>TKNumberField</code>:</p>

<pre>
&lt;span data-var="cookies" class="<strong>TKNumberField</strong>"&gt;
</pre>

<p>And our statement becomes:</p>

<div id="cookieExample4" class="example">
    <div class="exampleTop"></div>
    <div class="exampleCenter">
        <p>When you eat <span data-var="cookies" class="TKNumberField" data-size="3"> cookies</span>, you consume <b data-var="calories"> calories</b>. That's <span data-var="dailyPercent" data-format="%.0f">%</span> of your recommended daily calories.</p>
    </div>
    <div class="exampleBottom"></div>
</div>

<p>TangleKit contains a growing selection of classes, and you can define your own classes easily.</p>


<h2>Possibilities</h2>

<p>We just worked through a very simple example, to give you a taste of what you can tangle. But there's much more you can do.</p>

<ul class="dotted">
<li>Create rich data visualizations, such as charts and graphs, using Tangle classes.</li>
<li>Create dynamic data displays, such as stock tickers and weather reports, using Tangle to maintain a clean separation between back-end data and front-end views.</li>
<li>Pass around strings, arrays, and other objects in variables, for more data-heavy applications.</li>
<li>Create controls and views that use multiple variables at once.</li>
</ul>

<p>You might want to look over the <a href="reference.html">API reference</a>, or just <a href="download.html">download Tangle</a> and dive right in.</p>


</div> <!-- body -->


<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- footer -->

<div id="footer">
<div id="footerShadow"></div>

<div class="author"><a href="http://worrydream.com/">Bret Victor</a></div>

<div class="menu">
    <a href="guide.html">Getting Started</a> &nbsp; &nbsp;
    <a href="reference.html">API Reference</a> &nbsp; &nbsp;
    <a href="download.html">Download</a> &nbsp; &nbsp;
    <a href="https://groups.google.com/group/tangle-talk/topics">Discuss</a>
</div>

</div> <!-- footer -->


</div> <!-- everything -->
</body></html>
Something went wrong with that request. Please try again.