fix(curriculum): Convert blockquote elements to triple backtick syntax for Data Visualization (#35995)

* fix: convert data visualization

* fix: reverted to blockquote

* fix: changed js to json

Co-Authored-By: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>

* fix: cleaned up code

Co-Authored-By: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
This commit is contained in:
Randell Dawson
2019-05-14 05:04:05 -07:00
committed by Tom
parent 933350c148
commit dd6011b2cc
18 changed files with 211 additions and 21 deletions

View File

@ -13,7 +13,15 @@ The next step is to render the axis on the SVG canvas. To do so, you can use a g
Unlike <code>rect</code>, <code>circle</code>, and <code>text</code>, an axis is just a straight line when it's rendered. Because it is a simple shape, using <code>g</code> works. Unlike <code>rect</code>, <code>circle</code>, and <code>text</code>, an axis is just a straight line when it's rendered. Because it is a simple shape, using <code>g</code> works.
The last step is to apply a <code>transform</code> attribute to position the axis on the SVG canvas in the right place. Otherwise, the line would render along the border of SVG canvas and wouldn't be visible. The last step is to apply a <code>transform</code> attribute to position the axis on the SVG canvas in the right place. Otherwise, the line would render along the border of SVG canvas and wouldn't be visible.
SVG supports different types of <code>transforms</code>, but positioning an axis needs <code>translate</code>. When it's applied to the <code>g</code> element, it moves the whole group over and down by the given amounts. Here's an example: SVG supports different types of <code>transforms</code>, but positioning an axis needs <code>translate</code>. When it's applied to the <code>g</code> element, it moves the whole group over and down by the given amounts. Here's an example:
<blockquote>const xAxis = d3.axisBottom(xScale);<br><br>svg.append("g")<br>&nbsp;&nbsp; .attr("transform", "translate(0, " + (h - padding) + ")")<br>&nbsp;&nbsp; .call(xAxis);</blockquote>
```js
const xAxis = d3.axisBottom(xScale);
svg.append("g")
.attr("transform", "translate(0, " + (h - padding) + ")")
.call(xAxis);
```
The above code places the x-axis at the bottom of the SVG canvas. Then it's passed as an argument to the <code>call()</code> method. The above code places the x-axis at the bottom of the SVG canvas. Then it's passed as an argument to the <code>call()</code> method.
The y-axis works is the same way, except the <code>translate</code> argument is in the form (x, 0). Because <code>translate</code> is a string in the <code>attr()</code> method above, you can use concatenation to include variable values for its arguments. The y-axis works is the same way, except the <code>translate</code> argument is in the form (x, 0). Because <code>translate</code> is a string in the <code>attr()</code> method above, you can use concatenation to include variable values for its arguments.
</section> </section>

View File

@ -14,7 +14,13 @@ Two other useful methods are <code>append()</code> and <code>text()</code>.
The <code>append()</code> method takes an argument for the element you want to add to the document. It appends an HTML node to a selected item, and returns a handle to that node. The <code>append()</code> method takes an argument for the element you want to add to the document. It appends an HTML node to a selected item, and returns a handle to that node.
The <code>text()</code> method either sets the text of the selected node, or gets the current text. To set the value, you pass a string as an argument inside the parentheses of the method. The <code>text()</code> method either sets the text of the selected node, or gets the current text. To set the value, you pass a string as an argument inside the parentheses of the method.
Here's an example that selects an unordered list, appends a list item, and adds text: Here's an example that selects an unordered list, appends a list item, and adds text:
<blockquote>d3.select("ul")<br>&nbsp;&nbsp;.append("li")<br>&nbsp;&nbsp;.text("Very important item");</blockquote>
```js
d3.select("ul")
.append("li")
.text("Very important item");
```
D3 allows you to chain several methods together with periods to perform a number of actions in a row. D3 allows you to chain several methods together with periods to perform a number of actions in a row.
</section> </section>

View File

@ -8,7 +8,13 @@ challengeType: 6
<section id='description'> <section id='description'>
D3 is about visualization and presentation of data. It's likely you'll want to change the styling of elements based on the data. You can use a callback function in the <code>style()</code> method to change the styling for different elements. D3 is about visualization and presentation of data. It's likely you'll want to change the styling of elements based on the data. You can use a callback function in the <code>style()</code> method to change the styling for different elements.
For example, you may want to color a data point blue if has a value less than 20, and red otherwise. You can use a callback function in the <code>style()</code> method and include the conditional logic. The callback function uses the <code>d</code> parameter to represent the data point: For example, you may want to color a data point blue if has a value less than 20, and red otherwise. You can use a callback function in the <code>style()</code> method and include the conditional logic. The callback function uses the <code>d</code> parameter to represent the data point:
<blockquote>selection.style("color", (d) => {<br>&nbsp;&nbsp;/* Logic that returns the color based on a condition */<br>});</blockquote>
```js
selection.style("color", (d) => {
/* Logic that returns the color based on a condition */
});
```
The <code>style()</code> method is not limited to setting the <code>color</code> - it can be used with other CSS properties as well. The <code>style()</code> method is not limited to setting the <code>color</code> - it can be used with other CSS properties as well.
</section> </section>

View File

@ -8,7 +8,14 @@ challengeType: 6
<section id='description'> <section id='description'>
The last challenge added only one rectangle to the <code>svg</code> element to represent a bar. Here, you'll combine what you've learned so far about <code>data()</code>, <code>enter()</code>, and SVG shapes to create and append a rectangle for each data point in <code>dataset</code>. The last challenge added only one rectangle to the <code>svg</code> element to represent a bar. Here, you'll combine what you've learned so far about <code>data()</code>, <code>enter()</code>, and SVG shapes to create and append a rectangle for each data point in <code>dataset</code>.
A previous challenge showed the format for how to create and append a <code>div</code> for each item in <code>dataset</code>: A previous challenge showed the format for how to create and append a <code>div</code> for each item in <code>dataset</code>:
<blockquote>d3.select("body").selectAll("div")<br>&nbsp;&nbsp;.data(dataset)<br>&nbsp;&nbsp;.enter()<br>&nbsp;&nbsp;.append("div")</blockquote>
```js
d3.select("body").selectAll("div")
.data(dataset)
.enter()
.append("div")
```
There are a few differences working with <code>rect</code> elements instead of <code>divs</code>. The <code>rects</code> must be appended to an <code>svg</code> element, not directly to the <code>body</code>. Also, you need to tell D3 where to place each <code>rect</code> within the <code>svg</code> area. The bar placement will be covered in the next challenge. There are a few differences working with <code>rect</code> elements instead of <code>divs</code>. The <code>rects</code> must be appended to an <code>svg</code> element, not directly to the <code>body</code>. Also, you need to tell D3 where to place each <code>rect</code> within the <code>svg</code> area. The bar placement will be covered in the next challenge.
</section> </section>

View File

@ -7,7 +7,16 @@ challengeType: 6
## Description ## Description
<section id='description'> <section id='description'>
The height of each bar can be set to the value of the data point in the array, similar to how the <code>x</code> value was set dynamically. The height of each bar can be set to the value of the data point in the array, similar to how the <code>x</code> value was set dynamically.
<blockquote>selection.attr("property", (d, i) => {<br>&nbsp;&nbsp;/* <br>&nbsp;&nbsp;* d is the data point value<br>&nbsp;&nbsp;* i is the index of the data point in the array<br>&nbsp;&nbsp;*/<br>})</blockquote>
```js
selection.attr("property", (d, i) => {
/*
* d is the data point value
* i is the index of the data point in the array
*/
})
```
</section> </section>
## Instructions ## Instructions

View File

@ -10,7 +10,16 @@ The last challenge created and appended a rectangle to the <code>svg</code> elem
The placement of a rectangle is handled by the <code>x</code> and <code>y</code> attributes. They tell D3 where to start drawing the shape in the <code>svg</code> area. The last challenge set them each to 0, so every bar was placed in the upper-left corner. The placement of a rectangle is handled by the <code>x</code> and <code>y</code> attributes. They tell D3 where to start drawing the shape in the <code>svg</code> area. The last challenge set them each to 0, so every bar was placed in the upper-left corner.
For a bar chart, all of the bars should sit on the same vertical level, which means the <code>y</code> value stays the same (at 0) for all bars. The <code>x</code> value, however, needs to change as you add new bars. Remember that larger <code>x</code> values push items farther to the right. As you go through the array elements in <code>dataset</code>, the x value should increase. For a bar chart, all of the bars should sit on the same vertical level, which means the <code>y</code> value stays the same (at 0) for all bars. The <code>x</code> value, however, needs to change as you add new bars. Remember that larger <code>x</code> values push items farther to the right. As you go through the array elements in <code>dataset</code>, the x value should increase.
The <code>attr()</code> method in D3 accepts a callback function to dynamically set that attribute. The callback function takes two arguments, one for the data point itself (usually <code>d</code>) and one for the index of the data point in the array. The second argument for the index is optional. Here's the format: The <code>attr()</code> method in D3 accepts a callback function to dynamically set that attribute. The callback function takes two arguments, one for the data point itself (usually <code>d</code>) and one for the index of the data point in the array. The second argument for the index is optional. Here's the format:
<blockquote>selection.attr("property", (d, i) => {<br>&nbsp;&nbsp;/* <br>&nbsp;&nbsp;* d is the data point value<br>&nbsp;&nbsp;* i is the index of the data point in the array<br>&nbsp;&nbsp;*/<br>})</blockquote>
```js
selection.attr("property", (d, i) => {
/*
* d is the data point value
* i is the index of the data point in the array
*/
})
```
It's important to note that you do NOT need to write a <code>for</code> loop or use <code>forEach()</code> to iterate over the items in the data set. Recall that the <code>data()</code> method parses the data set, and any method that's chained after <code>data()</code> is run once for each item in the data set. It's important to note that you do NOT need to write a <code>for</code> loop or use <code>forEach()</code> to iterate over the items in the data set. Recall that the <code>data()</code> method parses the data set, and any method that's chained after <code>data()</code> is run once for each item in the data set.
</section> </section>

View File

@ -10,7 +10,21 @@ By default, scales use the identity relationship - the input value maps to the o
Say a data set has values ranging from 50 to 480. This is the input information for a scale, and is also known as the domain. Say a data set has values ranging from 50 to 480. This is the input information for a scale, and is also known as the domain.
You want to map those points along the <code>x</code> axis on the SVG canvas, between 10 units and 500 units. This is the output information, which is also known as the range. You want to map those points along the <code>x</code> axis on the SVG canvas, between 10 units and 500 units. This is the output information, which is also known as the range.
The <code>domain()</code> and <code>range()</code> methods set these values for the scale. Both methods take an array of at least two elements as an argument. Here's an example: The <code>domain()</code> and <code>range()</code> methods set these values for the scale. Both methods take an array of at least two elements as an argument. Here's an example:
<blockquote>// Set a domain<br>// The domain covers the set of input values<br>scale.domain([50, 480]);<br>// Set a range<br>// The range covers the set of output values<br>scale.range([10, 500]);<br>scale(50) // Returns 10<br>scale(480) // Returns 500<br>scale(325) // Returns 323.37<br>scale(750) // Returns 807.67<br>d3.scaleLinear()</blockquote>
```js
// Set a domain
// The domain covers the set of input values
scale.domain([50, 480]);
// Set a range
// The range covers the set of output values
scale.range([10, 500]);
scale(50) // Returns 10
scale(480) // Returns 500
scale(325) // Returns 323.37
scale(750) // Returns 807.67
d3.scaleLinear()
```
Notice that the scale uses the linear relationship between the domain and range values to figure out what the output should be for a given number. The minimum value in the domain (50) maps to the minimum value (10) in the range. Notice that the scale uses the linear relationship between the domain and range values to figure out what the output should be for a given number. The minimum value in the domain (50) maps to the minimum value (10) in the range.
</section> </section>

View File

@ -8,7 +8,12 @@ challengeType: 6
<section id='description'> <section id='description'>
With the scales set up, it's time to map the scatter plot again. The scales are like processing functions that turn the x and y raw data into values that fit and render correctly on the SVG canvas. They keep the data within the screen's plotting area. With the scales set up, it's time to map the scatter plot again. The scales are like processing functions that turn the x and y raw data into values that fit and render correctly on the SVG canvas. They keep the data within the screen's plotting area.
You set the coordinate attribute values for an SVG shape with the scaling function. This includes <code>x</code> and <code>y</code> attributes for <code>rect</code> or <code>text</code> elements, or <code>cx</code> and <code>cy</code> for <code>circles</code>. Here's an example: You set the coordinate attribute values for an SVG shape with the scaling function. This includes <code>x</code> and <code>y</code> attributes for <code>rect</code> or <code>text</code> elements, or <code>cx</code> and <code>cy</code> for <code>circles</code>. Here's an example:
<blockquote>shape<br>&nbsp;&nbsp;.attr("x", (d) => xScale(d[0]))</blockquote>
```js
shape
.attr("x", (d) => xScale(d[0]))
```
Scales set shape coordinate attributes to place the data points onto the SVG canvas. You don't need to apply scales when you display the actual data value, for example, in the <code>text()</code> method for a tooltip or label. Scales set shape coordinate attributes to place the data points onto the SVG canvas. You don't need to apply scales when you display the actual data value, for example, in the <code>text()</code> method for a tooltip or label.
</section> </section>

View File

@ -10,7 +10,30 @@ The D3 <code>min()</code> and <code>max()</code> methods are useful to help set
Given a complex data set, one priority is to set the scale so the visualization fits the SVG container's width and height. You want all the data plotted inside the SVG canvas so it's visible on the web page. Given a complex data set, one priority is to set the scale so the visualization fits the SVG container's width and height. You want all the data plotted inside the SVG canvas so it's visible on the web page.
The example below sets the x-axis scale for scatter plot data. The <code>domain()</code> method passes information to the scale about the raw data values for the plot. The <code>range()</code> method gives it information about the actual space on the web page for the visualization. The example below sets the x-axis scale for scatter plot data. The <code>domain()</code> method passes information to the scale about the raw data values for the plot. The <code>range()</code> method gives it information about the actual space on the web page for the visualization.
In the example, the domain goes from 0 to the maximum in the set. It uses the <code>max()</code> method with a callback function based on the x values in the arrays. The range uses the SVG canvas' width (<code>w</code>), but it includes some padding, too. This puts space between the scatter plot dots and the edge of the SVG canvas. In the example, the domain goes from 0 to the maximum in the set. It uses the <code>max()</code> method with a callback function based on the x values in the arrays. The range uses the SVG canvas' width (<code>w</code>), but it includes some padding, too. This puts space between the scatter plot dots and the edge of the SVG canvas.
<blockquote>const dataset = [<br>&nbsp;&nbsp;[ 34, 78 ],<br>&nbsp;&nbsp;[ 109, 280 ],<br>&nbsp;&nbsp;[ 310, 120 ],<br>&nbsp;&nbsp;[ 79, 411 ],<br>&nbsp;&nbsp;[ 420, 220 ],<br>&nbsp;&nbsp;[ 233, 145 ],<br>&nbsp;&nbsp;[ 333, 96 ],<br>&nbsp;&nbsp;[ 222, 333 ],<br>&nbsp;&nbsp;[ 78, 320 ],<br>&nbsp;&nbsp;[ 21, 123 ]<br>];<br>const w = 500;<br>const h = 500;<br><br>// Padding between the SVG canvas boundary and the plot<br>const padding = 30;<br>const xScale = d3.scaleLinear()<br>&nbsp;&nbsp;.domain([0, d3.max(dataset, (d) => d[0])])<br>&nbsp;&nbsp;.range([padding, w - padding]);</blockquote>
```js
const dataset = [
[ 34, 78 ],
[ 109, 280 ],
[ 310, 120 ],
[ 79, 411 ],
[ 420, 220 ],
[ 233, 145 ],
[ 333, 96 ],
[ 222, 333 ],
[ 78, 320 ],
[ 21, 123 ]
];
const w = 500;
const h = 500;
// Padding between the SVG canvas boundary and the plot
const padding = 30;
const xScale = d3.scaleLinear()
.domain([0, d3.max(dataset, (d) => d[0])])
.range([padding, w - padding]);
```
The padding may be confusing at first. Picture the x-axis as a horizontal line from 0 to 500 (the width value for the SVG canvas). Including the padding in the <code>range()</code> method forces the plot to start at 30 along that line (instead of 0), and end at 470 (instead of 500). The padding may be confusing at first. Picture the x-axis as a horizontal line from 0 to 500 (the width value for the SVG canvas). Including the padding in the <code>range()</code> method forces the plot to start at 30 along that line (instead of 0), and end at 470 (instead of 500).
</section> </section>

View File

@ -9,11 +9,24 @@ challengeType: 6
The D3 methods <code>domain()</code> and <code>range()</code> set that information for your scale based on the data. There are a couple methods to make that easier. The D3 methods <code>domain()</code> and <code>range()</code> set that information for your scale based on the data. There are a couple methods to make that easier.
Often when you set the domain, you'll want to use the minimum and maximum values within the data set. Trying to find these values manually, especially in a large data set, may cause errors. Often when you set the domain, you'll want to use the minimum and maximum values within the data set. Trying to find these values manually, especially in a large data set, may cause errors.
D3 has two methods - <code>min()</code> and <code>max()</code> to return this information. Here's an example: D3 has two methods - <code>min()</code> and <code>max()</code> to return this information. Here's an example:
<blockquote>const exampleData = [34, 234, 73, 90, 6, 52];<br>d3.min(exampleData) // Returns 6<br>d3.max(exampleData) // Returns 234</blockquote>
```js
const exampleData = [34, 234, 73, 90, 6, 52];
d3.min(exampleData) // Returns 6
d3.max(exampleData) // Returns 234
```
A dataset may have nested arrays, like the [x, y] coordinate pairs that were in the scatter plot example. In that case, you need to tell D3 how to calculate the maximum and minimum. A dataset may have nested arrays, like the [x, y] coordinate pairs that were in the scatter plot example. In that case, you need to tell D3 how to calculate the maximum and minimum.
Fortunately, both the <code>min()</code> and <code>max()</code> methods take a callback function. Fortunately, both the <code>min()</code> and <code>max()</code> methods take a callback function.
In this example, the callback function's argument <code>d</code> is for the current inner array. The callback needs to return the element from the inner array (the x or y value) over which you want to compute the maximum or minimum. Here's an example for how to find the min and max values with an array of arrays: In this example, the callback function's argument <code>d</code> is for the current inner array. The callback needs to return the element from the inner array (the x or y value) over which you want to compute the maximum or minimum. Here's an example for how to find the min and max values with an array of arrays:
<blockquote>const locationData = [[1, 7],[6, 3],[8, 3]];<br>// Returns the smallest number out of the first elements<br>const minX = d3.min(locationData, (d) => d[0]);<br>// minX compared 1, 6, and 8 and is set to 1</blockquote>
```js
const locationData = [[1, 7],[6, 3],[8, 3]];
// Returns the smallest number out of the first elements
const minX = d3.min(locationData, (d) => d[0]);
// minX compared 1, 6, and 8 and is set to 1
```
</section> </section>
## Instructions ## Instructions

View File

@ -11,7 +11,21 @@ The first step is to make D3 aware of the data. The <code>data()</code> method i
A common workflow pattern is to create a new element in the document for each piece of data in the set. D3 has the <code>enter()</code> method for this purpose. A common workflow pattern is to create a new element in the document for each piece of data in the set. D3 has the <code>enter()</code> method for this purpose.
When <code>enter()</code> is combined with the <code>data()</code> method, it looks at the selected elements from the page and compares them to the number of data items in the set. If there are fewer elements than data items, it creates the missing elements. When <code>enter()</code> is combined with the <code>data()</code> method, it looks at the selected elements from the page and compares them to the number of data items in the set. If there are fewer elements than data items, it creates the missing elements.
Here is an example that selects a <code>ul</code> element and creates a new list item based on the number of entries in the array: Here is an example that selects a <code>ul</code> element and creates a new list item based on the number of entries in the array:
<blockquote>&lt;body&gt;<br>&nbsp;&nbsp;&lt;ul&gt;&lt;/ul&gt;<br>&nbsp;&nbsp;&lt;script&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;const dataset = ["a", "b", "c"];<br>&nbsp;&nbsp;&nbsp;&nbsp;d3.select("ul").selectAll("li")<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.data(dataset)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.enter()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.append("li")<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.text("New item");<br>&nbsp;&nbsp;&lt;/script&gt;<br>&lt;/body&gt;</blockquote>
```html
<body>
<ul></ul>
<script>
const dataset = ["a", "b", "c"];
d3.select("ul").selectAll("li")
.data(dataset)
.enter()
.append("li")
.text("New item");
</script>
</body>
```
It may seem confusing to select elements that don't exist yet. This code is telling D3 to first select the <code>ul</code> on the page. Next, select all list items, which returns an empty selection. Then the <code>data()</code> method reviews the dataset and runs the following code three times, once for each item in the array. The <code>enter()</code> method sees there are no <code>li</code> elements on the page, but it needs 3 (one for each piece of data in <code>dataset</code>). New <code>li</code> elements are appended to the <code>ul</code> and have the text "New item". It may seem confusing to select elements that don't exist yet. This code is telling D3 to first select the <code>ul</code> on the page. Next, select all list items, which returns an empty selection. Then the <code>data()</code> method reviews the dataset and runs the following code three times, once for each item in the array. The <code>enter()</code> method sees there are no <code>li</code> elements on the page, but it needs 3 (one for each piece of data in <code>dataset</code>). New <code>li</code> elements are appended to the <code>ul</code> and have the text "New item".
</section> </section>

View File

@ -15,7 +15,12 @@ The first and last character you see in the JSON data are square brackets <code>
You learned earlier that objects contain "key-value pairs" that are separated by commas. In the Cat Photo example, the first object has <code>"id":0</code> where "id" is a key and 0 is its corresponding value. Similarly, there are keys for "imageLink", "altText", and "codeNames". Each cat photo object has these same keys, but with different values. You learned earlier that objects contain "key-value pairs" that are separated by commas. In the Cat Photo example, the first object has <code>"id":0</code> where "id" is a key and 0 is its corresponding value. Similarly, there are keys for "imageLink", "altText", and "codeNames". Each cat photo object has these same keys, but with different values.
Another interesting "key-value pair" in the first object is <code>"codeNames":["Juggernaut","Mrs. Wallace","ButterCup"]</code>. Here "codeNames" is the key and its value is an array of three strings. It's possible to have arrays of objects as well as a key with an array as a value. Another interesting "key-value pair" in the first object is <code>"codeNames":["Juggernaut","Mrs. Wallace","ButterCup"]</code>. Here "codeNames" is the key and its value is an array of three strings. It's possible to have arrays of objects as well as a key with an array as a value.
Remember how to access data in arrays and objects. Arrays use bracket notation to access a specific index of an item. Objects use either bracket or dot notation to access the value of a given property. Here's an example that prints the "altText" of the first cat photo - note that the parsed JSON data in the editor is saved in a variable called <code>json</code>: Remember how to access data in arrays and objects. Arrays use bracket notation to access a specific index of an item. Objects use either bracket or dot notation to access the value of a given property. Here's an example that prints the "altText" of the first cat photo - note that the parsed JSON data in the editor is saved in a variable called <code>json</code>:
<blockquote>console.log(json[0].altText);<br>// Prints "A white cat wearing a green helmet shaped melon on its head."</blockquote>
```js
console.log(json[0].altText);
// Prints "A white cat wearing a green helmet shaped melon on its head."
```
</section> </section>
## Instructions ## Instructions

View File

@ -11,14 +11,37 @@ You can use a <code>forEach</code> method to loop through the data since the cat
First, declare an html variable with <code>var html = "";</code>. First, declare an html variable with <code>var html = "";</code>.
Then, loop through the JSON, adding HTML to the variable that wraps the key names in <code>strong</code> tags, followed by the value. When the loop is finished, you render it. Then, loop through the JSON, adding HTML to the variable that wraps the key names in <code>strong</code> tags, followed by the value. When the loop is finished, you render it.
Here's the code that does this: Here's the code that does this:
<blockquote>json.forEach(function(val) {</br>&nbsp;&nbsp;var keys = Object.keys(val);</br>&nbsp;&nbsp;html += "&lt;div class = 'cat'&gt;";</br>&nbsp;&nbsp;keys.forEach(function(key) {</br>&nbsp;&nbsp;&nbsp;&nbsp;html += "&lt;strong&gt;" + key + "&lt;/strong&gt;: " + val[key] + "&lt;br&gt;";</br>&nbsp;&nbsp;});</br>&nbsp;&nbsp;html += "&lt;/div&gt;&lt;br&gt;";</br>});</blockquote>
```js
json.forEach(function(val) {
var keys = Object.keys(val);
html += "<div class = 'cat'>";
keys.forEach(function(key) {
html += "<strong>" + key + "</strong>: " + val[key] + "<br>";
});
html += "</div><br>";
});
```
</section> </section>
## Instructions ## Instructions
<section id='instructions'> <section id='instructions'>
Add a <code>forEach</code> method to loop over the JSON data and create the HTML elements to display it. Add a <code>forEach</code> method to loop over the JSON data and create the HTML elements to display it.
Here is some example JSON Here is some example JSON
<blockquote>[</br>&nbsp;&nbsp;{</br>&nbsp;&nbsp;&nbsp;&nbsp;"id":0,</br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"imageLink":"https://s3.amazonaws.com/freecodecamp/funny-cat.jpg",</br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"altText":"A white cat wearing a green helmet shaped melon on its head. ",</br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"codeNames":[ "Juggernaut", "Mrs. Wallace", "Buttercup"</br>&nbsp;&nbsp;&nbsp;&nbsp;]</br>&nbsp;&nbsp;}</br>]</blockquote>
```json
[
{
"id":0,
"imageLink":"https://s3.amazonaws.com/freecodecamp/funny-cat.jpg",
"altText":"A white cat wearing a green helmet shaped melon on its head. ",
"codeNames":[ "Juggernaut", "Mrs. Wallace", "Buttercup"
]
}
]
```
</section> </section>
## Tests ## Tests

View File

@ -11,7 +11,15 @@ The navigator will get the user's current longitude and latitude.
You will see a prompt to allow or block this site from knowing your current location. The challenge can be completed either way, as long as the code is correct. You will see a prompt to allow or block this site from knowing your current location. The challenge can be completed either way, as long as the code is correct.
By selecting allow, you will see the text on the output phone change to your latitude and longitude. By selecting allow, you will see the text on the output phone change to your latitude and longitude.
Here's code that does this: Here's code that does this:
<blockquote>if (navigator.geolocation){<br>&nbsp;&nbsp;navigator.geolocation.getCurrentPosition(function(position) {<br>&nbsp;&nbsp;&nbsp;&nbsp;document.getElementById('data').innerHTML="latitude: "+ position.coords.latitude + "&lt;br&gt;longitude: " + position.coords.longitude;<br>&nbsp;&nbsp;});<br>}</blockquote>
```js
if (navigator.geolocation){
navigator.geolocation.getCurrentPosition(function(position) {
document.getElementById('data').innerHTML="latitude: " + position.coords.latitude + "<br>longitude: " + position.coords.longitude;
});
}
```
First, it checks if the <code>navigator.geolocation</code> object exists. If it does, the <code>getCurrentPosition</code> method on that object is called, which initiates an asynchronous request for the user's position. If the request is successful, the callback function in the method runs. This function accesses the <code>position</code> object's values for latitude and longitude using dot notation and updates the HTML. First, it checks if the <code>navigator.geolocation</code> object exists. If it does, the <code>getCurrentPosition</code> method on that object is called, which initiates an asynchronous request for the user's position. If the request is successful, the callback function in the method runs. This function accesses the <code>position</code> object's values for latitude and longitude using dot notation and updates the HTML.
</section> </section>

View File

@ -13,7 +13,17 @@ JSON syntax looks very similar to JavaScript object literal notation. JSON has o
These properties and their values are often referred to as "key-value pairs". These properties and their values are often referred to as "key-value pairs".
However, JSON transmitted by APIs are sent as <code>bytes</code>, and your application receives it as a <code>string</code>. These can be converted into JavaScript objects, but they are not JavaScript objects by default. The <code>JSON.parse</code> method parses the string and constructs the JavaScript object described by it. However, JSON transmitted by APIs are sent as <code>bytes</code>, and your application receives it as a <code>string</code>. These can be converted into JavaScript objects, but they are not JavaScript objects by default. The <code>JSON.parse</code> method parses the string and constructs the JavaScript object described by it.
You can request the JSON from freeCodeCamp's Cat Photo API. Here's the code you can put in your click event to do this: You can request the JSON from freeCodeCamp's Cat Photo API. Here's the code you can put in your click event to do this:
<blockquote>req=new XMLHttpRequest();<br>req.open("GET",'/json/cats.json',true);<br>req.send();<br>req.onload=function(){<br>&nbsp;&nbsp;json=JSON.parse(req.responseText);<br>&nbsp;&nbsp;document.getElementsByClassName('message')[0].innerHTML=JSON.stringify(json);<br>};</blockquote>
```js
req=new XMLHttpRequest();
req.open("GET",'/json/cats.json',true);
req.send();
req.onload=function(){
json=JSON.parse(req.responseText);
document.getElementsByClassName('message')[0].innerHTML=JSON.stringify(json);
};
```
Here's a review of what each piece is doing. The JavaScript <code>XMLHttpRequest</code> object has a number of properties and methods that are used to transfer data. First, an instance of the <code>XMLHttpRequest</code> object is created and saved in the <code>req</code> variable. Here's a review of what each piece is doing. The JavaScript <code>XMLHttpRequest</code> object has a number of properties and methods that are used to transfer data. First, an instance of the <code>XMLHttpRequest</code> object is created and saved in the <code>req</code> variable.
Next, the <code>open</code> method initializes a request - this example is requesting data from an API, therefore is a "GET" request. The second argument for <code>open</code> is the URL of the API you are requesting data from. The third argument is a Boolean value where <code>true</code> makes it an asynchronous request. Next, the <code>open</code> method initializes a request - this example is requesting data from an API, therefore is a "GET" request. The second argument for <code>open</code> is the URL of the API you are requesting data from. The third argument is a Boolean value where <code>true</code> makes it an asynchronous request.
The <code>send</code> method sends the request. Finally, the <code>onload</code> event handler parses the returned data and applies the <code>JSON.stringify</code> method to convert the JavaScript object into a string. This string is then inserted as the message text. The <code>send</code> method sends the request. Finally, the <code>onload</code> event handler parses the returned data and applies the <code>JSON.stringify</code> method to convert the JavaScript object into a string. This string is then inserted as the message text.

View File

@ -7,9 +7,19 @@ challengeType: 6
## Description ## Description
<section id='description'> <section id='description'>
You want your code to execute only once your page has finished loading. For that purpose, you can attach a JavaScript event to the document called <code>DOMContentLoaded</code>. Here's the code that does this: You want your code to execute only once your page has finished loading. For that purpose, you can attach a JavaScript event to the document called <code>DOMContentLoaded</code>. Here's the code that does this:
<blockquote>document.addEventListener('DOMContentLoaded',function() {<br><br>});</blockquote>
```js
document.addEventListener('DOMContentLoaded',function() {
});
```
You can implement event handlers that go inside of the <code>DOMContentLoaded</code> function. You can implement an <code>onclick</code> event handler which triggers when the user clicks on the element with id <code>getMessage</code>, by adding the following code: You can implement event handlers that go inside of the <code>DOMContentLoaded</code> function. You can implement an <code>onclick</code> event handler which triggers when the user clicks on the element with id <code>getMessage</code>, by adding the following code:
<blockquote>document.getElementById('getMessage').onclick=function(){};</blockquote>
```js
document.getElementById('getMessage').onclick=function(){};
```
</section> </section>
## Instructions ## Instructions

View File

@ -8,7 +8,21 @@ challengeType: 6
<section id='description'> <section id='description'>
In the previous examples, you received data from an external resource. You can also send data to an external resource, as long as that resource supports AJAX requests and you know the URL. In the previous examples, you received data from an external resource. You can also send data to an external resource, as long as that resource supports AJAX requests and you know the URL.
JavaScript's <code>XMLHttpRequest</code> method is also used to post data to a server. Here's an example: JavaScript's <code>XMLHttpRequest</code> method is also used to post data to a server. Here's an example:
<blockquote>const xhr = new XMLHttpRequest();<br>xhr.open('POST', url, true);<br>xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');<br>xhr.onreadystatechange = function () {<br>&nbsp;&nbsp;if (xhr.readyState === 4 && xhr.status === 201){<br>&nbsp;&nbsp;&nbsp;&nbsp;const serverResponse = JSON.parse(xhr.response);<br>&nbsp;&nbsp;&nbsp;&nbsp;document.getElementsByClassName('message')[0].textContent = serverResponse.userName + serverResponse.suffix;<br>&nbsp;&nbsp;}<br>};<br>const body = JSON.stringify({ userName: userName, suffix: ' loves cats!' });<br>xhr.send(body);</blockquote>
```js
const xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 201){
const serverResponse = JSON.parse(xhr.response);
document.getElementsByClassName('message')[0].textContent = serverResponse.userName + serverResponse.suffix;
}
};
const body = JSON.stringify({ userName: userName, suffix: ' loves cats!' });
xhr.send(body);
```
You've seen several of these methods before. Here the <code>open</code> method initializes the request as a "POST" to the given URL of the external resource, and uses the <code>true</code> Boolean to make it asynchronous. You've seen several of these methods before. Here the <code>open</code> method initializes the request as a "POST" to the given URL of the external resource, and uses the <code>true</code> Boolean to make it asynchronous.
The <code>setRequestHeader</code> method sets the value of an HTTP request header, which contains information about the sender and the request. It must be called after the <code>open</code> method, but before the <code>send</code> method. The two parameters are the name of the header and the value to set as the body of that header. The <code>setRequestHeader</code> method sets the value of an HTTP request header, which contains information about the sender and the request. It must be called after the <code>open</code> method, but before the <code>send</code> method. The two parameters are the name of the header and the value to set as the body of that header.
Next, the <code>onreadystatechange</code> event listener handles a change in the state of the request. A <code>readyState</code> of 4 means the operation is complete, and a <code>status</code> of 201 means it was a successful request. The document's HTML can be updated. Next, the <code>onreadystatechange</code> event listener handles a change in the state of the request. A <code>readyState</code> of 4 means the operation is complete, and a <code>status</code> of 201 means it was a successful request. The document's HTML can be updated.

View File

@ -9,7 +9,13 @@ challengeType: 6
If you don't want to render every cat photo you get from the freeCodeCamp Cat Photo API, you can pre-filter the JSON before looping through it. If you don't want to render every cat photo you get from the freeCodeCamp Cat Photo API, you can pre-filter the JSON before looping through it.
Given that the JSON data is stored in an array, you can use the <code>filter</code> method to filter out the cat whose "id" key has a value of 1. Given that the JSON data is stored in an array, you can use the <code>filter</code> method to filter out the cat whose "id" key has a value of 1.
Here's the code to do this: Here's the code to do this:
<blockquote>json = json.filter(function(val) {<br>&nbsp;&nbsp;return (val.id !== 1);<br>});</blockquote>
```js
json = json.filter(function(val) {
return (val.id !== 1);
});
```
</section> </section>
## Instructions ## Instructions