Platform
Solutions
Resources
Pricing
Sign in
Sign up
workbook
Learning ObservableJS.
Workspace
Fork
Public
By
Roy Francis
Edited
Apr 17, 2023
Fork of
Learning Vis Tools Tutorial 6: Javascript basics and Observable
Insert cell
Insert cell
Insert cell
// Try to change the value of "radius" and hit "shitf+enter". You will see the "area" cell changes automatically
radius
=
2
Insert cell
// The variable "area" depends on "radius", its value will be updated whenever "radius" changes
area
=
Math
.
PI
*
Math
.
pow
(
radius
,
2
)
Insert cell
Insert cell
Insert cell
{
let
length
=
3
return
length
*
length
}
Insert cell
Insert cell
Insert cell
// Declare an array with square brackets "[]"
visualChannels
=
[
'position'
,
'length'
,
'angle'
,
'area'
,
'color'
,
'curvature'
]
Insert cell
// Get the length of an array
visualChannels
.
length
Insert cell
// Access an item in an array
'Most effective channel: '
+
visualChannels
[
0
]
Insert cell
Insert cell
// Concatenate two arrays
moreVisualChannels
=
visualChannels
.
concat
(
[
'color hue'
,
'color saturation'
,
'color luminance'
]
)
Insert cell
// To sort an array, we use "sort"
moreVisualChannels
.
sort
(
)
Insert cell
/******************************************************************************
* TODO: *
* Try to create two lists of colors, then concatenate them, and sort in *
* alphabetical order! *
* The two lists are: *
* red, green, blue *
* cyan, magenta, yellow, black *
******************************************************************************/
/******************************************************************************
* END OF YOUR CODE *
******************************************************************************/
Insert cell
Insert cell
Insert cell
// Declare an object
typesOfData
=
(
{
ordered
:
[
1
,
2
,
3
,
4
,
5
]
,
categorical
:
[
'strawberry'
,
'apple'
,
'orange'
]
}
)
Insert cell
// To access an attribute of an object, we simply use "."
typesOfData
.
categorical
Insert cell
Insert cell
Insert cell
// To modify an attribute of an object, we simply assign a value to it
{
let
typesOfData
=
{
ordered
:
[
1
,
2
,
3
,
4
,
5
]
,
categorical
:
[
'strawberry'
,
'apple'
,
'orange'
]
}
typesOfData
.
categorical
=
[
'strawberry'
,
'apple'
,
'orange'
,
'banana'
]
return
typesOfData
.
categorical
}
Insert cell
/******************************************************************************
* TODO: *
* Try to modify the values of the "ordered" attribute to 1, 10, 100, 1000! *
******************************************************************************/
/******************************************************************************
* END OF YOUR CODE *
******************************************************************************/
Insert cell
Insert cell
// If statement
{
let
color
=
'cyan'
let
hex
=
''
if
(
color
===
'cyan'
)
{
hex
=
rgb2hex
(
0
,
255
,
255
)
}
else
if
(
color
===
'magenta'
)
{
hex
=
rgb2hex
(
255
,
0
,
255
)
}
else
if
(
color
===
'yellow'
)
{
hex
=
rgb2hex
(
255
,
255
,
0
)
}
else
{
hex
=
rgb2hex
(
255
,
255
,
255
)
}
return
hex
}
Insert cell
// Loop through items in an array
{
let
rgb
=
[
'red'
,
'green'
,
'blue'
]
let
rgbValues
=
[
[
255
,
0
,
0
]
,
[
0
,
255
,
0
]
,
[
0
,
0
,
255
]
]
let
rgbHex
=
[
]
for
(
let
i
=
0
;
i
<
rgb
.
length
;
i
++
)
{
let
[
r
,
g
,
b
]
=
rgbValues
[
i
]
// append an item to the array
rgbHex
.
push
(
rgb2hex
(
r
,
g
,
b
)
)
}
return
rgbHex
}
Insert cell
/******************************************************************************
* TODO: *
* Try to find the hex codes of cyan, magenta, yellow and black! *
******************************************************************************/
/******************************************************************************
* END OF YOUR CODE *
******************************************************************************/
Insert cell
Insert cell
// Declare a function with keyword "function"
function
int2hex
(
n
)
{
return
n
>=
16
?
n
.
toString
(
16
)
:
'0'
+
n
.
toString
(
16
)
}
Insert cell
// Calling the "int2hex" function
int2hex
(
255
)
Insert cell
// Alternatively, we can declare a function using arrow
rgb2hex
=
(
r
=
0
,
g
=
0
,
b
=
0
)
=>
{
return
'#'
+
int2hex
(
r
)
+
int2hex
(
g
)
+
int2hex
(
b
)
}
Insert cell
rgb2hex
(
64
,
224
,
208
)
Insert cell
// Converting color name to hex code
function
rgbColor2hex
(
color
)
{
if
(
color
===
'red'
)
{
return
rgb2hex
(
255
,
0
,
0
)
}
else
if
(
color
===
'green'
)
{
return
rgb2hex
(
0
,
255
,
0
)
}
else
{
return
rgb2hex
(
0
,
0
,
255
)
}
}
Insert cell
rgbColor2hex
(
'red'
)
Insert cell
/******************************************************************************
* TODO: *
* Try to use arrow function expression to create a function that takes color *
* name as input and return hex code for cyan, magenta, yellow and black! *
******************************************************************************/
/******************************************************************************
* END OF YOUR CODE *
******************************************************************************/
Insert cell
Insert cell
// Built-in array function "map"
// It calls the "rgbColor2hex" function for each item in the array
[
'red'
,
'green'
,
'blue'
]
.
map
(
rgbColor2hex
)
Insert cell
/******************************************************************************
* TODO: *
* Try to map the "cyan", "magenta", "yellow", "black" over the function you *
* have created above to get their hex codes! *
******************************************************************************/
/******************************************************************************
* END OF YOUR CODE *
******************************************************************************/
Insert cell
Insert cell
function
getDataFromServer
(
color
,
callback
)
{
setTimeout
(
function
(
)
{
callback
(
rgbColor2hex
(
color
)
)
}
,
5000
)
}
Insert cell
// Run this cell, the value of "colorInHex" will be updated in 5 seconds
mutable
colorInHex
=
'Waiting for server...'
Insert cell
Insert cell
getDataFromServer
(
'red'
,
function
(
hex
)
{
mutable
colorInHex
=
`The hex code of "Red" is ${
hex
}. Run the cell below to try again!`
}
)
Insert cell
Insert cell
Insert cell
// Get the current date and time, in "ticks"
Date
.
now
(
)
Insert cell
// Make "ticks" human readable
new
Date
(
Date
.
now
(
)
)
Insert cell
// Access a specific part of a "date", there are also hour, minute, second and
// millisecond accessible. Be awared that we need to add 1 to the value returned
// from getMonth because it counts from 0, which means January.
{
let
now
=
new
Date
(
Date
.
now
(
)
)
// A string encapsulated with backtick "`" is a template string, it will
// evaluate the expression inside the placeholder "${}"
return
`Year: ${
now
.
getFullYear
(
)
} Month: ${
now
.
getMonth
(
)
+
1
} Day: ${
now
.
getDate
(
)
}`
}
Insert cell
// Create a date object with a specific date. Be reminded, month counts from 0
new
Date
(
2019
,
4
,
3
)
Insert cell
// Javascript does not provide arithematic manipulation for datetime, we need to
// get the value, add/subtract then set the value
{
let
oldDate
=
new
Date
(
2019
,
4
,
3
)
oldDate
.
setDate
(
oldDate
.
getDate
(
)
+
2
)
return
oldDate
}
Insert cell
Insert cell
Insert cell
Insert cell
// Import d3, "@5" specifies the version we want
d3
=
require
(
'd3@5'
)
Insert cell
// Import vega-embed
vegaEmbed
=
require
(
"vega-embed@6"
)
Insert cell
// Import vega-lite-api from another Observable notebook (https://observablehq.com/@vega/vega-lite-api)
import
{
vl
}
from
'@vega/vega-lite-api'
Insert cell
Insert cell
// Load pokemon_tsne.csv from the tutorial repository on GitHub
pokemonBaseStats
=
d3
.
csv
(
'https://raw.githubusercontent.com/leoyuholo/learning-vis-tools/master/tutorial06/lab6/pokemon_tsne.csv'
)
Insert cell
Insert cell
/*
* vega-lite-api makes it intiutive to plot with vega-lite
*
* The following is actually a single Javascript statement, it uses a
* common pattern in Javascript called "method chaining".
*
* "vl.markPoint()" returns an object that with many methods,
* including what we are about to use, "width", "height", "title", etc.
*
* Each of these methods returns an object that also has these methods,
* but with a different internal state.
* For example, before calling "height", the internal state is:
* { width: 500 }
* After calling ".height(400)", the method returns an object with state
* { width: 500, height: 400}
*
* The most important method call is "encode(...)". It takes an unordered list
* of arguments that specifies the visual encodings. In our case, x and y
* encode the dimension reduction result of t-sne and color encodes whether
* the pokemon "is_legendary". Tooltip can also be specified as an encoding
* channel. Notice that there is a data type specifier in the "field" method,
* "fieldQ()" means quantitative data and "fieldN" means nominal data.
*
* And after we called it with all the methods we want, "title", "width",
* "height" and "encode", we call the "render" method, which returns a plot for
* Observable notebook to render.
*/
vl
.
markPoint
(
)
.
title
(
'Pokemon base stats t-sne'
)
.
width
(
500
)
.
height
(
400
)
.
data
(
pokemonBaseStats
)
.
encode
(
vl
.
x
(
)
.
fieldQ
(
'x'
)
,
vl
.
y
(
)
.
fieldQ
(
'y'
)
,
vl
.
color
(
)
.
fieldN
(
'is_legendary'
)
,
vl
.
tooltip
(
[
'name'
,
'hp'
,
'speed'
,
'attack'
,
'defense'
,
'sp_attack'
,
'sp_defense'
,
'is_legendary'
]
)
)
.
render
(
)
Insert cell
/******************************************************************************
* TODO: *
* Try to plot other attributes of Pokemons with vega-lite-api, and find the *
* trend! *
* For example, change the color channel to "attack"! Don't forget to change *
* the data type as well! It is "Q" for quantitative, "O" for ordinal, *
* "N" for nominal and "T" for temporal. *
******************************************************************************/
/******************************************************************************
* END OF YOUR CODE *
******************************************************************************/
Insert cell
// This is the Vega-Lite equivalent to the plot we made above
// It takes a Javascript object, with all the specification of a plot,
// and returns the exact same visualization.
vegaEmbed
(
{
data
:
{
values
:
pokemonBaseStats
}
,
width
:
500
,
height
:
400
,
title
:
'Pokemon base stats t-sne'
,
mark
:
'point'
,
encoding
:
{
x
:
{
field
:
'x'
,
type
:
"quantitative"
}
,
y
:
{
field
:
'y'
,
type
:
"quantitative"
}
,
color
:
{
field
:
'is_legendary'
}
,
tooltip
:
[
{
field
:
'name'
}
,
{
field
:
'hp'
}
,
{
field
:
'speed'
}
,
{
field
:
'attack'
}
,
{
field
:
'defense'
}
,
{
field
:
'sp_attack'
}
,
{
field
:
'sp_defense'
}
,
{
field
:
'is_legendary'
}
]
}
}
)
Insert cell
/******************************************************************************
* TODO: *
* Try to plot other attributes of Pokemons with vega-lite! *
* Most of the time, the data type will be inferred automatically, if it does *
* not, you may specify it alongside the field, for example: *
* color: { field: 'attack', type: 'q' } *
******************************************************************************/
/******************************************************************************
* END OF YOUR CODE *
******************************************************************************/
Insert cell
Insert cell
One platform
to build and deploy the best data apps
Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Try it for free
Learn more
Compare fork
Fork
View
Export
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
radius
Add comment
Copy import
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
area
Add comment
Copy import
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
visualChannels
Add comment
Copy import
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
moreVisualChannels
Add comment
Copy import
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
typesOfData
Add comment
Copy import
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
int2hex
Add comment
Copy import
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
rgb2hex
Add comment
Copy import
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
rgbColor2hex
Add comment
Copy import
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
getDataFromServer
Add comment
Copy import
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
colorInHex
Add comment
Copy import
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
d3
Add comment
Copy import
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
vegaEmbed
Add comment
Copy import
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Copy import
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
pokemonBaseStats
Add comment
Copy import
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML
Edit
Add comment
Select
Duplicate
Copy link
Embed
Delete
JavaScript
Markdown
HTML