D3 Run Function Again After Chage

D3 Basics

Web Programmer Tools


Debugging & Programmer Tools

In social club to debug your D3 lawmaking, it will be necessary that you're a little familiar with the debugging tools bachelor in your spider web browser. Accessing the JavaScript console will be necessary for finding bugs in your code.

Programmer Tools in Firefox

Within Firefox, the Developer tools can be institute nether the Web Developer menu.

Developer Tools in Chrome

In Chrome, the developer tools can be found nether Wrench -> Tools

When y'all're debugging, looking at the JavaScript conole is useful for finding syntax problems. Near time the error console will give you a line number as to where the trouble started in your script.

Using the inspector is helpful for finding problem in DOM. You can inspect specific elements on the page. When you inspect a DOM element the develop tool will testify you the relevant code in the text window.

It'south not necessary for beginners to be knowledagble on all the unlike features available in the programmer tools. Being able to inspect elements and reading the JavaScript error console is a good commencement.

horizontal line

Selections

Selections are very important for coding in d3 equally you cannot do much without them. Earlier you can change or alter whatsoever elements in d3 you must first select them. This tin can be done using either d3.select(this) or d3.selectAll(this) where "this" is the specific element(s) yous are trying to select. .select() will simply select the commencement element that matches to the criteria specified, if you are selecting ane of several objects that have this criteria and then be sure to remember that this will select the first 1 in document traversal social club. .selectAll() will but select all the elements that match the criteria specified and return them every bit an assortment of elements. Y'all can select elements in the following ways:

Tag

                d3.select("div")              

Grade

                d3.select(".classname")              

Unique identifier

                d3.select("#line")              

Attribute

                d3.select("[color=blackness]")              

Containment

                d3.select("parent kid")              

Selectors can too utalize AND and OR operators also. To make a selection of the intersection of two selectors merely place them side by side, while for the union you just put a comma in between them as illustrated beneath:

AND:

                d3.select("this that")              

OR:

                d3.select("this, that")              

Information technology is too possible to utilize Subselections to restrict your selections to the descendants of other elements. For example, say you want to select the very outset bold element in every paragraph, you would use the following code:

                d3.selectAll("p").select("b")              

After you accept an element selected you tin can and then call any number of operators on them to change them, such as attributes and styles, and and then use the method chaining syntax of jQuery. jQuery attributes

horizontal line

Attributes/Styles


Changing Attributes and Styles

D3 provides methods for irresolute attributes and styles of elements. Nosotros'll await at the nuts of .attr() and .way() so y'all can begin using these to adjust SVG attributes and styles.

While .attr() and .manner() can be used to style non-SVG elements, for the purposes of this tutorial, we'll simply be using these methods in the context of SVG.

In gild to use .attr() and .style() they accept to called on a selection.

In the code below, we utilize D3 methods to select a circle element, change its radius and color.

<!DOCTYPE html>   <html>     <head>       <script type="text/javascript" src="http://mbostock.github.com/d3/d3.js"></script>     </head>     <body>       <div id="instance">         <svg width="100" height="100">           <circle id = "myCircle" cx="fifty" cy="50" r="30" ></circle>         </svg>       </div>       <script blazon="text/javascript">         var circleDemo = d3.select("#myCircle");           circleDemo.attr("r", 40);           circleDemo.fashion("stroke", "black");           circleDemo.style("make full", "orange");           </script>     </torso>   </html>              

Because CSS styling isn't specified, the circle would be filled black, if we didn't change the styles.

                <circle id = "myCircle" cx="50" cy="50" r="30" ></circle>              

To begin modifying the circumvolve, we first need to create a selection. We'll select myCircle and assign information technology to a D3 variable called circleDemo.

circleDemo contains our selection pointing to the SVG circle element myCircle within the DOM.

                var circleDemo = d3.select("#myCircle");              

Now that we have the circle element assigned to a D3 variable, we can brainstorm change the attributes and styles.

.attr() Method

.attr() is used to alter an chemical element's attributes. Attributes that are used to initially define an chemical element can be passed through .attr() This lets you alter existing elements and gear up new attribute values. Attributes such as an SVG element'south size or position can be inverse with .attr()

.attr() requires it exist given two values: The attribute to exist changed, and the new value for the specified attribute.

In order to use .attr() is must chosen on a pick.

                choice.attr("aspect string", new value)              

To change the circumvolve'southward size, we'll call the .attr() method on our circleDemo selection.

We phone call .attr() and pass the aspect nosotros want to change ("r") with its new value (40).

                circleDemo.attr("r", 40);              

Now when the circle is drawn in the browser, the radius is ready to twoscore.

Note: It'south important to go along in mind that D3 has not created a new chemical element. Instead, D3 is modifying the existing circle.

.style() Method

.style() changes the CSS styling of the selected element. You can alter how an element looks every bit long as it can be specified through CSS. This allows for styling changes to exist outside D3. Equally CSS changes and evolves, D3 can utilize these new changes without the need of a patch.

.style() requires information technology passed ii values -- the CSS style that's going to exist modified and the new value.

.fashion() requires that information technology be chosen on a choice.

                selection.style("CSS Way string", new value)              

Here we have inverse 2 CSS styles --The color of the stroke (line used to draw the element) and the fill colour.

                circleDemo.style("stroke", "blackness");   circleDemo.way("fill", "white");              

Notation: The CSS changes D3 makes are done directly to the document. The changes are not being washed to the circleDemo variable. Instead circleDemo is a pointer to the circle element in the certificate which is being changed.

Recap of .attr() and .style()

While these elementary examples only demonstrate the most basic usage of .attr() and .style(), more than functionally can be gained past combining these methods with data-binding and mouse events. In the after examples, we'll explore how these ii methods can be used in combination with data.

As a review, copy the code at the very top of the page and try changing unlike attributes and styles for the circle chemical element.

Note: Exterior of D3, aspect and styling terminology tin can be disruptive. For example, what D3 calls styles, the SVG standard calls presentation attributes.

horizontal line

Data Binding, suspend, enter()


Binding Data with .data()

Normally when you you lot store a value in programming languages, information technology's done past assigning a value to a variable.

In JavaScript if we wanted to store values (1, two, iii, and 4) in an array nosotros would intialize a variable and assign the values every bit follows:

                var myArray = [ane, 2, 3, iv];              

D3 does not shop data within variables. Instead, D3 stores information within the DOM selectors by calling the selection.information() method.

In order to utilise the .data() method, information technology has to exist chosen from a selector, and passed an assortment of values.

                selection.information([assortment])              

When .data() is called it joins the assortment of values with the array of selections that called it.

NOTE: A selection will always be an array of certificate elements. This is true for both select() and selectAll().

If we wanted to assign the values (10, 15, 20, 25) to selection containing 4 circumvolve elements, in D3 this would exist done by calling .data() on the option circleSelections and passing the array [x, 15, 20, 25] .

                myCircle.data([x, xv, 20, 25])              

when .data() executes it takes the array [x, 15, 20, 25] and joins it with the selection array circleSelections.

                data[    5      ,      10      ,      fifteen      ,      20    ]                          |              |              |              |                          |              |              |              |                          |              |              |              |                          v              v              v              five   circleSelections [  <circle>,     <circumvolve>,      <circle>,       <circumvolve> ]              

.data() takes the commencement value in the assortment and joins it with the starting time selection from circleSelections.

NOTE: When .information() is called it iterates over the array and passes each value downwardly the method concatenation.

5 gets joined with the first <circle> and stored within the DOM.
5 is and then passed downwardly the method chain, until the concatenation completes.
10 is joined with the 2d <circle> and stored within the DOM
10 is then passed downward the method concatenation, until the concatenation completes.
... so on


A Data Bounden Example

Since .data() returns the values from the array information technology'southward been passed, nosotros can use these values to change attributes and styles for SVG elements with a method chain.

Annotation: It's possible to use .data() for changing other elements, but we'll focus on SVG.

If we had 5 circle elements

created from the following code:

                <div id="data_example1">     <svg width="375" top="100">       <circle id = "myCircle" cx="30" cy="50" r="30" ></circle>       <circle id = "myCircle" cx="100" cy="50" r="thirty" ></circle>       <circle id = "myCircle" cx="170" cy="50" r="30" ></circle>       <circumvolve id = "myCircle" cx="240" cy="50" r="30" ></circumvolve>       <circle id = "myCircle" cx="310" cy="l" r="30" ></circle>     </svg>   </div>              

D3 can change the radius past using values from from an array radiusData.

                radiusData = [10, 15, xx, 25, 30];              

.information() volition join the information to the selection
.attr() will accept the joined data, and exist used to change the radius.

<!DOCTYPE html>   <html>     <head>     <script blazon="text/javascript" src="http://mbostock.github.com/d3/d3.js">     </script>     </head>     <trunk>       <div id="data_example1">         <svg width="375" top="100">           <circumvolve id = "myCircle" cx="30" cy="l" r="30" ></circle>           <circle id = "myCircle" cx="100" cy="l" r="30" ></circle>           <circle id = "myCircle" cx="170" cy="50" r="thirty" ></circle>           <circumvolve id = "myCircle" cx="240" cy="50" r="xxx" ></circumvolve>           <circle id = "myCircle" cx="310" cy="50" r="30" ></circle>         </svg>       </div>       <script type="text/javascript">       //radiusData is an array containing the new radius        //for the circle elements         radiusData = [10, 15, twenty, 25, 30]; 		       //Select the div chemical element         selectExample = d3.select("#data_example1");        //Nosotros'll select all the circumvolve from within the selected <div> element         selectExample.selectAll("circle")           .data(radiusData)           .attr("r", part(d){return d});       </script>     </trunk>   </html>              

Initially we select the <div> chemical element containing all the circle elements.

                selectExample = d3.select("#data_example1");              

Nosotros tin then select all the circle elements within selectExample.
This will return an array of circumvolve element selections.

                selectExample.selectAll("circumvolve")              

When we call .data() information technology will join the values from radiusData with the circle elements.
As .data() iterates beyond the assortment of circumvolve selections, it returns the current radiusData value.

                .data(radiusData)              

By calling .information() in a method concatenation, D3 iterates over the data assortment (radiusData) and returns the present value to methods down the chain. This allows us to use values in radiusData with other methods, like .attr().

This functionality tin be used to alter radius using values from from the array radiusData.
This results in .attr() being called 5x. One for each value within the radiusData array.
Each time .attr() is called, it will receive a unlike value from radiusData.

In our example, a each value from radiusData called d is beingness passed downwardly the chain.

Annotation: The value beingness returned from .data() and passed down the chain could have been given whatsoever non-conflicting name.

Now that .attr() is existence passed a value, we can set the aspect we want to modify ("r") and pass the new value through an bearding function.

                .attr("r", function(d){render d});              

The resulting circles wait like

Joining Multiple Values with .data()

.data() can be used to join multiple values to a unmarried selection.
It'due south possible to pass an array of assortment to .data()

The assortment of arrays can incorporate multidimensional data that can exist applied to each choice.

In this example circleData contains the radius and colour for each circle element.
circle[0] contains the assortment [10, "rgb(246, 239, 247)"]

                circleData = [[10, "rgb(246, 239, 247)"], [15, "rgb(189,201,225)"],   [20, "rgb(103,169,207)"], [25, "rgb(28,144,153)"], [thirty, "rgb(i,108,89)"]];              

When selection.data(circleData) is chosen, it will render an array of values ["radius", "color"] for each selection.

In social club to change colors and radius nosotros chain .attr() method calls and index the array that'southward returned by .data().

                selectExample.selectAll("circle")     .information(circleData)     .attr("r", part(d){return d[0]})     .style("fill", function(d){return d[one]});              

We use an bearding part and pass .attr() the assortment d. To set the radius value, nosotros use an anonymous role which returns the first element (d[0]) in the array.

To set up the style we use the similar code, but instead access the 2d element of d.

for the offset circle selection, the equivalent code would await like

                .attr("r", 10)   .fashion("fill", "rgb(246, 239, 247)");              

The final code follows:

<!DOCTYPE html>   <html>     <head> 	  <script blazon="text/javascript" src="http://mbostock.github.com/d3/d3.js" >       </script> 	</caput>     <body>       <div id="data_example2">       <svg width="375" meridian="100">         <circumvolve id = "myCircle" cx="thirty" cy="50" r="thirty" ></circumvolve>         <circle id = "myCircle" cx="100" cy="l" r="30" ></circle>         <circle id = "myCircle" cx="170" cy="50" r="30" ></circle>         <circumvolve id = "myCircle" cx="240" cy="50" r="30" ></circle>         <circle id = "myCircle" cx="310" cy="50" r="thirty"  ></circumvolve>       </svg>       </div>       <script type="text/javascript"> 	   	  //radiusData is an array containing the new radius for the circumvolve elements       circleData = [[ten, "rgb(246, 239, 247)"], [15, "rgb(189,201,225)"], 	         [20, "rgb(103,169,207)"], [25, "rgb(28,144,153)"], [xxx, "rgb(ane,108,89)"]]; 	         //Select the div element       selectExample = d3.select("#data_example2"); 	         //We'll select all the circle from within the selected <div> chemical element       selectExample.selectAll("circle")         .information(circleData)         .attr("r", function(d){return d[0]})         .style("fill up", function(d){render d[1]});       </script>     </trunk>   </html>              

The code above results in these circles.


.enter() and .suspend()

In the previous instance we hard coded the circle elements. While this was useful for explaining D3, it's non amendable to making changings to the code. If we wanted to change the circles to a different svg element, it would accept to be done line by line.

We can meliorate the code past using D3 generate and append elements into the DOM. Past doing this, changes can be made by editing a few lines of code.

In this instance, we'll use .enter() and .suspend() to manipulate the DOM and add circle elements.

NOTE: .append() can exist used to add any valid selection, tag, container or chemical element into the DOM. It can be used to add <p>, <div>, text, <svg> elements, etc. But nosotros'll focus on using .suspend() to add together SVG elements.

Annotation: .enter() can only be used after a .data() method call. .
enter()
is used to bespeak that new elements will be added to the electric current choice.
An .append() or .insert() follows an .enter() call.

The condensed version of the previous examples looks like this:

<!DOCTYPE html>   <html>     <caput>      <script type="text/javascript" src="http://mbostock.github.com/d3/d3.js" >      </script>     </caput>     <body>      <div id="data_example3"></div>      <script type="text/javascript">      circleData = [[ten, "rgb(246, 239, 247)"], [xv, "rgb(189,201,225)"],       [xx, "rgb(103,169,207)"], [25, "rgb(28,144,153)"],        [30, "rgb(1,108,89)"]]; 	       var selectDiv = d3.select("#data_example3")       .append("svg:svg")       .attr("width", circleData.length * 100)       .attr("height", 100); 	        selectDiv.selectAll("circle")       .data(circleData)       .enter()       .append("circle")       .attr("cx", function(d){return d[0]*14})       .attr("cy", 50)       .attr("r", function(d){return d[0]})       .manner("fill", function(d){return d[1]}); 	        </script>     </body>   </html>              

d3.select returns the <div id="data_example3"> option and passes information technology the next method in the chain.

                var selectDiv = d3.select("#data_example3")              

.append() takes the <div id="data_example3"> selection and adds a svg container.

Notation: When .suspend() adds items, the added item is a child of the electric current selection.

Subsequently adding the svg:svg container .append() completes past returning the current selection.
The current selection will always be the element that was added.

.append() returns the <svg> container as the pick.

                .suspend("svg:svg")              

The width is specified for the current option (svg container).

                .attr("width", circleData.length * 100)              

The height is prepare.
When the method concatenation ends, selectDiv points to the <svg> container selection within the <div> element.

                .attr("pinnacle", 100);              

At this point in the code, selectDiv points to the <svg> container.
Calling .selectAll.("circle") selects all the circle elements within the <svg> pick.
Considering <svg> does not comprise whatsoever circle elements, .selectAll.("circle") returns an empty array.

                selectDiv.selectAll("circle")              

Now when .information(circleData) is called, its binding data to an empty selection assortment.

                .data(circleData)              

To suspend elements, we first must call .enter()

NOTE: .enter() can only be called after on a information selection
.enter() takes the pick returned by .data() and prepares it for calculation elements.
Elements can exist added using .suspend() and .insert().

                .enter()              

.append() adds a child circle chemical element below the <svg> parent node.

Note: Later on after the circle is added .suspend() returns the circle element equally the current pick.

                .append("circle")              

Now that a circle element exists, we can use the data array returned by .data(circleData) and use it to set attributes and styles for the current circle.

                .attr("cx", office(d){return d[0]*14})   .attr("cy", 50)   .attr("r", office(d){return d[0]})   .fashion("make full", office(d){return d[1]});              

This condense condensed code gives the same results.

Epitomize of .enter() and .append()

.enter() must follow a .data() method phone call.
.enter() uses the current selection every bit the parent node for the elements added with .append().
.append() can exist used to add more than svg elements.

horizontal line

Mouse Events

D3 uses the syntax selection.on(blazon[,listener]) to add together or remove event listeners for interaction. The type is an event type proper noun similar "click", "mouseover", or "submit". The listener is triggered by the mouse consequence to practise something about the current DOM element. For case:

                .on("mouseover", function(){d3.select(this).style("fill up", "green");})   .on("mouseout", role(){d3.select(this).style("make full", "white");});              

The case uses anonymouse functions to alter elements from an existing DOM. The styles are altered according to a part. Then this lawmaking snippet "listens" to the mouse event and do changes accordingly.

                <div id="mouseEvent_example"></div>     <script type="text/javascript">       var sampleSVG = d3.select("#mouseEvent_example")         .append("svg:svg")         .attr("width", 200)         .attr("height", 200);            sampleSVG.append("svg:rect")         .style("stroke", "gray")         .style("fill", "white")         .attr("x", fifty)         .attr("y", l)         .attr("width", 100)         .attr("height", 100)         .on("mouseover", role(){d3.select(this).style("fill", "light-green");})         .on("mouseout", function(){d3.select(this).mode("fill", "white");});     </script>              

The above is the source code of the instance. Let'south encounter some other example on mouse events:

This time if you click on the square, it will be randomly assigned a rainbow color. We can do that by assigning an array of colors to the pool with these ii lines of code:

                var source = ["carmine", "orange", "yellowish", "green", "blue", "indigo", "violet"];    var color = source[Math.floor(Math.random()*source.length)];              

Notation: On mouseout, the square is refilled with the default white color. If you click on the square again, it could exist filled with another rainbow color because of the following code:

                .on("click", function(){d3.select(this).manner("fill", function()     {render source[Math.flooring(Math.random()*source.length)];});})   .on("mouseout", office(){d3.select(this).style("fill", "white");});              

horizontal line

Buttons

Buttons are useful for edifice visulizations. The <button> is an HTML tag. It's not exclusive to D3.

Past combining buttons and mouse events, D3 can provide interactivity.

In this example, nosotros'll apply the HTML button tag to execute D3 code that changes the attributes of two circles.

<!DOCTYPE html>   <html>     <head>       <script blazon="text/javascript" src="http://mbostock.github.com/d3/d3.js"></script>       <style = blazon='text/css'>         .buttonex button {           left: 220px;           position: absolute;           acme: 320px;           width: 80px;         }       </manner>     </head>     <body>       <div class = "buttonex" id="example99">         <push button>Randomize</button>       </div>              <script type="text/javascript">        //data = [[radius, cx, cy, colour]]         data = [[x, twenty, twenty, "rgb(224, 236, 244)"],  	    [30, fifty, 50, "rgb(136, 86, 167)"]] 	           var w = 300, h = 300;         var myExample = d3.select("#example99")           .append("svg:svg")           .attr("width", w)           .attr("height", h) 	           myExample.selectAll("circle")           .information(data)           .enter()           .append("circle")           .attr("r", role(d){return d[0]})           .attr("cx", function(d){return d[1]})           .attr("cy", function(d){render d[ii]})           .way("stroke", "blackness")           .mode("fill", function(d){return d[three]}); 	           d3.select("#example99 button").on("click", function() {           myExample.selectAll("circle")             .attr("cx", office(){return Math.random() * west})             .attr("cy", function(){return Math.random() * h}); 	         </script>     </body>   </html>              

We beginning by setting the position of the button using CSS styles and class.

                <style = type='text/css'>   .buttonex push button {     left: 220px;     position: absolute;     superlative: 320px;     width: 80px;     }              

Creating a button is uncomplicated. Here we've created a button with the text Randomize. The button in this case is created inside a <div> element.

                <push button>Randomize</button>              

Using what nosotros've learned from selections and mouse events, nosotros can define an anonymous role that executes when the button is clicked.
The anonymous function will modify the cx and cy positions to random values.

                d3.select("#example99 button")       .on("click", part() {         myExample.selectAll("circle")           .attr("cx", function(){return Math.random() * w})           .attr("cy", office(){return Math.random() * h});       });              

We start by selecting the button from the div element.

                d3.select("#example99 button)              

Side by side we ascertain the on-click mouse event for the selection (which is the push).
Nosotros'll define an anonymous part that executes when the button is clicked.

                .on("click", function() {              

When the Randomize is clicked, the anonymous role selects all the circles and changes the cx and cy attributes to random values.

                function() {myExample.selectAll("circle")     .attr("cx", part(){return Math.random() * w})     .attr("cy", function(){return Math.random() * h}); 	}              

The final event looks similar

horizontal line

Transitions

A transition is used on a choice to allow information technology's operators to utilize smoothly over time, this allows for an eye pleasing effect when updating visual elements on the display. All that is needed to add a transition to your selection is simply to add the "transition()" operator to your selection as demonstrated below:

                d3.select("this").transition()              

Many of the operators supported for selection are too supported for transitions, such every bit attributes and styles, however in that location are some that are not supported, such as append.

Delay and Duration

By default the transition will start immediately and will last for a elapsing of 250ms, this can be changed using the .delay() and .duration() operators. These can exist called with a specified constant in milliseconds such equally .delay(3000) for 3 seconds, or they tin can be called with a function that volition evaluate for each element in the current pick. These functions are chosen with ii parameters, d for the electric current datum and i for the current index. So in the below example say our selection contains ii elements, and then the first element will transition afterwards a filibuster of 1s while the second chemical element will transition after a delay of two seconds, remember that index i starts at 0 for the first element.

                d3.select("this")      .transition()     .delay(function (d,i) { return 1000*(i + 1);})     .attr("stroke", "blue")              

Ease

Equally you tin imagine there is more than than one way to brand a smooth transition when irresolute an element, and that's where the .ease() operator comes in. By default a transition will use a cubic easing function, and then the modify will occur on a cubic calibration. There are several other types including linear (changes at a linear footstep) and bounce (simulates a bouncy collision). For a complete listing of available ease functions see here. Below is an case of using the bounce ease role. Just click anywhere on the graph to encounter it in action.

                d3.select("this)     .transition()     .ease("bounce")              


Notation: Click on the graph to a higher place to see the transition.

barnettwituare.blogspot.com

Source: https://website.education.wisc.edu/~swu28/d3t/concept.html

0 Response to "D3 Run Function Again After Chage"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel