Starting:
Recently, due to the company’s project requirements, the revealed board interface has been reconstructed to adapt to the normal display of 1G memory TV of android 5.1 and 4.4 versions of 70 inch and 55 inch. After memory usage screening, it is determined to replace the previous canvas+fabric.min.js with d3.js to reduce memory usage. Because the previous periodic refresh of the interface will lead to more and more memory, thus crashing; After the replacement, the memory usage is reduced from the original 670M and stabilized at about 340M, which is about twice as low. Moreover, the stability is better and the rendering interface is faster.
Memory Usage (MB) test
(1) directly open Google: 433~ 296,297.1
(2) HTML + CSS +js Google open this page: 452->359 again refresh this page: 415->370 many times refresh: 383->349
(3) SVG Google open this page: 369->237 again refresh this page: 308->250 times refresh: 307->256
(4)d3.js Google open this page: 356->241 again refresh this page: 314->241 many times refresh: 312->250
(5) Open this webpage (new-D3) : 506->336, 306.7 refresh this webpage again: 430->316; 404->309 multiple refresh: 412->318; 407 – > 313.6
(5-1) Reveal the board to open this page (new -d3, plus periodic refresh) : 506->386 Refresh this page again: 392->362 refresh: 423->368, wait for a period of time 444
(5-2) Reveal board open this page (new -d3, complete – plus periodic refresh) : 464->335 Refresh this page again: 393->337 refresh many times: 452->343, etc for some time 335.1
(5-3) Reveal board page opened for 40 minutes (debugging) : do not go to the channel operation: XX minutes before 294, XX minutes after 158.6 channel operation, change data: 340->296.9, etc. 293.2, 273.7
(6) Open this page (old – Canvas) : 594->506 and refresh this page again: 549->657 and refresh it many times: 694->661
svg – polygon:
- Top left: Distance from the left of the external SVG distance from the top
- Bottom left: Distance from the left the distance from the top
- The distance from the bottom right corner to the left side to the top
- Distance between the upper right corner and the left side Distance from the top
Here’s how to find the documentation online before taking some time to understand and practice.
- d3.v3.js
- Alignedleft.com/tutorials/d…
Scott MurrayD3 tutorial
reference
<script type="text/javascript" src="d3/d3.v3.js"></script>
Copy the code
Add elements
d3.select("body").append("p").text("New paragraph!");
Copy the code
Link way
d3.select("body")
.append("p")
.text("New paragraph!");
Copy the code
To no chain
var body = d3.select("body");
var p = body.append("p");
p.text("New paragraph!");
Copy the code
Data binding
1. Data
var dataset = [ 5.10.15.20.25 ];
Copy the code
2.DOM element selection
d3.select("body").selectAll("p")
.data(dataset)
.enter()
.append("p")
.text("New paragraph!");
Copy the code
.selectAll(“p”) – Selects all paragraphs in the DOM. An empty selection is returned because it does not yet exist. Think of the empty selection as representing the upcoming paragraph.
.data(dataset) – Calculates and parses our data values. We have five values in our data set, so all operations after this point will be performed five times, one for each value.
.Enter () – To create a new data binding element, you must use Enter (). This method looks at the DOM first and then at the data passed to it. If there are more data values than the corresponding DOM element, Enter () creates a new placeholder element on which you can handle magic. It then passes the reference to the new placeholder to the next step in the chain.
.append(“p”) – accepts enter() as created by the placeholder and inserts the p element into the DOM. Long live! It then passes the reference to the newly created element to the next step in the chain.
.text(“New paragraph!” ) — references the newly created content P and inserts a text value.
Where is the data?
console.log(d3.selectAll("p"))
Copy the code
Print: New Paragraph! New paragraph! New paragraph! New paragraph! New paragraph!
Using the data
Let’s change the last line to:
.text(function(d) { return d; });
Copy the code
Print: 5, 10, 15, 20, 25
High function
If you’re not familiar with writing your own functions (that is, methods), the basic structure of a function definition is:
function(input_value) {
//Calculate something here
return output_value;
}
Copy the code
The function we used above is very simple, nothing fancy
function(d) {
return d;
}
Copy the code
And wrapped in D3’s text() function, so anything returned by our function will be passed to text().
.text(function(d) {
return d;
});
Copy the code
You want to preserve data
Don’t work
.text("I can count up to " + d);
Copy the code
If you don’t use anonymous functions, d has no value. Think of its D as a lonely little placeholder value, and all it needs is the embrace of a warm parasite with a caring function.
Could be:
.text(function(d) { // <-- Note tender embrace at left
return "I can count up to " + d;
});
Copy the code
Print: I can count up to 5 I can count up to 10 I can count up to 15 I can count up to 20 I can count up to 25
Beyond words
Add another line
.style("color"."red");
Copy the code
Print: Now all text is red
.style("color".function(d) {
if (d > 15) { //Threshold of 15
return "red";
} else {
return "black"; }});Copy the code
Print: Note that the first three lines are black, but once D passes any threshold of 15, the text turns red.
Drawing div
To get started, continue with our simple data set:
var dataset = [ 5.10.15.20.25 ];
Copy the code
Shared styles are put into a class called bar:
div.bar {
display: inline-block;
width: 20px;
height: 75px; /* We'll override this later */
background-color: teal;
}
Copy the code
or
div class="bar"></div>
Copy the code
Set properties -attr()
attr()
<p class="caption">
<select id="country">
<img src="logo.png" width="100px" alt="Logo" />
Copy the code
Contains five attributes (and corresponding values), all of which can be used to set the attr () : the class | | caption id country SRC | logo. The PNG width 100 px Alt | | logo
To give our divsa class bar, we can use:
.attr("class"."bar")
Copy the code
Lesson Notes – Classed ()
Classed () this method can be used to quickly apply an element or remove a class from an element. The above line of code could be rewritten as:
.classed("bar".true)
Copy the code
Back to the bar
div.bar {
display: inline-block;
width: 20px;
height: 75px;
background-color: teal;
}
Copy the code
var dataset = [ 5.10.15.20.25 ];
d3.select("body").selectAll("div")
.data(dataset)
.enter()
.append("div")
.attr("class"."bar");
Copy the code
Print: You should see five vertical bars, generating one vertical bar for each point in our dataset, which look like a large rectangle even though there are no Spaces between them.
Set style-style ()
style()
<div style="height: 75px;"></div>
Copy the code
Add it to the end of the D3 code:
.style("height".function(d) {
return d + "px";
});
Copy the code
Print: As D3 traverses each data point, the value D of is set to the value of the corresponding data point. Therefore, we set the height to D (the current data value) plus PX (in the specified units of pixels). The resulting heights will be 5px, 10px, 15px, 20px and 25px.
Make these bars higher:
.style("height".function(d) {
var barHeight = d * 5; //Scale up by factor of 5
return barHeight + "px";
});
Copy the code
Power of data ()
var dataset = [ 25.7.5.26.11.8.25.14.23.19.14.11.22.29.11.13.12.17.18.10.24.18.25.9.3 ];
d3.select("body").selectAll("div")
.data(dataset) // <-- The answer is here!
.enter()
.append("div")
.attr("class"."bar")
.style("height".function(d) {
var barHeight = d * 5;
return barHeight + "px";
});
Copy the code
Enter data() with ten values and it will loop ten times. Give it a million values and it will loop a million times. (Be patient.)
This is the power of data() — smart enough to walk through the full length of any data set you throw at it, executing each method below it in the chain while updating the context of each method, so D always refers to the point in the loop where the current data is.
Random data
var dataset = []; //Initialize empty array
for (var i = 0; i < 25; i++) { //Loop 25 times
var newNumber = Math.random() * 30; //New random number (0-30)
dataset.push(newNumber); //Add new number to array
}
Copy the code
01. Create an empty array dataset named. 02. Start a for loop that executes 25 times. 03. Each time, it generates a new random number with a value between 0 and 30. 04. The new number will be appended to the dataset array. (Push () is an array method that appends a new value to the end of an array.)
The console. The log (dataset). You should see a full array of 25 random data values. Print: [29.008557153312662, 27.358102895412994, 1.8531420247113806, 16.458962264131355, 26.23005996178159, 21.423858033433216, 23.02974585678495, 14.492293735898214, 1.4009596341184483, 4.870038095128395, 29.705936448111455, 29.545566415279104, 23.387205995731414, 18.928408390390054, 23.580675188245568, 0.8581797024793425, 22.09853928963049, 8.800467041052556, 9.877315663211355, 2.9875160127928657, 11.943283651942558, 27.60897370588235, 29.809121268489193, 9.074583100012381, 5.488617241879057]
Note that they are both decimal or floating point values (14.793717765714973), not integers or integers (14) like we originally used. If you need integers, you can use JavaScript’s math.round () method.
var newNumber = Math.round(Math.random() * 30);
Copy the code
It has indeed been rounded to whole numbers
SVG primer
SVG is more reliable, visually consistent, and faster. You can use vector drawing software like Illustrator to generate SVG files, but you need to learn how to generate them using code.
SVG element
You must create an SVG element before you can draw anything. You can think of SVG elements as canvases on which to render visual effects. (In this respect, SVG is conceptually similar to HTML’s Canvas element.) At a minimum, it is best to specify width and height. If these are not specified, SVG will take up as much space as possible in its enclosing elements.
<svg width="500" height="50">
</svg>
Copy the code
Also note that the browser assumes pixels as the default unit of measure. We specified the dimensions 500 and 50, not 500px and 50px. We can specify px explicitly, or any number of other supporting units, including EM, PT, in, cm, and mm.
Simple shape
These include rect, Circle, Ellipse, line, text, and path. The increased x value moves to the right and the increased y value moves down.
Rect draws a rectangle. Use x and y to specify the coordinates of the upper left corner, width and height to specify the dimensions. This rectangle fills the entire space of our SVG:
<rect x="0" y="0" width="500" height="50"/>
Copy the code
Circle Draw a circle. Use cx and cy to specify the coordinates of the center, and r to specify the radius. The circle is in the cX center of our 500-pixel wide SVG because its (” center-x “) value is 250.
<circle cx="250" cy="25" r="25"/>
Copy the code
Ellipse is similar, but requires a separate radius value for each axis. It’s r using rx and RY.
<ellipse cx="250" cy="25" rx="100" ry="25"/>
Copy the code
Draw a line. Use x1 and y1 to specify one end of the line, x2 and y2 to specify the other end. A stroke color must be visible in the row specified.
<line x1="0" y1="0" x2="500" y2="50" stroke="black"/>
Copy the code
Text Displays the text. Use x to specify the position of the left edge, and y to specify the type of vertical position of the baseline.
<text x="250" y="25">Easy-peasy</text>
Copy the code
Text inherits the CSS-specified font style of its parent element unless otherwise noted. We can rewrite the format as follows:
<text x="250" y="25" font-family="sans-serif" font-size="25" fill="gray">Easy-peasy</text>
Copy the code
Sets the style of the SVG element
The default style is a black fill without strokes. The common attributes of SVG are:
- Fill – color value. As with CSS, the color can be specified as
- Named color – orange
- Hex value -# 3388AA or # 38A
- RGB value – RGB (10, 150, 20)
- RGB — RGBA with Alpha transparency (10, 150, 20, 0.5)
- Stroke – Color value.
- Stroke-width — Numeric measurement (usually in pixels).
- Opacity – a number between 0.0 (fully transparent) and 1.0 (fully opaque).
text:
- font-family
- font-size
In another parallel to CSS, there are two ways to apply styles to SVG elements: directly (inline) as attributes of the element, or using CSS style rules; New class for CSS style target.
Layering and drawing order
There are no “layers” in SVG, and no real concept of depth. SVG does not support the Z-index property of CSS, so shapes can only be arranged in the two-dimensional X/Y plane.
transparency
There are two ways to apply opacity: use an RGB color with alpha or set a opacity value.
Note that when used with RGBA (), transparency is applied to fill and stroke colors, respectively. To apply opacity to the entire element, set a opacity property.
Draw the SVG
All attributes of an SVG element are specified as attributes.
<element property="value"/>
Copy the code
Create SVG
d3.select("body").append("svg");
Copy the code
Advice:
var svg = d3.select("body").append("svg");
Copy the code
By creating a new variable SVG, we can capture the returned reference append().
To simplify your life, I recommend putting the width and height values in variables at the top of the code
//Width and height
var w = 500;
var h = 50;
//Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
Copy the code
Data-driven shapes
var dataset = [ 5.10.15.20.25 ];
svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle");
Copy the code
Data () iterates over each data point, and circle creates one for each data point. Remember, selectAll() will return empty references to all circles (which don’t yet exist), data() will bind our data to the element we’re about to create, Enter () will return placeholder references to the new element, append() and finally Circle will add a to the DOM.
// Complete code
//Width and height
var w = 500;
var h = 50;
//Data
var dataset = [ 5.10.15.20.25 ];
//Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width".500)
.attr("height".50);
var circles = svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle");
circles.attr("cx".function(d, i) {
return (i * 50) + 25;
})
.attr("cy", h/2)
.attr("r".function(d) {
return d;
});
Copy the code
Generation:
<svg width="500" height="50">
<circle cx="25" cy="25" r="5"></circle>
<circle cx="75" cy="25" r="10"></circle>
<circle cx="125" cy="25" r="15"></circle>
<circle cx="175" cy="25" r="20"></circle>
<circle cx="225" cy="25" r="25"></circle>
</svg>
Copy the code
Take a step-by-step look at the code:
circles.attr("cx".function(d, i) {
return (i * 50) + 25;
})
Copy the code
(0 * 50) + 25 returns 25 (1 * 50) + 25 returns 75 (2 * 50) + 25 returns 125 (3 * 50) + 25 returns 175 (4 * 50) + 25 returns 225
Beautiful color, oh!
.attr("fill"."yellow")
.attr("stroke"."orange")
.attr("stroke-width".function(d) {
return d/2;
});
Copy the code
The data type
variable
Variables are data, the smallest building blocks of data. Variables are the basis for all other data structures, which are just different configurations of variables. Be aware that it is a loosely typed language, which means that you do not have to specify up front what type of information will be stored in variables. However, JavaScript automatically types variables based on the type of information you assign to them.
An array of
var numbers = [ 5.10.15.20.25 ];
Copy the code
ID | Value
------------
0 | 5
1 | 10
2 | 15
3 | 20
4 | 25
Copy the code
What to do array ()
Without arrays and powerful for() loops, code-based data visualization would be impossible.
for (var i = 0; i < numbers.length; i++) {
console.log(numbers[i]); //Print value to console
}
Copy the code
object
Arrays are great for simple lists of values, but for more complex data sets, you’ll need to put data into objects.
var fruit = {
kind: "grape".color: "red".quantity: 12.tasty: true
};
Copy the code
Object + array
var fruits = [
{
kind: "grape".color: "red".quantity: 12.tasty: true
},
{
kind: "kiwi".color: "brown".quantity: 98.tasty: true
},
{
kind: "banana".color: "yellow".quantity: 0.tasty: true}];Copy the code
JSON format
var jsonFruit = {
"kind": "grape"."color": "red"."quantity": 12."tasty": true
};
Copy the code
GeoJSON
Just as JSON is just a formal syntax for existing JavaScript objects, GeoJSON is a formal syntax for JSON objects optimized for storing geographic data.
var geodata = {
"type": "FeatureCollection"."features": [{"type": "Feature"."geometry": {
"type": "Point"."coordinates": [ 150.1282427, -24.471803]},"properties": {
"type": "town"}}};Copy the code
Make bar charts
Let’s go back to the bar chart we made using the div element. We will then modify this code to draw bar graphs in SVG, giving us more flexibility in visual rendering.
New diagram
var w = 500;
var h = 100;
var barPadding = 1; // <-- New!
var dataset = [ 5.10.13.19.21.25.22.18.15.13.11.12.15.20.18.17.16.18.23.25 ];
//Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x".function(d, i) {
return i * (w / dataset.length);
})
.attr("y".function(d) {
return h - (d * 4);
})
.attr("width", w / dataset.length - barPadding)
.attr("height".function(d) {
return d * 4;
});
Copy the code
color
.attr("fill"."teal");
Copy the code
Use data-driven colors
.attr("fill".function(d) {
return "rgb(0, 0, " + (d * 10) + ")";
});
Copy the code
The label
The actual data values need to be displayed as text in a visual file.
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
Copy the code
Use the text() method to extend the code to include a data value within each element
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text(function(d) {
return d;
})
.attr("text-anchor"."middle")
.attr("x".function(d, i) {
return i * (w / dataset.length) + (w / dataset.length - barPadding) / 2;
})
.attr("y".function(d) {
return h - (d * 4) + 14;
})
.attr("font-family"."sans-serif")
.attr("font-size"."11px")
.attr("fill"."white");
Copy the code
Make scatter charts
We’ve just drawn a bar graph with simple data – just a one-dimensional set of numbers. However, when you have two sets of values to draw against each other, you need a second dimension. A scatter plot is a common type of visualization that represents two sets of corresponding values on two different axes: horizontal and vertical, x and y.
data
var dataset = [
[5.20], [480.90], [250.50], [100.33], [330.95],
[410.12], [475.44], [25.67], [85.21], [220.88]].Copy the code
You can see that each of the 10 rows corresponds to a point in our visualization. [5, 20] For example, for row, we use its 5 as the x value and its 20 for y.
A scatter diagram
//Width and height
var w = 500;
var h = 100;
var dataset = [
[5.20], [480.90], [250.50], [100.33], [330.95],
[410.12], [475.44], [25.67], [85.21], [220.88]].//Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle")
.attr("cx".function(d) {
return d[0];
})
.attr("cy".function(d) {
return d[1];
})
.attr("r".5);
Copy the code
size
.attr("r".function(d) {
return Math.sqrt(h - d[1]);
});
Copy the code
The label
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text(function(d) {
return d[0] + "," + d[1];
})
.attr("x".function(d) {
return d[0];
})
.attr("y".function(d) {
return d[1];
})
.attr("font-family"."sans-serif")
.attr("font-size"."11px")
.attr("fill"."red");
Copy the code
scale
“Scale is a function that maps from the input domain to the output range.” The D3 scale is your ability to define its parameters. Once they are created, you can call the scale function, pass it to the data value, and it nicely returns the scaled output value. You can define and use as many scales as you want.
Apples and pixels
var dataset = [ 100.200.300.400.500 ];
Copy the code
We have been using the data values directly as display values, ignoring the unit differences. Therefore, if 500 apples are sold, the corresponding bar chart will be 500 pixels high.
That might work, but what about next month? A year later, 1,800 apples sold, right? Your audience will have to buy larger monitors to be able to see those very tall apple bars at full height! (Um, apple sticks!)
The domain and range
- Input! Field!
- The output! Range!
Create a scale with an input field of 100,500 and an output range of 10,350. If you give the scale a value of 100, it returns 10. If you give it 500, it will spit back 350.
The normalization of
Normalization is the process of mapping a numeric value to a new value between 0 and 1 based on the lowest and highest possible values. For example, if there are 365 days in a year, the day 310 corresponds to about 0.85 or 85% of the year.
Create a proportion
By accessing D3’s scale generator, D3.scale then enters the desired scale type.
var scale = d3.scale.linear();
Copy the code
We can set the graduated input field to 100,500 by passing these values domain() as an array to the method:
scale.domain([100.500]);
Copy the code
Set the output range in a similar way:
scale.range([10.350]);
Copy the code
These steps can be done individually, as described above, or linked together as a line of code:
var scale = d3.scale.linear()
.domain([100.500])
.range([10.350]);
Copy the code
Either way, our scales work!
scale(100); //Returns 10
scale(300); //Returns 180
scale(500); //Returns 350
Copy the code
Scale the scatter diagram
Such as min() and Max () to quickly analyze our data set. For example, this loops through each x value in the array and returns the largest value:
var xScale = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) { return d[0]; })])
.range([0, w]);
var yScale = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) { return d[1]; })])
.range([0, h]);
// Return the scale value (instead of the original value) :
.attr("cx".function(d) {
return xScale(d[0]);
})
.attr("cy".function(d) {
return yScale(d[1]);
})
.attr("x".function(d) {
return xScale(d[0]);
})
.attr("y".function(d) {
return yScale(d[1]);
})
Copy the code
Complete code:
//Width and height
var w = 500;
var h = 100;
var dataset = [
[5.20], [480.90], [250.50], [100.33], [330.95],
[410.12], [475.44], [25.67], [85.21], [220.88]].//Create scale functions
var xScale = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) { return d[0]; })])
.range([0, w]);
var yScale = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) { return d[1]; })])
.range([0, h]);
//Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle")
.attr("cx".function(d) {
return xScale(d[0]);
})
.attr("cy".function(d) {
return yScale(d[1]);
})
.attr("r".function(d) {
return Math.sqrt(h - d[1]);
});
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text(function(d) {
return d[0] + "," + d[1];
})
.attr("x".function(d) {
return xScale(d[0]);
})
.attr("y".function(d) {
return yScale(d[1]);
})
.attr("font-family"."sans-serif")
.attr("font-size"."11px")
.attr("fill"."red");
Copy the code
To perfect the plot
var padding = 20;
//Width and height
var w = 500;
var h = 300;
var padding = 20;
var dataset = [
[5.20], [480.90], [250.50], [100.33], [330.95],
[410.12], [475.44], [25.67], [85.21], [220.88],
[600.150]].//Create scale functions
var xScale = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) { return d[0]; })])
.range([padding, w - padding * 2]);
var yScale = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) { return d[1]; })])
.range([h - padding, padding]);
var rScale = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) { return d[1]; })])
.range([2.5]);
//Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle")
.attr("cx".function(d) {
return xScale(d[0]);
})
.attr("cy".function(d) {
return yScale(d[1]);
})
.attr("r".function(d) {
return rScale(d[1]);
});
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text(function(d) {
return d[0] + "," + d[1];
})
.attr("x".function(d) {
return xScale(d[0]);
})
.attr("y".function(d) {
return yScale(d[1]);
})
.attr("font-family"."sans-serif")
.attr("font-size"."11px")
.attr("fill"."red");
Copy the code
Other methods
D3.scale.linear () has several other handy methods that are worth mentioning here:
- Nice () – This tells the scale to take whatever input field you’re given, range() and expand both ends to the nearest rounding value. “For example, for the field [0.20147987687960267, 0.996679553296417], the good field is [0.2, 1].”
- RangeRound () – rangeRound() is used instead of range() and all values in the scale output are rounded to the nearest whole number. This is useful if you want shapes to have precise pixel values to avoid blurred edges due to anti-aliasing.
- Clamp () — By default, linear scales can return values beyond a specified range. For example, if a given value is outside its expected input field, the decimal place returns a number that is also outside the output range. .clamp(true) However, the call scale forces all output values to be within the specified range. This means that excessive values are rounded to the lower or higher value of the range (whichever is closest).
Other scales
In addition to the Linear scale (discussed above), D3 has several other scale methods built in:
- Identity – 1:1 ratio, mainly for pixel values
- SQRT – square root scale
- Pow — Power scale (good for gym)
- Log – logarithmic scale
- Quantize – A linear scale with a range of outputs with discrete values, suitable for cases where data is to be classified into “buckets”
- Quantile – Similar to the above, but with discrete values in the input field (when you already have “buckets”)
- Ordinal – Ordinal scale output using non-quantitative values such as category name; Perfect for comparing apples and oranges
Number of shaft
The axe introduced
Much like the scaling function, the axis in D3 is really the function for you to define its parameters. Unlike the scale, when the axis function is called, it does not return a value. Instead, it generates visual elements of the axis, including lines, labels, and scale lines.
Note that the axis functions are SVG-specific because they generate SVG elements. In addition, the axis is intended for quantitative scale (as opposed to sequential scale).
Set the shaft
Use d3.svg.axis() to create a generic axis function:
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom");
// The call() function in D3 takes the selection as input and passes the selection to any function. Call () passes the selection to the xAxis function, so our axis generates g in new.
svg.append("g")
.call(d3.svg.axis()
.scale(xScale)
.orient("bottom"));
Copy the code
Clean it
svg.append("g")
.attr("class"."axis") //Assign "axis" class
.call(xAxis);
Copy the code
.axis path,
.axis line {
fill: none;
stroke: black;
shape-rendering: crispEdges;
}
.axis text {
font-family: sans-serif;
font-size: 11px;
}
Copy the code
We can push the entire axis group to the bottom by transform:
svg.append("g")
.attr("class"."axis")
.attr("transform"."translate(0," + (h - padding) + ")")
.call(xAxis);
Copy the code
Note the use of (H-padding), so the top edge of the group is set to H, and the height of the entire image minus the padding value we created earlier.
Check the tick
You can customize the various aspects of the axis using the following command, starting with approximate ticks() :
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.ticks(5); //Set rough # of ticks
Copy the code
Why not?
Time to mark the vertical axis! Add it near the top of the code
//Define Y axis
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left")
.ticks(5);
// Near the bottom:
//Create Y axis
svg.append("g")
.attr("class"."axis")
.attr("transform"."translate(" + padding + ", 0)")
.call(yAxis);
// Note that the label will be directed left, and the yAxis group will be converted to the right padding by a g-count.
Copy the code
Finishing touches
To prove to you that our new axis is dynamic and extensible, I’d like to switch from using static data sets to using random numbers:
//Dynamic, random dataset
var dataset = [];
var numDataPoints = 50;
var xRange = Math.random() * 1000;
var yRange = Math.random() * 1000;
for (var i = 0; i < numDataPoints; i++) {
var newNumber1 = Math.round(Math.random() * xRange);
var newNumber2 = Math.round(Math.random() * yRange);
dataset.push([newNumber1, newNumber2]);
}
// This code initializes an empty array, loops 50 times, selects two random numbers each time, and adds (" pushes ") the pair to the dataset array.
Copy the code
// Complete code<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="utf-8">
<title>D3 Demo: Axes</title>
<script type="text/javascript" src=".. /d3/d3.v3.min.js"></script>
<style type="text/css">
.axis path,
.axis line {
fill: none;
stroke: black;
shape-rendering: crispEdges;
}
.axis text {
font-family: sans-serif;
font-size: 11px;
}
</style>
</head>
<body>
<script type="text/javascript">
//Width and height
var w = 500;
var h = 300;
var padding = 20;
var dataset = [
[5.20], [480.90], [250.50], [100.33], [330.95],
[410.12], [475.44], [25.67], [85.21], [220.88],
[600.150]].//Create scale functions
var xScale = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) { return d[0]; })])
.range([padding, w - padding * 2]);
var yScale = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) { return d[1]; })])
.range([h - padding, padding]);
var rScale = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) { return d[1]; })])
.range([2.5]);
//Define X axis
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom");
//Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
//Create circles
svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle")
.attr("cx".function(d) {
return xScale(d[0]);
})
.attr("cy".function(d) {
return yScale(d[1]);
})
.attr("r".function(d) {
return rScale(d[1]);
});
//Create labels
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text(function(d) {
return d[0] + "," + d[1];
})
.attr("x".function(d) {
return xScale(d[0]);
})
.attr("y".function(d) {
return yScale(d[1]);
})
.attr("font-family"."sans-serif")
.attr("font-size"."11px")
.attr("fill"."red");
//Create X axis
svg.append("g")
.attr("class"."axis")
.attr("transform"."translate(0," + (h - padding) + ")")
.call(xAxis);
</script>
</body>
</html>
Copy the code
Formatted scale label
We’ve been using integers – integers – nice and easy. But data is often messy, in which case you might want to have more control over the formatting of the axis labels. Enter tickFormat() so that you can specify the format of the number.
var formatAsPercentage = d3.format("1%");
Copy the code
Then, tell your axis to use the formatting function on its scale, for example:
xAxis.tickFormat(formatAsPercentage);
Copy the code
Check out my Eyeo Festival talk on the D3 transition