Video 3.1 React.js: Introduction Chris Murphy · Property of Penn Engineering, Chris Murphy Normal...

Preview:

Citation preview

Video 3.1

React.js: Introduction

Chris Murphy

SD4x-3.1 1

Property of Penn Engineering, Chris Murphy

Review

• JavaScript: a general-purpose, easy-to-use programming language

• DOM: representation of structure of HTML page, which can be manipulated using JavaScript

• jQuery: library that simplifies accessing/using the DOM

SD4x-3.1 2

Property of Penn Engineering, Chris Murphy

What is React?

• JavaScript library for building user interfaces

• HTML page is composed of recyclable, interactive ‘components’ that have a lifecycle during which the state of the component changes

• Highly efficient because of notion of VirtualDOM

• Created and maintained by Facebook

• Used in production by many well known companies

• Netflix

• WhatsApp, Instagram

• Atlassian(BitBucket, HipChat, Jira)

• Codecademy

• Airbnb

• Pinterest

• Dropbox

• PayPal

• Reddit

• Salesforce

• Squarespace

• New York Times

• Treehouse

• eBay

• Trulia

• Expedia

• Visa

• Wolfram Alpha

SD4x-3.1 3

Property of Penn Engineering, Chris Murphy

Why React?

• Modularity: organize code into reusable components that can work together

• Lifecycle maintenance: modifying component based on state; event listeners; simplified conditional rendering

• JSX: write HTML within JavaScript

SD4x-3.1 4

Property of Penn Engineering, Chris Murphy

Components

• Building blocks of React

• Make up the nodes included in the VirtualDOM

• Include and maintain a state that changes with events

• Each component maintains state independently

• Applications can be configured to respond to component level events

SD4x-3.1 5

Property of Penn Engineering, Chris Murphy

VirtualDOM

• Node tree that represents HTML elements, their attributes, and content as objects and properties

• Selectively renders and re-renders subtrees of nodes based on state changes

• Efficient because it does the least amount of DOM manipulation to update components

• Provides a layer of abstraction to the developer, providing simpler programming model and high performance

SD4x-3.1 6

Property of Penn Engineering, Chris Murphy

Normal DOM – How it Works

• When a node is updated, the browser updates (re-renders) all nodes

SD4x-3.1 7

Property of Penn Engineering, Chris Murphy

Normal DOM – How it Works

• When a node is updated, the browser updates (re-renders) all nodes

SD4x-3.1 8

Property of Penn Engineering, Chris Murphy

Normal DOM – How it Works

• When a node is updated, the browser updates (re-renders) all nodes

Change has been made to any given

node

SD4x-3.1 9

Property of Penn Engineering, Chris Murphy

Normal DOM – How it Works

• When a node is updated, the browser updates (re-renders) all nodes

Change has been made to any given

node

Re-render all nodes to reflect the change

SD4x-3.1 10

Property of Penn Engineering, Chris Murphy

VirtualDOM – How it Works

• When a node is updated, two things occur:

• ‘diff’ to determine which nodes within DOM have changed

• ‘reconciliation’ to update the nodes that are affected

SD4x-3.1 11

Property of Penn Engineering, Chris Murphy

VirtualDOM – How it Works

• When a node is updated, two things occur:

• ‘diff’ to determine which nodes within DOM have changed

• ‘reconciliation’ to update the nodes that are affected

Identify nodes that have changed

(‘diff’)

SD4x-3.1 12

Property of Penn Engineering, Chris Murphy

VirtualDOM – How it Works

• When a node is updated, two things occur:

• ‘diff’ to determine which nodes within DOM have changed

• ‘reconciliation’ to update the nodes that are affected

Identify nodes that have changed

(‘diff’)

Identify nodes that are affected by the

change (reconciliation)

SD4x-3.1 13

Property of Penn Engineering, Chris Murphy

VirtualDOM – How it Works

• When a node is updated, two things occur:

• ‘diff’ to determine which nodes within DOM have changed

• ‘reconciliation’ to update the nodes that are affected

Identify nodes that have changed

(‘diff’)

Identify nodes that are affected by the

change (reconciliation)

Re-render ONLY the nodes that were

affected by change

SD4x-3.1 14

Property of Penn Engineering, Chris Murphy

Developing with React

1. Within the page’s HTML, allocate a position on the page in which the desired React component will be rendered, e.g. a div

2. Create a React component in JavaScript

• Establish an initial state

• Define any events that could change the component’s state over its lifecycle

• Define the function to render the HTML

3. Drop the component into position allocated in Step 1

SD4x-3.1 15

Property of Penn Engineering, Chris Murphy

Getting Started

<!DOCTYPE html>

<html>

<head>

<title>ReactJS Example</title>

<script src="react.js"></script>

<script src="react-dom.js"></script>

</head>

<body>

<div id="container"></div>

<script type="text/jsx">

<!-- Insert React code here -->

</script>

</body>

</html>

• Create a div in the HTML to represent the location where the React component will be placed

• Write JavaScript code to create and display component in div

SD4x-3.1 16

Property of Penn Engineering, Chris Murphy

Getting Started

<!DOCTYPE html>

<html>

<head>

<title>ReactJS Example</title>

<script src="react.js"></script>

<script src="react-dom.js"></script>

</head>

<body>

<div id="container"></div>

<script type="text/jsx">

<!-- Insert React code here -->

</script>

</body>

</html>

• Create a div in the HTML to represent the location where the React component will be placed

• Write JavaScript code to create and display component in div

SD4x-3.1 17

Property of Penn Engineering, Chris Murphy

Getting Started

<!DOCTYPE html>

<html>

<head>

<title>ReactJS Example</title>

<script src="react.js"></script>

<script src="react-dom.js"></script>

</head>

<body>

<div id="container"></div>

<script type="text/jsx">

<!-- Insert React code here -->

</script>

</body>

</html>

• Create a div in the HTML to represent the location where the React component will be placed

• Write JavaScript code to create and display component in div

SD4x-3.1 18

Property of Penn Engineering, Chris Murphy

Getting Started

<!DOCTYPE html>

<html>

<head>

<title>ReactJS Example</title>

<script src="react.js"></script>

<script src="react-dom.js"></script>

</head>

<body>

<div id="container"></div>

<script type="text/jsx">

<!-- Insert React code here -->

</script>

</body>

</html>

• Create a div in the HTML to represent the location where the React component will be placed

• Write JavaScript code to create and display component in div

SD4x-3.1 19

Property of Penn Engineering, Chris Murphy

Getting Started

<!DOCTYPE html>

<html>

<head>

<title>ReactJS Example</title>

<script src="react.js"></script>

<script src="react-dom.js"></script>

</head>

<body>

<div id="container"></div>

<script type="text/jsx">

<!-- Insert React code here -->

</script>

</body>

</html>

• Create a div in the HTML to represent the location where the React component will be placed

• Write JavaScript code to create and display component in div

SD4x-3.1 20

Property of Penn Engineering, Chris Murphy

Getting Started

<!DOCTYPE html>

<html>

<head>

<title>ReactJS Example</title>

<script src="react.js"></script>

<script src="react-dom.js"></script>

</head>

<body>

<div id="container"></div>

<script type="text/jsx">

<!-- Insert React code here -->

</script>

</body>

</html>

• Create a div in the HTML to represent the location where the React component will be placed

• Write JavaScript code to create and display component in div

SD4x-3.1 21

Property of Penn Engineering, Chris Murphy

Getting Started

<!DOCTYPE html>

<html>

<head>

<title>ReactJS Example</title>

<script src="react.js"></script>

<script src="react-dom.js"></script>

</head>

<body>

<div id="container"></div>

<script type="text/jsx">

<!-- Insert React code here -->

</script>

</body>

</html>

• Create a div in the HTML to represent the location where the React component will be placed

• Write JavaScript code to create and display component in div

SD4x-3.1 22

Property of Penn Engineering, Chris Murphy

Getting Started

<!DOCTYPE html>

<html>

<head>

<title>ReactJS Example</title>

<script src="react.js"></script>

<script src="react-dom.js"></script>

</head>

<body>

<div id="container"></div>

<script type="text/jsx">

<!-- Insert React code here -->

</script>

</body>

</html>

• Create a div in the HTML to represent the location where the React component will be placed

• Write JavaScript code to create and display component in div

SD4x-3.1 23

Property of Penn Engineering, Chris Murphy

JSX

• JSX – JavaScript XML Syntax Transform

• Allows user to write HTML-like tags within JavaScript

• Converts text (HTML) to React code

SD4x-3.1 24

Property of Penn Engineering, Chris Murphy

Rendering Elements using JSX

<div id="container"></div>

<script type='text/jsx'>

ReactDOM.render(

<h1>Hello, World!</h1>,

document.getElementById('container')

);

</script>

SD4x-3.1 25

Property of Penn Engineering, Chris Murphy

Rendering Elements using JSX

<div id="container"></div>

<script type='text/jsx'>

ReactDOM.render(

<h1>Hello, World!</h1>,

document.getElementById('container')

);

</script>

SD4x-3.1 26

Property of Penn Engineering, Chris Murphy

Rendering Elements using JSX

<div id="container"></div>

<script type='text/jsx'>

ReactDOM.render(

<h1>Hello, World!</h1>,

document.getElementById('container')

);

</script>

SD4x-3.1 27

Property of Penn Engineering, Chris Murphy

Rendering Elements using JSX

<div id="container"></div>

<script type='text/jsx'>

ReactDOM.render(

<h1>Hello, World!</h1>,

document.getElementById('container')

);

</script>

SD4x-3.1 28

Property of Penn Engineering, Chris Murphy

Rendering Elements using JSX

<div id="container"></div>

<script type='text/jsx'>

ReactDOM.render(

<h1>Hello, World!</h1>,

document.getElementById('container')

);

</script>

SD4x-3.1 29

Property of Penn Engineering, Chris Murphy

Rendering Elements using JSX

<div id="container"></div>

<script type='text/jsx'>

ReactDOM.render(

<h1>Hello, World!</h1>,

document.getElementById('container')

);

</script>

SD4x-3.1 30

Property of Penn Engineering, Chris Murphy

Hello, React!

SD4x-3.1 31

<!DOCTYPE html>

<html>

<head>

<title>ReactJS Example</title>

<script src="react.js"></script>

<script src="react-dom.js"></script>

</head>

<body>

<div id='container'></div>

<script type='text/jsx'>

ReactDOM.render(

<h1> Hello, React! </h1>,

document.getElementById('container')

);

</script>

</body>

</html>

Property of Penn Engineering, Chris Murphy

Hello, React!

SD4x-3.1 32

<!DOCTYPE html>

<html>

<head>

<title>ReactJS Example</title>

<script src="react.js"></script>

<script src="react-dom.js"></script>

</head>

<body>

<div id='container'></div>

<script type='text/jsx'>

ReactDOM.render(

<h1> Hello, React! </h1>,

document.getElementById('container')

);

</script>

</body>

</html>

Property of Penn Engineering, Chris Murphy

Hello, React!

SD4x-3.1 33

<!DOCTYPE html>

<html>

<head>

<title>ReactJS Example</title>

<script src="react.js"></script>

<script src="react-dom.js"></script>

</head>

<body>

<div id='container'></div>

<script type='text/jsx'>

ReactDOM.render(

<h1> Hello, React! </h1>,

document.getElementById('container')

);

</script>

</body>

</html>

Property of Penn Engineering, Chris Murphy

Hello, React!

SD4x-3.1 34

<!DOCTYPE html>

<html>

<head>

<title>ReactJS Example</title>

<script src="react.js"></script>

<script src="react-dom.js"></script>

</head>

<body>

<div id='container'></div>

<script type='text/jsx'>

ReactDOM.render(

<h1> Hello, React! </h1>,

document.getElementById('container')

);

</script>

</body>

</html>

Property of Penn Engineering, Chris Murphy

Hello, React!

SD4x-3.1 35

<!DOCTYPE html>

<html>

<head>

<title>ReactJS Example</title>

<script src="react.js"></script>

<script src="react-dom.js"></script>

</head>

<body>

<div id='container'></div>

<script type='text/jsx'>

ReactDOM.render(

<h1> Hello, React! </h1>,

document.getElementById('container')

);

</script>

</body>

</html>

Property of Penn Engineering, Chris Murphy

Hello, React!

SD4x-3.1 36

<!DOCTYPE html>

<html>

<head>

<title>ReactJS Example</title>

<script src="react.js"></script>

<script src="react-dom.js"></script>

</head>

<body>

<div id='container'></div>

<script type='text/jsx'>

ReactDOM.render(

<h1> Hello, React! </h1>,

document.getElementById('container')

);

</script>

</body>

</html>

Property of Penn Engineering, Chris Murphy

Hello, React!

SD4x-3.1 37

<!DOCTYPE html>

<html>

<head>

<title>ReactJS Example</title>

<script src="react.js"></script>

<script src="react-dom.js"></script>

</head>

<body>

<div id='container'></div>

<script type='text/jsx'>

ReactDOM.render(

<h1> Hello, React! </h1>,

document.getElementById('container')

);

</script>

</body>

</html>

Property of Penn Engineering, Chris Murphy

Looking Ahead

• Defining React components

• Reacting to user events

• Interaction between React components

• Developing large applications with React

SD4x-3.1 38

Property of Penn Engineering, Chris Murphy

Looking Ahead

• Defining React components

• Reacting to user events

• Interaction between React components

• Developing large applications with React

SD4x-3.1 39

Video 3.2

React Components

Chris Murphy

SD4x-3.2 40

Property of Penn Engineering, Chris Murphy

Review

• React allows us to create custom components and insert them into the VirtualDOM in our HTML page

• This allows for selective rendering and modular development of dynamic behavior

SD4x-3.2 41

Property of Penn Engineering, Chris Murphy

React Components

• Components are JavaScript objects based off the React.Component prototype

• Components define properties, event-based state variables, and callback functions

• A component’s render() function is used to render its HTML

• VirtualDOM manages each component’s lifecycle and calls its render() function as needed

SD4x-3.2 42

Property of Penn Engineering, Chris Murphy

Creating React Components

• React.createClass() allows us to define a component

• This function takes an object containing the component’s specifications as an argument:

var HelloComponent = React.createClass ({

render: function() {

return (

<h1>Hello, React!</h1>

);

}

});

SD4x-3.2 43

Property of Penn Engineering, Chris Murphy

Creating React Components

• React.createClass() allows us to define a component

• This function takes an object containing the component’s specifications as an argument:

var HelloComponent = React.createClass ({

render: function() {

return (

<h1>Hello, React!</h1>

);

}

});

SD4x-3.2 44

Property of Penn Engineering, Chris Murphy

Creating React Components

• React.createClass() allows us to define a component

• This function takes an object containing the component’s specifications as an argument:

var HelloComponent = React.createClass ({

render: function() {

return (

<h1>Hello, React!</h1>

);

}

});

SD4x-3.2 45

Property of Penn Engineering, Chris Murphy

Creating React Components

• React.createClass() allows us to define a component

• This function takes an object containing the component’s specifications as an argument:

var HelloComponent = React.createClass ({

render: function() {

return (

<h1>Hello, React!</h1>

);

}

});

SD4x-3.2 46

Property of Penn Engineering, Chris Murphy

Creating React Components

• React.createClass() allows us to define a component

• This function takes an object containing the component’s specifications as an argument:

var HelloComponent = React.createClass ({

render: function() {

return (

<h1>Hello, React!</h1>

);

}

});

SD4x-3.2 47

Property of Penn Engineering, Chris Murphy

Creating React Components

• React.createClass() allows us to define a component

• This function takes an object containing the component’s specifications as an argument:

var HelloComponent = React.createClass ({

render: function() {

return (

<h1>Hello, React!</h1>

);

}

});

SD4x-3.2 48

Property of Penn Engineering, Chris Murphy

Creating React Components

• React.createClass() allows us to define a component

• This function takes an object containing the component’s specifications as an argument:

var HelloComponent = React.createClass ({

render: function() {

return (

<h1>Hello, React!</h1>

);

}

});

SD4x-3.2 49

Property of Penn Engineering, Chris Murphy

Creating React Components

• React.createClass() allows us to define a component

• This function takes an object containing the component’s specifications as an argument:

var HelloComponent = React.createClass ({

render: function() {

return (

<h1>Hello, React!</h1>

);

}

});

SD4x-3.2 50

Property of Penn Engineering, Chris Murphy

Creating React Components

• React.createClass() allows us to define a component

• This function takes an object containing the component’s specifications as an argument:

• Once we create the custom component, we can render it in the same way as HTML elements

var HelloComponent = React.createClass ({

render: function() {

return (

<h1>Hello, React!</h1>

);

}

});

ReactDOM.render(

<HelloComponent />,

document.getElementById('container')

);

SD4x-3.2 51

Property of Penn Engineering, Chris Murphy

Creating React Components

• React.createClass() allows us to define a component

• This function takes an object containing the component’s specifications as an argument:

• Once we create the custom component, we can render it in the same way as HTML elements

var HelloComponent = React.createClass ({

render: function() {

return (

<h1>Hello, React!</h1>

);

}

});

ReactDOM.render(

<HelloComponent />,

document.getElementById('container')

);

SD4x-3.2 52

Property of Penn Engineering, Chris Murphy

Creating React Components

• React.createClass() allows us to define a component

• This function takes an object containing the component’s specifications as an argument:

• Once we create the custom component, we can render it in the same way as HTML elements

var HelloComponent = React.createClass ({

render: function() {

return (

<h1>Hello, React!</h1>

);

}

});

ReactDOM.render(

<HelloComponent />,

document.getElementById('container')

);

SD4x-3.2 53

Property of Penn Engineering, Chris Murphy

Creating React Components

• React.createClass() allows us to define a component

• This function takes an object containing the component’s specifications as an argument:

• Once we create the custom component, we can render it in the same way as HTML elements

var HelloComponent = React.createClass ({

render: function() {

return (

<h1>Hello, React!</h1>

);

}

});

ReactDOM.render(

<HelloComponent />,

document.getElementById('container')

);

SD4x-3.2 54

Property of Penn Engineering, Chris Murphy

Creating React Components

• React.createClass() allows us to define a component

• This function takes an object containing the component’s specifications as an argument:

• Once we create the custom component, we can render it in the same way as HTML elements

var HelloComponent = React.createClass ({

render: function() {

return (

<h1>Hello, React!</h1>

);

}

});

ReactDOM.render(

<HelloComponent />,

document.getElementById('container')

);

SD4x-3.2 55

Property of Penn Engineering, Chris Murphy

Creating Custom Components – ES6

• ES6 is a more recent version of JavaScript syntax

• We can define a class instead of a single object

class HelloComponent extends React.Component {

render() {

return (

<h1>Hello, React!</h1>

);

}

}

ReactDOM.render(

<HelloComponent />,

document.getElementById('container')

);

SD4x-3.2 56

Property of Penn Engineering, Chris Murphy

Creating Custom Components – ES6

• ES6 is a more recent version of JavaScript syntax

• We can define a class instead of a single object

class HelloComponent extends React.Component {

render() {

return (

<h1>Hello, React!</h1>

);

}

}

ReactDOM.render(

<HelloComponent />,

document.getElementById('container')

);

SD4x-3.2 57

Property of Penn Engineering, Chris Murphy

Creating Custom Components – ES6

• ES6 is a more recent version of JavaScript syntax

• We can define a class instead of a single object

class HelloComponent extends React.Component {

render() {

return (

<h1>Hello, React!</h1>

);

}

}

ReactDOM.render(

<HelloComponent />,

document.getElementById('container')

);

SD4x-3.2 58

Property of Penn Engineering, Chris Murphy

Creating Custom Components – ES6

• ES6 is a more recent version of JavaScript syntax

• We can define a class instead of a single object

class HelloComponent extends React.Component {

render() {

return (

<h1>Hello, React!</h1>

);

}

}

ReactDOM.render(

<HelloComponent />,

document.getElementById('container')

);

SD4x-3.2 59

Property of Penn Engineering, Chris Murphy

Creating Custom Components – ES6

• ES6 is a more recent version of JavaScript syntax

• We can define a class instead of a single object

class HelloComponent extends React.Component {

render() {

return (

<h1>Hello, React!</h1>

);

}

}

ReactDOM.render(

<HelloComponent />,

document.getElementById('container')

);

SD4x-3.2 60

Property of Penn Engineering, Chris Murphy

Creating Custom Components – ES6

• ES6 is a more recent version of JavaScript syntax

• We can define a class instead of a single object

class HelloComponent extends React.Component {

render() {

return (

<h1>Hello, React!</h1>

);

}

}

ReactDOM.render(

<HelloComponent />,

document.getElementById('container')

);

SD4x-3.2 61

Property of Penn Engineering, Chris Murphy

React Component Attributes

• Properties

• Attributes and values that are set when the component is created

• Should never be modified after initialization

SD4x-3.2 62

Property of Penn Engineering, Chris Murphy

React Component Attributes

• Properties

• Attributes and values that are set when the component is created

• Should never be modified after initialization

• State

• Attributes and values that represent the current state of the component, based on what it does/represents

• Can be modified during the component’s lifecycle

SD4x-3.2 63

Property of Penn Engineering, Chris Murphy

React Component Attributes

• Properties

• Attributes and values that are set when the component is created

• Should never be modified after initialization

• State

• Attributes and values that represent the current state of the component, based on what it does/represents

• Can be modified during the component’s lifecycle

• Both properties and state can be used when rendering the component

SD4x-3.2 64

Property of Penn Engineering, Chris Murphy

Component Properties

• Should always be assigned upon object creation, never modified afterward

• Component accesses its properties through this.props

SD4x-3.2 65

Property of Penn Engineering, Chris Murphy

Component Properties

• Should always be assigned upon object creation, never modified afterward

• Component accesses its properties through this.props

ReactDOM.render(

<HelloUser name="Maria" />,

document.getElementById('container')

);

SD4x-3.2 66

Property of Penn Engineering, Chris Murphy

Component Properties

• Should always be assigned upon object creation, never modified afterward

• Component accesses its properties through this.props

ReactDOM.render(

<HelloUser name="Maria" />,

document.getElementById('container')

);

SD4x-3.2 67

Property of Penn Engineering, Chris Murphy

Component Properties

• Should always be assigned upon object creation, never modified afterward

• Component accesses its properties through this.props

ReactDOM.render(

<HelloUser name="Maria" />,

document.getElementById('container')

);

SD4x-3.2 68

Property of Penn Engineering, Chris Murphy

Component Properties

• Should always be assigned upon object creation, never modified afterward

• Component accesses its properties through this.props

class HelloUser extends React.Component {

render() {

return (

<h1>Hello {this.props.name}!</h1>

);

}

}

ReactDOM.render(

<HelloUser name="Maria" />,

document.getElementById('container')

);

SD4x-3.2 69

Property of Penn Engineering, Chris Murphy

Component Properties

• Should always be assigned upon object creation, never modified afterward

• Component accesses its properties through this.props

class HelloUser extends React.Component {

render() {

return (

<h1>Hello {this.props.name}!</h1>

);

}

}

ReactDOM.render(

<HelloUser name="Maria" />,

document.getElementById('container')

);

SD4x-3.2 70

Property of Penn Engineering, Chris Murphy

Component Properties

• Should always be assigned upon object creation, never modified afterward

• Component accesses its properties through this.props

class HelloUser extends React.Component {

render() {

return (

<h1>Hello {this.props.name}!</h1>

);

}

}

ReactDOM.render(

<HelloUser name="Maria" />,

document.getElementById('container')

);

SD4x-3.2 71

Property of Penn Engineering, Chris Murphy

Component Properties

• Should always be assigned upon object creation, never modified afterward

• Component accesses its properties through this.props

class HelloUser extends React.Component {

render() {

return (

<h1>Hello {this.props.name}!</h1>

);

}

}

ReactDOM.render(

<HelloUser name="Maria" />,

document.getElementById('container')

);

SD4x-3.2 72

Property of Penn Engineering, Chris Murphy

Component Properties

• Should always be assigned upon object creation, never modified afterward

• Component accesses its properties through this.props

class HelloUser extends React.Component {

render() {

return (

<h1>Hello {this.props.name}!</h1>

);

}

}

ReactDOM.render(

<HelloUser name="Maria" />,

document.getElementById('container')

);

SD4x-3.2 73

Property of Penn Engineering, Chris Murphy

Component Properties

• Should always be assigned upon object creation, never modified afterward

• Component accesses its properties through this.props

class HelloUser extends React.Component {

render() {

return (

<h1>Hello {this.props.name}!</h1>

);

}

}

ReactDOM.render(

<HelloUser name="Maria" />,

document.getElementById('container')

);

SD4x-3.2 74

Property of Penn Engineering, Chris Murphy

Component Properties

• Should always be assigned upon object creation, never modified afterward

• Component accesses its properties through this.props

class HelloUser extends React.Component {

render() {

return (

<h1>Hello {this.props.name}!</h1>

);

}

}

ReactDOM.render(

<HelloUser name="Maria" />,

document.getElementById('container')

);

SD4x-3.2 75

Property of Penn Engineering, Chris Murphy

Component Properties

• Should always be assigned upon object creation, never modified afterward

• Component accesses its properties through this.props

class HelloUser extends React.Component {

render() {

return (

<h1>Hello {this.props.name}!</h1>

);

}

}

ReactDOM.render(

<HelloUser name="Maria" />,

document.getElementById('container')

);

SD4x-3.2 76

Property of Penn Engineering, Chris Murphy

Component Properties

• Should always be assigned upon object creation, never modified afterward

• Component accesses its properties through this.props

class HelloUser extends React.Component {

render() {

return (

<h1>Hello {this.props.name}!</h1>

);

}

}

ReactDOM.render(

<HelloUser name="Maria" />,

document.getElementById('container')

);

SD4x-3.2 77

Property of Penn Engineering, Chris Murphy

Component State

• The set of variables that can change during the component’s lifecycle

• Should be initialized in the constructor

• Component accesses its state through this.state

SD4x-3.2 78

Property of Penn Engineering, Chris Murphy

class TimesViewed extends React.Component {

constructor(props) {

super(props);

var timesViewed = 0;

if (localStorage.timesViewed) {

timesViewed = localStorage.timesViewed;

}

timesViewed++;

this.state = { numViews: timesViewed };

localStorage.timesViewed = timesViewed;

}

render() {

return <b>{this.state.numViews}</b>;

}

}

ReactDOM.render(

<TimesViewed />,

document.getElementById('container')

);

SD4x-3.2 79

Property of Penn Engineering, Chris Murphy

class TimesViewed extends React.Component {

constructor(props) {

super(props);

var timesViewed = 0;

if (localStorage.timesViewed) {

timesViewed = localStorage.timesViewed;

}

timesViewed++;

this.state = { numViews: timesViewed };

localStorage.timesViewed = timesViewed;

}

render() {

return <b>{this.state.numViews}</b>;

}

}

ReactDOM.render(

<TimesViewed />,

document.getElementById('container')

);

SD4x-3.2 80

Property of Penn Engineering, Chris Murphy

class TimesViewed extends React.Component {

constructor(props) {

super(props);

var timesViewed = 0;

if (localStorage.timesViewed) {

timesViewed = localStorage.timesViewed;

}

timesViewed++;

this.state = { numViews: timesViewed };

localStorage.timesViewed = timesViewed;

}

render() {

return <b>{this.state.numViews}</b>;

}

}

ReactDOM.render(

<TimesViewed />,

document.getElementById('container')

);

SD4x-3.2 81

Property of Penn Engineering, Chris Murphy

class TimesViewed extends React.Component {

constructor(props) {

super(props);

var timesViewed = 0;

if (localStorage.timesViewed) {

timesViewed = localStorage.timesViewed;

}

timesViewed++;

this.state = { numViews: timesViewed };

localStorage.timesViewed = timesViewed;

}

render() {

return <b>{this.state.numViews}</b>;

}

}

ReactDOM.render(

<TimesViewed />,

document.getElementById('container')

);

SD4x-3.2 82

Property of Penn Engineering, Chris Murphy

class TimesViewed extends React.Component {

constructor(props) {

super(props);

var timesViewed = 0;

if (localStorage.timesViewed) {

timesViewed = localStorage.timesViewed;

}

timesViewed++;

this.state = { numViews: timesViewed };

localStorage.timesViewed = timesViewed;

}

render() {

return <b>{this.state.numViews}</b>;

}

}

ReactDOM.render(

<TimesViewed />,

document.getElementById('container')

);

SD4x-3.2 83

Property of Penn Engineering, Chris Murphy

class TimesViewed extends React.Component {

constructor(props) {

super(props);

var timesViewed = 0;

if (localStorage.timesViewed) {

timesViewed = localStorage.timesViewed;

}

timesViewed++;

this.state = { numViews: timesViewed };

localStorage.timesViewed = timesViewed;

}

render() {

return <b>{this.state.numViews}</b>;

}

}

ReactDOM.render(

<TimesViewed />,

document.getElementById('container')

);

SD4x-3.2 84

Property of Penn Engineering, Chris Murphy

class TimesViewed extends React.Component {

constructor(props) {

super(props);

var timesViewed = 0;

if (localStorage.timesViewed) {

timesViewed = localStorage.timesViewed;

}

timesViewed++;

this.state = { numViews: timesViewed };

localStorage.timesViewed = timesViewed;

}

render() {

return <b>{this.state.numViews}</b>;

}

}

ReactDOM.render(

<TimesViewed />,

document.getElementById('container')

);

SD4x-3.2 85

Property of Penn Engineering, Chris Murphy

class TimesViewed extends React.Component {

constructor(props) {

super(props);

var timesViewed = 0;

if (localStorage.timesViewed) {

timesViewed = localStorage.timesViewed;

}

timesViewed++;

this.state = { numViews: timesViewed };

localStorage.timesViewed = timesViewed;

}

render() {

return <b>{this.state.numViews}</b>;

}

}

ReactDOM.render(

<TimesViewed />,

document.getElementById('container')

);

SD4x-3.2 86

Property of Penn Engineering, Chris Murphy

class TimesViewed extends React.Component {

constructor(props) {

super(props);

var timesViewed = 0;

if (localStorage.timesViewed) {

timesViewed = localStorage.timesViewed;

}

timesViewed++;

this.state = { numViews: timesViewed };

localStorage.timesViewed = timesViewed;

}

render() {

return <b>{this.state.numViews}</b>;

}

}

ReactDOM.render(

<TimesViewed />,

document.getElementById('container')

);

SD4x-3.2 87

Property of Penn Engineering, Chris Murphy

class TimesViewed extends React.Component {

constructor(props) {

super(props);

var timesViewed = 0;

if (localStorage.timesViewed) {

timesViewed = localStorage.timesViewed;

}

timesViewed++;

this.state = { numViews: timesViewed };

localStorage.timesViewed = timesViewed;

}

render() {

return <b>{this.state.numViews}</b>;

}

}

ReactDOM.render(

<TimesViewed />,

document.getElementById('container')

);

SD4x-3.2 88

Property of Penn Engineering, Chris Murphy

class TimesViewed extends React.Component {

constructor(props) {

super(props);

var timesViewed = 0;

if (localStorage.timesViewed) {

timesViewed = localStorage.timesViewed;

}

timesViewed++;

this.state = { numViews: timesViewed };

localStorage.timesViewed = timesViewed;

}

render() {

return <b>{this.state.numViews}</b>;

}

}

ReactDOM.render(

<TimesViewed />,

document.getElementById('container')

);

SD4x-3.2 89

Property of Penn Engineering, Chris Murphy

class TimesViewed extends React.Component {

constructor(props) {

super(props);

var timesViewed = 0;

if (localStorage.timesViewed) {

timesViewed = localStorage.timesViewed;

}

timesViewed++;

this.state = { numViews: timesViewed };

localStorage.timesViewed = timesViewed;

}

render() {

return <b>{this.state.numViews}</b>;

}

}

ReactDOM.render(

<TimesViewed />,

document.getElementById('container')

);

SD4x-3.2 90

Property of Penn Engineering, Chris Murphy

class TimesViewed extends React.Component {

constructor(props) {

super(props);

var timesViewed = 0;

if (localStorage.timesViewed) {

timesViewed = localStorage.timesViewed;

}

timesViewed++;

this.state = { numViews: timesViewed };

localStorage.timesViewed = timesViewed;

}

render() {

return <b>{this.state.numViews}</b>;

}

}

ReactDOM.render(

<TimesViewed />,

document.getElementById('container')

);

SD4x-3.2 91

Property of Penn Engineering, Chris Murphy

class TimesViewed extends React.Component {

constructor(props) {

super(props);

var timesViewed = 0;

if (localStorage.timesViewed) {

timesViewed = localStorage.timesViewed;

}

timesViewed++;

this.state = { numViews: timesViewed };

localStorage.timesViewed = timesViewed;

}

render() {

return <b>{this.state.numViews}</b>;

}

}

ReactDOM.render(

<TimesViewed />,

document.getElementById('container')

);

SD4x-3.2 92

Property of Penn Engineering, Chris Murphy

class TimesViewed extends React.Component {

constructor(props) {

super(props);

var timesViewed = 0;

if (localStorage.timesViewed) {

timesViewed = localStorage.timesViewed;

}

timesViewed++;

this.state = { numViews: timesViewed };

localStorage.timesViewed = timesViewed;

}

render() {

return <b>{this.state.numViews}</b>;

}

}

ReactDOM.render(

<TimesViewed />,

document.getElementById('container')

);

SD4x-3.2 93

Property of Penn Engineering, Chris Murphy

class TimesViewed extends React.Component {

constructor(props) {

super(props);

var timesViewed = 0;

if (localStorage.timesViewed) {

timesViewed = localStorage.timesViewed;

}

timesViewed++;

this.state = { numViews: timesViewed };

localStorage.timesViewed = timesViewed;

}

render() {

return <b>{this.state.numViews}</b>;

}

}

ReactDOM.render(

<TimesViewed />,

document.getElementById('container')

);

SD4x-3.2 94

Property of Penn Engineering, Chris Murphy

Component Lifecycle

• The React VirtualDOM invokes callback functions on components during their lifecycle

• These functions fall into three categories:

• Mounting

• Updating

• Unmounting

• You can optionally implement these for controlling the component

SD4x-3.2 95

Property of Penn Engineering, Chris Murphy

Component Lifecycle: Mounting

• Called when a component is being created and added to the VirtualDOM

• constructor: creates component, initializes state based on properties

• componentWillMount: invoked before component is added to VirtualDOM

• componentDidMount: invoked after component has been added to VirtualDOM and has been rendered

SD4x-3.2 96

Property of Penn Engineering, Chris Murphy

Component Lifecycle: Updating

• Called when a component’s props or state is changing and the component is re-rendered

• componentWillReceiveProps: invoked before receiving new props, e.g. when its parent component re-renders

• shouldComponentUpdate: can be used to determine whether to re-render

• componentWillUpdate: invoked before re-rendering after change to state

• componentDidUpdate: invoked after being re-rendered

SD4x-3.2 97

Property of Penn Engineering, Chris Murphy

Component Lifecycle: Unmounting

• Called when a component is being removed from the VirtualDOM

• componentWillUnmount: invoked before component is removed from VirtualDOM and destroyed

SD4x-3.2 98

Property of Penn Engineering, Chris Murphy

Summary

• React components are JavaScript objects that can be used as HTML elements in the VirtualDOM

• A component’s render() function is used to render its HTML

• A component’s properties are assigned when it is created

• A component’s state can change during its lifecycle

• A component’s lifecycle functions are invoked depending on relevant activities

SD4x-3.2 99

Video 3.3

React Events

Chris Murphy

SD4x-3.3 100

Property of Penn Engineering, Chris Murphy

Review

• React allows us to insert JavaScript elements/components into VirtualDOM

• We can create additional components using the React.Component class as a base

• Components have two types of attributes

• Properties: set at initialization and immutable thereafter

• State: change in response to user events

• Component callback functions can be bound to HTML events

SD4x-3.3 101

Property of Penn Engineering, Chris Murphy

Changing Component State

• A component’s state typically changes in response to some user action or “event”

• We can bind an event to a callback function within a React component

• That component can then change state using its setState function

• This will automatically re-render the component and any other affected component

SD4x-3.3 102

Property of Penn Engineering, Chris Murphy SD4x-3.3 103

Property of Penn Engineering, Chris Murphy SD4x-3.3 104

Property of Penn Engineering, Chris Murphy

class Counter extends React.Component {

constructor(props) {

super(props);

this.state = { count: 0 };

}

incrementCount() { // callback function

this.setState( { count: this.state.count + 1; } );

}

render() { // invoked when setState is called

return (

<div> Count: { this.state.count }

<button type="button"

onClick={ this.incrementCount.bind(this); } >

Increment

</button>

</div>

);

}

};

SD4x-3.3 105

Property of Penn Engineering, Chris Murphy

class Counter extends React.Component {

constructor(props) {

super(props);

this.state = { count: 0 };

}

incrementCount() { // callback function

this.setState( { count: this.state.count + 1; } );

}

render() { // invoked when setState is called

return (

<div> Count: { this.state.count }

<button type="button"

onClick={ this.incrementCount.bind(this); } >

Increment

</button>

</div>

);

}

};

SD4x-3.3 106

Property of Penn Engineering, Chris Murphy

class Counter extends React.Component {

constructor(props) {

super(props);

this.state = { count: 0 };

}

incrementCount() { // callback function

this.setState( { count: this.state.count + 1; } );

}

render() { // invoked when setState is called

return (

<div> Count: { this.state.count }

<button type="button"

onClick={ this.incrementCount.bind(this); } >

Increment

</button>

</div>

);

}

};

SD4x-3.3 107

Property of Penn Engineering, Chris Murphy

class Counter extends React.Component {

constructor(props) {

super(props);

this.state = { count: 0 };

}

incrementCount() { // callback function

this.setState( { count: this.state.count + 1; } );

}

render() { // invoked when setState is called

return (

<div> Count: { this.state.count }

<button type="button"

onClick={ this.incrementCount.bind(this); } >

Increment

</button>

</div>

);

}

};

SD4x-3.3 108

Property of Penn Engineering, Chris Murphy

class Counter extends React.Component {

constructor(props) {

super(props);

this.state = { count: 0 };

}

incrementCount() { // callback function

this.setState( { count: this.state.count + 1; } );

}

render() { // invoked when setState is called

return (

<div> Count: { this.state.count }

<button type="button"

onClick={ this.incrementCount.bind(this); } >

Increment

</button>

</div>

);

}

};

SD4x-3.3 109

Property of Penn Engineering, Chris Murphy

class Counter extends React.Component {

constructor(props) {

super(props);

this.state = { count: 0 };

}

incrementCount() { // callback function

this.setState( { count: this.state.count + 1; } );

}

render() { // invoked when setState is called

return (

<div> Count: { this.state.count }

<button type="button"

onClick={ this.incrementCount.bind(this); } >

Increment

</button>

</div>

);

}

};

SD4x-3.3 110

Property of Penn Engineering, Chris Murphy

class Counter extends React.Component {

constructor(props) {

super(props);

this.state = { count: 0 };

}

incrementCount() { // callback function

this.setState( { count: this.state.count + 1; } );

}

render() { // invoked when setState is called

return (

<div> Count: { this.state.count }

<button type="button"

onClick={ this.incrementCount.bind(this); } >

Increment

</button>

</div>

);

}

};

SD4x-3.3 111

Property of Penn Engineering, Chris Murphy

class Counter extends React.Component {

constructor(props) {

super(props);

this.state = { count: 0 };

}

incrementCount() { // callback function

this.setState( { count: this.state.count + 1; } );

}

render() { // invoked when setState is called

return (

<div> Count: { this.state.count }

<button type="button"

onClick={ this.incrementCount.bind(this); } >

Increment

</button>

</div>

);

}

};

SD4x-3.3 112

Property of Penn Engineering, Chris Murphy

class Counter extends React.Component {

constructor(props) {

super(props);

this.state = { count: 0 };

}

incrementCount() { // callback function

this.setState( { count: this.state.count + 1; } );

}

render() { // invoked when setState is called

return (

<div> Count: { this.state.count }

<button type="button"

onClick={ this.incrementCount.bind(this); } >

Increment

</button>

</div>

);

}

};

SD4x-3.3 113

Property of Penn Engineering, Chris Murphy

class Counter extends React.Component {

constructor(props) {

super(props);

this.state = { count: 0 };

}

incrementCount() { // callback function

this.setState( { count: this.state.count + 1; } );

}

render() { // invoked when setState is called

return (

<div> Count: { this.state.count }

<button type="button"

onClick={ this.incrementCount.bind(this); } >

Increment

</button>

</div>

);

}

};

SD4x-3.3 114

Property of Penn Engineering, Chris Murphy

class Counter extends React.Component {

constructor(props) {

super(props);

this.state = { count: 0 };

}

incrementCount() { // callback function

this.setState( { count: this.state.count + 1; } );

}

render() { // invoked when setState is called

return (

<div> Count: { this.state.count }

<button type="button"

onClick={ this.incrementCount.bind(this); } >

Increment

</button>

</div>

);

}

};

SD4x-3.3 115

Property of Penn Engineering, Chris Murphy

class Counter extends React.Component {

constructor(props) {

super(props);

this.state = { count: 0 };

}

incrementCount() { // callback function

this.setState( { count: this.state.count + 1; } );

}

render() { // invoked when setState is called

return (

<div> Count: { this.state.count }

<button type="button"

onClick={ this.incrementCount.bind(this); } >

Increment

</button>

</div>

);

}

};

SD4x-3.3 116

Property of Penn Engineering, Chris Murphy

class Counter extends React.Component {

constructor(props) {

super(props);

this.state = { count: 0 };

}

incrementCount() { // callback function

this.setState( { count: this.state.count + 1; } );

}

render() { // invoked when setState is called

return (

<div> Count: { this.state.count }

<button type="button"

onClick={ this.incrementCount.bind(this); } >

Increment

</button>

</div>

);

}

};

SD4x-3.3 117

Property of Penn Engineering, Chris Murphy

class Counter extends React.Component {

constructor(props) {

super(props);

this.state = { count: 0 };

}

incrementCount() { // callback function

this.setState( { count: this.state.count + 1; } );

}

render() { // invoked when setState is called

return (

<div> Count: { this.state.count }

<button type="button"

onClick={ this.incrementCount.bind(this); } >

Increment

</button>

</div>

);

}

};

SD4x-3.3 118

Property of Penn Engineering, Chris Murphy

class Counter extends React.Component {

constructor(props) {

super(props);

this.state = { count: 0 };

}

incrementCount() { // callback function

this.setState( { count: this.state.count + 1; } );

}

render() { // invoked when setState is called

return (

<div> Count: { this.state.count }

<button type="button"

onClick={ this.incrementCount.bind(this); } >

Increment

</button>

</div>

);

}

};

SD4x-3.3 119

Property of Penn Engineering, Chris Murphy

class Counter extends React.Component {

constructor(props) {

super(props);

this.state = { count: 0 };

}

incrementCount() { // callback function

this.setState( { count: this.state.count + 1; } );

}

render() { // invoked when setState is called

return (

<div> Count: { this.state.count }

<button type="button"

onClick={ this.incrementCount.bind(this); } >

Increment

</button>

</div>

);

}

};

SD4x-3.3 120

Property of Penn Engineering, Chris Murphy

class Counter extends React.Component {

constructor(props) {

super(props);

this.state = { count: 0 };

}

incrementCount() { // callback function

this.setState( { count: this.state.count + 1; } );

}

render() { // invoked when setState is called

return (

<div> Count: { this.state.count }

<button type="button"

onClick={ this.incrementCount.bind(this); } >

Increment

</button>

</div>

);

}

};

SD4x-3.3 121

Property of Penn Engineering, Chris Murphy SD4x-3.3 122

Property of Penn Engineering, Chris Murphy SD4x-3.3 123

Property of Penn Engineering, Chris Murphy SD4x-3.3 124

Property of Penn Engineering, Chris Murphy SD4x-3.3 125

Property of Penn Engineering, Chris Murphy SD4x-3.3 126

Property of Penn Engineering, Chris Murphy SD4x-3.3 127

Property of Penn Engineering, Chris Murphy SD4x-3.3 128

Property of Penn Engineering, Chris Murphy

ReactDOM.render(

<div>

<LikeButton name="Java" />

<LikeButton name="JavaScript" />

</div>,

document.getElementById('container'));

SD4x-3.3 129

Property of Penn Engineering, Chris Murphy

ReactDOM.render(

<div>

<LikeButton name="Java" />

<LikeButton name="JavaScript" />

</div>,

document.getElementById('container'));

SD4x-3.3 130

Property of Penn Engineering, Chris Murphy

ReactDOM.render(

<div>

<LikeButton name="Java" />

<LikeButton name="JavaScript" />

</div>,

document.getElementById('container'));

SD4x-3.3 131

Property of Penn Engineering, Chris Murphy

ReactDOM.render(

<div>

<LikeButton name="Java" />

<LikeButton name="JavaScript" />

</div>,

document.getElementById('container'));

SD4x-3.3 132

Property of Penn Engineering, Chris Murphy

ReactDOM.render(

<div>

<LikeButton name="Java" />

<LikeButton name="JavaScript" />

</div>,

document.getElementById('container'));

SD4x-3.3 133

Property of Penn Engineering, Chris Murphy

ReactDOM.render(

<div>

<LikeButton name="Java" />

<LikeButton name="JavaScript" />

</div>,

document.getElementById('container'));

SD4x-3.3 134

Property of Penn Engineering, Chris Murphy

class LikeButton extends React.Component {

constructor(props) {

super(props);

this.state = { liked : false };

}

toggle() {

this.setState( {liked: !this.state.liked} );

}

render() {

var name = this.props.name;

var txt = this.state.liked ? 'Unlike' : 'Like';

var myColor = this.state.liked ? 'red' : 'black';

var weight = this.state.liked ? 'bold' : 'normal';

return (

<p><span style={{color:myColor, fontWeight:weight }}>

{name} </span>

<span onClick={this.toggle.bind(this)}>

{'\ud83d\udc4d' + txt}

</span> </p> );

}

};

SD4x-3.3 135

Property of Penn Engineering, Chris Murphy

class LikeButton extends React.Component {

constructor(props) {

super(props);

this.state = { liked : false };

}

toggle() {

this.setState( {liked: !this.state.liked} );

}

render() {

var name = this.props.name;

var txt = this.state.liked ? 'Unlike' : 'Like';

var myColor = this.state.liked ? 'red' : 'black';

var weight = this.state.liked ? 'bold' : 'normal';

return (

<p><span style={{color:myColor, fontWeight:weight }}>

{name} </span>

<span onClick={this.toggle.bind(this)}>

{'\ud83d\udc4d' + txt}

</span> </p> );

}

};

SD4x-3.3 136

Property of Penn Engineering, Chris Murphy

class LikeButton extends React.Component {

constructor(props) {

super(props);

this.state = { liked : false };

}

toggle() {

this.setState( {liked: !this.state.liked} );

}

render() {

var name = this.props.name;

var txt = this.state.liked ? 'Unlike' : 'Like';

var myColor = this.state.liked ? 'red' : 'black';

var weight = this.state.liked ? 'bold' : 'normal';

return (

<p><span style={{color:myColor, fontWeight:weight }}>

{name} </span>

<span onClick={this.toggle.bind(this)}>

{'\ud83d\udc4d' + txt}

</span> </p> );

}

};

SD4x-3.3 137

Property of Penn Engineering, Chris Murphy

class LikeButton extends React.Component {

constructor(props) {

super(props);

this.state = { liked : false };

}

toggle() {

this.setState( {liked: !this.state.liked} );

}

render() {

var name = this.props.name;

var txt = this.state.liked ? 'Unlike' : 'Like';

var myColor = this.state.liked ? 'red' : 'black';

var weight = this.state.liked ? 'bold' : 'normal';

return (

<p><span style={{color:myColor, fontWeight:weight }}>

{name} </span>

<span onClick={this.toggle.bind(this)}>

{'\ud83d\udc4d' + txt}

</span> </p> );

}

};

SD4x-3.3 138

Property of Penn Engineering, Chris Murphy

class LikeButton extends React.Component {

constructor(props) {

super(props);

this.state = { liked : false };

}

toggle() {

this.setState( {liked: !this.state.liked} );

}

render() {

var name = this.props.name;

var txt = this.state.liked ? 'Unlike' : 'Like';

var myColor = this.state.liked ? 'red' : 'black';

var weight = this.state.liked ? 'bold' : 'normal';

return (

<p><span style={{color:myColor, fontWeight:weight }}>

{name} </span>

<span onClick={this.toggle.bind(this)}>

{'\ud83d\udc4d' + txt}

</span> </p> );

}

};

SD4x-3.3 139

Property of Penn Engineering, Chris Murphy

class LikeButton extends React.Component {

constructor(props) {

super(props);

this.state = { liked : false };

}

toggle() {

this.setState( {liked: !this.state.liked} );

}

render() {

var name = this.props.name;

var txt = this.state.liked ? 'Unlike' : 'Like';

var myColor = this.state.liked ? 'red' : 'black';

var weight = this.state.liked ? 'bold' : 'normal';

return (

<p><span style={{color:myColor, fontWeight:weight }}>

{name} </span>

<span onClick={this.toggle.bind(this)}>

{'\ud83d\udc4d' + txt}

</span> </p> );

}

};

SD4x-3.3 140

Property of Penn Engineering, Chris Murphy

class LikeButton extends React.Component {

constructor(props) {

super(props);

this.state = { liked : false };

}

toggle() {

this.setState( {liked: !this.state.liked} );

}

render() {

var name = this.props.name;

var txt = this.state.liked ? 'Unlike' : 'Like';

var myColor = this.state.liked ? 'red' : 'black';

var weight = this.state.liked ? 'bold' : 'normal';

return (

<p><span style={{color:myColor, fontWeight:weight }}>

{name} </span>

<span onClick={this.toggle.bind(this)}>

{'\ud83d\udc4d' + txt}

</span> </p> );

}

};

SD4x-3.3 141

Property of Penn Engineering, Chris Murphy

class LikeButton extends React.Component {

constructor(props) {

super(props);

this.state = { liked : false };

}

toggle() {

this.setState( {liked: !this.state.liked} );

}

render() {

var name = this.props.name;

var txt = this.state.liked ? 'Unlike' : 'Like';

var myColor = this.state.liked ? 'red' : 'black';

var weight = this.state.liked ? 'bold' : 'normal';

return (

<p><span style={{color:myColor, fontWeight:weight }}>

{name} </span>

<span onClick={this.toggle.bind(this)}>

{'\ud83d\udc4d' + txt}

</span> </p> );

}

};

SD4x-3.3 142

Property of Penn Engineering, Chris Murphy

class LikeButton extends React.Component {

constructor(props) {

super(props);

this.state = { liked : false };

}

toggle() {

this.setState( {liked: !this.state.liked} );

}

render() {

var name = this.props.name;

var txt = this.state.liked ? 'Unlike' : 'Like';

var myColor = this.state.liked ? 'red' : 'black';

var weight = this.state.liked ? 'bold' : 'normal';

return (

<p><span style={{color:myColor, fontWeight:weight }}>

{name} </span>

<span onClick={this.toggle.bind(this)}>

{'\ud83d\udc4d' + txt}

</span> </p> );

}

};

SD4x-3.3 143

Property of Penn Engineering, Chris Murphy

class LikeButton extends React.Component {

constructor(props) {

super(props);

this.state = { liked : false };

}

toggle() {

this.setState( {liked: !this.state.liked} );

}

render() {

var name = this.props.name;

var txt = this.state.liked ? 'Unlike' : 'Like';

var myColor = this.state.liked ? 'red' : 'black';

var weight = this.state.liked ? 'bold' : 'normal';

return (

<p><span style={{color:myColor, fontWeight:weight }}>

{name} </span>

<span onClick={this.toggle.bind(this)}>

{'\ud83d\udc4d' + txt}

</span> </p> );

}

};

SD4x-3.3 144

Property of Penn Engineering, Chris Murphy

class LikeButton extends React.Component {

constructor(props) {

super(props);

this.state = { liked : false };

}

toggle() {

this.setState( {liked: !this.state.liked} );

}

render() {

var name = this.props.name;

var txt = this.state.liked ? 'Unlike' : 'Like';

var myColor = this.state.liked ? 'red' : 'black';

var weight = this.state.liked ? 'bold' : 'normal';

return (

<p><span style={{color:myColor, fontWeight:weight }}>

{name} </span>

<span onClick={this.toggle.bind(this)}>

{'\ud83d\udc4d' + txt}

</span> </p> );

}

};

SD4x-3.3 145

Property of Penn Engineering, Chris Murphy

class LikeButton extends React.Component {

constructor(props) {

super(props);

this.state = { liked : false };

}

toggle() {

this.setState( {liked: !this.state.liked} );

}

render() {

var name = this.props.name;

var txt = this.state.liked ? 'Unlike' : 'Like';

var myColor = this.state.liked ? 'red' : 'black';

var weight = this.state.liked ? 'bold' : 'normal';

return (

<p><span style={{color:myColor, fontWeight:weight }}>

{name} </span>

<span onClick={this.toggle.bind(this)}>

{'\ud83d\udc4d' + txt}

</span> </p> );

}

};

SD4x-3.3 146

Property of Penn Engineering, Chris Murphy

class LikeButton extends React.Component {

constructor(props) {

super(props);

this.state = { liked : false };

}

toggle() {

this.setState( {liked: !this.state.liked} );

}

render() {

var name = this.props.name;

var txt = this.state.liked ? 'Unlike' : 'Like';

var myColor = this.state.liked ? 'red' : 'black';

var weight = this.state.liked ? 'bold' : 'normal';

return (

<p><span style={{color:myColor, fontWeight:weight }}>

{name} </span>

<span onClick={this.toggle.bind(this)}>

{'\ud83d\udc4d' + txt}

</span> </p> );

}

};

SD4x-3.3 147

Property of Penn Engineering, Chris Murphy

class LikeButton extends React.Component {

constructor(props) {

super(props);

this.state = { liked : false };

}

toggle() {

this.setState( {liked: !this.state.liked} );

}

render() {

var name = this.props.name;

var txt = this.state.liked ? 'Unlike' : 'Like';

var myColor = this.state.liked ? 'red' : 'black';

var weight = this.state.liked ? 'bold' : 'normal';

return (

<p><span style={{color:myColor, fontWeight:weight }}>

{name} </span>

<span onClick={this.toggle.bind(this)}>

{'\ud83d\udc4d' + txt}

</span> </p> );

}

};

SD4x-3.3 148

Property of Penn Engineering, Chris Murphy

class LikeButton extends React.Component {

constructor(props) {

super(props);

this.state = { liked : false };

}

toggle() {

this.setState( {liked: !this.state.liked} );

}

render() {

var name = this.props.name;

var txt = this.state.liked ? 'Unlike' : 'Like';

var myColor = this.state.liked ? 'red' : 'black';

var weight = this.state.liked ? 'bold' : 'normal';

return (

<p><span style={{color:myColor, fontWeight:weight }}>

{name} </span>

<span onClick={this.toggle.bind(this)}>

{'\ud83d\udc4d' + txt}

</span> </p> );

}

};

SD4x-3.3 149

Property of Penn Engineering, Chris Murphy

class LikeButton extends React.Component {

constructor(props) {

super(props);

this.state = { liked : false };

}

toggle() {

this.setState( {liked: !this.state.liked} );

}

render() {

var name = this.props.name;

var txt = this.state.liked ? 'Unlike' : 'Like';

var myColor = this.state.liked ? 'red' : 'black';

var weight = this.state.liked ? 'bold' : 'normal';

return (

<p><span style={{color:myColor, fontWeight:weight }}>

{name} </span>

<span onClick={this.toggle.bind(this)}>

{'\ud83d\udc4d' + txt}

</span> </p> );

}

};

SD4x-3.3 150

Property of Penn Engineering, Chris Murphy

class LikeButton extends React.Component {

constructor(props) {

super(props);

this.state = { liked : false };

}

toggle() {

this.setState( {liked: !this.state.liked} );

}

render() {

var name = this.props.name;

var txt = this.state.liked ? 'Unlike' : 'Like';

var myColor = this.state.liked ? 'red' : 'black';

var weight = this.state.liked ? 'bold' : 'normal';

return (

<p><span style={{color:myColor, fontWeight:weight }}>

{name} </span>

<span onClick={this.toggle.bind(this)}>

{'\ud83d\udc4d' + txt}

</span> </p> );

}

};

SD4x-3.3 151

Property of Penn Engineering, Chris Murphy

class LikeButton extends React.Component {

constructor(props) {

super(props);

this.state = { liked : false };

}

toggle() {

this.setState( {liked: !this.state.liked} );

}

render() {

var name = this.props.name;

var txt = this.state.liked ? 'Unlike' : 'Like';

var myColor = this.state.liked ? 'red' : 'black';

var weight = this.state.liked ? 'bold' : 'normal';

return (

<p><span style={{color:myColor, fontWeight:weight }}>

{name} </span>

<span onClick={this.toggle.bind(this)}>

{'\ud83d\udc4d' + txt}

</span> </p> );

}

};

SD4x-3.3 152

Property of Penn Engineering, Chris Murphy

class LikeButton extends React.Component {

constructor(props) {

super(props);

this.state = { liked : false };

}

toggle() {

this.setState( {liked: !this.state.liked} );

}

render() {

var name = this.props.name;

var txt = this.state.liked ? 'Unlike' : 'Like';

var myColor = this.state.liked ? 'red' : 'black';

var weight = this.state.liked ? 'bold' : 'normal';

return (

<p><span style={{color:myColor, fontWeight:weight }}>

{name} </span>

<span onClick={this.toggle.bind(this)}>

{'\ud83d\udc4d' + txt}

</span> </p> );

}

};

SD4x-3.3 153

Property of Penn Engineering, Chris Murphy

class LikeButton extends React.Component {

constructor(props) {

super(props);

this.state = { liked : false };

}

toggle() {

this.setState( {liked: !this.state.liked} );

}

render() {

var name = this.props.name;

var txt = this.state.liked ? 'Unlike' : 'Like';

var myColor = this.state.liked ? 'red' : 'black';

var weight = this.state.liked ? 'bold' : 'normal';

return (

<p><span style={{color:myColor, fontWeight:weight }}>

{name} </span>

<span onClick={this.toggle.bind(this)}>

{'\ud83d\udc4d' + txt}

</span> </p> );

}

};

SD4x-3.3 154

Property of Penn Engineering, Chris Murphy

class LikeButton extends React.Component {

constructor(props) {

super(props);

this.state = { liked : false };

}

toggle() {

this.setState( {liked: !this.state.liked} );

}

render() {

var name = this.props.name;

var txt = this.state.liked ? 'Unlike' : 'Like';

var myColor = this.state.liked ? 'red' : 'black';

var weight = this.state.liked ? 'bold' : 'normal';

return (

<p><span style={{color:myColor, fontWeight:weight }}>

{name} </span>

<span onClick={this.toggle.bind(this)}>

{'\ud83d\udc4d' + txt}

</span> </p> );

}

};

SD4x-3.3 155

Property of Penn Engineering, Chris Murphy

class LikeButton extends React.Component {

constructor(props) {

super(props);

this.state = { liked : false };

}

toggle() {

this.setState( {liked: !this.state.liked} );

}

render() {

var name = this.props.name;

var txt = this.state.liked ? 'Unlike' : 'Like';

var myColor = this.state.liked ? 'red' : 'black';

var weight = this.state.liked ? 'bold' : 'normal';

return (

<p><span style={{color:myColor, fontWeight:weight }}>

{name} </span>

<span onClick={this.toggle.bind(this)}>

{'\ud83d\udc4d' + txt}

</span> </p> );

}

};

SD4x-3.3 156

Property of Penn Engineering, Chris Murphy

class LikeButton extends React.Component {

constructor(props) {

super(props);

this.state = { liked : false };

}

toggle() {

this.setState( {liked: !this.state.liked} );

}

render() {

var name = this.props.name;

var txt = this.state.liked ? 'Unlike' : 'Like';

var myColor = this.state.liked ? 'red' : 'black';

var weight = this.state.liked ? 'bold' : 'normal';

return (

<p><span style={{color:myColor, fontWeight:weight }}>

{name} </span>

<span onClick={this.toggle.bind(this)}>

{'\ud83d\udc4d' + txt}

</span> </p> );

}

};

SD4x-3.3 157

Property of Penn Engineering, Chris Murphy

class LikeButton extends React.Component {

constructor(props) {

super(props);

this.state = { liked : false };

}

toggle() {

this.setState( {liked: !this.state.liked} );

}

render() {

var name = this.props.name;

var txt = this.state.liked ? 'Unlike' : 'Like';

var myColor = this.state.liked ? 'red' : 'black';

var weight = this.state.liked ? 'bold' : 'normal';

return (

<p><span style={{color:myColor, fontWeight:weight }}>

{name} </span>

<span onClick={this.toggle.bind(this)}>

{'\ud83d\udc4d' + txt}

</span> </p> );

}

};

SD4x-3.3 158

Property of Penn Engineering, Chris Murphy

class LikeButton extends React.Component {

constructor(props) {

super(props);

this.state = { liked : false };

}

toggle() {

this.setState( {liked: !this.state.liked} );

}

render() {

var name = this.props.name;

var txt = this.state.liked ? 'Unlike' : 'Like';

var myColor = this.state.liked ? 'red' : 'black';

var weight = this.state.liked ? 'bold' : 'normal';

return (

<p><span style={{color:myColor, fontWeight:weight }}>

{name} </span>

<span onClick={this.toggle.bind(this)}>

{'\ud83d\udc4d' + txt}

</span> </p> );

}

};

SD4x-3.3 159

Property of Penn Engineering, Chris Murphy

class LikeButton extends React.Component {

constructor(props) {

super(props);

this.state = { liked : false };

}

toggle() {

this.setState( {liked: !this.state.liked} );

}

render() {

var name = this.props.name;

var txt = this.state.liked ? 'Unlike' : 'Like';

var myColor = this.state.liked ? 'red' : 'black';

var weight = this.state.liked ? 'bold' : 'normal';

return (

<p><span style={{color:myColor, fontWeight:weight }}>

{name} </span>

<span onClick={this.toggle.bind(this)}>

{'\ud83d\udc4d' + txt}

</span> </p> );

}

};

SD4x-3.3 160

Property of Penn Engineering, Chris Murphy

class LikeButton extends React.Component {

constructor(props) {

super(props);

this.state = { liked : false };

}

toggle() {

this.setState( {liked: !this.state.liked} );

}

render() {

var name = this.props.name;

var txt = this.state.liked ? 'Unlike' : 'Like';

var myColor = this.state.liked ? 'red' : 'black';

var weight = this.state.liked ? 'bold' : 'normal';

return (

<p><span style={{color:myColor, fontWeight:weight }}>

{name} </span>

<span onClick={this.toggle.bind(this)}>

{'\ud83d\udc4d' + txt}

</span> </p> );

}

};

SD4x-3.3 161

Property of Penn Engineering, Chris Murphy

class LikeButton extends React.Component {

constructor(props) {

super(props);

this.state = { liked : false };

}

toggle() {

this.setState( {liked: !this.state.liked} );

}

render() {

var name = this.props.name;

var txt = this.state.liked ? 'Unlike' : 'Like';

var myColor = this.state.liked ? 'red' : 'black';

var weight = this.state.liked ? 'bold' : 'normal';

return (

<p><span style={{color:myColor, fontWeight:weight }}>

{name} </span>

<span onClick={this.toggle.bind(this)}>

{'\ud83d\udc4d' + txt}

</span> </p> );

}

};

SD4x-3.3 162

Property of Penn Engineering, Chris Murphy

class LikeButton extends React.Component {

constructor(props) {

super(props);

this.state = { liked : false };

}

toggle() {

this.setState( {liked: !this.state.liked} );

}

render() {

var name = this.props.name;

var txt = this.state.liked ? 'Unlike' : 'Like';

var myColor = this.state.liked ? 'red' : 'black';

var weight = this.state.liked ? 'bold' : 'normal';

return (

<p><span style={{color:myColor, fontWeight:weight }}>

{name} </span>

<span onClick={this.toggle.bind(this)}>

{'\ud83d\udc4d' + txt}

</span> </p> );

}

};

SD4x-3.3 163

Property of Penn Engineering, Chris Murphy

class LikeButton extends React.Component {

constructor(props) {

super(props);

this.state = { liked : false };

}

toggle() {

this.setState( {liked: !this.state.liked} );

}

render() {

var name = this.props.name;

var txt = this.state.liked ? 'Unlike' : 'Like';

var myColor = this.state.liked ? 'red' : 'black';

var weight = this.state.liked ? 'bold' : 'normal';

return (

<p><span style={{color:myColor, fontWeight:weight }}>

{name} </span>

<span onClick={this.toggle.bind(this)}>

{'\ud83d\udc4d' + txt}

</span> </p> );

}

};

SD4x-3.3 164

Property of Penn Engineering, Chris Murphy

class LikeButton extends React.Component {

constructor(props) {

super(props);

this.state = { liked : false };

}

toggle() {

this.setState( {liked: !this.state.liked} );

}

render() {

var name = this.props.name;

var txt = this.state.liked ? 'Unlike' : 'Like';

var myColor = this.state.liked ? 'red' : 'black';

var weight = this.state.liked ? 'bold' : 'normal';

return (

<p><span style={{color:myColor, fontWeight:weight }}>

{name} </span>

<span onClick={this.toggle.bind(this)}>

{'\ud83d\udc4d' + txt}

</span> </p> );

}

};

SD4x-3.3 165

Property of Penn Engineering, Chris Murphy

class LikeButton extends React.Component {

constructor(props) {

super(props);

this.state = { liked : false };

}

toggle() {

this.setState( {liked: !this.state.liked} );

}

render() {

var name = this.props.name;

var txt = this.state.liked ? 'Unlike' : 'Like';

var myColor = this.state.liked ? 'red' : 'black';

var weight = this.state.liked ? 'bold' : 'normal';

return (

<p><span style={{color:myColor, fontWeight:weight }}>

{name} </span>

<span onClick={this.toggle.bind(this)}>

{'\ud83d\udc4d' + txt}

</span> </p> );

}

};

SD4x-3.3 166

Property of Penn Engineering, Chris Murphy SD4x-3.3 167

Property of Penn Engineering, Chris Murphy SD4x-3.3 168

Property of Penn Engineering, Chris Murphy SD4x-3.3 169

Property of Penn Engineering, Chris Murphy SD4x-3.3 170

Property of Penn Engineering, Chris Murphy SD4x-3.3 171

Property of Penn Engineering, Chris Murphy

class MyText extends React.Component {

constructor(props) {

super(props);

this.state = { bold : false, color : 'black' };

}

handleMouseOver() {

this.setState( { bold : true } );

}

handleMouseOut() {

this.setState( { bold: false } );

}

handleClick() {

if (this.state.color == 'red' )

this.setState( { color: 'black' } );

else

this.setState( { color: 'red' } );

}

. . .

SD4x-3.3 172

Property of Penn Engineering, Chris Murphy

class MyText extends React.Component {

constructor(props) {

super(props);

this.state = { bold : false, color : 'black' };

}

handleMouseOver() {

this.setState( { bold : true } );

}

handleMouseOut() {

this.setState( { bold: false } );

}

handleClick() {

if (this.state.color == 'red' )

this.setState( { color: 'black' } );

else

this.setState( { color: 'red' } );

}

. . .

SD4x-3.3 173

Property of Penn Engineering, Chris Murphy

class MyText extends React.Component {

constructor(props) {

super(props);

this.state = { bold : false, color : 'black' };

}

handleMouseOver() {

this.setState( { bold : true } );

}

handleMouseOut() {

this.setState( { bold: false } );

}

handleClick() {

if (this.state.color == 'red' )

this.setState( { color: 'black' } );

else

this.setState( { color: 'red' } );

}

. . .

SD4x-3.3 174

Property of Penn Engineering, Chris Murphy

class MyText extends React.Component {

constructor(props) {

super(props);

this.state = { bold : false, color : 'black' };

}

handleMouseOver() {

this.setState( { bold : true } );

}

handleMouseOut() {

this.setState( { bold: false } );

}

handleClick() {

if (this.state.color == 'red' )

this.setState( { color: 'black' } );

else

this.setState( { color: 'red' } );

}

. . .

SD4x-3.3 175

Property of Penn Engineering, Chris Murphy

class MyText extends React.Component {

constructor(props) {

super(props);

this.state = { bold : false, color : 'black' };

}

handleMouseOver() {

this.setState( { bold : true } );

}

handleMouseOut() {

this.setState( { bold: false } );

}

handleClick() {

if (this.state.color == 'red' )

this.setState( { color: 'black' } );

else

this.setState( { color: 'red' } );

}

. . .

SD4x-3.3 176

Property of Penn Engineering, Chris Murphy

class MyText extends React.Component {

constructor(props) {

super(props);

this.state = { bold : false, color : 'black' };

}

handleMouseOver() {

this.setState( { bold : true } );

}

handleMouseOut() {

this.setState( { bold: false } );

}

handleClick() {

if (this.state.color == 'red' )

this.setState( { color: 'black' } );

else

this.setState( { color: 'red' } );

}

. . .

SD4x-3.3 177

Property of Penn Engineering, Chris Murphy

class MyText extends React.Component {

constructor(props) {

super(props);

this.state = { bold : false, color : 'black' };

}

handleMouseOver() {

this.setState( { bold : true } );

}

handleMouseOut() {

this.setState( { bold: false } );

}

handleClick() {

if (this.state.color == 'red' )

this.setState( { color: 'black' } );

else

this.setState( { color: 'red' } );

}

. . .

SD4x-3.3 178

Property of Penn Engineering, Chris Murphy

class MyText extends React.Component {

constructor(props) {

super(props);

this.state = { bold : false, color : 'black' };

}

handleMouseOver() {

this.setState( { bold : true } );

}

handleMouseOut() {

this.setState( { bold: false } );

}

handleClick() {

if (this.state.color == 'red' )

this.setState( { color: 'black' } );

else

this.setState( { color: 'red' } );

}

. . .

SD4x-3.3 179

Property of Penn Engineering, Chris Murphy

class MyText extends React.Component {

constructor(props) {

super(props);

this.state = { bold : false, color : 'black' };

}

handleMouseOver() {

this.setState( { bold : true } );

}

handleMouseOut() {

this.setState( { bold: false } );

}

handleClick() {

if (this.state.color == 'red' )

this.setState( { color: 'black' } );

else

this.setState( { color: 'red' } );

}

. . .

SD4x-3.3 180

Property of Penn Engineering, Chris Murphy

class MyText extends React.Component {

constructor(props) {

super(props);

this.state = { bold : false, color : 'black' };

}

handleMouseOver() {

this.setState( { bold : true } );

}

handleMouseOut() {

this.setState( { bold: false } );

}

handleClick() {

if (this.state.color == 'red' )

this.setState( { color: 'black' } );

else

this.setState( { color: 'red' } );

}

. . .

SD4x-3.3 181

Property of Penn Engineering, Chris Murphy

class MyText extends React.Component {

constructor(props) {

super(props);

this.state = { bold : false, color : 'black' };

}

handleMouseOver() {

this.setState( { bold : true } );

}

handleMouseOut() {

this.setState( { bold: false } );

}

handleClick() {

if (this.state.color == 'red' )

this.setState( { color: 'black' } );

else

this.setState( { color: 'red' } );

}

. . .

SD4x-3.3 182

Property of Penn Engineering, Chris Murphy

class MyText extends React.Component {

constructor(props) {

super(props);

this.state = { bold : false, color : 'black' };

}

handleMouseOver() {

this.setState( { bold : true } );

}

handleMouseOut() {

this.setState( { bold: false } );

}

handleClick() {

if (this.state.color == 'red' )

this.setState( { color: 'black' } );

else

this.setState( { color: 'red' } );

}

. . .

SD4x-3.3 183

Property of Penn Engineering, Chris Murphy

class MyText extends React.Component {

constructor(props) {

super(props);

this.state = { bold : false, color : 'black' };

}

handleMouseOver() {

this.setState( { bold : true } );

}

handleMouseOut() {

this.setState( { bold: false } );

}

handleClick() {

if (this.state.color == 'red' )

this.setState( { color: 'black' } );

else

this.setState( { color: 'red' } );

}

. . .

SD4x-3.3 184

Property of Penn Engineering, Chris Murphy

class MyText extends React.Component {

constructor(props) {

super(props);

this.state = { bold : false, color : 'black' };

}

handleMouseOver() {

this.setState( { bold : true } );

}

handleMouseOut() {

this.setState( { bold: false } );

}

handleClick() {

if (this.state.color == 'red' )

this.setState( { color: 'black' } );

else

this.setState( { color: 'red' } );

}

. . .

SD4x-3.3 185

Property of Penn Engineering, Chris Murphy

class MyText extends React.Component {

. . .

render () {

var myColor = this.state.color;

var weight = this.state.bold ? 'bold' : 'normal' ;

return (

<span style={ {color:myColor, fontWeight:weight} }

onClick={this.handleClick.bind(this)}

onMouseOver={this.handleMouseOver.bind(this)}

onMouseOut={this.handleMouseOut.bind(this)} >

{this.props.text}

</span>

);

}

};

ReactDOM.render(

<div><MyText text="Look at me!" /></div>,

document.getElementById('container')

);

SD4x-3.3 186

Property of Penn Engineering, Chris Murphy

class MyText extends React.Component {

. . .

render () {

var myColor = this.state.color;

var weight = this.state.bold ? 'bold' : 'normal' ;

return (

<span style={ {color:myColor, fontWeight:weight} }

onClick={this.handleClick.bind(this)}

onMouseOver={this.handleMouseOver.bind(this)}

onMouseOut={this.handleMouseOut.bind(this)} >

{this.props.text}

</span>

);

}

};

ReactDOM.render(

<div><MyText text="Look at me!" /></div>,

document.getElementById('container')

);

SD4x-3.3 187

Property of Penn Engineering, Chris Murphy

class MyText extends React.Component {

. . .

render () {

var myColor = this.state.color;

var weight = this.state.bold ? 'bold' : 'normal' ;

return (

<span style={ {color:myColor, fontWeight:weight} }

onClick={this.handleClick.bind(this)}

onMouseOver={this.handleMouseOver.bind(this)}

onMouseOut={this.handleMouseOut.bind(this)} >

{this.props.text}

</span>

);

}

};

ReactDOM.render(

<div><MyText text="Look at me!" /></div>,

document.getElementById('container')

);

SD4x-3.3 188

Property of Penn Engineering, Chris Murphy

class MyText extends React.Component {

. . .

render () {

var myColor = this.state.color;

var weight = this.state.bold ? 'bold' : 'normal' ;

return (

<span style={ {color:myColor, fontWeight:weight} }

onClick={this.handleClick.bind(this)}

onMouseOver={this.handleMouseOver.bind(this)}

onMouseOut={this.handleMouseOut.bind(this)} >

{this.props.text}

</span>

);

}

};

ReactDOM.render(

<div><MyText text="Look at me!" /></div>,

document.getElementById('container')

);

SD4x-3.3 189

Property of Penn Engineering, Chris Murphy

class MyText extends React.Component {

. . .

render () {

var myColor = this.state.color;

var weight = this.state.bold ? 'bold' : 'normal' ;

return (

<span style={ {color:myColor, fontWeight:weight} }

onClick={this.handleClick.bind(this)}

onMouseOver={this.handleMouseOver.bind(this)}

onMouseOut={this.handleMouseOut.bind(this)} >

{this.props.text}

</span>

);

}

};

ReactDOM.render(

<div><MyText text="Look at me!" /></div>,

document.getElementById('container')

);

SD4x-3.3 190

Property of Penn Engineering, Chris Murphy

class MyText extends React.Component {

. . .

render () {

var myColor = this.state.color;

var weight = this.state.bold ? 'bold' : 'normal' ;

return (

<span style={ {color:myColor, fontWeight:weight} }

onClick={this.handleClick.bind(this)}

onMouseOver={this.handleMouseOver.bind(this)}

onMouseOut={this.handleMouseOut.bind(this)} >

{this.props.text}

</span>

);

}

};

ReactDOM.render(

<div><MyText text="Look at me!" /></div>,

document.getElementById('container')

);

SD4x-3.3 191

Property of Penn Engineering, Chris Murphy

class MyText extends React.Component {

. . .

render () {

var myColor = this.state.color;

var weight = this.state.bold ? 'bold' : 'normal' ;

return (

<span style={ {color:myColor, fontWeight:weight} }

onClick={this.handleClick.bind(this)}

onMouseOver={this.handleMouseOver.bind(this)}

onMouseOut={this.handleMouseOut.bind(this)} >

{this.props.text}

</span>

);

}

};

ReactDOM.render(

<div><MyText text="Look at me!" /></div>,

document.getElementById('container')

);

SD4x-3.3 192

Property of Penn Engineering, Chris Murphy

class MyText extends React.Component {

. . .

render () {

var myColor = this.state.color;

var weight = this.state.bold ? 'bold' : 'normal' ;

return (

<span style={ {color:myColor, fontWeight:weight} }

onClick={this.handleClick.bind(this)}

onMouseOver={this.handleMouseOver.bind(this)}

onMouseOut={this.handleMouseOut.bind(this)} >

{this.props.text}

</span>

);

}

};

ReactDOM.render(

<div><MyText text="Look at me!" /></div>,

document.getElementById('container')

);

SD4x-3.3 193

Property of Penn Engineering, Chris Murphy

class MyText extends React.Component {

. . .

render () {

var myColor = this.state.color;

var weight = this.state.bold ? 'bold' : 'normal' ;

return (

<span style={ {color:myColor, fontWeight:weight} }

onClick={this.handleClick.bind(this)}

onMouseOver={this.handleMouseOver.bind(this)}

onMouseOut={this.handleMouseOut.bind(this)} >

{this.props.text}

</span>

);

}

};

ReactDOM.render(

<div><MyText text="Look at me!" /></div>,

document.getElementById('container')

);

SD4x-3.3 194

Property of Penn Engineering, Chris Murphy

class MyText extends React.Component {

. . .

render () {

var myColor = this.state.color;

var weight = this.state.bold ? 'bold' : 'normal' ;

return (

<span style={ {color:myColor, fontWeight:weight} }

onClick={this.handleClick.bind(this)}

onMouseOver={this.handleMouseOver.bind(this)}

onMouseOut={this.handleMouseOut.bind(this)} >

{this.props.text}

</span>

);

}

};

ReactDOM.render(

<div><MyText text="Look at me!" /></div>,

document.getElementById('container')

);

SD4x-3.3 195

Property of Penn Engineering, Chris Murphy

class MyText extends React.Component {

. . .

render () {

var myColor = this.state.color;

var weight = this.state.bold ? 'bold' : 'normal' ;

return (

<span style={ {color:myColor, fontWeight:weight} }

onClick={this.handleClick.bind(this)}

onMouseOver={this.handleMouseOver.bind(this)}

onMouseOut={this.handleMouseOut.bind(this)} >

{this.props.text}

</span>

);

}

};

ReactDOM.render(

<div><MyText text="Look at me!" /></div>,

document.getElementById('container')

);

SD4x-3.3 196

Property of Penn Engineering, Chris Murphy

class MyText extends React.Component {

. . .

render () {

var myColor = this.state.color;

var weight = this.state.bold ? 'bold' : 'normal' ;

return (

<span style={ {color:myColor, fontWeight:weight} }

onClick={this.handleClick.bind(this)}

onMouseOver={this.handleMouseOver.bind(this)}

onMouseOut={this.handleMouseOut.bind(this)} >

{this.props.text}

</span>

);

}

};

ReactDOM.render(

<div><MyText text="Look at me!" /></div>,

document.getElementById('container')

);

SD4x-3.3 197

Property of Penn Engineering, Chris Murphy

Summary

• We can bind user events in HTML elements to callback functions in React components

• When we invoke a component’s setStatefunction, the render function will automatically be called and the component’s appearance can change accordingly

SD4x-3.3 198

Video 3.4

React Component Interaction

Chris Murphy

SD4x-3.4 199

Property of Penn Engineering, Chris Murphy

Review

• We can bind user events in HTML elements to callback functions in React components

• When we invoke a component’s setStatefunction, the render function will automatically be called and the component’s appearance can change accordingly

• Re-rendering one component may necessitate re-rendering others as well

SD4x-3.4 200

Property of Penn Engineering, Chris Murphy SD4x-3.4 201

Property of Penn Engineering, Chris Murphy SD4x-3.4 202

Property of Penn Engineering, Chris Murphy SD4x-3.4 203

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

constructor(props) {

super(props);

var allItems = [ "Anteater", "Bear", "Cat",

"Dog", "Elephant" ];

this.state = { initialItems: allItems,

currentItems: allItems };

}

filterList(input) { // callback function

var updatedList = this.state.initialItems;

updatedList = updatedList.filter(function(item){

return item.search(input.target.value) !== -1;

});

this.setState( { currentItems: updatedList } );

}

. . .

SD4x-3.4 204

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

constructor(props) {

super(props);

var allItems = [ "Anteater", "Bear", "Cat",

"Dog", "Elephant" ];

this.state = { initialItems: allItems,

currentItems: allItems };

}

filterList(input) { // callback function

var updatedList = this.state.initialItems;

updatedList = updatedList.filter(function(item){

return item.search(input.target.value) !== -1;

});

this.setState( { currentItems: updatedList } );

}

. . .

SD4x-3.4 205

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

constructor(props) {

super(props);

var allItems = [ "Anteater", "Bear", "Cat",

"Dog", "Elephant" ];

this.state = { initialItems: allItems,

currentItems: allItems };

}

filterList(input) { // callback function

var updatedList = this.state.initialItems;

updatedList = updatedList.filter(function(item){

return item.search(input.target.value) !== -1;

});

this.setState( { currentItems: updatedList } );

}

. . .

SD4x-3.4 206

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

constructor(props) {

super(props);

var allItems = [ "Anteater", "Bear", "Cat",

"Dog", "Elephant" ];

this.state = { initialItems: allItems,

currentItems: allItems };

}

filterList(input) { // callback function

var updatedList = this.state.initialItems;

updatedList = updatedList.filter(function(item){

return item.search(input.target.value) !== -1;

});

this.setState( { currentItems: updatedList } );

}

. . .

SD4x-3.4 207

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

constructor(props) {

super(props);

var allItems = [ "Anteater", "Bear", "Cat",

"Dog", "Elephant" ];

this.state = { initialItems: allItems,

currentItems: allItems };

}

filterList(input) { // callback function

var updatedList = this.state.initialItems;

updatedList = updatedList.filter(function(item){

return item.search(input.target.value) !== -1;

});

this.setState( { currentItems: updatedList } );

}

. . .

SD4x-3.4 208

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

constructor(props) {

super(props);

var allItems = [ "Anteater", "Bear", "Cat",

"Dog", "Elephant" ];

this.state = { initialItems: allItems,

currentItems: allItems };

}

filterList(input) { // callback function

var updatedList = this.state.initialItems;

updatedList = updatedList.filter(function(item){

return item.search(input.target.value) !== -1;

});

this.setState( { currentItems: updatedList } );

}

. . .

SD4x-3.4 209

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

constructor(props) {

super(props);

var allItems = [ "Anteater", "Bear", "Cat",

"Dog", "Elephant" ];

this.state = { initialItems: allItems,

currentItems: allItems };

}

filterList(input) { // callback function

var updatedList = this.state.initialItems;

updatedList = updatedList.filter(function(item){

return item.search(input.target.value) !== -1;

});

this.setState( { currentItems: updatedList } );

}

. . .

SD4x-3.4 210

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

constructor(props) {

super(props);

var allItems = [ "Anteater", "Bear", "Cat",

"Dog", "Elephant" ];

this.state = { initialItems: allItems,

currentItems: allItems };

}

filterList(input) { // callback function

var updatedList = this.state.initialItems;

updatedList = updatedList.filter(function(item){

return item.search(input.target.value) !== -1;

});

this.setState( { currentItems: updatedList } );

}

. . .

SD4x-3.4 211

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

constructor(props) {

super(props);

var allItems = [ "Anteater", "Bear", "Cat",

"Dog", "Elephant" ];

this.state = { initialItems: allItems,

currentItems: allItems };

}

filterList(input) { // callback function

var updatedList = this.state.initialItems;

updatedList = updatedList.filter(function(item){

return item.search(input.target.value) !== -1;

});

this.setState( { currentItems: updatedList } );

}

. . .

SD4x-3.4 212

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

constructor(props) {

super(props);

var allItems = [ "Anteater", "Bear", "Cat",

"Dog", "Elephant" ];

this.state = { initialItems: allItems,

currentItems: allItems };

}

filterList(input) { // callback function

var updatedList = this.state.initialItems;

updatedList = updatedList.filter(function(item){

return item.search(input.target.value) !== -1;

});

this.setState( { currentItems: updatedList } );

}

. . .

SD4x-3.4 213

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

constructor(props) {

super(props);

var allItems = [ "Anteater", "Bear", "Cat",

"Dog", "Elephant" ];

this.state = { initialItems: allItems,

currentItems: allItems };

}

filterList(input) { // callback function

var updatedList = this.state.initialItems;

updatedList = updatedList.filter(function(item){

return item.search(input.target.value) !== -1;

});

this.setState( { currentItems: updatedList } );

}

. . .

SD4x-3.4 214

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

constructor(props) {

super(props);

var allItems = [ "Anteater", "Bear", "Cat",

"Dog", "Elephant" ];

this.state = { initialItems: allItems,

currentItems: allItems };

}

filterList(input) { // callback function

var updatedList = this.state.initialItems;

updatedList = updatedList.filter(function(item){

return item.search(input.target.value) !== -1;

});

this.setState( { currentItems: updatedList } );

}

. . .

SD4x-3.4 215

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

constructor(props) {

super(props);

var allItems = [ "Anteater", "Bear", "Cat",

"Dog", "Elephant" ];

this.state = { initialItems: allItems,

currentItems: allItems };

}

filterList(input) { // callback function

var updatedList = this.state.initialItems;

updatedList = updatedList.filter(function(item){

return item.search(input.target.value) !== -1;

});

this.setState( { currentItems: updatedList } );

}

. . .

SD4x-3.4 216

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

constructor(props) {

super(props);

var allItems = [ "Anteater", "Bear", "Cat",

"Dog", "Elephant" ];

this.state = { initialItems: allItems,

currentItems: allItems };

}

filterList(input) { // callback function

var updatedList = this.state.initialItems;

updatedList = updatedList.filter(function(item){

return item.search(input.target.value) !== -1;

});

this.setState( { currentItems: updatedList } );

}

. . .

SD4x-3.4 217

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

constructor(props) {

super(props);

var allItems = [ "Anteater", "Bear", "Cat",

"Dog", "Elephant" ];

this.state = { initialItems: allItems,

currentItems: allItems };

}

filterList(input) { // callback function

var updatedList = this.state.initialItems;

updatedList = updatedList.filter(function(item){

return item.search(input.target.value) !== -1;

});

this.setState( { currentItems: updatedList } );

}

. . .

SD4x-3.4 218

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

constructor(props) {

super(props);

var allItems = [ "Anteater", "Bear", "Cat",

"Dog", "Elephant" ];

this.state = { initialItems: allItems,

currentItems: allItems };

}

filterList(input) { // callback function

var updatedList = this.state.initialItems;

updatedList = updatedList.filter(function(item){

return item.search(input.target.value) !== -1;

});

this.setState( { currentItems: updatedList } );

}

. . .

SD4x-3.4 219

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

constructor(props) {

super(props);

var allItems = [ "Anteater", "Bear", "Cat",

"Dog", "Elephant" ];

this.state = { initialItems: allItems,

currentItems: allItems };

}

filterList(input) { // callback function

var updatedList = this.state.initialItems;

updatedList = updatedList.filter(function(item){

return item.search(input.target.value) !== -1;

});

this.setState( { currentItems: updatedList } );

}

. . .

SD4x-3.4 220

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

constructor(props) {

super(props);

var allItems = [ "Anteater", "Bear", "Cat",

"Dog", "Elephant" ];

this.state = { initialItems: allItems,

currentItems: allItems };

}

filterList(input) { // callback function

var updatedList = this.state.initialItems;

updatedList = updatedList.filter(function(item){

return item.search(input.target.value) !== -1;

});

this.setState( { currentItems: updatedList } );

}

. . .

SD4x-3.4 221

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

constructor(props) {

super(props);

var allItems = [ "Anteater", "Bear", "Cat",

"Dog", "Elephant" ];

this.state = { initialItems: allItems,

currentItems: allItems };

}

filterList(input) { // callback function

var updatedList = this.state.initialItems;

updatedList = updatedList.filter(function(item){

return item.search(input.target.value) !== -1;

});

this.setState( { currentItems: updatedList } );

}

. . .

SD4x-3.4 222

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

. . .

render(){

return (

<div><input type="text" placeholder="Search"

onChange={this.filterList.bind(this)}/>

<ListItems items={this.state.currentItems}/>

</div>

);

}

};

class ListItems extends React.Component {

render(){

return (

<ul> { this.props.items.map(function(item) {

return <li key={item}> {item} </li> } ) } </ul>

);

}

};

ReactDOM.render(<FilteredList/>,

document.getElementById('container'));

SD4x-3.4 223

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

. . .

render(){

return (

<div><input type="text" placeholder="Search"

onChange={this.filterList.bind(this)}/>

<ListItems items={this.state.currentItems}/>

</div>

);

}

};

class ListItems extends React.Component {

render(){

return (

<ul> { this.props.items.map(function(item) {

return <li key={item}> {item} </li> } ) } </ul>

);

}

};

ReactDOM.render(<FilteredList/>,

document.getElementById('container'));

SD4x-3.4 224

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

. . .

render(){

return (

<div><input type="text" placeholder="Search"

onChange={this.filterList.bind(this)}/>

<ListItems items={this.state.currentItems}/>

</div>

);

}

};

class ListItems extends React.Component {

render(){

return (

<ul> { this.props.items.map(function(item) {

return <li key={item}> {item} </li> } ) } </ul>

);

}

};

ReactDOM.render(<FilteredList/>,

document.getElementById('container'));

SD4x-3.4 225

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

. . .

render(){

return (

<div><input type="text" placeholder="Search"

onChange={this.filterList.bind(this)}/>

<ListItems items={this.state.currentItems}/>

</div>

);

}

};

class ListItems extends React.Component {

render(){

return (

<ul> { this.props.items.map(function(item) {

return <li key={item}> {item} </li> } ) } </ul>

);

}

};

ReactDOM.render(<FilteredList/>,

document.getElementById('container'));

SD4x-3.4 226

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

. . .

render(){

return (

<div><input type="text" placeholder="Search"

onChange={this.filterList.bind(this)}/>

<ListItems items={this.state.currentItems}/>

</div>

);

}

};

class ListItems extends React.Component {

render(){

return (

<ul> { this.props.items.map(function(item) {

return <li key={item}> {item} </li> } ) } </ul>

);

}

};

ReactDOM.render(<FilteredList/>,

document.getElementById('container'));

SD4x-3.4 227

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

. . .

render(){

return (

<div><input type="text" placeholder="Search"

onChange={this.filterList.bind(this)}/>

<ListItems items={this.state.currentItems}/>

</div>

);

}

};

class ListItems extends React.Component {

render(){

return (

<ul> { this.props.items.map(function(item) {

return <li key={item}> {item} </li> } ) } </ul>

);

}

};

ReactDOM.render(<FilteredList/>,

document.getElementById('container'));

SD4x-3.4 228

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

. . .

render(){

return (

<div><input type="text" placeholder="Search"

onChange={this.filterList.bind(this)}/>

<ListItems items={this.state.currentItems}/>

</div>

);

}

};

class ListItems extends React.Component {

render(){

return (

<ul> { this.props.items.map(function(item) {

return <li key={item}> {item} </li> } ) } </ul>

);

}

};

ReactDOM.render(<FilteredList/>,

document.getElementById('container'));

SD4x-3.4 229

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

. . .

render(){

return (

<div><input type="text" placeholder="Search"

onChange={this.filterList.bind(this)}/>

<ListItems items={this.state.currentItems}/>

</div>

);

}

};

class ListItems extends React.Component {

render(){

return (

<ul> { this.props.items.map(function(item) {

return <li key={item}> {item} </li> } ) } </ul>

);

}

};

ReactDOM.render(<FilteredList/>,

document.getElementById('container'));

SD4x-3.4 230

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

. . .

render(){

return (

<div><input type="text" placeholder="Search"

onChange={this.filterList.bind(this)}/>

<ListItems items={this.state.currentItems}/>

</div>

);

}

};

class ListItems extends React.Component {

render(){

return (

<ul> { this.props.items.map(function(item) {

return <li key={item}> {item} </li> } ) } </ul>

);

}

};

ReactDOM.render(<FilteredList/>,

document.getElementById('container'));

SD4x-3.4 231

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

. . .

render(){

return (

<div><input type="text" placeholder="Search"

onChange={this.filterList.bind(this)}/>

<ListItems items={this.state.currentItems}/>

</div>

);

}

};

class ListItems extends React.Component {

render(){

return (

<ul> { this.props.items.map(function(item) {

return <li key={item}> {item} </li> } ) } </ul>

);

}

};

ReactDOM.render(<FilteredList/>,

document.getElementById('container'));

SD4x-3.4 232

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

. . .

render(){

return (

<div><input type="text" placeholder="Search"

onChange={this.filterList.bind(this)}/>

<ListItems items={this.state.currentItems}/>

</div>

);

}

};

class ListItems extends React.Component {

render(){

return (

<ul> { this.props.items.map(function(item) {

return <li key={item}> {item} </li> } ) } </ul>

);

}

};

ReactDOM.render(<FilteredList/>,

document.getElementById('container'));

SD4x-3.4 233

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

. . .

render(){

return (

<div><input type="text" placeholder="Search"

onChange={this.filterList.bind(this)}/>

<ListItems items={this.state.currentItems}/>

</div>

);

}

};

class ListItems extends React.Component {

render(){

return (

<ul> { this.props.items.map(function(item) {

return <li key={item}> {item} </li> } ) } </ul>

);

}

};

ReactDOM.render(<FilteredList/>,

document.getElementById('container'));

SD4x-3.4 234

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

. . .

render(){

return (

<div><input type="text" placeholder="Search"

onChange={this.filterList.bind(this)}/>

<ListItems items={this.state.currentItems}/>

</div>

);

}

};

class ListItems extends React.Component {

render(){

return (

<ul> { this.props.items.map(function(item) {

return <li key={item}> {item} </li> } ) } </ul>

);

}

};

ReactDOM.render(<FilteredList/>,

document.getElementById('container'));

SD4x-3.4 235

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

. . .

render(){

return (

<div><input type="text" placeholder="Search"

onChange={this.filterList.bind(this)}/>

<ListItems items={this.state.currentItems}/>

</div>

);

}

};

class ListItems extends React.Component {

render(){

return (

<ul> { this.props.items.map(function(item) {

return <li key={item}> {item} </li> } ) } </ul>

);

}

};

ReactDOM.render(<FilteredList/>,

document.getElementById('container'));

SD4x-3.4 236

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

. . .

render(){

return (

<div><input type="text" placeholder="Search"

onChange={this.filterList.bind(this)}/>

<ListItems items={this.state.currentItems}/>

</div>

);

}

};

class ListItems extends React.Component {

render(){

return (

<ul> { this.props.items.map(function(item) {

return <li key={item}> {item} </li> } ) } </ul>

);

}

};

ReactDOM.render(<FilteredList/>,

document.getElementById('container'));

SD4x-3.4 237

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

. . .

render(){

return (

<div><input type="text" placeholder="Search"

onChange={this.filterList.bind(this)}/>

<ListItems items={this.state.currentItems}/>

</div>

);

}

};

class ListItems extends React.Component {

render(){

return (

<ul> { this.props.items.map(function(item) {

return <li key={item}> {item} </li> } ) } </ul>

);

}

};

ReactDOM.render(<FilteredList/>,

document.getElementById('container'));

SD4x-3.4 238

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

. . .

render(){

return (

<div><input type="text" placeholder="Search"

onChange={this.filterList.bind(this)}/>

<ListItems items={this.state.currentItems}/>

</div>

);

}

};

class ListItems extends React.Component {

render(){

return (

<ul> { this.props.items.map(function(item) {

return <li key={item}> {item} </li> } ) } </ul>

);

}

};

ReactDOM.render(<FilteredList/>,

document.getElementById('container'));

SD4x-3.4 239

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

. . .

render(){

return (

<div><input type="text" placeholder="Search"

onChange={this.filterList.bind(this)}/>

<ListItems items={this.state.currentItems}/>

</div>

);

}

};

class ListItems extends React.Component {

render(){

return (

<ul> { this.props.items.map(function(item) {

return <li key={item}> {item} </li> } ) } </ul>

);

}

};

ReactDOM.render(<FilteredList/>,

document.getElementById('container'));

SD4x-3.4 240

Property of Penn Engineering, Chris Murphy

class FilteredList extends React.Component {

. . .

render(){

return (

<div><input type="text" placeholder="Search"

onChange={this.filterList.bind(this)}/>

<ListItems items={this.state.currentItems}/>

</div>

);

}

};

class ListItems extends React.Component {

render(){

return (

<ul> { this.props.items.map(function(item) {

return <li key={item}> {item} </li> } ) } </ul>

);

}

};

ReactDOM.render(<FilteredList/>,

document.getElementById('container'));

SD4x-3.4 241

Property of Penn Engineering, Chris Murphy SD4x-3.4 242

Property of Penn Engineering, Chris Murphy SD4x-3.4 243

Property of Penn Engineering, Chris Murphy SD4x-3.4 244

Property of Penn Engineering, Chris Murphy SD4x-3.4 245

Property of Penn Engineering, Chris Murphy SD4x-3.4 246

Property of Penn Engineering, Chris Murphy

class TodoApp extends React.Component {

constructor(props) {

super(props);

this.state = {items: [], text: ' ', id: 0};

}

handleChange(e) {

this.setState( { text: e.target.value } );

}

handleSubmit(e) {

e.preventDefault(); // so as not to reload the page

var newItem = { text: this.state.text,

id: this.state.id };

this.setState( {

items: this.state.items.concat(newItem),

text: ' ',

id: this.state.id + 1

});

}

SD4x-3.4 247

Property of Penn Engineering, Chris Murphy

class TodoApp extends React.Component {

constructor(props) {

super(props);

this.state = {items: [], text: ' ', id: 0};

}

handleChange(e) {

this.setState( { text: e.target.value } );

}

handleSubmit(e) {

e.preventDefault(); // so as not to reload the page

var newItem = { text: this.state.text,

id: this.state.id };

this.setState( {

items: this.state.items.concat(newItem),

text: ' ',

id: this.state.id + 1

});

}

SD4x-3.4 248

Property of Penn Engineering, Chris Murphy

class TodoApp extends React.Component {

constructor(props) {

super(props);

this.state = {items: [], text: ' ', id: 0};

}

handleChange(e) {

this.setState( { text: e.target.value } );

}

handleSubmit(e) {

e.preventDefault(); // so as not to reload the page

var newItem = { text: this.state.text,

id: this.state.id };

this.setState( {

items: this.state.items.concat(newItem),

text: ' ',

id: this.state.id + 1

});

}

SD4x-3.4 249

Property of Penn Engineering, Chris Murphy

class TodoApp extends React.Component {

constructor(props) {

super(props);

this.state = {items: [], text: ' ', id: 0};

}

handleChange(e) {

this.setState( { text: e.target.value } );

}

handleSubmit(e) {

e.preventDefault(); // so as not to reload the page

var newItem = { text: this.state.text,

id: this.state.id };

this.setState( {

items: this.state.items.concat(newItem),

text: ' ',

id: this.state.id + 1

});

}

SD4x-3.4 250

Property of Penn Engineering, Chris Murphy

class TodoApp extends React.Component {

constructor(props) {

super(props);

this.state = {items: [], text: ' ', id: 0};

}

handleChange(e) {

this.setState( { text: e.target.value } );

}

handleSubmit(e) {

e.preventDefault(); // so as not to reload the page

var newItem = { text: this.state.text,

id: this.state.id };

this.setState( {

items: this.state.items.concat(newItem),

text: ' ',

id: this.state.id + 1

});

}

SD4x-3.4 251

Property of Penn Engineering, Chris Murphy

class TodoApp extends React.Component {

constructor(props) {

super(props);

this.state = {items: [], text: ' ', id: 0};

}

handleChange(e) {

this.setState( { text: e.target.value } );

}

handleSubmit(e) {

e.preventDefault(); // so as not to reload the page

var newItem = { text: this.state.text,

id: this.state.id };

this.setState( {

items: this.state.items.concat(newItem),

text: ' ',

id: this.state.id + 1

});

}

SD4x-3.4 252

Property of Penn Engineering, Chris Murphy

class TodoApp extends React.Component {

constructor(props) {

super(props);

this.state = {items: [], text: ' ', id: 0};

}

handleChange(e) {

this.setState( { text: e.target.value } );

}

handleSubmit(e) {

e.preventDefault(); // so as not to reload the page

var newItem = { text: this.state.text,

id: this.state.id };

this.setState( {

items: this.state.items.concat(newItem),

text: ' ',

id: this.state.id + 1

});

}

SD4x-3.4 253

Property of Penn Engineering, Chris Murphy

class TodoApp extends React.Component {

constructor(props) {

super(props);

this.state = {items: [], text: ' ', id: 0};

}

handleChange(e) {

this.setState( { text: e.target.value } );

}

handleSubmit(e) {

e.preventDefault(); // so as not to reload the page

var newItem = { text: this.state.text,

id: this.state.id };

this.setState( {

items: this.state.items.concat(newItem),

text: ' ',

id: this.state.id + 1

});

}

SD4x-3.4 254

Property of Penn Engineering, Chris Murphy

class TodoApp extends React.Component {

constructor(props) {

super(props);

this.state = {items: [], text: ' ', id: 0};

}

handleChange(e) {

this.setState( { text: e.target.value } );

}

handleSubmit(e) {

e.preventDefault(); // so as not to reload the page

var newItem = { text: this.state.text,

id: this.state.id };

this.setState( {

items: this.state.items.concat(newItem),

text: ' ',

id: this.state.id + 1

});

}

SD4x-3.4 255

Property of Penn Engineering, Chris Murphy

class TodoApp extends React.Component {

constructor(props) {

super(props);

this.state = {items: [], text: ' ', id: 0};

}

handleChange(e) {

this.setState( { text: e.target.value } );

}

handleSubmit(e) {

e.preventDefault(); // so as not to reload the page

var newItem = { text: this.state.text,

id: this.state.id };

this.setState( {

items: this.state.items.concat(newItem),

text: ' ',

id: this.state.id + 1

});

}

SD4x-3.4 256

Property of Penn Engineering, Chris Murphy

class TodoApp extends React.Component {

constructor(props) {

super(props);

this.state = {items: [], text: ' ', id: 0};

}

handleChange(e) {

this.setState( { text: e.target.value } );

}

handleSubmit(e) {

e.preventDefault(); // so as not to reload the page

var newItem = { text: this.state.text,

id: this.state.id };

this.setState( {

items: this.state.items.concat(newItem),

text: ' ',

id: this.state.id + 1

});

}

SD4x-3.4 257

Property of Penn Engineering, Chris Murphy

class TodoApp extends React.Component {

constructor(props) {

super(props);

this.state = {items: [], text: ' ', id: 0};

}

handleChange(e) {

this.setState( { text: e.target.value } );

}

handleSubmit(e) {

e.preventDefault(); // so as not to reload the page

var newItem = { text: this.state.text,

id: this.state.id };

this.setState( {

items: this.state.items.concat(newItem),

text: ' ',

id: this.state.id + 1

});

}

SD4x-3.4 258

Property of Penn Engineering, Chris Murphy

class TodoApp extends React.Component {

constructor(props) {

super(props);

this.state = {items: [], text: ' ', id: 0};

}

handleChange(e) {

this.setState( { text: e.target.value } );

}

handleSubmit(e) {

e.preventDefault(); // so as not to reload the page

var newItem = { text: this.state.text,

id: this.state.id };

this.setState( {

items: this.state.items.concat(newItem),

text: ' ',

id: this.state.id + 1

});

}

SD4x-3.4 259

Property of Penn Engineering, Chris Murphy

class TodoApp extends React.Component {

constructor(props) {

super(props);

this.state = {items: [], text: ' ', id: 0};

}

handleChange(e) {

this.setState( { text: e.target.value } );

}

handleSubmit(e) {

e.preventDefault(); // so as not to reload the page

var newItem = { text: this.state.text,

id: this.state.id };

this.setState( {

items: this.state.items.concat(newItem),

text: ' ',

id: this.state.id + 1

});

}

SD4x-3.4 260

Property of Penn Engineering, Chris Murphy

class TodoApp extends React.Component {

constructor(props) {

super(props);

this.state = {items: [], text: ' ', id: 0};

}

handleChange(e) {

this.setState( { text: e.target.value } );

}

handleSubmit(e) {

e.preventDefault(); // so as not to reload the page

var newItem = { text: this.state.text,

id: this.state.id };

this.setState( {

items: this.state.items.concat(newItem),

text: ' ',

id: this.state.id + 1

});

}

SD4x-3.4 261

Property of Penn Engineering, Chris Murphy

class TodoApp extends React.Component {

constructor(props) {

super(props);

this.state = {items: [], text: ' ', id: 0};

}

handleChange(e) {

this.setState( { text: e.target.value } );

}

handleSubmit(e) {

e.preventDefault(); // so as not to reload the page

var newItem = { text: this.state.text,

id: this.state.id };

this.setState( {

items: this.state.items.concat(newItem),

text: ' ',

id: this.state.id + 1

});

}

SD4x-3.4 262

Property of Penn Engineering, Chris Murphy

class TodoApp extends React.Component {

constructor(props) {

super(props);

this.state = {items: [], text: ' ', id: 0};

}

handleChange(e) {

this.setState( { text: e.target.value } );

}

handleSubmit(e) {

e.preventDefault(); // so as not to reload the page

var newItem = { text: this.state.text,

id: this.state.id };

this.setState( {

items: this.state.items.concat(newItem),

text: ' ',

id: this.state.id + 1

});

}

SD4x-3.4 263

Property of Penn Engineering, Chris Murphy

class TodoApp extends React.Component {

constructor(props) {

super(props);

this.state = {items: [], text: ' ', id: 0};

}

handleChange(e) {

this.setState( { text: e.target.value } );

}

handleSubmit(e) {

e.preventDefault(); // so as not to reload the page

var newItem = { text: this.state.text,

id: this.state.id };

this.setState( {

items: this.state.items.concat(newItem),

text: ' ',

id: this.state.id + 1

});

}

SD4x-3.4 264

Property of Penn Engineering, Chris Murphy

class TodoApp extends React.Component {

constructor(props) {

super(props);

this.state = {items: [], text: ' ', id: 0};

}

handleChange(e) {

this.setState( { text: e.target.value } );

}

handleSubmit(e) {

e.preventDefault(); // so as not to reload the page

var newItem = { text: this.state.text,

id: this.state.id };

this.setState( {

items: this.state.items.concat(newItem),

text: ' ',

id: this.state.id + 1

});

}

SD4x-3.4 265

Property of Penn Engineering, Chris Murphy

class TodoApp extends React.Component {

. . .

render() {

return (

<div>

<h3>TO-DO LIST</h3>

<TodoList items={this.state.items} />

<form onSubmit={this.handleSubmit.bind(this)}>

<input onChange={this.handleChange.bind(this)}

value={this.state.text} />

<button>Add</button>

</form>

</div>

);

}

};

SD4x-3.4 266

Property of Penn Engineering, Chris Murphy

class TodoApp extends React.Component {

. . .

render() {

return (

<div>

<h3>TO-DO LIST</h3>

<TodoList items={this.state.items} />

<form onSubmit={this.handleSubmit.bind(this)}>

<input onChange={this.handleChange.bind(this)}

value={this.state.text} />

<button>Add</button>

</form>

</div>

);

}

};

SD4x-3.4 267

Property of Penn Engineering, Chris Murphy

class TodoApp extends React.Component {

. . .

render() {

return (

<div>

<h3>TO-DO LIST</h3>

<TodoList items={this.state.items} />

<form onSubmit={this.handleSubmit.bind(this)}>

<input onChange={this.handleChange.bind(this)}

value={this.state.text} />

<button>Add</button>

</form>

</div>

);

}

};

SD4x-3.4 268

Property of Penn Engineering, Chris Murphy

class TodoApp extends React.Component {

. . .

render() {

return (

<div>

<h3>TO-DO LIST</h3>

<TodoList items={this.state.items} />

<form onSubmit={this.handleSubmit.bind(this)}>

<input onChange={this.handleChange.bind(this)}

value={this.state.text} />

<button>Add</button>

</form>

</div>

);

}

};

SD4x-3.4 269

Property of Penn Engineering, Chris Murphy

class TodoApp extends React.Component {

. . .

render() {

return (

<div>

<h3>TO-DO LIST</h3>

<TodoList items={this.state.items} />

<form onSubmit={this.handleSubmit.bind(this)}>

<input onChange={this.handleChange.bind(this)}

value={this.state.text} />

<button>Add</button>

</form>

</div>

);

}

};

SD4x-3.4 270

Property of Penn Engineering, Chris Murphy

class TodoApp extends React.Component {

. . .

render() {

return (

<div>

<h3>TO-DO LIST</h3>

<TodoList items={this.state.items} />

<form onSubmit={this.handleSubmit.bind(this)}>

<input onChange={this.handleChange.bind(this)}

value={this.state.text} />

<button>Add</button>

</form>

</div>

);

}

};

SD4x-3.4 271

Property of Penn Engineering, Chris Murphy

class TodoApp extends React.Component {

. . .

render() {

return (

<div>

<h3>TO-DO LIST</h3>

<TodoList items={this.state.items} />

<form onSubmit={this.handleSubmit.bind(this)}>

<input onChange={this.handleChange.bind(this)}

value={this.state.text} />

<button>Add</button>

</form>

</div>

);

}

};

SD4x-3.4 272

Property of Penn Engineering, Chris Murphy

class TodoApp extends React.Component {

. . .

render() {

return (

<div>

<h3>TO-DO LIST</h3>

<TodoList items={this.state.items} />

<form onSubmit={this.handleSubmit.bind(this)}>

<input onChange={this.handleChange.bind(this)}

value={this.state.text} />

<button>Add</button>

</form>

</div>

);

}

};

SD4x-3.4 273

Property of Penn Engineering, Chris Murphy

class TodoApp extends React.Component {

. . .

render() {

return (

<div>

<h3>TO-DO LIST</h3>

<TodoList items={this.state.items} />

<form onSubmit={this.handleSubmit.bind(this)}>

<input onChange={this.handleChange.bind(this)}

value={this.state.text} />

<button>Add</button>

</form>

</div>

);

}

};

SD4x-3.4 274

Property of Penn Engineering, Chris Murphy

class TodoApp extends React.Component {

. . .

render() {

return (

<div>

<h3>TO-DO LIST</h3>

<TodoList items={this.state.items} />

<form onSubmit={this.handleSubmit.bind(this)}>

<input onChange={this.handleChange.bind(this)}

value={this.state.text} />

<button>Add</button>

</form>

</div>

);

}

};

SD4x-3.4 275

Property of Penn Engineering, Chris Murphy

class TodoList extends React.Component {

render() {

return (

<ul>

{this.props.items.map(function (item) {

return

<TodoItem id={item.id} text={item.text}/>

})}

</ul>

);

}

}

class TodoApp extends React.Component {

. . .

render() {

return (

. . .

<TodoList items={this.state.items} />

. . .

SD4x-3.4 276

Property of Penn Engineering, Chris Murphy

class TodoList extends React.Component {

render() {

return (

<ul>

{this.props.items.map(function (item) {

return

<TodoItem id={item.id} text={item.text}/>

})}

</ul>

);

}

}

class TodoApp extends React.Component {

. . .

render() {

return (

. . .

<TodoList items={this.state.items} />

. . .

SD4x-3.4 277

Property of Penn Engineering, Chris Murphy

class TodoList extends React.Component {

render() {

return (

<ul>

{this.props.items.map(function (item) {

return

<TodoItem id={item.id} text={item.text}/>

})}

</ul>

);

}

}

class TodoApp extends React.Component {

. . .

render() {

return (

. . .

<TodoList items={this.state.items} />

. . .

SD4x-3.4 278

Property of Penn Engineering, Chris Murphy

class TodoList extends React.Component {

render() {

return (

<ul>

{this.props.items.map(function (item) {

return

<TodoItem id={item.id} text={item.text}/>

})}

</ul>

);

}

}

class TodoApp extends React.Component {

. . .

render() {

return (

. . .

<TodoList items={this.state.items} />

. . .

SD4x-3.4 279

Property of Penn Engineering, Chris Murphy

class TodoList extends React.Component {

render() {

return (

<ul>

{this.props.items.map(function (item) {

return

<TodoItem id={item.id} text={item.text}/>

})}

</ul>

);

}

}

class TodoApp extends React.Component {

. . .

render() {

return (

. . .

<TodoList items={this.state.items} />

. . .

SD4x-3.4 280

Property of Penn Engineering, Chris Murphy

class TodoList extends React.Component {

render() {

return (

<ul>

{this.props.items.map(function (item) {

return

<TodoItem id={item.id} text={item.text}/>

})}

</ul>

);

}

}

class TodoApp extends React.Component {

. . .

render() {

return (

. . .

<TodoList items={this.state.items} />

. . .

SD4x-3.4 281

Property of Penn Engineering, Chris Murphy

class TodoList extends React.Component {

render() {

return (

<ul>

{this.props.items.map(function (item) {

return

<TodoItem id={item.id} text={item.text}/>

})}

</ul>

);

}

}

class TodoApp extends React.Component {

. . .

render() {

return (

. . .

<TodoList items={this.state.items} />

. . .

SD4x-3.4 282

Property of Penn Engineering, Chris Murphy

class TodoList extends React.Component {

render() {

return (

<ul>

{this.props.items.map(function (item) {

return

<TodoItem id={item.id} text={item.text}/>

})}

</ul>

);

}

}

class TodoApp extends React.Component {

. . .

render() {

return (

. . .

<TodoList items={this.state.items} />

. . .

SD4x-3.4 283

Property of Penn Engineering, Chris Murphy

class TodoList extends React.Component {

render() {

return (

<ul>

{this.props.items.map(function (item) {

return

<TodoItem id={item.id} text={item.text}/>

})}

</ul>

);

}

}

class TodoApp extends React.Component {

. . .

render() {

return (

. . .

<TodoList items={this.state.items} />

. . .

SD4x-3.4 284

Property of Penn Engineering, Chris Murphy

class TodoList extends React.Component {

render() {

return (

<ul>

{this.props.items.map(function (item) {

return

<TodoItem id={item.id} text={item.text}/>

})}

</ul>

);

}

}

class TodoApp extends React.Component {

. . .

render() {

return (

. . .

<TodoList items={this.state.items} />

. . .

SD4x-3.4 285

Property of Penn Engineering, Chris Murphy

class TodoList extends React.Component {

render() {

return (

<ul>

{this.props.items.map(function (item) {

return

<TodoItem id={item.id} text={item.text}/>

})}

</ul>

);

}

}

class TodoApp extends React.Component {

. . .

render() {

return (

. . .

<TodoList items={this.state.items} />

. . .

SD4x-3.4 286

Property of Penn Engineering, Chris Murphy

class TodoList extends React.Component {

render() {

return (

<ul>

{this.props.items.map(function (item) {

return

<TodoItem id={item.id} text={item.text}/>

})}

</ul>

);

}

}

class TodoApp extends React.Component {

. . .

render() {

return (

. . .

<TodoList items={this.state.items} />

. . .

SD4x-3.4 287

Property of Penn Engineering, Chris Murphy

class TodoList extends React.Component {

render() {

return (

<ul>

{this.props.items.map(function (item) {

return

<TodoItem id={item.id} text={item.text}/>

})}

</ul>

);

}

}

class TodoApp extends React.Component {

. . .

render() {

return (

. . .

<TodoList items={this.state.items} />

. . .

SD4x-3.4 288

Property of Penn Engineering, Chris Murphy

class TodoItem extends React.Component {

constructor(props) {

super(props);

this.state = { amDone: false };

}

handleClick() {

this.setState( { amDone: !this.state.amDone} );

}

render() {

var line = this.state.amDone ? 'line-through' : 'none';

return (

<li key={this.props.id}

onClick={this.handleClick.bind(this)}

style={{textDecoration:line}}>

{this.props.text} </li>

);

}

}

SD4x-3.4 289

Property of Penn Engineering, Chris Murphy

class TodoItem extends React.Component {

constructor(props) {

super(props);

this.state = { amDone: false };

}

handleClick() {

this.setState( { amDone: !this.state.amDone} );

}

render() {

var line = this.state.amDone ? 'line-through' : 'none';

return (

<li key={this.props.id}

onClick={this.handleClick.bind(this)}

style={{textDecoration:line}}>

{this.props.text} </li>

);

}

}

SD4x-3.4 290

Property of Penn Engineering, Chris Murphy

class TodoItem extends React.Component {

constructor(props) {

super(props);

this.state = { amDone: false };

}

handleClick() {

this.setState( { amDone: !this.state.amDone} );

}

render() {

var line = this.state.amDone ? 'line-through' : 'none';

return (

<li key={this.props.id}

onClick={this.handleClick.bind(this)}

style={{textDecoration:line}}>

{this.props.text} </li>

);

}

}

SD4x-3.4 291

Property of Penn Engineering, Chris Murphy

class TodoItem extends React.Component {

constructor(props) {

super(props);

this.state = { amDone: false };

}

handleClick() {

this.setState( { amDone: !this.state.amDone} );

}

render() {

var line = this.state.amDone ? 'line-through' : 'none';

return (

<li key={this.props.id}

onClick={this.handleClick.bind(this)}

style={{textDecoration:line}}>

{this.props.text} </li>

);

}

}

SD4x-3.4 292

Property of Penn Engineering, Chris Murphy

class TodoItem extends React.Component {

constructor(props) {

super(props);

this.state = { amDone: false };

}

handleClick() {

this.setState( { amDone: !this.state.amDone} );

}

render() {

var line = this.state.amDone ? 'line-through' : 'none';

return (

<li key={this.props.id}

onClick={this.handleClick.bind(this)}

style={{textDecoration:line}}>

{this.props.text} </li>

);

}

}

SD4x-3.4 293

Property of Penn Engineering, Chris Murphy

class TodoItem extends React.Component {

constructor(props) {

super(props);

this.state = { amDone: false };

}

handleClick() {

this.setState( { amDone: !this.state.amDone} );

}

render() {

var line = this.state.amDone ? 'line-through' : 'none';

return (

<li key={this.props.id}

onClick={this.handleClick.bind(this)}

style={{textDecoration:line}}>

{this.props.text} </li>

);

}

}

SD4x-3.4 294

Property of Penn Engineering, Chris Murphy

class TodoItem extends React.Component {

constructor(props) {

super(props);

this.state = { amDone: false };

}

handleClick() {

this.setState( { amDone: !this.state.amDone} );

}

render() {

var line = this.state.amDone ? 'line-through' : 'none';

return (

<li key={this.props.id}

onClick={this.handleClick.bind(this)}

style={{textDecoration:line}}>

{this.props.text} </li>

);

}

}

SD4x-3.4 295

Property of Penn Engineering, Chris Murphy

class TodoItem extends React.Component {

constructor(props) {

super(props);

this.state = { amDone: false };

}

handleClick() {

this.setState( { amDone: !this.state.amDone} );

}

render() {

var line = this.state.amDone ? 'line-through' : 'none';

return (

<li key={this.props.id}

onClick={this.handleClick.bind(this)}

style={{textDecoration:line}}>

{this.props.text} </li>

);

}

}

SD4x-3.4 296

Property of Penn Engineering, Chris Murphy

class TodoItem extends React.Component {

constructor(props) {

super(props);

this.state = { amDone: false };

}

handleClick() {

this.setState( { amDone: !this.state.amDone} );

}

render() {

var line = this.state.amDone ? 'line-through' : 'none';

return (

<li key={this.props.id}

onClick={this.handleClick.bind(this)}

style={{textDecoration:line}}>

{this.props.text} </li>

);

}

}

SD4x-3.4 297

Property of Penn Engineering, Chris Murphy

class TodoItem extends React.Component {

constructor(props) {

super(props);

this.state = { amDone: false };

}

handleClick() {

this.setState( { amDone: !this.state.amDone} );

}

render() {

var line = this.state.amDone ? 'line-through' : 'none';

return (

<li key={this.props.id}

onClick={this.handleClick.bind(this)}

style={{textDecoration:line}}>

{this.props.text} </li>

);

}

}

SD4x-3.4 298

Property of Penn Engineering, Chris Murphy

class TodoItem extends React.Component {

constructor(props) {

super(props);

this.state = { amDone: false };

}

handleClick() {

this.setState( { amDone: !this.state.amDone} );

}

render() {

var line = this.state.amDone ? 'line-through' : 'none';

return (

<li key={this.props.id}

onClick={this.handleClick.bind(this)}

style={{textDecoration:line}}>

{this.props.text} </li>

);

}

}

SD4x-3.4 299

Property of Penn Engineering, Chris Murphy

class TodoItem extends React.Component {

constructor(props) {

super(props);

this.state = { amDone: false };

}

handleClick() {

this.setState( { amDone: !this.state.amDone} );

}

render() {

var line = this.state.amDone ? 'line-through' : 'none';

return (

<li key={this.props.id}

onClick={this.handleClick.bind(this)}

style={{textDecoration:line}}>

{this.props.text} </li>

);

}

}

SD4x-3.4 300

Property of Penn Engineering, Chris Murphy

class TodoItem extends React.Component {

constructor(props) {

super(props);

this.state = { amDone: false };

}

handleClick() {

this.setState( { amDone: !this.state.amDone} );

}

render() {

var line = this.state.amDone ? 'line-through' : 'none';

return (

<li key={this.props.id}

onClick={this.handleClick.bind(this)}

style={{textDecoration:line}}>

{this.props.text} </li>

);

}

}

SD4x-3.4 301

Property of Penn Engineering, Chris Murphy

class TodoItem extends React.Component {

constructor(props) {

super(props);

this.state = { amDone: false };

}

handleClick() {

this.setState( { amDone: !this.state.amDone} );

}

render() {

var line = this.state.amDone ? 'line-through' : 'none';

return (

<li key={this.props.id}

onClick={this.handleClick.bind(this)}

style={{textDecoration:line}}>

{this.props.text} </li>

);

}

}

SD4x-3.4 302

Property of Penn Engineering, Chris Murphy

Review

• React allows us to create reusable, modularized components that can be combined to form web applications

• React handles re-rendering of components based on the structure of VirtualDOM

SD4x-3.4 303

Video 3.5

React Component Interaction – part 2

Chris Murphy

SD4x-3.5 304

Property of Penn Engineering, Chris Murphy

Review

• React allows us to create reusable, modularized components that can be combined to form web applications

• React handles re-rendering of components based on the structure of VirtualDOM

SD4x-3.5 305

Property of Penn Engineering, Chris Murphy SD4x-3.5 306

Property of Penn Engineering, Chris Murphy SD4x-3.5 307

Property of Penn Engineering, Chris Murphy SD4x-3.5 308

Property of Penn Engineering, Chris Murphy SD4x-3.5 309

Property of Penn Engineering, Chris Murphy SD4x-3.5 310

Property of Penn Engineering, Chris Murphy SD4x-3.5 311

Property of Penn Engineering, Chris Murphy SD4x-3.5 312

Property of Penn Engineering, Chris Murphy SD4x-3.5 313

Property of Penn Engineering, Chris Murphy SD4x-3.5 314

Property of Penn Engineering, Chris Murphy SD4x-3.5 315

Property of Penn Engineering, Chris Murphy SD4x-3.5 316

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

constructor(props) {

super(props);

this.state = { input1: 0, input2: 0, product: 0 };

this.multiply = this.multiply.bind(this);

}

multiply(id, val) {

if (id == 1) {

this.setState( { input1: val,

product: val * this.state.input2 } );

}

else if (id == 2) {

this.setState( { input2: val,

product: this.state.input1 * val } );

}

}

. . .

SD4x-3.5 317

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

constructor(props) {

super(props);

this.state = { input1: 0, input2: 0, product: 0 };

this.multiply = this.multiply.bind(this);

}

multiply(id, val) {

if (id == 1) {

this.setState( { input1: val,

product: val * this.state.input2 } );

}

else if (id == 2) {

this.setState( { input2: val,

product: this.state.input1 * val } );

}

}

. . .

SD4x-3.5 318

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

constructor(props) {

super(props);

this.state = { input1: 0, input2: 0, product: 0 };

this.multiply = this.multiply.bind(this);

}

multiply(id, val) {

if (id == 1) {

this.setState( { input1: val,

product: val * this.state.input2 } );

}

else if (id == 2) {

this.setState( { input2: val,

product: this.state.input1 * val } );

}

}

. . .

SD4x-3.5 319

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

constructor(props) {

super(props);

this.state = { input1: 0, input2: 0, product: 0 };

this.multiply = this.multiply.bind(this);

}

multiply(id, val) {

if (id == 1) {

this.setState( { input1: val,

product: val * this.state.input2 } );

}

else if (id == 2) {

this.setState( { input2: val,

product: this.state.input1 * val } );

}

}

. . .

SD4x-3.5 320

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

constructor(props) {

super(props);

this.state = { input1: 0, input2: 0, product: 0 };

this.multiply = this.multiply.bind(this);

}

multiply(id, val) {

if (id == 1) {

this.setState( { input1: val,

product: val * this.state.input2 } );

}

else if (id == 2) {

this.setState( { input2: val,

product: this.state.input1 * val } );

}

}

. . .

SD4x-3.5 321

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

constructor(props) {

super(props);

this.state = { input1: 0, input2: 0, product: 0 };

this.multiply = this.multiply.bind(this);

}

multiply(id, val) {

if (id == 1) {

this.setState( { input1: val,

product: val * this.state.input2 } );

}

else if (id == 2) {

this.setState( { input2: val,

product: this.state.input1 * val } );

}

}

. . .

SD4x-3.5 322

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

constructor(props) {

super(props);

this.state = { input1: 0, input2: 0, product: 0 };

this.multiply = this.multiply.bind(this);

}

multiply(id, val) {

if (id == 1) {

this.setState( { input1: val,

product: val * this.state.input2 } );

}

else if (id == 2) {

this.setState( { input2: val,

product: this.state.input1 * val } );

}

}

. . .

SD4x-3.5 323

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

constructor(props) {

super(props);

this.state = { input1: 0, input2: 0, product: 0 };

this.multiply = this.multiply.bind(this);

}

multiply(id, val) {

if (id == 1) {

this.setState( { input1: val,

product: val * this.state.input2 } );

}

else if (id == 2) {

this.setState( { input2: val,

product: this.state.input1 * val } );

}

}

. . .

SD4x-3.5 324

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

constructor(props) {

super(props);

this.state = { input1: 0, input2: 0, product: 0 };

this.multiply = this.multiply.bind(this);

}

multiply(id, val) {

if (id == 1) {

this.setState( { input1: val,

product: val * this.state.input2 } );

}

else if (id == 2) {

this.setState( { input2: val,

product: this.state.input1 * val } );

}

}

. . .

SD4x-3.5 325

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

constructor(props) {

super(props);

this.state = { input1: 0, input2: 0, product: 0 };

this.multiply = this.multiply.bind(this);

}

multiply(id, val) {

if (id == 1) {

this.setState( { input1: val,

product: val * this.state.input2 } );

}

else if (id == 2) {

this.setState( { input2: val,

product: this.state.input1 * val } );

}

}

. . .

SD4x-3.5 326

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

constructor(props) {

super(props);

this.state = { input1: 0, input2: 0, product: 0 };

this.multiply = this.multiply.bind(this);

}

multiply(id, val) {

if (id == 1) {

this.setState( { input1: val,

product: val * this.state.input2 } );

}

else if (id == 2) {

this.setState( { input2: val,

product: this.state.input1 * val } );

}

}

. . .

SD4x-3.5 327

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

constructor(props) {

super(props);

this.state = { input1: 0, input2: 0, product: 0 };

this.multiply = this.multiply.bind(this);

}

multiply(id, val) {

if (id == 1) {

this.setState( { input1: val,

product: val * this.state.input2 } );

}

else if (id == 2) {

this.setState( { input2: val,

product: this.state.input1 * val } );

}

}

. . .

SD4x-3.5 328

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

constructor(props) {

super(props);

this.state = { input1: 0, input2: 0, product: 0 };

this.multiply = this.multiply.bind(this);

}

multiply(id, val) {

if (id == 1) {

this.setState( { input1: val,

product: val * this.state.input2 } );

}

else if (id == 2) {

this.setState( { input2: val,

product: this.state.input1 * val } );

}

}

. . .

SD4x-3.5 329

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

constructor(props) {

super(props);

this.state = { input1: 0, input2: 0, product: 0 };

this.multiply = this.multiply.bind(this);

}

multiply(id, val) {

if (id == 1) {

this.setState( { input1: val,

product: val * this.state.input2 } );

}

else if (id == 2) {

this.setState( { input2: val,

product: this.state.input1 * val } );

}

}

. . .

SD4x-3.5 330

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

constructor(props) {

super(props);

this.state = { input1: 0, input2: 0, product: 0 };

this.multiply = this.multiply.bind(this);

}

multiply(id, val) {

if (id == 1) {

this.setState( { input1: val,

product: val * this.state.input2 } );

}

else if (id == 2) {

this.setState( { input2: val,

product: this.state.input1 * val } );

}

}

. . .

SD4x-3.5 331

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

constructor(props) {

super(props);

this.state = { input1: 0, input2: 0, product: 0 };

this.multiply = this.multiply.bind(this);

}

multiply(id, val) {

if (id == 1) {

this.setState( { input1: val,

product: val * this.state.input2 } );

}

else if (id == 2) {

this.setState( { input2: val,

product: this.state.input1 * val } );

}

}

. . .

SD4x-3.5 332

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

constructor(props) {

super(props);

this.state = { input1: 0, input2: 0, product: 0 };

this.multiply = this.multiply.bind(this);

}

multiply(id, val) {

if (id == 1) {

this.setState( { input1: val,

product: val * this.state.input2 } );

}

else if (id == 2) {

this.setState( { input2: val,

product: this.state.input1 * val } );

}

}

. . .

SD4x-3.5 333

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

. . .

render() {

return (

<div>

<NumberInputField id="1" action={this.multiply}/>

<NumberInputField id="2" action={this.multiply}/>

<OutputField product={this.state.product}/>

</div>

);

}

}

SD4x-3.5 334

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

. . .

render() {

return (

<div>

<NumberInputField id="1" action={this.multiply}/>

<NumberInputField id="2" action={this.multiply}/>

<OutputField product={this.state.product}/>

</div>

);

}

}

SD4x-3.5 335

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

. . .

render() {

return (

<div>

<NumberInputField id="1" action={this.multiply}/>

<NumberInputField id="2" action={this.multiply}/>

<OutputField product={this.state.product}/>

</div>

);

}

}

SD4x-3.5 336

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

. . .

render() {

return (

<div>

<NumberInputField id="1" action={this.multiply}/>

<NumberInputField id="2" action={this.multiply}/>

<OutputField product={this.state.product}/>

</div>

);

}

}

SD4x-3.5 337

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

. . .

render() {

return (

<div>

<NumberInputField id="1" action={this.multiply}/>

<NumberInputField id="2" action={this.multiply}/>

<OutputField product={this.state.product}/>

</div>

);

}

}

SD4x-3.5 338

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

. . .

render() {

return (

<div>

<NumberInputField id="1" action={this.multiply}/>

<NumberInputField id="2" action={this.multiply}/>

<OutputField product={this.state.product}/>

</div>

);

}

}

SD4x-3.5 339

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

. . .

render() {

return (

<div>

<NumberInputField id="1" action={this.multiply}/>

<NumberInputField id="2" action={this.multiply}/>

<OutputField product={this.state.product}/>

</div>

);

}

}

SD4x-3.5 340

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

. . .

<NumberInputField id="1" action={this.multiply}/>

. . .

SD4x-3.5 341

class NumberInputField extends React.Component {

constructor(props) {

super(props);

this.handleChange = this.handleChange.bind(this);

}

handleChange(e) {

this.props.action(this.props.id, e.target.value);

}

render() {

return(

<input onChange={this.handleChange}></input>

);

}

}

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

. . .

<NumberInputField id="1" action={this.multiply}/>

. . .

SD4x-3.5 342

class NumberInputField extends React.Component {

constructor(props) {

super(props);

this.handleChange = this.handleChange.bind(this);

}

handleChange(e) {

this.props.action(this.props.id, e.target.value);

}

render() {

return(

<input onChange={this.handleChange}></input>

);

}

}

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

. . .

<NumberInputField id="1" action={this.multiply}/>

. . .

SD4x-3.5 343

class NumberInputField extends React.Component {

constructor(props) {

super(props);

this.handleChange = this.handleChange.bind(this);

}

handleChange(e) {

this.props.action(this.props.id, e.target.value);

}

render() {

return(

<input onChange={this.handleChange}></input>

);

}

}

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

. . .

<NumberInputField id="1" action={this.multiply}/>

. . .

SD4x-3.5 344

class NumberInputField extends React.Component {

constructor(props) {

super(props);

this.handleChange = this.handleChange.bind(this);

}

handleChange(e) {

this.props.action(this.props.id, e.target.value);

}

render() {

return(

<input onChange={this.handleChange}></input>

);

}

}

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

. . .

<NumberInputField id="1" action={this.multiply}/>

. . .

SD4x-3.5 345

class NumberInputField extends React.Component {

constructor(props) {

super(props);

this.handleChange = this.handleChange.bind(this);

}

handleChange(e) {

this.props.action(this.props.id, e.target.value);

}

render() {

return(

<input onChange={this.handleChange}></input>

);

}

}

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

. . .

<NumberInputField id="1" action={this.multiply}/>

. . .

SD4x-3.5 346

class NumberInputField extends React.Component {

constructor(props) {

super(props);

this.handleChange = this.handleChange.bind(this);

}

handleChange(e) {

this.props.action(this.props.id, e.target.value);

}

render() {

return(

<input onChange={this.handleChange}></input>

);

}

}

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

. . .

<NumberInputField id="1" action={this.multiply}/>

. . .

SD4x-3.5 347

class NumberInputField extends React.Component {

constructor(props) {

super(props);

this.handleChange = this.handleChange.bind(this);

}

handleChange(e) {

this.props.action(this.props.id, e.target.value);

}

render() {

return(

<input onChange={this.handleChange}></input>

);

}

}

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

. . .

<NumberInputField id="1" action={this.multiply}/>

. . .

SD4x-3.5 348

class NumberInputField extends React.Component {

constructor(props) {

super(props);

this.handleChange = this.handleChange.bind(this);

}

handleChange(e) {

this.props.action(this.props.id, e.target.value);

}

render() {

return(

<input onChange={this.handleChange}></input>

);

}

}

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

. . .

<NumberInputField id="1" action={this.multiply}/>

. . .

SD4x-3.5 349

class NumberInputField extends React.Component {

constructor(props) {

super(props);

this.handleChange = this.handleChange.bind(this);

}

handleChange(e) {

this.props.action(this.props.id, e.target.value);

}

render() {

return(

<input onChange={this.handleChange}></input>

);

}

}

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

. . .

<NumberInputField id="1" action={this.multiply}/>

. . .

SD4x-3.5 350

class NumberInputField extends React.Component {

constructor(props) {

super(props);

this.handleChange = this.handleChange.bind(this);

}

handleChange(e) {

this.props.action(this.props.id, e.target.value);

}

render() {

return(

<input onChange={this.handleChange}></input>

);

}

}

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

. . .

<NumberInputField id="1" action={this.multiply}/>

. . .

SD4x-3.5 351

class NumberInputField extends React.Component {

constructor(props) {

super(props);

this.handleChange = this.handleChange.bind(this);

}

handleChange(e) {

this.props.action(this.props.id, e.target.value);

}

render() {

return(

<input onChange={this.handleChange}></input>

);

}

}

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

. . .

<NumberInputField id="1" action={this.multiply}/>

. . .

SD4x-3.5 352

class NumberInputField extends React.Component {

constructor(props) {

super(props);

this.handleChange = this.handleChange.bind(this);

}

handleChange(e) {

this.props.action(this.props.id, e.target.value);

}

render() {

return(

<input onChange={this.handleChange}></input>

);

}

}

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

. . .

<NumberInputField id="1" action={this.multiply}/>

. . .

SD4x-3.5 353

class NumberInputField extends React.Component {

constructor(props) {

super(props);

this.handleChange = this.handleChange.bind(this);

}

handleChange(e) {

this.props.action(this.props.id, e.target.value);

}

render() {

return(

<input onChange={this.handleChange}></input>

);

}

}

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

. . .

multiply(id, val) {

if (id == 1) {

this.setState( { input1: val,

product: val * this.state.input2 } );

}

else if (id == 2) {

this.setState( { input2: val,

product: this.state.input1 * val } );

}

}

. . .

SD4x-3.5 354

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

. . .

multiply(id, val) {

if (id == 1) {

this.setState( { input1: val,

product: val * this.state.input2 } );

}

else if (id == 2) {

this.setState( { input2: val,

product: this.state.input1 * val } );

}

}

. . .

SD4x-3.5 355

Property of Penn Engineering, Chris Murphy

class Multiplier extends React.Component {

. . .

multiply(id, val) {

if (id == 1) {

this.setState( { input1: val,

product: val * this.state.input2 } );

}

else if (id == 2) {

this.setState( { input2: val,

product: this.state.input1 * val } );

}

}

. . .

SD4x-3.5 356

Property of Penn Engineering, Chris Murphy

class OutputField extends React.Component {

render() {

return(

<div>The product is {this.props.product}.

</div>

);

}

}

ReactDOM.render(<Multiplier/>,

document.getElementById('container'));

class Multiplier extends React.Component {

. . .

<OutputField product={this.state.product}/>

. . .

SD4x-3.5 357

Property of Penn Engineering, Chris Murphy

class OutputField extends React.Component {

render() {

return(

<div>The product is {this.props.product}.

</div>

);

}

}

ReactDOM.render(<Multiplier/>,

document.getElementById('container'));

class Multiplier extends React.Component {

. . .

<OutputField product={this.state.product}/>

. . .

SD4x-3.5 358

Property of Penn Engineering, Chris Murphy

class OutputField extends React.Component {

render() {

return(

<div>The product is {this.props.product}.

</div>

);

}

}

ReactDOM.render(<Multiplier/>,

document.getElementById('container'));

class Multiplier extends React.Component {

. . .

<OutputField product={this.state.product}/>

. . .

SD4x-3.5 359

Property of Penn Engineering, Chris Murphy

class OutputField extends React.Component {

render() {

return(

<div>The product is {this.props.product}.

</div>

);

}

}

ReactDOM.render(<Multiplier/>,

document.getElementById('container'));

class Multiplier extends React.Component {

. . .

<OutputField product={this.state.product}/>

. . .

SD4x-3.5 360

Property of Penn Engineering, Chris Murphy

class OutputField extends React.Component {

render() {

return(

<div>The product is {this.props.product}.

</div>

);

}

}

ReactDOM.render(<Multiplier/>,

document.getElementById('container'));

class Multiplier extends React.Component {

. . .

<OutputField product={this.state.product}/>

. . .

SD4x-3.5 361

Property of Penn Engineering, Chris Murphy

class OutputField extends React.Component {

render() {

return(

<div>The product is {this.props.product}.

</div>

);

}

}

ReactDOM.render(<Multiplier/>,

document.getElementById('container'));

class Multiplier extends React.Component {

. . .

<OutputField product={this.state.product}/>

. . .

SD4x-3.5 362

Property of Penn Engineering, Chris Murphy

class OutputField extends React.Component {

render() {

return(

<div>The product is {this.props.product}.

</div>

);

}

}

ReactDOM.render(<Multiplier/>,

document.getElementById('container'));

class Multiplier extends React.Component {

. . .

<OutputField product={this.state.product}/>

. . .

SD4x-3.5 363

Property of Penn Engineering, Chris Murphy

class OutputField extends React.Component {

render() {

return(

<div>The product is {this.props.product}.

</div>

);

}

}

ReactDOM.render(<Multiplier/>,

document.getElementById('container'));

class Multiplier extends React.Component {

. . .

<OutputField product={this.state.product}/>

. . .

SD4x-3.5 364

Property of Penn Engineering, Chris Murphy

Review

• React allows us to create reusable, modularized components that can be combined to form web applications

• Components can communicate with each other via callback methods that are set as props

SD4x-3.5 365

Video 3.6

React and APIs

Chris Murphy

SD4x-3.6 366

Property of Penn Engineering, Chris Murphy

Review

• React allows us to create modular JavaScript components that we can use in our HTML pages to develop web applications

• How can we take advantage of the modular nature of the Web?

SD4x-3.6 367

Property of Penn Engineering, Chris Murphy

Web development in the old days

SD4x-3.6 368

Property of Penn Engineering, Chris Murphy

Designing software for the Web

• How can we make this better?

• Use design paradigms with the following goals:

• Break up code into distinct components

• The components interact with each other in a “standard” manner

• Makes it easy to change any component

• Less dependency and coupling

SD4x-3.6 369

Property of Penn Engineering, Chris Murphy

Service-Oriented Architecture

• Letter by Jeff Bezos to all employees at Amazon (circa 2002)

• “All teams will henceforth expose their data and functionality through service interfaces.”

• “The only communication allowed is via service interface calls over the network.”

• “All service interfaces, without exception, must be designed from the ground up to be externalizable. That is to say, the team must plan and design to be able to expose the interface to developers in the outside world. No exceptions.”

SD4x-3.6 370

Property of Penn Engineering, Chris Murphy

Software as a Service (SaaS)

• Extends the idea of Service-oriented Architecture

• SaaS – entire software runs as a service

• Examples

• Google Docs (as opposed to Microsoft Word)

• Gmail (as opposed to email clients like Outlook)

• Cloud9 (as opposed to Eclipse)

SD4x-3.6 371

Property of Penn Engineering, Chris Murphy

Software as a Service: Advantages

• No user installation is needed

• Less likely to lose data

• Users can collaborate with each other

• Upgrading software and datasets is easy

• Software is centralized in a single environment (don’t need to worry about versions of operating systems, etc.)

• User’s computer (hardware and software specifications) don’t matter – usually all that’s needed is a web browser

SD4x-3.6 372

Property of Penn Engineering, Chris Murphy

Microservices

SD4x-3.6 373

Property of Penn Engineering, Chris Murphy

Microservices

SD4x-3.6 374

Property of Penn Engineering, Chris Murphy

REST

• How do well-designed web servers behave?

• Define a set of rules and conventions

• REST: REpresentational State Transfer

• Collection of resources on which specific operations can be performed

• URI names resources, not pages or actions

• Self-contained - which resource, what to do with it, server doesn’t need to maintain state between requests

SD4x-3.6 375

Property of Penn Engineering, Chris Murphy

What is an API?

• An API is an Application Programming Interface

• In web programming, an API is a URL or a set of URLs that returns pure data to requests

• APIs can be used to incorporate data and functionality from other sources in your webapp

SD4x-3.6 376

Property of Penn Engineering, Chris Murphy

The New York Times

• The New York Times is an American daily newspaper company

• The New York Times provides a variety of APIs that provide article data, books data, movies data, and more

• You can see more about available APIs and request access at https://developer.nytimes.com/

SD4x-3.6 377

Property of Penn Engineering, Chris Murphy

Our Goal

• Created a webapp that creates a dashboard of clickable New York Times article images

SD4x-3.6 378

Property of Penn Engineering, Chris Murphy

Getting Started

• Request a developer key for the Article Search API at https://developer.nytimes.com/

• You can test out the API and what the returned data looks like at https://developer.nytimes.com/article_search_v2.json

SD4x-3.6 379

Property of Penn Engineering, Chris Murphy

Structure

• First, let’s create a new React component named ArticlesGrid to store the data in the page

class ArticlesGrid extends React.Component {

constructor (props) {

super(props);

this.state = {

articles: []

};

}

. . .

SD4x-3.6 380

Property of Penn Engineering, Chris Murphy

Structure

• First, let’s create a new React component named ArticlesGrid to store the data in the page

class ArticlesGrid extends React.Component {

constructor (props) {

super(props);

this.state = {

articles: []

};

}

. . .

SD4x-3.6 381

Property of Penn Engineering, Chris Murphy

Structure

• First, let’s create a new React component named ArticlesGrid to store the data in the page

class ArticlesGrid extends React.Component {

constructor (props) {

super(props);

this.state = {

articles: []

};

}

. . .

SD4x-3.6 382

Property of Penn Engineering, Chris Murphy

Structure

• First, let’s create a new React component named ArticlesGrid to store the data in the page

class ArticlesGrid extends React.Component {

constructor (props) {

super(props);

this.state = {

articles: []

};

}

. . .

SD4x-3.6 383

Property of Penn Engineering, Chris Murphy

Getting Data

• Let’s start by getting some data from the API with a search term.

• We will do this with jQuery AJAXclass ArticlesGrid extends React.Component {

. . .

componentDidMount () {

var url=

'http://api.nytimes.com/svc/search/v2/articlesearch.json?'

+ 'api-key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

$.getJSON(url, function(data, status) {

return this.setState({articles: this.parse(data)});

}.bind(this));

}

. . .

SD4x-3.6 384

Property of Penn Engineering, Chris Murphy

Getting Data

• Let’s start by getting some data from the API with a search term.

• We will do this with jQuery AJAXclass ArticlesGrid extends React.Component {

. . .

componentDidMount () {

var url=

'http://api.nytimes.com/svc/search/v2/articlesearch.json?'

+ 'api-key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

$.getJSON(url, function(data, status) {

return this.setState({articles: this.parse(data)});

}.bind(this));

}

. . .

SD4x-3.6 385

Property of Penn Engineering, Chris Murphy

Getting Data

• Let’s start by getting some data from the API with a search term.

• We will do this with jQuery AJAXclass ArticlesGrid extends React.Component {

. . .

componentDidMount () {

var url=

'http://api.nytimes.com/svc/search/v2/articlesearch.json?'

+ 'api-key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

$.getJSON(url, function(data, status) {

return this.setState({articles: this.parse(data)});

}.bind(this));

}

. . .

SD4x-3.6 386

Property of Penn Engineering, Chris Murphy

Getting Data

• Let’s start by getting some data from the API with a search term.

• We will do this with jQuery AJAX

SD4x-3.6 387

class ArticlesGrid extends React.Component {

. . .

componentDidMount () {

var url=

'http://api.nytimes.com/svc/search/v2/articlesearch.json?'

+ 'api-key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

$.getJSON(url, function(data, status) {

return this.setState({articles: this.parse(data)});

}.bind(this));

}

. . .

Property of Penn Engineering, Chris Murphy

Getting Data

• Let’s start by getting some data from the API with a search term.

• We will do this with jQuery AJAXclass ArticlesGrid extends React.Component {

. . .

componentDidMount () {

var url=

'http://api.nytimes.com/svc/search/v2/articlesearch.json?'

+ 'api-key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

$.getJSON(url, function(data, status) {

return this.setState({articles: this.parse(data)});

}.bind(this));

}

. . .

SD4x-3.6 388

Property of Penn Engineering, Chris Murphy

Getting Data

• Let’s start by getting some data from the API with a search term.

• We will do this with jQuery AJAXclass ArticlesGrid extends React.Component {

. . .

componentDidMount () {

var url=

'http://api.nytimes.com/svc/search/v2/articlesearch.json?'

+ 'api-key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

$.getJSON(url, function(data, status) {

return this.setState({articles: this.parse(data)});

}.bind(this));

}

. . .

SD4x-3.6 389

Property of Penn Engineering, Chris Murphy

Getting Data

• Let’s start by getting some data from the API with a search term.

• We will do this with jQuery AJAX

SD4x-3.6 390

class ArticlesGrid extends React.Component {

. . .

componentDidMount () {

var url=

'http://api.nytimes.com/svc/search/v2/articlesearch.json?'

+ 'api-key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

$.getJSON(url, function(data, status) {

return this.setState({articles: this.parse(data)});

}.bind(this));

}

. . .

Property of Penn Engineering, Chris Murphy

Getting Data

• Let’s start by getting some data from the API with a search term.

• We will do this with jQuery AJAX

SD4x-3.6 391

class ArticlesGrid extends React.Component {

. . .

componentDidMount () {

var url=

'http://api.nytimes.com/svc/search/v2/articlesearch.json?'

+ 'api-key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

$.getJSON(url, function(data, status) {

return this.setState({articles: this.parse(data)});

}.bind(this));

}

. . .

Property of Penn Engineering, Chris Murphy

Getting Data

• Let’s start by getting some data from the API with a search term.

• We will do this with jQuery AJAXclass ArticlesGrid extends React.Component {

. . .

componentDidMount () {

var url=

'http://api.nytimes.com/svc/search/v2/articlesearch.json?'

+ 'api-key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

$.getJSON(url, function(data, status) {

return this.setState({articles: this.parse(data)});

}.bind(this));

}

. . .

SD4x-3.6 392

Property of Penn Engineering, Chris Murphy

Getting Data

• Let’s start by getting some data from the API with a search term.

• We will do this with jQuery AJAXclass ArticlesGrid extends React.Component {

. . .

componentDidMount () {

var url=

'http://api.nytimes.com/svc/search/v2/articlesearch.json?'

+ 'api-key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

$.getJSON(url, function(data, status) {

return this.setState({articles: this.parse(data)});

}.bind(this));

}

. . .

SD4x-3.6 393

Property of Penn Engineering, Chris Murphy

Getting Data

• Let’s start by getting some data from the API with a search term.

• We will do this with jQuery AJAXclass ArticlesGrid extends React.Component {

. . .

componentDidMount () {

var url=

'http://api.nytimes.com/svc/search/v2/articlesearch.json?'

+ 'api-key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

$.getJSON(url, function(data, status) {

return this.setState({articles: this.parse(data)});

}.bind(this));

}

. . .

SD4x-3.6 394

Property of Penn Engineering, Chris Murphy

Getting Data

• Let’s start by getting some data from the API with a search term.

• We will do this with jQuery AJAXclass ArticlesGrid extends React.Component {

. . .

componentDidMount () {

var url=

'http://api.nytimes.com/svc/search/v2/articlesearch.json?'

+ 'api-key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

$.getJSON(url, function(data, status) {

return this.setState({articles: this.parse(data)});

}.bind(this));

}

. . .

SD4x-3.6 395

Property of Penn Engineering, Chris Murphy SD4x-3.6 396

{

"response": {

"meta": {

"hits": 4251,

"time": 36,

"offset": 0

},

"docs": [

{

"web_url": "https://query.nytimes.com/gst/...",

"snippet": "Having invited Senator LA FOLLETTE to make a

statement of his cause and case in today's TIMES, we would

refer to it only with becoming courtesy. Its great lack must

be obvious to every reader. This is its extreme indefiniteness.

The Senator uses w...",

"lead_paragraph": "Having invited Senator LA FOLLETTE

to make a statement of his cause and case in today's TIMES,

we would refer to it only with becoming courtesy. Its great

lack must be obvious to every reader. This is its extreme

indefiniteness. The Senator uses with vehemence a great many

terms without defining one of them.",

. . .

}

{

"web_url": "https://query.nytimes.com/gst/...",

"snippet": ”At Washington last week the spokesman...

Property of Penn Engineering, Chris Murphy SD4x-3.6 397

{

"response": {

"meta": {

"hits": 4251,

"time": 36,

"offset": 0

},

"docs": [

{

"web_url": "https://query.nytimes.com/gst/...",

"snippet": "Having invited Senator LA FOLLETTE to make a

statement of his cause and case in today's TIMES, we would

refer to it only with becoming courtesy. Its great lack must

be obvious to every reader. This is its extreme indefiniteness.

The Senator uses w...",

"lead_paragraph": "Having invited Senator LA FOLLETTE

to make a statement of his cause and case in today's TIMES,

we would refer to it only with becoming courtesy. Its great

lack must be obvious to every reader. This is its extreme

indefiniteness. The Senator uses with vehemence a great many

terms without defining one of them.",

. . .

}

{

"web_url": "https://query.nytimes.com/gst/...",

"snippet": ”At Washington last week the spokesman...

Property of Penn Engineering, Chris Murphy SD4x-3.6 398

{

"response": {

"meta": {

"hits": 4251,

"time": 36,

"offset": 0

},

"docs": [

{

"web_url": "https://query.nytimes.com/gst/...",

"snippet": "Having invited Senator LA FOLLETTE to make a

statement of his cause and case in today's TIMES, we would

refer to it only with becoming courtesy. Its great lack must

be obvious to every reader. This is its extreme indefiniteness.

The Senator uses w...",

"lead_paragraph": "Having invited Senator LA FOLLETTE

to make a statement of his cause and case in today's TIMES,

we would refer to it only with becoming courtesy. Its great

lack must be obvious to every reader. This is its extreme

indefiniteness. The Senator uses with vehemence a great many

terms without defining one of them.",

. . .

}

{

"web_url": "https://query.nytimes.com/gst/...",

"snippet": ”At Washington last week the spokesman...

Property of Penn Engineering, Chris Murphy SD4x-3.6 399

{

"response": {

"meta": {

"hits": 4251,

"time": 36,

"offset": 0

},

"docs": [

{

"web_url": "https://query.nytimes.com/gst/...",

"snippet": "Having invited Senator LA FOLLETTE to make a

statement of his cause and case in today's TIMES, we would

refer to it only with becoming courtesy. Its great lack must

be obvious to every reader. This is its extreme indefiniteness.

The Senator uses w...",

"lead_paragraph": "Having invited Senator LA FOLLETTE

to make a statement of his cause and case in today's TIMES,

we would refer to it only with becoming courtesy. Its great

lack must be obvious to every reader. This is its extreme

indefiniteness. The Senator uses with vehemence a great many

terms without defining one of them.",

. . .

}

{

"web_url": "https://query.nytimes.com/gst/...",

"snippet": ”At Washington last week the spokesman...

Property of Penn Engineering, Chris Murphy SD4x-3.6 400

{

"response": {

"meta": {

"hits": 4251,

"time": 36,

"offset": 0

},

"docs": [

{

"web_url": "https://query.nytimes.com/gst/...",

"snippet": "Having invited Senator LA FOLLETTE to make a

statement of his cause and case in today's TIMES, we would

refer to it only with becoming courtesy. Its great lack must

be obvious to every reader. This is its extreme indefiniteness.

The Senator uses w...",

"lead_paragraph": "Having invited Senator LA FOLLETTE

to make a statement of his cause and case in today's TIMES,

we would refer to it only with becoming courtesy. Its great

lack must be obvious to every reader. This is its extreme

indefiniteness. The Senator uses with vehemence a great many

terms without defining one of them.",

. . .

}

{

"web_url": "https://query.nytimes.com/gst/...",

"snippet": ”At Washington last week the spokesman...

Property of Penn Engineering, Chris Murphy SD4x-3.6 401

{

"response": {

"meta": {

"hits": 4251,

"time": 36,

"offset": 0

},

"docs": [

{

"web_url": "https://query.nytimes.com/gst/...",

"snippet": "Having invited Senator LA FOLLETTE to make a

statement of his cause and case in today's TIMES, we would

refer to it only with becoming courtesy. Its great lack must

be obvious to every reader. This is its extreme indefiniteness.

The Senator uses w...",

"lead_paragraph": "Having invited Senator LA FOLLETTE

to make a statement of his cause and case in today's TIMES,

we would refer to it only with becoming courtesy. Its great

lack must be obvious to every reader. This is its extreme

indefiniteness. The Senator uses with vehemence a great many

terms without defining one of them.",

. . .

}

{

"web_url": "https://query.nytimes.com/gst/...",

"snippet": ”At Washington last week the spokesman...

Property of Penn Engineering, Chris Murphy SD4x-3.6 402

{

"response": {

"meta": {

"hits": 4251,

"time": 36,

"offset": 0

},

"docs": [

{

"web_url": "https://query.nytimes.com/gst/...",

"snippet": "Having invited Senator LA FOLLETTE to make a

statement of his cause and case in today's TIMES, we would

refer to it only with becoming courtesy. Its great lack must

be obvious to every reader. This is its extreme indefiniteness.

The Senator uses w...",

"lead_paragraph": "Having invited Senator LA FOLLETTE

to make a statement of his cause and case in today's TIMES,

we would refer to it only with becoming courtesy. Its great

lack must be obvious to every reader. This is its extreme

indefiniteness. The Senator uses with vehemence a great many

terms without defining one of them.",

. . .

}

{

"web_url": "https://query.nytimes.com/gst/...",

"snippet": ”At Washington last week the spokesman...

Property of Penn Engineering, Chris Murphy

Parsing Data

• The NY Times API will return a lot of raw data!

• Let’s parse the data into something we can use

• For each article, we’ll keep the image URL, title, and URL to original article if a large image exists

SD4x-3.6 403

Property of Penn Engineering, Chris Murphy

class ArticlesGrid extends React.Component {

. . .

parse(results) {

if( !results || !results.response ) return [];

var articles = results.response.docs;

var parsedArticles = [];

for (var i = 0; i < articles.length; i++) {

var article = articles[i];

if (article.multimedia.find(this.isXL)) {

parsedArticles.push({

id: article._id,

title: article.headline.main || 'Untitled',

imageURL: article.multimedia.find(this.isXL).url || '#',

webURL: article.web_url || '#'

});

}

}

return parsedArticles;

}

isXL (image) {

return image.subtype === 'xlarge';

}

SD4x-3.6 404

Property of Penn Engineering, Chris Murphy

class ArticlesGrid extends React.Component {

. . .

parse(results) {

if( !results || !results.response ) return [];

var articles = results.response.docs;

var parsedArticles = [];

for (var i = 0; i < articles.length; i++) {

var article = articles[i];

if (article.multimedia.find(this.isXL)) {

parsedArticles.push({

id: article._id,

title: article.headline.main || 'Untitled',

imageURL: article.multimedia.find(this.isXL).url || '#',

webURL: article.web_url || '#'

});

}

}

return parsedArticles;

}

isXL (image) {

return image.subtype === 'xlarge';

}

SD4x-3.6 405

Property of Penn Engineering, Chris Murphy

class ArticlesGrid extends React.Component {

. . .

parse(results) {

if( !results || !results.response ) return [];

var articles = results.response.docs;

var parsedArticles = [];

for (var i = 0; i < articles.length; i++) {

var article = articles[i];

if (article.multimedia.find(this.isXL)) {

parsedArticles.push({

id: article._id,

title: article.headline.main || 'Untitled',

imageURL: article.multimedia.find(this.isXL).url || '#',

webURL: article.web_url || '#'

});

}

}

return parsedArticles;

}

isXL (image) {

return image.subtype === 'xlarge';

}

SD4x-3.6 406

Property of Penn Engineering, Chris Murphy

class ArticlesGrid extends React.Component {

. . .

parse(results) {

if( !results || !results.response ) return [];

var articles = results.response.docs;

var parsedArticles = [];

for (var i = 0; i < articles.length; i++) {

var article = articles[i];

if (article.multimedia.find(this.isXL)) {

parsedArticles.push({

id: article._id,

title: article.headline.main || 'Untitled',

imageURL: article.multimedia.find(this.isXL).url || '#',

webURL: article.web_url || '#'

});

}

}

return parsedArticles;

}

isXL (image) {

return image.subtype === 'xlarge';

}

SD4x-3.6 407

Property of Penn Engineering, Chris Murphy

class ArticlesGrid extends React.Component {

. . .

parse(results) {

if( !results || !results.response ) return [];

var articles = results.response.docs;

var parsedArticles = [];

for (var i = 0; i < articles.length; i++) {

var article = articles[i];

if (article.multimedia.find(this.isXL)) {

parsedArticles.push({

id: article._id,

title: article.headline.main || 'Untitled',

imageURL: article.multimedia.find(this.isXL).url || '#',

webURL: article.web_url || '#'

});

}

}

return parsedArticles;

}

isXL (image) {

return image.subtype === 'xlarge';

}

SD4x-3.6 408

Property of Penn Engineering, Chris Murphy

class ArticlesGrid extends React.Component {

. . .

parse(results) {

if( !results || !results.response ) return [];

var articles = results.response.docs;

var parsedArticles = [];

for (var i = 0; i < articles.length; i++) {

var article = articles[i];

if (article.multimedia.find(this.isXL)) {

parsedArticles.push({

id: article._id,

title: article.headline.main || 'Untitled',

imageURL: article.multimedia.find(this.isXL).url || '#',

webURL: article.web_url || '#'

});

}

}

return parsedArticles;

}

isXL (image) {

return image.subtype === 'xlarge';

}

SD4x-3.6 409

Property of Penn Engineering, Chris Murphy

class ArticlesGrid extends React.Component {

. . .

parse(results) {

if( !results || !results.response ) return [];

var articles = results.response.docs;

var parsedArticles = [];

for (var i = 0; i < articles.length; i++) {

var article = articles[i];

if (article.multimedia.find(this.isXL)) {

parsedArticles.push({

id: article._id,

title: article.headline.main || 'Untitled',

imageURL: article.multimedia.find(this.isXL).url || '#',

webURL: article.web_url || '#'

});

}

}

return parsedArticles;

}

isXL (image) {

return image.subtype === 'xlarge';

}

SD4x-3.6 410

Property of Penn Engineering, Chris Murphy

class ArticlesGrid extends React.Component {

. . .

parse(results) {

if( !results || !results.response ) return [];

var articles = results.response.docs;

var parsedArticles = [];

for (var i = 0; i < articles.length; i++) {

var article = articles[i];

if (article.multimedia.find(this.isXL)) {

parsedArticles.push({

id: article._id,

title: article.headline.main || 'Untitled',

imageURL: article.multimedia.find(this.isXL).url || '#',

webURL: article.web_url || '#'

});

}

}

return parsedArticles;

}

isXL (image) {

return image.subtype === 'xlarge';

}

SD4x-3.6 411

Property of Penn Engineering, Chris Murphy

class ArticlesGrid extends React.Component {

. . .

parse(results) {

if( !results || !results.response ) return [];

var articles = results.response.docs;

var parsedArticles = [];

for (var i = 0; i < articles.length; i++) {

var article = articles[i];

if (article.multimedia.find(this.isXL)) {

parsedArticles.push({

id: article._id,

title: article.headline.main || 'Untitled',

imageURL: article.multimedia.find(this.isXL).url || '#',

webURL: article.web_url || '#'

});

}

}

return parsedArticles;

}

isXL (image) {

return image.subtype === 'xlarge';

}

SD4x-3.6 412

Property of Penn Engineering, Chris Murphy

class ArticlesGrid extends React.Component {

. . .

parse(results) {

if( !results || !results.response ) return [];

var articles = results.response.docs;

var parsedArticles = [];

for (var i = 0; i < articles.length; i++) {

var article = articles[i];

if (article.multimedia.find(this.isXL)) {

parsedArticles.push({

id: article._id,

title: article.headline.main || 'Untitled',

imageURL: article.multimedia.find(this.isXL).url || '#',

webURL: article.web_url || '#'

});

}

}

return parsedArticles;

}

isXL (image) {

return image.subtype === 'xlarge';

}

SD4x-3.6 413

Property of Penn Engineering, Chris Murphy

class ArticlesGrid extends React.Component {

. . .

parse(results) {

if( !results || !results.response ) return [];

var articles = results.response.docs;

var parsedArticles = [];

for (var i = 0; i < articles.length; i++) {

var article = articles[i];

if (article.multimedia.find(this.isXL)) {

parsedArticles.push({

id: article._id,

title: article.headline.main || 'Untitled',

imageURL: article.multimedia.find(this.isXL).url || '#',

webURL: article.web_url || '#'

});

}

}

return parsedArticles;

}

isXL (image) {

return image.subtype === 'xlarge';

}

SD4x-3.6 414

Property of Penn Engineering, Chris Murphy

class ArticlesGrid extends React.Component {

. . .

parse(results) {

if( !results || !results.response ) return [];

var articles = results.response.docs;

var parsedArticles = [];

for (var i = 0; i < articles.length; i++) {

var article = articles[i];

if (article.multimedia.find(this.isXL)) {

parsedArticles.push({

id: article._id,

title: article.headline.main || 'Untitled',

imageURL: article.multimedia.find(this.isXL).url || '#',

webURL: article.web_url || '#'

});

}

}

return parsedArticles;

}

isXL (image) {

return image.subtype === 'xlarge';

}

SD4x-3.6 415

Property of Penn Engineering, Chris Murphy

class ArticlesGrid extends React.Component {

. . .

parse(results) {

if( !results || !results.response ) return [];

var articles = results.response.docs;

var parsedArticles = [];

for (var i = 0; i < articles.length; i++) {

var article = articles[i];

if (article.multimedia.find(this.isXL)) {

parsedArticles.push({

id: article._id,

title: article.headline.main || 'Untitled',

imageURL: article.multimedia.find(this.isXL).url || '#',

webURL: article.web_url || '#'

});

}

}

return parsedArticles;

}

isXL (image) {

return image.subtype === 'xlarge';

}

SD4x-3.6 416

Property of Penn Engineering, Chris Murphy

class ArticlesGrid extends React.Component {

. . .

parse(results) {

if( !results || !results.response ) return [];

var articles = results.response.docs;

var parsedArticles = [];

for (var i = 0; i < articles.length; i++) {

var article = articles[i];

if (article.multimedia.find(this.isXL)) {

parsedArticles.push({

id: article._id,

title: article.headline.main || 'Untitled',

imageURL: article.multimedia.find(this.isXL).url || '#',

webURL: article.web_url || '#'

});

}

}

return parsedArticles;

}

isXL (image) {

return image.subtype === 'xlarge';

}

SD4x-3.6 417

Property of Penn Engineering, Chris Murphy

class ArticlesGrid extends React.Component {

. . .

parse(results) {

if( !results || !results.response ) return [];

var articles = results.response.docs;

var parsedArticles = [];

for (var i = 0; i < articles.length; i++) {

var article = articles[i];

if (article.multimedia.find(this.isXL)) {

parsedArticles.push({

id: article._id,

title: article.headline.main || 'Untitled',

imageURL: article.multimedia.find(this.isXL).url || '#',

webURL: article.web_url || '#'

});

}

}

return parsedArticles;

}

isXL (image) {

return image.subtype === 'xlarge';

}

SD4x-3.6 418

Property of Penn Engineering, Chris Murphy

Displaying Data

• Now that we have the data, let’s make a component to display each article!

• This is shorthand for a component that only has a “render” function

var Article = function({article}) {

var imgURL = 'https://static01.nyt.com/' + article.imageURL;

return (

<div className='article'>

<a className='article-link' href={article.webURL}>

<img className='article-image'

title={article.title}

src={imgURL} />

</a>

</div>

);

}

SD4x-3.6 419

Property of Penn Engineering, Chris Murphy

Displaying Data

• Now that we have the data, let’s make a component to display each article!

• This is shorthand for a component that only has a “render” function

var Article = function({article}) {

var imgURL = 'https://static01.nyt.com/' + article.imageURL;

return (

<div className='article'>

<a className='article-link' href={article.webURL}>

<img className='article-image'

title={article.title}

src={imgURL} />

</a>

</div>

);

}

SD4x-3.6 420

Property of Penn Engineering, Chris Murphy

Displaying Data

• Now that we have the data, let’s make a component to display each article!

• This is shorthand for a component that only has a “render” function

var Article = function({article}) {

var imgURL = 'https://static01.nyt.com/' + article.imageURL;

return (

<div className='article'>

<a className='article-link' href={article.webURL}>

<img className='article-image'

title={article.title}

src={imgURL} />

</a>

</div>

);

}

SD4x-3.6 421

Property of Penn Engineering, Chris Murphy

Displaying Data

• Now that we have the data, let’s make a component to display each article!

• This is shorthand for a component that only has a “render” function

var Article = function({article}) {

var imgURL = 'https://static01.nyt.com/' + article.imageURL;

return (

<div className='article'>

<a className='article-link' href={article.webURL}>

<img className='article-image'

title={article.title}

src={imgURL} />

</a>

</div>

);

}

SD4x-3.6 422

Property of Penn Engineering, Chris Murphy

Displaying Data

• Now that we have the data, let’s make a component to display each article!

• This is shorthand for a component that only has a “render” function

var Article = function({article}) {

var imgURL = 'https://static01.nyt.com/' + article.imageURL;

return (

<div className='article'>

<a className='article-link' href={article.webURL}>

<img className='article-image'

title={article.title}

src={imgURL} />

</a>

</div>

);

}

SD4x-3.6 423

Property of Penn Engineering, Chris Murphy

Displaying Data

• Now that we have the data, let’s make a component to display each article!

• This is shorthand for a component that only has a “render” function

var Article = function({article}) {

var imgURL = 'https://static01.nyt.com/' + article.imageURL;

return (

<div className='article'>

<a className='article-link' href={article.webURL}>

<img className='article-image'

title={article.title}

src={imgURL} />

</a>

</div>

);

}

SD4x-3.6 424

Property of Penn Engineering, Chris Murphy

Displaying Data

• Now that we have the data, let’s make a component to display each article!

• This is shorthand for a component that only has a “render” function

var Article = function({article}) {

var imgURL = 'https://static01.nyt.com/' + article.imageURL;

return (

<div className='article'>

<a className='article-link' href={article.webURL}>

<img className='article-image'

title={article.title}

src={imgURL} />

</a>

</div>

);

}

SD4x-3.6 425

Property of Penn Engineering, Chris Murphy

Displaying Data

• Now that we have the data, let’s make a component to display each article!

• This is shorthand for a component that only has a “render” function

var Article = function({article}) {

var imgURL = 'https://static01.nyt.com/' + article.imageURL;

return (

<div className='article'>

<a className='article-link' href={article.webURL}>

<img className='article-image'

title={article.title}

src={imgURL} />

</a>

</div>

);

}

SD4x-3.6 426

Property of Penn Engineering, Chris Murphy

Displaying Data

• Now that we have the data, let’s make a component to display each article!

• This is shorthand for a component that only has a “render” function

var Article = function({article}) {

var imgURL = 'https://static01.nyt.com/' + article.imageURL;

return (

<div className='article'>

<a className='article-link' href={article.webURL}>

<img className='article-image'

title={article.title}

src={imgURL} />

</a>

</div>

);

}

SD4x-3.6 427

Property of Penn Engineering, Chris Murphy

Displaying Data

• Now that we have the data, let’s make a component to display each article!

• This is shorthand for a component that only has a “render” function

var Article = function({article}) {

var imgURL = 'https://static01.nyt.com/' + article.imageURL;

return (

<div className='article'>

<a className='article-link' href={article.webURL}>

<img className='article-image'

title={article.title}

src={imgURL} />

</a>

</div>

);

}

SD4x-3.6 428

Property of Penn Engineering, Chris Murphy

Displaying Data

• Now that we have the data, let’s make a component to display each article!

• This is shorthand for a component that only has a “render” function

var Article = function({article}) {

var imgURL = 'https://static01.nyt.com/' + article.imageURL;

return (

<div className='article'>

<a className='article-link' href={article.webURL}>

<img className='article-image'

title={article.title}

src={imgURL} />

</a>

</div>

);

}

SD4x-3.6 429

Property of Penn Engineering, Chris Murphy

Displaying Data

• Now that we have the data, let’s make a component to display each article!

• This is shorthand for a component that only has a “render” function

var Article = function({article}) {

var imgURL = 'https://static01.nyt.com/' + article.imageURL;

return (

<div className='article'>

<a className='article-link' href={article.webURL}>

<img className='article-image'

title={article.title}

src={imgURL} />

</a>

</div>

);

}

SD4x-3.6 430

Property of Penn Engineering, Chris Murphy

Displaying Data

• Now that we have the data, let’s make a component to display each article!

• This is shorthand for a component that only has a “render” function

var Article = function({article}) {

var imgURL = 'https://static01.nyt.com/' + article.imageURL;

return (

<div className='article'>

<a className='article-link' href={article.webURL}>

<img className='article-image'

title={article.title}

src={imgURL} />

</a>

</div>

);

}

SD4x-3.6 431

Property of Penn Engineering, Chris Murphy

Displaying Data

• Now that we have the data, let’s make a component to display each article!

• This is shorthand for a component that only has a “render” function

var Article = function({article}) {

var imgURL = 'https://static01.nyt.com/' + article.imageURL;

return (

<div className='article'>

<a className='article-link' href={article.webURL}>

<img className='article-image'

title={article.title}

src={imgURL} />

</a>

</div>

);

}

SD4x-3.6 432

Property of Penn Engineering, Chris Murphy

Displaying Data

• Finally, we can render the Articles Grid to tie it all together.

class ArticlesGrid extends React.Component {

. . .

render () {

return this.state.articles && (

<div className='articles'>

{ this.state.articles.map( function (article) {

return <Article article={article} key={article._id} />;

})}

</div>

);

}

SD4x-3.6 433

Property of Penn Engineering, Chris Murphy

Displaying Data

• Finally, we can render the Articles Grid to tie it all together.

class ArticlesGrid extends React.Component {

. . .

render () {

return this.state.articles && (

<div className='articles'>

{ this.state.articles.map( function (article) {

return <Article article={article} key={article._id} />;

})}

</div>

);

}

SD4x-3.6 434

Property of Penn Engineering, Chris Murphy

Displaying Data

• Finally, we can render the Articles Grid to tie it all together.

class ArticlesGrid extends React.Component {

. . .

render () {

return this.state.articles && (

<div className='articles'>

{ this.state.articles.map( function (article) {

return <Article article={article} key={article._id} />;

})}

</div>

);

}

SD4x-3.6 435

Property of Penn Engineering, Chris Murphy

Displaying Data

• Finally, we can render the Articles Grid to tie it all together.

class ArticlesGrid extends React.Component {

. . .

render () {

return this.state.articles && (

<div className='articles'>

{ this.state.articles.map( function (article) {

return <Article article={article} key={article._id} />;

})}

</div>

);

}

SD4x-3.6 436

Property of Penn Engineering, Chris Murphy

Displaying Data

• Finally, we can render the Articles Grid to tie it all together.

class ArticlesGrid extends React.Component {

. . .

render () {

return this.state.articles && (

<div className='articles'>

{ this.state.articles.map( function (article) {

return <Article article={article} key={article._id} />;

})}

</div>

);

}

SD4x-3.6 437

Property of Penn Engineering, Chris Murphy

Displaying Data

• Finally, we can render the Articles Grid to tie it all together.

class ArticlesGrid extends React.Component {

. . .

render () {

return this.state.articles && (

<div className='articles'>

{ this.state.articles.map( function (article) {

return <Article article={article} key={article._id} />;

})}

</div>

);

}

SD4x-3.6 438

Property of Penn Engineering, Chris Murphy

Displaying Data

• Finally, we can render the Articles Grid to tie it all together.

class ArticlesGrid extends React.Component {

. . .

render () {

return this.state.articles && (

<div className='articles'>

{ this.state.articles.map( function (article) {

return <Article article={article} key={article._id} />;

})}

</div>

);

}

SD4x-3.6 439

Property of Penn Engineering, Chris Murphy

Displaying Data

• Finally, we can render the Articles Grid to tie it all together.

class ArticlesGrid extends React.Component {

. . .

render () {

return this.state.articles && (

<div className='articles'>

{ this.state.articles.map( function (article) {

return <Article article={article} key={article._id} />;

})}

</div>

);

}

SD4x-3.6 440

Property of Penn Engineering, Chris Murphy

Displaying Data

• Finally, we can render the Articles Grid to tie it all together.

class ArticlesGrid extends React.Component {

. . .

render () {

return this.state.articles && (

<div className='articles'>

{ this.state.articles.map( function (article) {

return <Article article={article} key={article._id} />;

})}

</div>

);

}

SD4x-3.6 441

Property of Penn Engineering, Chris Murphy

Displaying Data

• Finally, we can render the Articles Grid to tie it all together.

class ArticlesGrid extends React.Component {

. . .

render () {

return this.state.articles && (

<div className='articles'>

{ this.state.articles.map( function (article) {

return <Article article={article} key={article._id} />;

})}

</div>

);

}

SD4x-3.6 442

Property of Penn Engineering, Chris Murphy

Displaying Data

• Finally, we can render the Articles Grid to tie it all together.

class ArticlesGrid extends React.Component {

. . .

render () {

return this.state.articles && (

<div className='articles'>

{ this.state.articles.map( function (article) {

return <Article article={article} key={article._id} />;

})}

</div>

);

}

SD4x-3.6 443

Property of Penn Engineering, Chris Murphy

Summary

• Service Oriented Architecture and Software as a Service (SaaS) simplify the creation of web applications by allowing for combinations of online components

• We can accesses services via RESTful APIs and develop React components to make use of them

SD4x-3.6 444

Video 3.7

React App Development

Chris Murphy

SD4x-3.7 445

Property of Penn Engineering, Chris Murphy

Review

• React allows us to create web applications by developing reusable, modular components

• So far, we’ve seen how to define components within the HTML pages

• How do we develop larger applications with multiple components?

SD4x-3.7 446

Property of Penn Engineering, Chris Murphy

Node.js - Introduction

• Node.js is a free, open source platform and framework built in JavaScript

• Includes suite of tools that allows user to prepare JavaScript (and thus React) applications for deployment

• Utilizes Node.js Package Manager (npm) to install programs and manage dependencies

SD4x-3.7 447

Property of Penn Engineering, Chris Murphy

Node.js - Benefits

• Instead of including all JavaScript code in a <script> tag, now we can separate the components into different files to make code more modular

• Node.js allows us to incorporate dependencies of the code within the current file

var React = require('react');

var ReactDOM = require('react-dom');

import MyComponent from './MyComponent.js';

SD4x-3.7 448

Property of Penn Engineering, Chris Murphy

Node.js - Benefits

• Instead of including all JavaScript code in a <script> tag, now we can separate the components into different files to make code more modular

• Node.js allows us to incorporate dependencies of the code within the current file

var React = require('react');

var ReactDOM = require('react-dom');

import MyComponent from './MyComponent.js';

SD4x-3.7 449

Property of Penn Engineering, Chris Murphy

Node.js - Benefits

• Instead of including all JavaScript code in a <script> tag, now we can separate the components into different files to make code more modular

• Node.js allows us to incorporate dependencies of the code within the current file

var React = require('react');

var ReactDOM = require('react-dom');

import MyComponent from './MyComponent.js';

SD4x-3.7 450

Property of Penn Engineering, Chris Murphy

Node.js - Installation

• Navigate to https://nodejs.org/en/download/ and download and install Node.js and appropriate packages

• Although npm always comes with a Node.jsinstallation, be sure to update the version to the most recent with the following command.

npm install npm -g

SD4x-3.7 451

Property of Penn Engineering, Chris Murphy

Creating a React App - Considerations

• Including dependencies (React, React-DOM libraries, etc.)

• Making code compatible with browsers that only support older versions of JavaScript

• Transforming JSX into JavaScript

• Modularity: implementing modules in separate files, bundling them as dependencies

SD4x-3.7 452

Property of Penn Engineering, Chris Murphy

Creating a React App with Node.js - Setup

• Fortunately, there exists a package (through npm) that takes all of the above into consideration when creating a React app

• Incorporates Babel for JSX and ES6 transformation

• Incorporates Webpack for bundling

SD4x-3.7 453

npm install -g create-react-app

Property of Penn Engineering, Chris Murphy

Creating a React App with Node.js - Setup

• Fortunately, there exists a package (through npm) that takes all of the above into consideration when creating a React app

• Incorporates Babel for JSX and ES6 transformation

• Incorporates Webpack for bundling

• To create new React app, run the following command in the desired parent directory of new application

create-react-app my-app

SD4x-3.7 454

npm install -g create-react-app

Property of Penn Engineering, Chris Murphy

Anatomy of a React App

SD4x-3.7 455

• package.json: information about app, lists of dependencies, shortcuts for scripts

• public: directory containing HTML files, images, other static web content

• src: directory containing JavaScript and CSS files

Property of Penn Engineering, Chris Murphy

Starting React App with Node.js

• You can start the default app as follows:

cd my-app/

npm start

SD4x-3.7 456

Property of Penn Engineering, Chris Murphy

Starting React App with Node.js

• You can start the default app as follows:

• This will start a web server that listens for incoming HTTP requests on port 3000 on your computer

cd my-app/

npm start

SD4x-3.7 457

Property of Penn Engineering, Chris Murphy

Starting React App with Node.js

• You can start the default app as follows:

• This will start a web server that listens for incoming HTTP requests on port 3000 on your computer

• You can access the web server by accessing http://localhost:3000/ from your computer

cd my-app/

npm start

SD4x-3.7 458

Property of Penn Engineering, Chris Murphy SD4x-3.7 459

Property of Penn Engineering, Chris Murphy

Incorporating Components

• We can now create separate JavaScript files for each component.

• src/Counter.js would look like this:

var React = require('react');

class Counter extends React.Component {

constructor(props) { . . . }

incrementCount() { . . . }

render() { . . . }

};

export default Counter;

SD4x-3.7 460

Property of Penn Engineering, Chris Murphy

Incorporating Components

• We can now create separate JavaScript files for each component.

• src/Counter.js would look like this:

var React = require('react');

class Counter extends React.Component {

constructor(props) { . . . }

incrementCount() { . . . }

render() { . . . }

};

export default Counter;

SD4x-3.7 461

Property of Penn Engineering, Chris Murphy

Incorporating Components

• We can now create separate JavaScript files for each component.

• src/Counter.js would look like this:

var React = require('react');

class Counter extends React.Component {

constructor(props) { . . . }

incrementCount() { . . . }

render() { . . . }

};

export default Counter;

SD4x-3.7 462

Property of Penn Engineering, Chris Murphy

Incorporating Components

• We can now create separate JavaScript files for each component.

• src/Counter.js would look like this:

var React = require('react');

class Counter extends React.Component {

constructor(props) { . . . }

incrementCount() { . . . }

render() { . . . }

};

export default Counter;

SD4x-3.7 463

Property of Penn Engineering, Chris Murphy

Incorporating Components into the App

• Edit src/App.js as follows:

import Counter from './Counter.js';

SD4x-3.7 464

class App extends Component {

render() {

return (

<div className="App">

<Counter />

</div>

);

}

}

Property of Penn Engineering, Chris Murphy

Incorporating Components into the App

• Edit src/App.js as follows:

import Counter from './Counter.js';

SD4x-3.7 465

class App extends Component {

render() {

return (

<div className="App">

<Counter />

</div>

);

}

}

Property of Penn Engineering, Chris Murphy

Incorporating Components into the App

• Edit src/App.js as follows:

import Counter from './Counter.js';

SD4x-3.7 466

class App extends Component {

render() {

return (

<div className="App">

<Counter />

</div>

);

}

}

Property of Penn Engineering, Chris Murphy SD4x-3.7 467

Property of Penn Engineering, Chris Murphy SD4x-3.7 468

Property of Penn Engineering, Chris Murphy SD4x-3.7 469

Property of Penn Engineering, Chris Murphy SD4x-3.7 470

Property of Penn Engineering, Chris Murphy SD4x-3.7 471

Property of Penn Engineering, Chris Murphy SD4x-3.7 472

Property of Penn Engineering, Chris Murphy SD4x-3.7 473

Property of Penn Engineering, Chris Murphy SD4x-3.7 474

App

Property of Penn Engineering, Chris Murphy SD4x-3.7 475

AppDogs

Property of Penn Engineering, Chris Murphy SD4x-3.7 476

AppDogsDogItem

DogItem

Property of Penn Engineering, Chris Murphy SD4x-3.7 477

AppDogsDogItem

DogItem

AddDog

Property of Penn Engineering, Chris Murphy

import React, { Component } from 'react';

import Dogs from './components/Dogs';

import AddDog from './components/AddDog';

import './App.css';

class App extends Component {

constructor() { . . . }

handleAddDog(dog) { . . . }

handleDeleteDog(name) { . . . }

render() {

return (

<div className="App">

<Dogs dogs={this.state.dogs}

onDelete={this.handleDeleteDog.bind(this)} />

<AddDog onAddDog={this.handleAddDog.bind(this)} />

<hr />

</div>

);

}

};

SD4x-3.7 478

Property of Penn Engineering, Chris Murphy

import React, { Component } from 'react';

import Dogs from './components/Dogs';

import AddDog from './components/AddDog';

import './App.css';

class App extends Component {

constructor() { . . . }

handleAddDog(dog) { . . . }

handleDeleteDog(name) { . . . }

render() {

return (

<div className="App">

<Dogs dogs={this.state.dogs}

onDelete={this.handleDeleteDog.bind(this)} />

<AddDog onAddDog={this.handleAddDog.bind(this)} />

<hr />

</div>

);

}

};

SD4x-3.7 479

Property of Penn Engineering, Chris Murphy

import React, { Component } from 'react';

import Dogs from './components/Dogs';

import AddDog from './components/AddDog';

import './App.css';

class App extends Component {

constructor() { . . . }

handleAddDog(dog) { . . . }

handleDeleteDog(name) { . . . }

render() {

return (

<div className="App">

<Dogs dogs={this.state.dogs}

onDelete={this.handleDeleteDog.bind(this)} />

<AddDog onAddDog={this.handleAddDog.bind(this)} />

<hr />

</div>

);

}

};

SD4x-3.7 480

Property of Penn Engineering, Chris Murphy

import React, { Component } from 'react';

import Dogs from './components/Dogs';

import AddDog from './components/AddDog';

import './App.css';

class App extends Component {

constructor() { . . . }

handleAddDog(dog) { . . . }

handleDeleteDog(name) { . . . }

render() {

return (

<div className="App">

<Dogs dogs={this.state.dogs}

onDelete={this.handleDeleteDog.bind(this)} />

<AddDog onAddDog={this.handleAddDog.bind(this)} />

<hr />

</div>

);

}

};

SD4x-3.7 481

Property of Penn Engineering, Chris Murphy

import React, { Component } from 'react';

import Dogs from './components/Dogs';

import AddDog from './components/AddDog';

import './App.css';

class App extends Component {

constructor() { . . . }

handleAddDog(dog) { . . . }

handleDeleteDog(name) { . . . }

render() {

return (

<div className="App">

<Dogs dogs={this.state.dogs}

onDelete={this.handleDeleteDog.bind(this)} />

<AddDog onAddDog={this.handleAddDog.bind(this)} />

<hr />

</div>

);

}

};

SD4x-3.7 482

Property of Penn Engineering, Chris Murphy

import React, { Component } from 'react';

import Dogs from './components/Dogs';

import AddDog from './components/AddDog';

import './App.css';

class App extends Component {

constructor() { . . . }

handleAddDog(dog) { . . . }

handleDeleteDog(name) { . . . }

render() {

return (

<div className="App">

<Dogs dogs={this.state.dogs}

onDelete={this.handleDeleteDog.bind(this)} />

<AddDog onAddDog={this.handleAddDog.bind(this)} />

<hr />

</div>

);

}

};

SD4x-3.7 483

Property of Penn Engineering, Chris Murphy

import React, { Component } from 'react';

import Dogs from './components/Dogs';

import AddDog from './components/AddDog';

import './App.css';

class App extends Component {

constructor() { . . . }

handleAddDog(dog) { . . . }

handleDeleteDog(name) { . . . }

render() {

return (

<div className="App">

<Dogs dogs={this.state.dogs}

onDelete={this.handleDeleteDog.bind(this)} />

<AddDog onAddDog={this.handleAddDog.bind(this)} />

<hr />

</div>

);

}

};

SD4x-3.7 484

Property of Penn Engineering, Chris Murphy

import React, { Component } from 'react';

import Dogs from './components/Dogs';

import AddDog from './components/AddDog';

import './App.css';

class App extends Component {

constructor() { . . . }

handleAddDog(dog) { . . . }

handleDeleteDog(name) { . . . }

render() {

return (

<div className="App">

<Dogs dogs={this.state.dogs}

onDelete={this.handleDeleteDog.bind(this)} />

<AddDog onAddDog={this.handleAddDog.bind(this)} />

<hr />

</div>

);

}

};

SD4x-3.7 485

Property of Penn Engineering, Chris Murphy

import React, { Component } from 'react';

import Dogs from './components/Dogs';

import AddDog from './components/AddDog';

import './App.css';

class App extends Component {

constructor() { . . . }

handleAddDog(dog) { . . . }

handleDeleteDog(name) { . . . }

render() {

return (

<div className="App">

<Dogs dogs={this.state.dogs}

onDelete={this.handleDeleteDog.bind(this)} />

<AddDog onAddDog={this.handleAddDog.bind(this)} />

<hr />

</div>

);

}

};

SD4x-3.7 486

Property of Penn Engineering, Chris Murphy

import React, { Component } from 'react';

import Dogs from './components/Dogs';

import AddDog from './components/AddDog';

import './App.css';

class App extends Component {

constructor() { . . . }

handleAddDog(dog) { . . . }

handleDeleteDog(name) { . . . }

render() {

return (

<div className="App">

<Dogs dogs={this.state.dogs}

onDelete={this.handleDeleteDog.bind(this)} />

<AddDog onAddDog={this.handleAddDog.bind(this)} />

<hr />

</div>

);

}

};

SD4x-3.7 487

Property of Penn Engineering, Chris Murphy

import React, { Component } from 'react';

import Dogs from './components/Dogs';

import AddDog from './components/AddDog';

import './App.css';

class App extends Component {

constructor() { . . . }

handleAddDog(dog) { . . . }

handleDeleteDog(name) { . . . }

render() {

return (

<div className="App">

<Dogs dogs={this.state.dogs}

onDelete={this.handleDeleteDog.bind(this)} />

<AddDog onAddDog={this.handleAddDog.bind(this)} />

<hr />

</div>

);

}

};

SD4x-3.7 488

Property of Penn Engineering, Chris Murphy SD4x-3.7 489

AppDogs

AddDog

Property of Penn Engineering, Chris Murphy

import React, { Component } from 'react';

import Dogs from './components/Dogs';

import AddDog from './components/AddDog';

import './App.css';

class App extends Component {

constructor() { . . . }

handleAddDog(dog) { . . . }

handleDeleteDog(name) { . . . }

render() {

return (

<div className="App">

<Dogs dogs={this.state.dogs}

onDelete={this.handleDeleteDog.bind(this)} />

<AddDog onAddDog={this.handleAddDog.bind(this)} />

<hr />

</div>

);

}

};

SD4x-3.7 490

Property of Penn Engineering, Chris Murphy

import React, { Component } from 'react';

import Dogs from './components/Dogs';

import AddDog from './components/AddDog';

import './App.css';

class App extends Component {

constructor() { . . . }

handleAddDog(dog) { . . . }

handleDeleteDog(name) { . . . }

render() {

return (

<div className="App">

<Dogs dogs={this.state.dogs}

onDelete={this.handleDeleteDog.bind(this)} />

<AddDog onAddDog={this.handleAddDog.bind(this)} />

<hr />

</div>

);

}

};

SD4x-3.7 491

Property of Penn Engineering, Chris Murphy

Testing React Apps

• Mocha – widely used test runner (testing framework) used to run JavaScript tests

• Chai – assertion library for Behavior Driven Testing

• Enzyme – testing utility for React for manipulating and inspecting React Component state and output

SD4x-3.7 492

Property of Penn Engineering, Chris Murphy

Getting Started - Installation

• To include Enzyme and Chai as dependencies, run the following command:

npm install --save-dev enzyme react-test-renderer chai

SD4x-3.7 493

Property of Penn Engineering, Chris Murphy

Getting Started - Installation

• To include Enzyme and Chai as dependencies, run the following command:

• Note that the default file structure places all JavaScript and CSS code in the ‘src’ folder.

• We will create an additional folder within ‘src’ named ‘tests’ in which we include all testing scripts

• All test files must be in the form of *.test.js, e.g. Dogs.test.js

npm install --save-dev enzyme react-test-renderer chai

SD4x-3.7 494

Property of Penn Engineering, Chris Murphy

Getting Started

• Node.js should create a default App.test.js, or you can write your own

SD4x-3.7 495

Property of Penn Engineering, Chris Murphy

Getting Started

• Node.js should create a default App.test.js, or you can write your own

• Include libraries necessary for testing

• Import React and ReactDOM for component manipulation

• Import keywords from Enzyme

• Import keywords from Chai

import React from 'react';

import ReactDOM from 'react-dom';

import { mount, shallow } from 'enzyme';

import {expect} from 'chai';

SD4x-3.7 496

Property of Penn Engineering, Chris Murphy

Getting Started

• Node.js should create a default App.test.js, or you can write your own

• Include libraries necessary for testing

• Import React and ReactDOM for component manipulation

• Import keywords from Enzyme

• Import keywords from Chai

import React from 'react';

import ReactDOM from 'react-dom';

import { mount, shallow } from 'enzyme';

import {expect} from 'chai';

SD4x-3.7 497

Property of Penn Engineering, Chris Murphy

Getting Started

• Node.js should create a default App.test.js, or you can write your own

• Include libraries necessary for testing

• Import React and ReactDOM for component manipulation

• Import keywords from Enzyme

• Import keywords from Chai

import React from 'react';

import ReactDOM from 'react-dom';

import { mount, shallow } from 'enzyme';

import {expect} from 'chai';

SD4x-3.7 498

Property of Penn Engineering, Chris Murphy

Getting Started

• Node.js should create a default App.test.js, or you can write your own

• Include libraries necessary for testing

• Import React and ReactDOM for component manipulation

• Import keywords from Enzyme

• Import keywords from Chai

import React from 'react';

import ReactDOM from 'react-dom';

import { mount, shallow } from 'enzyme';

import {expect} from 'chai';

SD4x-3.7 499

Property of Penn Engineering, Chris Murphy

Anatomy of a React Test

import React from 'react';

import { expect } from 'chai';

import { mount, shallow } from 'enzyme';

import App from '../App';

describe("Test suite for App component", function(){

it("only one element in App class", function() {

const wrapper = shallow(<App />);

expect(wrapper.find(".App")).length(1);

});

});

SD4x-3.7 500

Property of Penn Engineering, Chris Murphy

Anatomy of a React Test

import React from 'react';

import { expect } from 'chai';

import { mount, shallow } from 'enzyme';

import App from '../App';

describe("Test suite for App component", function(){

it("only one element in App class", function() {

const wrapper = shallow(<App />);

expect(wrapper.find(".App")).length(1);

});

});

SD4x-3.7 501

Property of Penn Engineering, Chris Murphy

Anatomy of a React Test

import React from 'react';

import { expect } from 'chai';

import { mount, shallow } from 'enzyme';

import App from '../App';

describe("Test suite for App component", function(){

it("only one element in App class", function() {

const wrapper = shallow(<App />);

expect(wrapper.find(".App")).length(1);

});

});

SD4x-3.7 502

Property of Penn Engineering, Chris Murphy

Anatomy of a React Test

import React from 'react';

import { expect } from 'chai';

import { mount, shallow } from 'enzyme';

import App from '../App';

describe("Test suite for App component", function(){

it("only one element in App class", function() {

const wrapper = shallow(<App />);

expect(wrapper.find(".App")).length(1);

});

});

SD4x-3.7 503

Property of Penn Engineering, Chris Murphy

Anatomy of a React Test

import React from 'react';

import { expect } from 'chai';

import { mount, shallow } from 'enzyme';

import App from '../App';

describe("Test suite for App component", function(){

it("only one element in App class", function() {

const wrapper = shallow(<App />);

expect(wrapper.find(".App")).length(1);

});

});

SD4x-3.7 504

Property of Penn Engineering, Chris Murphy

Anatomy of a React Test

import React from 'react';

import { expect } from 'chai';

import { mount, shallow } from 'enzyme';

import App from '../App';

describe("Test suite for App component", function(){

it("only one element in App class", function() {

const wrapper = shallow(<App />);

expect(wrapper.find(".App")).length(1);

});

});

SD4x-3.7 505

Property of Penn Engineering, Chris Murphy

Anatomy of a React Test

import React from 'react';

import { expect } from 'chai';

import { mount, shallow } from 'enzyme';

import App from '../App';

describe("Test suite for App component", function(){

it("only one element in App class", function() {

const wrapper = shallow(<App />);

expect(wrapper.find(".App")).length(1);

});

});

SD4x-3.7 506

Property of Penn Engineering, Chris Murphy

Anatomy of a React Test

import React from 'react';

import { expect } from 'chai';

import { mount, shallow } from 'enzyme';

import App from '../App';

describe("Test suite for App component", function(){

it("only one element in App class", function() {

const wrapper = shallow(<App />);

expect(wrapper.find(".App")).length(1);

});

});

SD4x-3.7 507

Property of Penn Engineering, Chris Murphy

Anatomy of a React Test

import React from 'react';

import { expect } from 'chai';

import { mount, shallow } from 'enzyme';

import App from '../App';

describe("Test suite for App component", function(){

it("only one element in App class", function() {

const wrapper = shallow(<App />);

expect(wrapper.find(".App")).length(1);

});

});

SD4x-3.7 508

Property of Penn Engineering, Chris Murphy

Anatomy of a React Test

import React from 'react';

import { expect } from 'chai';

import { mount, shallow } from 'enzyme';

import App from '../App';

describe("Test suite for App component", function(){

it("only one element in App class", function() {

const wrapper = shallow(<App />);

expect(wrapper.find(".App")).length(1);

});

});

SD4x-3.7 509

Property of Penn Engineering, Chris Murphy

Anatomy of a React Test

import React from 'react';

import { expect } from 'chai';

import { mount, shallow } from 'enzyme';

import App from '../App';

describe("Test suite for App component", function(){

it("only one element in App class", function() {

const wrapper = shallow(<App />);

expect(wrapper.find(".App")).length(1);

});

});

SD4x-3.7 510

Property of Penn Engineering, Chris Murphy

Anatomy of a React Test

import React from 'react';

import { expect } from 'chai';

import { mount, shallow } from 'enzyme';

import App from '../App';

describe("Test suite for App component", function(){

it("only one element in App class", function() {

const wrapper = shallow(<App />);

expect(wrapper.find(".App")).length(1);

});

});

SD4x-3.7 511

Property of Penn Engineering, Chris Murphy

Anatomy of a React Test

import React from 'react';

import { expect } from 'chai';

import { mount, shallow } from 'enzyme';

import App from '../App';

describe("Test suite for App component", function(){

it("only one element in App class", function() {

const wrapper = shallow(<App />);

expect(wrapper.find(".App")).length(1);

});

});

SD4x-3.7 512

Property of Penn Engineering, Chris Murphy

Anatomy of a React Test

import React from 'react';

import { expect } from 'chai';

import { mount, shallow } from 'enzyme';

import App from '../App';

describe("Test suite for App component", function(){

it("only one element in App class", function() {

const wrapper = shallow(<App />);

expect(wrapper.find(".App")).length(1);

});

});

SD4x-3.7 513

Property of Penn Engineering, Chris Murphy

Anatomy of a React Test

import React from 'react';

import { expect } from 'chai';

import { mount, shallow } from 'enzyme';

import App from '../App';

describe("Test suite for App component", function(){

it("only one element in App class", function() {

const wrapper = shallow(<App />);

expect(wrapper.find(".App")).length(1);

});

});

SD4x-3.7 514

Property of Penn Engineering, Chris Murphy

Anatomy of a React Test

import React from 'react';

import { expect } from 'chai';

import { mount, shallow } from 'enzyme';

import App from '../App';

describe("Test suite for App component", function(){

it("only one element in App class", function() {

const wrapper = shallow(<App />);

expect(wrapper.find(".App")).length(1);

});

});

SD4x-3.7 515

Property of Penn Engineering, Chris Murphy

Anatomy of a React Test

import React from 'react';

import { expect } from 'chai';

import { mount, shallow } from 'enzyme';

import App from '../App';

describe("Test suite for App component", function(){

it("only one element in App class", function() {

const wrapper = shallow(<App />);

expect(wrapper.find(".App")).length(1);

});

});

SD4x-3.7 516

Property of Penn Engineering, Chris Murphy

Anatomy of a React Test

import React from 'react';

import { expect } from 'chai';

import { mount, shallow } from 'enzyme';

import App from '../App';

describe("Test suite for App component", function(){

it("only one element in App class", function() {

const wrapper = shallow(<App />);

expect(wrapper.find(".App")).length(1);

});

});

SD4x-3.7 517

Property of Penn Engineering, Chris Murphy

Testing React Component Relationships

it('Dog List contains two dogs', function() {

const wrapper = mount(<App/>);

expect(wrapper.find('Dogs')

.find('DogItem')).length(2);

});

SD4x-3.7 518

Property of Penn Engineering, Chris Murphy

Testing React Component Relationships

it('Dog List contains two dogs', function() {

const wrapper = mount(<App/>);

expect(wrapper.find('Dogs')

.find('DogItem')).length(2);

});

SD4x-3.7 519

Property of Penn Engineering, Chris Murphy

Testing React Component Relationships

it('Dog List contains two dogs', function() {

const wrapper = mount(<App/>);

expect(wrapper.find('Dogs')

.find('DogItem')).length(2);

});

SD4x-3.7 520

Property of Penn Engineering, Chris Murphy

Testing React Component Relationships

it('Dog List contains two dogs', function() {

const wrapper = mount(<App/>);

expect(wrapper.find('Dogs')

.find('DogItem')).length(2);

});

SD4x-3.7 521

Property of Penn Engineering, Chris Murphy

Testing React Component Relationships

it('Dog List contains two dogs', function() {

const wrapper = mount(<App/>);

expect(wrapper.find('Dogs')

.find('DogItem')).length(2);

});

SD4x-3.7 522

Property of Penn Engineering, Chris Murphy

Testing React Component Relationships

it('Dog List contains two dogs', function() {

const wrapper = mount(<App/>);

expect(wrapper.find('Dogs')

.find('DogItem')).length(2);

});

SD4x-3.7 523

Property of Penn Engineering, Chris Murphy

Testing React Component Relationships

it('Dog List contains two dogs', function() {

const wrapper = mount(<App/>);

expect(wrapper.find('Dogs')

.find('DogItem')).length(2);

});

SD4x-3.7 524

Property of Penn Engineering, Chris Murphy

Testing Data Entry and Form Submission

it("successfully adds dog to list when form submitted",

function() {

const wrapper = mount(<App/>);

const adddog = wrapper.find('AddDog');

adddog.find('#dogName').get(0).value = 'Lola';

adddog.find('#imageURL').get(0).value = 'https://

static.pexels.com/photos/54386/pexels-

photo-54386.jpeg';

adddog.find('#dogBreed').get(0).value = 'Beagle';

const form = adddog.find('form');

form.simulate('submit');

expect(wrapper.find('Dogs')

.find('DogItem')).length(3);

expect(wrapper.state().dogs[2].name == 'Lola');

});

SD4x-3.7 525

Property of Penn Engineering, Chris Murphy

Testing Data Entry and Form Submission

it("successfully adds dog to list when form submitted",

function() {

const wrapper = mount(<App/>);

const adddog = wrapper.find('AddDog');

adddog.find('#dogName').get(0).value = 'Lola';

adddog.find('#imageURL').get(0).value = 'https://

static.pexels.com/photos/54386/pexels-

photo-54386.jpeg';

adddog.find('#dogBreed').get(0).value = 'Beagle';

const form = adddog.find('form');

form.simulate('submit');

expect(wrapper.find('Dogs')

.find('DogItem')).length(3);

expect(wrapper.state().dogs[2].name == 'Lola');

});

SD4x-3.7 526

Property of Penn Engineering, Chris Murphy

Testing Data Entry and Form Submission

it("successfully adds dog to list when form submitted",

function() {

const wrapper = mount(<App/>);

const adddog = wrapper.find('AddDog');

adddog.find('#dogName').get(0).value = 'Lola';

adddog.find('#imageURL').get(0).value = 'https://

static.pexels.com/photos/54386/pexels-

photo-54386.jpeg';

adddog.find('#dogBreed').get(0).value = 'Beagle';

const form = adddog.find('form');

form.simulate('submit');

expect(wrapper.find('Dogs')

.find('DogItem')).length(3);

expect(wrapper.state().dogs[2].name == 'Lola');

});

SD4x-3.7 527

Property of Penn Engineering, Chris Murphy

Testing Data Entry and Form Submission

it("successfully adds dog to list when form submitted",

function() {

const wrapper = mount(<App/>);

const adddog = wrapper.find('AddDog');

adddog.find('#dogName').get(0).value = 'Lola';

adddog.find('#imageURL').get(0).value = 'https://

static.pexels.com/photos/54386/pexels-

photo-54386.jpeg';

adddog.find('#dogBreed').get(0).value = 'Beagle';

const form = adddog.find('form');

form.simulate('submit');

expect(wrapper.find('Dogs')

.find('DogItem')).length(3);

expect(wrapper.state().dogs[2].name == 'Lola');

});

SD4x-3.7 528

Property of Penn Engineering, Chris Murphy

Testing Data Entry and Form Submission

it("successfully adds dog to list when form submitted",

function() {

const wrapper = mount(<App/>);

const adddog = wrapper.find('AddDog');

adddog.find('#dogName').get(0).value = 'Lola';

adddog.find('#imageURL').get(0).value = 'https://

static.pexels.com/photos/54386/pexels-

photo-54386.jpeg';

adddog.find('#dogBreed').get(0).value = 'Beagle';

const form = adddog.find('form');

form.simulate('submit');

expect(wrapper.find('Dogs')

.find('DogItem')).length(3);

expect(wrapper.state().dogs[2].name == 'Lola');

});

SD4x-3.7 529

Property of Penn Engineering, Chris Murphy

Testing Data Entry and Form Submission

it("successfully adds dog to list when form submitted",

function() {

const wrapper = mount(<App/>);

const adddog = wrapper.find('AddDog');

adddog.find('#dogName').get(0).value = 'Lola';

adddog.find('#imageURL').get(0).value = 'https://

static.pexels.com/photos/54386/pexels-

photo-54386.jpeg';

adddog.find('#dogBreed').get(0).value = 'Beagle';

const form = adddog.find('form');

form.simulate('submit');

expect(wrapper.find('Dogs')

.find('DogItem')).length(3);

expect(wrapper.state().dogs[2].name == 'Lola');

});

SD4x-3.7 530

Property of Penn Engineering, Chris Murphy

Testing Data Entry and Form Submission

it("successfully adds dog to list when form submitted",

function() {

const wrapper = mount(<App/>);

const adddog = wrapper.find('AddDog');

adddog.find('#dogName').get(0).value = 'Lola';

adddog.find('#imageURL').get(0).value = 'https://

static.pexels.com/photos/54386/pexels-

photo-54386.jpeg';

adddog.find('#dogBreed').get(0).value = 'Beagle';

const form = adddog.find('form');

form.simulate('submit');

expect(wrapper.find('Dogs')

.find('DogItem')).length(3);

expect(wrapper.state().dogs[2].name == 'Lola');

});

SD4x-3.7 531

Property of Penn Engineering, Chris Murphy

Testing Data Entry and Form Submission

it("successfully adds dog to list when form submitted",

function() {

const wrapper = mount(<App/>);

const adddog = wrapper.find('AddDog');

adddog.find('#dogName').get(0).value = 'Lola';

adddog.find('#imageURL').get(0).value = 'https://

static.pexels.com/photos/54386/pexels-

photo-54386.jpeg';

adddog.find('#dogBreed').get(0).value = 'Beagle';

const form = adddog.find('form');

form.simulate('submit');

expect(wrapper.find('Dogs')

.find('DogItem')).length(3);

expect(wrapper.state().dogs[2].name == 'Lola');

});

SD4x-3.7 532

Property of Penn Engineering, Chris Murphy

Testing Data Entry and Form Submission

it("successfully adds dog to list when form submitted",

function() {

const wrapper = mount(<App/>);

const adddog = wrapper.find('AddDog');

adddog.find('#dogName').get(0).value = 'Lola';

adddog.find('#imageURL').get(0).value = 'https://

static.pexels.com/photos/54386/pexels-

photo-54386.jpeg';

adddog.find('#dogBreed').get(0).value = 'Beagle';

const form = adddog.find('form');

form.simulate('submit');

expect(wrapper.find('Dogs')

.find('DogItem')).length(3);

expect(wrapper.state().dogs[2].name == 'Lola');

});

SD4x-3.7 533

Property of Penn Engineering, Chris Murphy

Testing Data Entry and Form Submission

it("successfully adds dog to list when form submitted",

function() {

const wrapper = mount(<App/>);

const adddog = wrapper.find('AddDog');

adddog.find('#dogName').get(0).value = 'Lola';

adddog.find('#imageURL').get(0).value = 'https://

static.pexels.com/photos/54386/pexels-

photo-54386.jpeg';

adddog.find('#dogBreed').get(0).value = 'Beagle';

const form = adddog.find('form');

form.simulate('submit');

expect(wrapper.find('Dogs')

.find('DogItem')).length(3);

expect(wrapper.state().dogs[2].name == 'Lola');

});

SD4x-3.7 534

Property of Penn Engineering, Chris Murphy

Testing Data Entry and Form Submission

it("successfully adds dog to list when form submitted",

function() {

const wrapper = mount(<App/>);

const adddog = wrapper.find('AddDog');

adddog.find('#dogName').get(0).value = 'Lola';

adddog.find('#imageURL').get(0).value = 'https://

static.pexels.com/photos/54386/pexels-

photo-54386.jpeg';

adddog.find('#dogBreed').get(0).value = 'Beagle';

const form = adddog.find('form');

form.simulate('submit');

expect(wrapper.find('Dogs')

.find('DogItem')).length(3);

expect(wrapper.state().dogs[2].name == 'Lola');

});

SD4x-3.7 535

Property of Penn Engineering, Chris Murphy

Testing Data Entry and Form Submission

it("successfully adds dog to list when form submitted",

function() {

const wrapper = mount(<App/>);

const adddog = wrapper.find('AddDog');

adddog.find('#dogName').get(0).value = 'Lola';

adddog.find('#imageURL').get(0).value = 'https://

static.pexels.com/photos/54386/pexels-

photo-54386.jpeg';

adddog.find('#dogBreed').get(0).value = 'Beagle';

const form = adddog.find('form');

form.simulate('submit');

expect(wrapper.find('Dogs')

.find('DogItem')).length(3);

expect(wrapper.state().dogs[2].name == 'Lola');

});

SD4x-3.7 536

Property of Penn Engineering, Chris Murphy

Testing Data Entry and Form Submission

it("successfully adds dog to list when form submitted",

function() {

const wrapper = mount(<App/>);

const adddog = wrapper.find('AddDog');

adddog.find('#dogName').get(0).value = 'Lola';

adddog.find('#imageURL').get(0).value = 'https://

static.pexels.com/photos/54386/pexels-

photo-54386.jpeg';

adddog.find('#dogBreed').get(0).value = 'Beagle';

const form = adddog.find('form');

form.simulate('submit');

expect(wrapper.find('Dogs')

.find('DogItem')).length(3);

expect(wrapper.state().dogs[2].name == 'Lola');

});

SD4x-3.7 537

Property of Penn Engineering, Chris Murphy

Testing Data Entry and Form Submission

it("successfully adds dog to list when form submitted",

function() {

const wrapper = mount(<App/>);

const adddog = wrapper.find('AddDog');

adddog.find('#dogName').get(0).value = 'Lola';

adddog.find('#imageURL').get(0).value = 'https://

static.pexels.com/photos/54386/pexels-

photo-54386.jpeg';

adddog.find('#dogBreed').get(0).value = 'Beagle';

const form = adddog.find('form');

form.simulate('submit');

expect(wrapper.find('Dogs')

.find('DogItem')).length(3);

expect(wrapper.state().dogs[2].name == 'Lola');

});

SD4x-3.7 538

Property of Penn Engineering, Chris Murphy

Testing Data Entry and Form Submission

it("successfully adds dog to list when form submitted",

function() {

const wrapper = mount(<App/>);

const adddog = wrapper.find('AddDog');

adddog.find('#dogName').get(0).value = 'Lola';

adddog.find('#imageURL').get(0).value = 'https://

static.pexels.com/photos/54386/pexels-

photo-54386.jpeg';

adddog.find('#dogBreed').get(0).value = 'Beagle';

const form = adddog.find('form');

form.simulate('submit');

expect(wrapper.find('Dogs')

.find('DogItem')).length(3);

expect(wrapper.state().dogs[2].name == 'Lola');

});

SD4x-3.7 539

Property of Penn Engineering, Chris Murphy

Testing Data Entry and Form Submission

it("successfully adds dog to list when form submitted",

function() {

const wrapper = mount(<App/>);

const adddog = wrapper.find('AddDog');

adddog.find('#dogName').get(0).value = 'Lola';

adddog.find('#imageURL').get(0).value = 'https://

static.pexels.com/photos/54386/pexels-

photo-54386.jpeg';

adddog.find('#dogBreed').get(0).value = 'Beagle';

const form = adddog.find('form');

form.simulate('submit');

expect(wrapper.find('Dogs')

.find('DogItem')).length(3);

expect(wrapper.state().dogs[2].name == 'Lola');

});

SD4x-3.7 540

Property of Penn Engineering, Chris Murphy

Testing Data Entry and Form Submission

it("successfully adds dog to list when form submitted",

function() {

const wrapper = mount(<App/>);

const adddog = wrapper.find('AddDog');

adddog.find('#dogName').get(0).value = 'Lola';

adddog.find('#imageURL').get(0).value = 'https://

static.pexels.com/photos/54386/pexels-

photo-54386.jpeg';

adddog.find('#dogBreed').get(0).value = 'Beagle';

const form = adddog.find('form');

form.simulate('submit');

expect(wrapper.find('Dogs')

.find('DogItem')).length(3);

expect(wrapper.state().dogs[2].name == 'Lola');

});

SD4x-3.7 541

Property of Penn Engineering, Chris Murphy

Testing Data Entry and Form Submission

it("successfully adds dog to list when form submitted",

function() {

const wrapper = mount(<App/>);

const adddog = wrapper.find('AddDog');

adddog.find('#dogName').get(0).value = 'Lola';

adddog.find('#imageURL').get(0).value = 'https://

static.pexels.com/photos/54386/pexels-

photo-54386.jpeg';

adddog.find('#dogBreed').get(0).value = 'Beagle';

const form = adddog.find('form');

form.simulate('submit');

expect(wrapper.find('Dogs')

.find('DogItem')).length(3);

expect(wrapper.state().dogs[2].name == 'Lola');

});

SD4x-3.7 542

Property of Penn Engineering, Chris Murphy

Testing Data Entry and Form Submission

it("successfully adds dog to list when form submitted",

function() {

const wrapper = mount(<App/>);

const adddog = wrapper.find('AddDog');

adddog.find('#dogName').get(0).value = 'Lola';

adddog.find('#imageURL').get(0).value = 'https://

static.pexels.com/photos/54386/pexels-

photo-54386.jpeg';

adddog.find('#dogBreed').get(0).value = 'Beagle';

const form = adddog.find('form');

form.simulate('submit');

expect(wrapper.find('Dogs')

.find('DogItem')).length(3);

expect(wrapper.state().dogs[2].name == 'Lola');

});

SD4x-3.7 543

Property of Penn Engineering, Chris Murphy

Testing Links

it('removes dog from list when deleted', function() {

const wrapper = mount(<App/>);

const deleteLink = wrapper.find('a').first();

deleteLink.simulate('click');

expect(wrapper.find('Dogs')

.find('DogItem')).length(1);

});

SD4x-3.7 544

Property of Penn Engineering, Chris Murphy

Testing Links

it('removes dog from list when deleted', function() {

const wrapper = mount(<App/>);

const deleteLink = wrapper.find('a').first();

deleteLink.simulate('click');

expect(wrapper.find('Dogs')

.find('DogItem')).length(1);

});

SD4x-3.7 545

Property of Penn Engineering, Chris Murphy

Testing Links

it('removes dog from list when deleted', function() {

const wrapper = mount(<App/>);

const deleteLink = wrapper.find('a').first();

deleteLink.simulate('click');

expect(wrapper.find('Dogs')

.find('DogItem')).length(1);

});

SD4x-3.7 546

Property of Penn Engineering, Chris Murphy

Testing Links

it('removes dog from list when deleted', function() {

const wrapper = mount(<App/>);

const deleteLink = wrapper.find('a').first();

deleteLink.simulate('click');

expect(wrapper.find('Dogs')

.find('DogItem')).length(1);

});

SD4x-3.7 547

Property of Penn Engineering, Chris Murphy

Testing Links

it('removes dog from list when deleted', function() {

const wrapper = mount(<App/>);

const deleteLink = wrapper.find('a').first();

deleteLink.simulate('click');

expect(wrapper.find('Dogs')

.find('DogItem')).length(1);

});

SD4x-3.7 548

Property of Penn Engineering, Chris Murphy

Testing Links

it('removes dog from list when deleted', function() {

const wrapper = mount(<App/>);

const deleteLink = wrapper.find('a').first();

deleteLink.simulate('click');

expect(wrapper.find('Dogs')

.find('DogItem')).length(1);

});

SD4x-3.7 549

Property of Penn Engineering, Chris Murphy

Running Tests

• To run tests, navigate to the project within the terminal and run the following command:

npm run test

SD4x-3.7 550

Property of Penn Engineering, Chris Murphy SD4x-3.7 551

Property of Penn Engineering, Chris Murphy

Running Tests: Success!

SD4x-3.7 552

Property of Penn Engineering, Chris Murphy

Summary

• We can use Node.js to create React applications

• This allows us to put component code into separate .js files and then include them into our App as necessary

• Mocha, Chai, and Enzyme can be used for testing our React apps

SD4x-3.7 553

Video 3.8

ES6

Chris Murphy

SD4x-3.8 554

Property of Penn Engineering, Chris Murphy

What is ES6?

• ES6 stands for ECMAScript 6

• ECMAScript is the ”proper” name for JavaScript

• ES6 is the newest JavaScript Specification, released in 2015

SD4x-3.8 555

Property of Penn Engineering, Chris Murphy

What can you do with ES6?

• In ES6, you can…

• Define constants

• Use simpler notations for function declarations

• Build classes

• Refactor code into modules

• Store data in Sets, Maps, and Typed Arrays

• Copy objects in one line of code

• … and much more!

SD4x-3.8 556

Property of Penn Engineering, Chris Murphy

ES6 – Arrow Functions

• New syntax for defining functions using arrows

• ES5 Syntax:var arr = [1,2,3,4,5];

var square = function (n) {

return n*n;

};

arr.forEach( function(v, i) {

arr[i] = square(v);

});

SD4x-3.8 557

Property of Penn Engineering, Chris Murphy

ES6 – Arrow Functions

• New syntax for defining functions using arrows

• ES5 Syntax:var arr = [1,2,3,4,5];

var square = function (n) {

return n*n;

};

arr.forEach( function(v, i) {

arr[i] = square(v);

});

SD4x-3.8 558

Property of Penn Engineering, Chris Murphy

ES6 – Arrow Functions

• New syntax for defining functions using arrows

• ES5 Syntax:var arr = [1,2,3,4,5];

var square = function (n) {

return n*n;

};

arr.forEach( function(v, i) {

arr[i] = square(v);

});

SD4x-3.8 559

Property of Penn Engineering, Chris Murphy

ES6 – Arrow Functions

• New syntax for defining functions using arrows

• ES5 Syntax:

• ES6 Syntax:

var arr = [1,2,3,4,5];

var square = function (n) {

return n*n;

};

arr.forEach( function(v, i) {

arr[i] = square(v);

});

let arr = [1,2,3,4,5];

let square = n => {

return n*n;

};

arr.forEach( (v, i) => {

arr[i] = square(v);

});

SD4x-3.8 560

Property of Penn Engineering, Chris Murphy

ES6 – Arrow Functions

• New syntax for defining functions using arrows

• ES5 Syntax:

• ES6 Syntax:

var arr = [1,2,3,4,5];

var square = function (n) {

return n*n;

};

arr.forEach( function(v, i) {

arr[i] = square(v);

});

let arr = [1,2,3,4,5];

let square = n => {

return n*n;

};

arr.forEach( (v, i) => {

arr[i] = square(v);

});

SD4x-3.8 561

Property of Penn Engineering, Chris Murphy

ES6 – Arrow Functions

• New syntax for defining functions using arrows

• ES5 Syntax:

• ES6 Syntax:

var arr = [1,2,3,4,5];

var square = function (n) {

return n*n;

};

arr.forEach( function(v, i) {

arr[i] = square(v);

});

let arr = [1,2,3,4,5];

let square = n => {

return n*n;

};

arr.forEach( (v, i) => {

arr[i] = square(v);

});

SD4x-3.8 562

Property of Penn Engineering, Chris Murphy

ES6 – Arrow Functions

• New syntax for defining functions using arrows

• ES5 Syntax:

• ES6 Syntax:

var arr = [1,2,3,4,5];

var square = function (n) {

return n*n;

};

arr.forEach( function(v, i) {

arr[i] = square(v);

});

let arr = [1,2,3,4,5];

let square = n => {

return n*n;

};

arr.forEach( (v, i) => {

arr[i] = square(v);

});

SD4x-3.8 563

Property of Penn Engineering, Chris Murphy

ES6 – Arrow Functions

• New syntax for defining functions using arrows

• ES5 Syntax:

• ES6 Syntax:

var arr = [1,2,3,4,5];

var square = function (n) {

return n*n;

};

arr.forEach( function(v, i) {

arr[i] = square(v);

});

let arr = [1,2,3,4,5];

let square = n => {

return n*n;

};

arr.forEach( (v, i) => {

arr[i] = square(v);

});

SD4x-3.8 564

Property of Penn Engineering, Chris Murphy

ES6 – Default Parameter Values

• The “=“ symbol can be used to assign default values to function parameters

function pow (base, power = 2) {

return Math.pow(base, power);

};

SD4x-3.8 565

Property of Penn Engineering, Chris Murphy

ES6 – Default Parameter Values

• The “=“ symbol can be used to assign default values to function parameters

function pow (base, power = 2) {

return Math.pow(base, power);

};

SD4x-3.8 566

Property of Penn Engineering, Chris Murphy

ES6 – Default Parameter Values

• The “=“ symbol can be used to assign default values to function parameters

function pow (base, power = 2) {

return Math.pow(base, power);

};

SD4x-3.8 567

Property of Penn Engineering, Chris Murphy

ES6 – Default Parameter Values

• The “=“ symbol can be used to assign default values to function parameters

function pow (base, power = 2) {

return Math.pow(base, power);

};

console.log(pow(3));

SD4x-3.8 568

Property of Penn Engineering, Chris Murphy

ES6 – Default Parameter Values

• The “=“ symbol can be used to assign default values to function parameters

function pow (base, power = 2) {

return Math.pow(base, power);

};

console.log(pow(3));

SD4x-3.8 569

Property of Penn Engineering, Chris Murphy

ES6 – Default Parameter Values

• The “=“ symbol can be used to assign default values to function parameters

function pow (base, power = 2) {

return Math.pow(base, power);

};

console.log(pow(3));

SD4x-3.8 570

Property of Penn Engineering, Chris Murphy

ES6 – Default Parameter Values

• The “=“ symbol can be used to assign default values to function parameters

function pow (base, power = 2) {

return Math.pow(base, power);

};

console.log(pow(3)); // 9

SD4x-3.8 571

Property of Penn Engineering, Chris Murphy

ES6 – Default Parameter Values

• The “=“ symbol can be used to assign default values to function parameters

function pow (base, power = 2) {

return Math.pow(base, power);

};

console.log(pow(3)); // 9

console.log(pow(3,3));

SD4x-3.8 572

Property of Penn Engineering, Chris Murphy

ES6 – Default Parameter Values

• The “=“ symbol can be used to assign default values to function parameters

function pow (base, power = 2) {

return Math.pow(base, power);

};

console.log(pow(3)); // 9

console.log(pow(3,3));

SD4x-3.8 573

Property of Penn Engineering, Chris Murphy

ES6 – Default Parameter Values

• The “=“ symbol can be used to assign default values to function parameters

function pow (base, power = 2) {

return Math.pow(base, power);

};

console.log(pow(3)); // 9

console.log(pow(3,3)); // 27

SD4x-3.8 574

Property of Penn Engineering, Chris Murphy

ES6 – Template Literals

• Can define a template for rendering strings

• ES5 Syntax:

var person = { name: "Lydia" };

var msg = "Dear " + person.name + ",\n" + "How are you? ";

SD4x-3.8 575

Property of Penn Engineering, Chris Murphy

ES6 – Template Literals

• Can define a template for rendering strings

• ES5 Syntax:

var person = { name: "Lydia" };

var msg = "Dear " + person.name + ",\n" + "How are you? ";

SD4x-3.8 576

Property of Penn Engineering, Chris Murphy

ES6 – Template Literals

• Can define a template for rendering strings

• ES5 Syntax:

var person = { name: "Lydia" };

var msg = "Dear " + person.name + ",\n" + "How are you? ";

SD4x-3.8 577

Property of Penn Engineering, Chris Murphy

ES6 – Template Literals

• Can define a template for rendering strings

• ES5 Syntax:

var person = { name: "Lydia" };

var msg = "Dear " + person.name + ",\n" + "How are you? ";

SD4x-3.8 578

Property of Penn Engineering, Chris Murphy

ES6 – Template Literals

• Can define a template for rendering strings

• ES5 Syntax:

var person = { name: "Lydia" };

var msg = "Dear " + person.name + ",\n" + "How are you? ";

SD4x-3.8 579

Property of Penn Engineering, Chris Murphy

ES6 – Template Literals

• Can define a template for rendering strings

• ES5 Syntax:

• ES6 Syntax:

var person = { name: "Lydia" };

var msg = "Dear " + person.name + ",\n" + "How are you? ";

var person = { name: "Lydia" };

var msg = ‘Dear ${person.name},

How are you?‘

SD4x-3.8 580

Property of Penn Engineering, Chris Murphy

ES6 – Template Literals

• Can define a template for rendering strings

• ES5 Syntax:

• ES6 Syntax:

var person = { name: "Lydia" };

var msg = "Dear " + person.name + ",\n" + "How are you? ";

var person = { name: "Lydia" };

var msg = ‘Dear ${person.name},

How are you?‘

SD4x-3.8 581

Property of Penn Engineering, Chris Murphy

ES6 – Template Literals

• Can define a template for rendering strings

• ES5 Syntax:

• ES6 Syntax:

var person = { name: "Lydia" };

var msg = "Dear " + person.name + ",\n" + "How are you? ";

var person = { name: "Lydia" };

var msg = ‘Dear ${person.name},

How are you?‘

SD4x-3.8 582

Property of Penn Engineering, Chris Murphy

ES6 – Template Literals

• Can define a template for rendering strings

• ES5 Syntax:

• ES6 Syntax:

var person = { name: "Lydia" };

var msg = "Dear " + person.name + ",\n" + "How are you? ";

var person = { name: "Lydia" };

var msg = ‘Dear ${person.name},

How are you?‘

SD4x-3.8 583

Property of Penn Engineering, Chris Murphy

ES6 – Template Literals

• Can define a template for rendering strings

• ES5 Syntax:

• ES6 Syntax:

var person = { name: "Lydia" };

var msg = "Dear " + person.name + ",\n" + "How are you? ";

var person = { name: "Lydia" };

var msg = ‘Dear ${person.name},

How are you?‘

SD4x-3.8 584

Property of Penn Engineering, Chris Murphy

ES6 – Classes

• Instead of building prototypes, ES6 allows classes to be directly defined in more traditional OOP style

• ES5 Syntax: var Rectangle = function (height, width) {

this.height = height;

this.width = width;

}

Rectangle.prototype.area = function () {

return this.height * this.width;

}

SD4x-3.8 585

Property of Penn Engineering, Chris Murphy

ES6 – Classes

• Instead of building prototypes, ES6 allows classes to be directly defined in more traditional OOP style

• ES5 Syntax: var Rectangle = function (height, width) {

this.height = height;

this.width = width;

}

Rectangle.prototype.area = function () {

return this.height * this.width;

}

SD4x-3.8 586

Property of Penn Engineering, Chris Murphy

ES6 – Classes

• Instead of building prototypes, ES6 allows classes to be directly defined in more traditional OOP style

• ES5 Syntax: var Rectangle = function (height, width) {

this.height = height;

this.width = width;

}

Rectangle.prototype.area = function () {

return this.height * this.width;

}

SD4x-3.8 587

Property of Penn Engineering, Chris Murphy

ES6 – Classes

• Instead of building prototypes, ES6 allows classes to be directly defined in more traditional OOP style

• ES5 Syntax:

• ES6 Syntax:

var Rectangle = function (height, width) {

this.height = height;

this.width = width;

}

Rectangle.prototype.area = function () {

return this.height * this.width;

}

class Rectangle {

constructor (height, width) {

this.height = height;

this.width = width;

}

area () {

return this.height * this.width;

}

}

SD4x-3.8 588

Property of Penn Engineering, Chris Murphy

ES6 – Classes

• Instead of building prototypes, ES6 allows classes to be directly defined in more traditional OOP style

• ES5 Syntax:

• ES6 Syntax:

var Rectangle = function (height, width) {

this.height = height;

this.width = width;

}

Rectangle.prototype.area = function () {

return this.height * this.width;

}

class Rectangle {

constructor (height, width) {

this.height = height;

this.width = width;

}

area () {

return this.height * this.width;

}

}

SD4x-3.8 589

Property of Penn Engineering, Chris Murphy

ES6 – Classes

• Instead of building prototypes, ES6 allows classes to be directly defined in more traditional OOP style

• ES5 Syntax:

• ES6 Syntax:

var Rectangle = function (height, width) {

this.height = height;

this.width = width;

}

Rectangle.prototype.area = function () {

return this.height * this.width;

}

class Rectangle {

constructor (height, width) {

this.height = height;

this.width = width;

}

area () {

return this.height * this.width;

}

}

SD4x-3.8 590

Property of Penn Engineering, Chris Murphy

ES6 – Classes

• Instead of building prototypes, ES6 allows classes to be directly defined in more traditional OOP style

• ES5 Syntax:

• ES6 Syntax:

var Rectangle = function (height, width) {

this.height = height;

this.width = width;

}

Rectangle.prototype.area = function () {

return this.height * this.width;

}

class Rectangle {

constructor (height, width) {

this.height = height;

this.width = width;

}

area () {

return this.height * this.width;

}

}

SD4x-3.8 591

Property of Penn Engineering, Chris Murphy

ES6 – Classes

• Instead of building prototypes, ES6 allows classes to be directly defined in more traditional OOP style

• ES5 Syntax:

• ES6 Syntax:

var Rectangle = function (height, width) {

this.height = height;

this.width = width;

}

Rectangle.prototype.area = function () {

return this.height * this.width;

}

class Rectangle {

constructor (height, width) {

this.height = height;

this.width = width;

}

area () {

return this.height * this.width;

}

}

SD4x-3.8 592

Property of Penn Engineering, Chris Murphy

ES6 – Classes

• Instead of building prototypes, ES6 allows classes to be directly defined in more traditional OOP style

• ES5 Syntax:

• ES6 Syntax:

var Rectangle = function (height, width) {

this.height = height;

this.width = width;

}

Rectangle.prototype.area = function () {

return this.height * this.width;

}

class Rectangle {

constructor (height, width) {

this.height = height;

this.width = width;

}

area () {

return this.height * this.width;

}

}

SD4x-3.8 593

Property of Penn Engineering, Chris Murphy

ES6 Data Structures: Sets

• ES6 introduces a Set class

• Elements are distinct and maintain order

let s = new Set();

s.add("alligator"); // s = {"alligator"}

s.add("dolphin"); // s = {"alligator", "dolphin"}

s.add("fox"); // s = {"alligator", "dolphin", "fox"}

s.add("alligator"); // s = {"alligator", "dolphin", "fox"}

s.has("alligator"); // true

s.delete("alligator"); // s = {"dolphin", "fox"}

for (let v of s.values())

console.log(v); // prints each value in order

SD4x-3.8 594

Property of Penn Engineering, Chris Murphy

ES6 Data Structures: Sets

• ES6 introduces a Set class

• Elements are distinct and maintain order

let s = new Set();

s.add("alligator"); // s = {"alligator"}

s.add("dolphin"); // s = {"alligator", "dolphin"}

s.add("fox"); // s = {"alligator", "dolphin", "fox"}

s.add("alligator"); // s = {"alligator", "dolphin", "fox"}

s.has("alligator"); // true

s.delete("alligator"); // s = {"dolphin", "fox"}

for (let v of s.values())

console.log(v); // prints each value in order

SD4x-3.8 595

Property of Penn Engineering, Chris Murphy

ES6 Data Structures: Sets

• ES6 introduces a Set class

• Elements are distinct and maintain order

let s = new Set();

s.add("alligator"); // s = {"alligator"}

s.add("dolphin"); // s = {"alligator", "dolphin"}

s.add("fox"); // s = {"alligator", "dolphin", "fox"}

s.add("alligator"); // s = {"alligator", "dolphin", "fox"}

s.has("alligator"); // true

s.delete("alligator"); // s = {"dolphin", "fox"}

for (let v of s.values())

console.log(v); // prints each value in order

SD4x-3.8 596

Property of Penn Engineering, Chris Murphy

ES6 Data Structures: Sets

• ES6 introduces a Set class

• Elements are distinct and maintain order

let s = new Set();

s.add("alligator"); // s = {"alligator"}

s.add("dolphin"); // s = {"alligator", "dolphin"}

s.add("fox"); // s = {"alligator", "dolphin", "fox"}

s.add("alligator"); // s = {"alligator", "dolphin", "fox"}

s.has("alligator"); // true

s.delete("alligator"); // s = {"dolphin", "fox"}

for (let v of s.values())

console.log(v); // prints each value in order

SD4x-3.8 597

Property of Penn Engineering, Chris Murphy

ES6 Data Structures: Sets

• ES6 introduces a Set class

• Elements are distinct and maintain order

let s = new Set();

s.add("alligator"); // s = {"alligator"}

s.add("dolphin"); // s = {"alligator", "dolphin"}

s.add("fox"); // s = {"alligator", "dolphin", "fox"}

s.add("alligator"); // s = {"alligator", "dolphin", "fox"}

s.has("alligator"); // true

s.delete("alligator"); // s = {"dolphin", "fox"}

for (let v of s.values())

console.log(v); // prints each value in order

SD4x-3.8 598

Property of Penn Engineering, Chris Murphy

ES6 Data Structures: Sets

• ES6 introduces a Set class

• Elements are distinct and maintain order

let s = new Set();

s.add("alligator"); // s = {"alligator"}

s.add("dolphin"); // s = {"alligator", "dolphin"}

s.add("fox"); // s = {"alligator", "dolphin", "fox"}

s.add("alligator"); // s = {"alligator", "dolphin", "fox"}

s.has("alligator"); // true

s.delete("alligator"); // s = {"dolphin", "fox"}

for (let v of s.values())

console.log(v); // prints each value in order

SD4x-3.8 599

Property of Penn Engineering, Chris Murphy

ES6 Data Structures: Sets

• ES6 introduces a Set class

• Elements are distinct and maintain order

let s = new Set();

s.add("alligator"); // s = {"alligator"}

s.add("dolphin"); // s = {"alligator", "dolphin"}

s.add("fox"); // s = {"alligator", "dolphin", "fox"}

s.add("alligator"); // s = {"alligator", "dolphin", "fox"}

s.has("alligator"); // true

s.delete("alligator"); // s = {"dolphin", "fox"}

for (let v of s.values())

console.log(v); // prints each value in order

SD4x-3.8 600

Property of Penn Engineering, Chris Murphy

ES6 Data Structures: Sets

• ES6 introduces a Set class

• Elements are distinct and maintain order

let s = new Set();

s.add("alligator"); // s = {"alligator"}

s.add("dolphin"); // s = {"alligator", "dolphin"}

s.add("fox"); // s = {"alligator", "dolphin", "fox"}

s.add("alligator"); // s = {"alligator", "dolphin", "fox"}

s.has("alligator"); // true

s.delete("alligator"); // s = {"dolphin", "fox"}

for (let v of s.values())

console.log(v); // prints each value in order

SD4x-3.8 601

Property of Penn Engineering, Chris Murphy

ES6 Data Structures: Sets

• ES6 introduces a Set class

• Elements are distinct and maintain order

let s = new Set();

s.add("alligator"); // s = {"alligator"}

s.add("dolphin"); // s = {"alligator", "dolphin"}

s.add("fox"); // s = {"alligator", "dolphin", "fox"}

s.add("alligator"); // s = {"alligator", "dolphin", "fox"}

s.has("alligator"); // true

s.delete("alligator"); // s = {"dolphin", "fox"}

for (let v of s.values())

console.log(v); // prints each value in order

SD4x-3.8 602

Property of Penn Engineering, Chris Murphy

ES6 Data Structures: Sets

• ES6 introduces a Set class

• Elements are distinct and maintain order

let s = new Set();

s.add("alligator"); // s = {"alligator"}

s.add("dolphin"); // s = {"alligator", "dolphin"}

s.add("fox"); // s = {"alligator", "dolphin", "fox"}

s.add("alligator"); // s = {"alligator", "dolphin", "fox"}

s.has("alligator"); // true

s.delete("alligator"); // s = {"dolphin", "fox"}

for (let v of s.values())

console.log(v); // prints each value in order

SD4x-3.8 603

Property of Penn Engineering, Chris Murphy

ES6 Data Structures: Maps

• ES6 also introduces a Map class

• A Set of keys is mapped to corresponding values

let m = new Map();

m.set("dog", "rover"); // {"dog" => "rover"}

m.set("cat", "felix"); // {"dog" => "rover", "cat" => "felix"}

m.get("cat"); // "felix"

m.get("mouse"); // undefined

for (let [key, val] of m.entries())

console.log(key + ": " + val); // prints keys and values

SD4x-3.8 604

Property of Penn Engineering, Chris Murphy

ES6 Data Structures: Maps

• ES6 also introduces a Map class

• A Set of keys is mapped to corresponding values

let m = new Map();

m.set("dog", "rover"); // {"dog" => "rover"}

m.set("cat", "felix"); // {"dog" => "rover", "cat" => "felix"}

m.get("cat"); // "felix"

m.get("mouse"); // undefined

for (let [key, val] of m.entries())

console.log(key + ": " + val); // prints keys and values

SD4x-3.8 605

Property of Penn Engineering, Chris Murphy

ES6 Data Structures: Maps

• ES6 also introduces a Map class

• A Set of keys is mapped to corresponding values

let m = new Map();

m.set("dog", "rover"); // {"dog" => "rover"}

m.set("cat", "felix"); // {"dog" => "rover", "cat" => "felix"}

m.get("cat"); // "felix"

m.get("mouse"); // undefined

for (let [key, val] of m.entries())

console.log(key + ": " + val); // prints keys and values

SD4x-3.8 606

Property of Penn Engineering, Chris Murphy

ES6 Data Structures: Maps

• ES6 also introduces a Map class

• A Set of keys is mapped to corresponding values

let m = new Map();

m.set("dog", "rover"); // {"dog" => "rover"}

m.set("cat", "felix"); // {"dog" => "rover", "cat" => "felix"}

m.get("cat"); // "felix"

m.get("mouse"); // undefined

for (let [key, val] of m.entries())

console.log(key + ": " + val); // prints keys and values

SD4x-3.8 607

Property of Penn Engineering, Chris Murphy

ES6 Data Structures: Maps

• ES6 also introduces a Map class

• A Set of keys is mapped to corresponding values

let m = new Map();

m.set("dog", "rover"); // {"dog" => "rover"}

m.set("cat", "felix"); // {"dog" => "rover", "cat" => "felix"}

m.get("cat"); // "felix"

m.get("mouse"); // undefined

for (let [key, val] of m.entries())

console.log(key + ": " + val); // prints keys and values

SD4x-3.8 608

Property of Penn Engineering, Chris Murphy

ES6 Data Structures: Maps

• ES6 also introduces a Map class

• A Set of keys is mapped to corresponding values

let m = new Map();

m.set("dog", "rover"); // {"dog" => "rover"}

m.set("cat", "felix"); // {"dog" => "rover", "cat" => "felix"}

m.get("cat"); // "felix"

m.get("mouse"); // undefined

for (let [key, val] of m.entries())

console.log(key + ": " + val); // prints keys and values

SD4x-3.8 609

Property of Penn Engineering, Chris Murphy

ES6 Data Structures: Maps

• ES6 also introduces a Map class

• A Set of keys is mapped to corresponding values

let m = new Map();

m.set("dog", "rover"); // {"dog" => "rover"}

m.set("cat", "felix"); // {"dog" => "rover", "cat" => "felix"}

m.get("cat"); // "felix"

m.get("mouse"); // undefined

for (let [key, val] of m.entries())

console.log(key + ": " + val); // prints keys and values

SD4x-3.8 610

Property of Penn Engineering, Chris Murphy

ES6 Data Structures: Maps

• ES6 also introduces a Map class

• A Set of keys is mapped to corresponding values

let m = new Map();

m.set("dog", "rover"); // {"dog" => "rover"}

m.set("cat", "felix"); // {"dog" => "rover", "cat" => "felix"}

m.get("cat"); // "felix"

m.get("mouse"); // undefined

for (let [key, val] of m.entries())

console.log(key + ": " + val); // prints keys and values

SD4x-3.8 611

Property of Penn Engineering, Chris Murphy

Summary

• ES6 provides simplified syntax and new libraries and functionality

• We will use ES6 notation in the remaining lessons in the course

SD4x-3.8 612

Video 3.9

D3 Intro

Chris Murphy

SD4x-3.9 613

Property of Penn Engineering, Chris Murphy

Review

• We can use JavaScript to dynamically modify/create HTML elements in Web pages

• jQuery provides a simpler syntax and other additional features

• React allows us to create reusable, modular components

SD4x-3.9 614

Property of Penn Engineering, Chris Murphy

Standard SVG

• We can render basic visual elements in HTML using Scalable Vector Graphics (SVG)

• These are HTML elements that are included in the Web page

• They do not lose quality when the page is resized

• SVG elements are part of the DOM, so their attributes can be modified by CSS and JavaScript

SD4x-3.9 615

Property of Penn Engineering, Chris Murphy SD4x-3.9 616

Property of Penn Engineering, Chris Murphy SD4x-3.9 617

Property of Penn Engineering, Chris Murphy SD4x-3.9 618

Property of Penn Engineering, Chris Murphy SD4x-3.9 619

Property of Penn Engineering, Chris Murphy SD4x-3.9 620

Property of Penn Engineering, Chris Murphy

<html>

<head>

<style>

circle:hover {

fill:green;

};

</style>

</head>

<body>

<svg width="400" height="400">

<circle cx="50" cy="50" r="40"

stroke="blue" stroke-width="4" fill="yellow" />

<rect x="50" y="20" rx="20" ry="20"

width="150" height="150"

style="fill:red;stroke:black;stroke-width:5;opacity:0.5"

onclick="style.fill='cyan'" />

</svg>

</body>

</html>

SD4x-3.9 621

Property of Penn Engineering, Chris Murphy

<html>

<head>

<style>

circle:hover {

fill:green;

};

</style>

</head>

<body>

<svg width="400" height="400">

<circle cx="50" cy="50" r="40"

stroke="blue" stroke-width="4" fill="yellow" />

<rect x="50" y="20" rx="20" ry="20"

width="150" height="150"

style="fill:red;stroke:black;stroke-width:5;opacity:0.5"

onclick="style.fill='cyan'" />

</svg>

</body>

</html>

SD4x-3.9 622

Property of Penn Engineering, Chris Murphy

<html>

<head>

<style>

circle:hover {

fill:green;

};

</style>

</head>

<body>

<svg width="400" height="400">

<circle cx="50" cy="50" r="40"

stroke="blue" stroke-width="4" fill="yellow" />

<rect x="50" y="20" rx="20" ry="20"

width="150" height="150"

style="fill:red;stroke:black;stroke-width:5;opacity:0.5"

onclick="style.fill='cyan'" />

</svg>

</body>

</html>

SD4x-3.9 623

Property of Penn Engineering, Chris Murphy

<html>

<head>

<style>

circle:hover {

fill:green;

};

</style>

</head>

<body>

<svg width="400" height="400">

<circle cx="50" cy="50" r="40"

stroke="blue" stroke-width="4" fill="yellow" />

<rect x="50" y="20" rx="20" ry="20"

width="150" height="150"

style="fill:red;stroke:black;stroke-width:5;opacity:0.5"

onclick="style.fill='cyan'" />

</svg>

</body>

</html>

SD4x-3.9 624

Property of Penn Engineering, Chris Murphy

<html>

<head>

<style>

circle:hover {

fill:green;

};

</style>

</head>

<body>

<svg width="400" height="400">

<circle cx="50" cy="50" r="40"

stroke="blue" stroke-width="4" fill="yellow" />

<rect x="50" y="20" rx="20" ry="20"

width="150" height="150"

style="fill:red;stroke:black;stroke-width:5;opacity:0.5"

onclick="style.fill='cyan'" />

</svg>

</body>

</html>

SD4x-3.9 625

Property of Penn Engineering, Chris Murphy SD4x-3.9 626

50

Property of Penn Engineering, Chris Murphy SD4x-3.9 627

50

50

Property of Penn Engineering, Chris Murphy SD4x-3.9 628

50

50

Property of Penn Engineering, Chris Murphy

<html>

<head>

<style>

circle:hover {

fill:green;

};

</style>

</head>

<body>

<svg width="400" height="400">

<circle cx="50" cy="50" r="40"

stroke="blue" stroke-width="4" fill="yellow" />

<rect x="50" y="20" rx="20" ry="20"

width="150" height="150"

style="fill:red;stroke:black;stroke-width:5;opacity:0.5"

onclick="style.fill='cyan'" />

</svg>

</body>

</html>

SD4x-3.9 629

Property of Penn Engineering, Chris Murphy

<html>

<head>

<style>

circle:hover {

fill:green;

};

</style>

</head>

<body>

<svg width="400" height="400">

<circle cx="50" cy="50" r="40"

stroke="blue" stroke-width="4" fill="yellow" />

<rect x="50" y="20" rx="20" ry="20"

width="150" height="150"

style="fill:red;stroke:black;stroke-width:5;opacity:0.5"

onclick="style.fill='cyan'" />

</svg>

</body>

</html>

SD4x-3.9 630

Property of Penn Engineering, Chris Murphy

<html>

<head>

<style>

circle:hover {

fill:green;

};

</style>

</head>

<body>

<svg width="400" height="400">

<circle cx="50" cy="50" r="40"

stroke="blue" stroke-width="4" fill="yellow" />

<rect x="50" y="20" rx="20" ry="20"

width="150" height="150"

style="fill:red;stroke:black;stroke-width:5;opacity:0.5"

onclick="style.fill='cyan'" />

</svg>

</body>

</html>

SD4x-3.9 631

Property of Penn Engineering, Chris Murphy

<html>

<head>

<style>

circle:hover {

fill:green;

};

</style>

</head>

<body>

<svg width="400" height="400">

<circle cx="50" cy="50" r="40"

stroke="blue" stroke-width="4" fill="yellow" />

<rect x="50" y="20" rx="20" ry="20"

width="150" height="150"

style="fill:red;stroke:black;stroke-width:5;opacity:0.5"

onclick="style.fill='cyan'" />

</svg>

</body>

</html>

SD4x-3.9 632

Property of Penn Engineering, Chris Murphy

<html>

<head>

<style>

circle:hover {

fill:green;

};

</style>

</head>

<body>

<svg width="400" height="400">

<circle cx="50" cy="50" r="40"

stroke="blue" stroke-width="4" fill="yellow" />

<rect x="50" y="20" rx="20" ry="20"

width="150" height="150"

style="fill:red;stroke:black;stroke-width:5;opacity:0.5"

onclick="style.fill='cyan'" />

</svg>

</body>

</html>

SD4x-3.9 633

Property of Penn Engineering, Chris Murphy

<html>

<head>

<style>

circle:hover {

fill:green;

};

</style>

</head>

<body>

<svg width="400" height="400">

<circle cx="50" cy="50" r="40"

stroke="blue" stroke-width="4" fill="yellow" />

<rect x="50" y="20" rx="20" ry="20"

width="150" height="150"

style="fill:red;stroke:black;stroke-width:5;opacity:0.5"

onclick="style.fill='cyan'" />

</svg>

</body>

</html>

SD4x-3.9 634

Property of Penn Engineering, Chris Murphy

<html>

<head>

<style>

circle:hover {

fill:green;

};

</style>

</head>

<body>

<svg width="400" height="400">

<circle cx="50" cy="50" r="40"

stroke="blue" stroke-width="4" fill="yellow" />

<rect x="50" y="20" rx="20" ry="20"

width="150" height="150"

style="fill:red;stroke:black;stroke-width:5;opacity:0.5"

onclick="style.fill='cyan'" />

</svg>

</body>

</html>

SD4x-3.9 635

Property of Penn Engineering, Chris Murphy

<html>

<head>

<style>

circle:hover {

fill:green;

};

</style>

</head>

<body>

<svg width="400" height="400">

<circle cx="50" cy="50" r="40"

stroke="blue" stroke-width="4" fill="yellow" />

<rect x="50" y="20" rx="20" ry="20"

width="150" height="150"

style="fill:red;stroke:black;stroke-width:5;opacity:0.5"

onclick="style.fill='cyan'" />

</svg>

</body>

</html>

SD4x-3.9 636

Property of Penn Engineering, Chris Murphy

Dynamic SVG

• Since SVG elements are part of the DOM, we can use JavaScript to manipulate their attributes

• But we may also want to dynamically generate SVG elements based on user actions, data received from an API, etc.

SD4x-3.9 637

Property of Penn Engineering, Chris Murphy

D3: Data-Driven Documents

• D3.js is a JavaScript library for manipulating HTML documents based on data

• Data can be bound to DOM elements (HTML, SVG) and then we can programmatically apply data-driven transformations

• This can be used for generating HTML tables, SVG charts and graphs, etc.

SD4x-3.9 638

Property of Penn Engineering, Chris Murphy

<html>

<head>

</head>

<body>

<svg width="400" height="400">

<circle cx="50" cy="50" r="40"

stroke="blue" stroke-width="4" fill="yellow" />

</svg>

</body>

</html>

SD4x-3.9 639

Property of Penn Engineering, Chris Murphy

<html>

<head>

</head>

<body>

<svg width="400" height="400">

<circle cx="50" cy="50" r="40"

stroke="blue" stroke-width="4" fill="yellow" />

</svg>

</body>

</html>

SD4x-3.9 640

Property of Penn Engineering, Chris Murphy

<html>

<head>

</head>

<body>

<svg width="400" height="400">

<circle cx="50" cy="50" r="40"

stroke="blue" stroke-width="4" fill="yellow" />

</svg>

</body>

</html>

SD4x-3.9 641

Property of Penn Engineering, Chris Murphy

<html>

<head>

<script src="http://d3js.org/d3.v4.min.js"></script>

</head>

<body>

<svg width="400" height="400">

<circle />

</svg>

<script>

// next slide -->

</script>

</body>

</html>

SD4x-3.9 642

Property of Penn Engineering, Chris Murphy

<html>

<head>

<script src="http://d3js.org/d3.v4.min.js"></script>

</head>

<body>

<svg width="400" height="400">

<circle />

</svg>

<script>

// next slide -->

</script>

</body>

</html>

SD4x-3.9 643

Property of Penn Engineering, Chris Murphy

<html>

<head>

<script src="http://d3js.org/d3.v4.min.js"></script>

</head>

<body>

<svg width="400" height="400">

<circle />

</svg>

<script>

// next slide -->

</script>

</body>

</html>

SD4x-3.9 644

Property of Penn Engineering, Chris Murphy

<html>

<head>

<script src="http://d3js.org/d3.v4.min.js"></script>

</head>

<body>

<svg width="400" height="400">

<circle />

</svg>

<script>

// next slide -->

</script>

</body>

</html>

SD4x-3.9 645

Property of Penn Engineering, Chris Murphy

<html>

<head>

<script src="http://d3js.org/d3.v4.min.js"></script>

</head>

<body>

<svg width="400" height="400">

<circle />

</svg>

<script>

// next slide -->

</script>

</body>

</html>

SD4x-3.9 646

Property of Penn Engineering, Chris Murphy

<script>

var circle = {

x: 50,

y: 50,

r: 40,

stroke: 'blue',

width: 4,

fill: 'yellow'

};

var svg = d3.select("svg");

svg.select("circle")

.attr("cx", circle.x)

.attr("cy", circle.y)

.attr("r", circle.r)

.style("stroke", circle.stroke)

.style("stroke-width", circle.width);

.style("fill", circle.fill);

</script>

SD4x-3.9 647

Property of Penn Engineering, Chris Murphy

<script>

var circle = {

x: 50,

y: 50,

r: 40,

stroke: 'blue',

width: 4,

fill: 'yellow'

};

var svg = d3.select("svg");

svg.select("circle")

.attr("cx", circle.x)

.attr("cy", circle.y)

.attr("r", circle.r)

.style("stroke", circle.stroke)

.style("stroke-width", circle.width);

.style("fill", circle.fill);

</script>

SD4x-3.9 648

Property of Penn Engineering, Chris Murphy

<script>

var circle = {

x: 50,

y: 50,

r: 40,

stroke: 'blue',

width: 4,

fill: 'yellow'

};

var svg = d3.select("svg");

svg.select("circle")

.attr("cx", circle.x)

.attr("cy", circle.y)

.attr("r", circle.r)

.style("stroke", circle.stroke)

.style("stroke-width", circle.width);

.style("fill", circle.fill);

</script>

SD4x-3.9 649

Property of Penn Engineering, Chris Murphy

<script>

var circle = {

x: 50,

y: 50,

r: 40,

stroke: 'blue',

width: 4,

fill: 'yellow'

};

var svg = d3.select("svg");

svg.select("circle")

.attr("cx", circle.x)

.attr("cy", circle.y)

.attr("r", circle.r)

.style("stroke", circle.stroke)

.style("stroke-width", circle.width);

.style("fill", circle.fill);

</script>

SD4x-3.9 650

Property of Penn Engineering, Chris Murphy

<script>

var circle = {

x: 50,

y: 50,

r: 40,

stroke: 'blue',

width: 4,

fill: 'yellow'

};

var svg = d3.select("svg");

svg.select("circle")

.attr("cx", circle.x)

.attr("cy", circle.y)

.attr("r", circle.r)

.style("stroke", circle.stroke)

.style("stroke-width", circle.width);

.style("fill", circle.fill);

</script>

SD4x-3.9 651

Property of Penn Engineering, Chris Murphy

<script>

var circle = {

x: 50,

y: 50,

r: 40,

stroke: 'blue',

width: 4,

fill: 'yellow'

};

var svg = d3.select("svg");

svg.select("circle")

.attr("cx", circle.x)

.attr("cy", circle.y)

.attr("r", circle.r)

.style("stroke", circle.stroke)

.style("stroke-width", circle.width);

.style("fill", circle.fill);

</script>

SD4x-3.9 652

Property of Penn Engineering, Chris Murphy

<script>

var circle = {

x: 50,

y: 50,

r: 40,

stroke: 'blue',

width: 4,

fill: 'yellow'

};

var svg = d3.select("svg");

svg.select("circle")

.attr("cx", circle.x)

.attr("cy", circle.y)

.attr("r", circle.r)

.style("stroke", circle.stroke)

.style("stroke-width", circle.width);

.style("fill", circle.fill);

</script>

SD4x-3.9 653

Property of Penn Engineering, Chris Murphy

<script>

var circle = {

x: 50,

y: 50,

r: 40,

stroke: 'blue',

width: 4,

fill: 'yellow'

};

var svg = d3.select("svg");

svg.select("circle")

.attr("cx", circle.x)

.attr("cy", circle.y)

.attr("r", circle.r)

.style("stroke", circle.stroke)

.style("stroke-width", circle.width);

.style("fill", circle.fill);

</script>

SD4x-3.9 654

Property of Penn Engineering, Chris Murphy

<script>

var circle = {

x: 50,

y: 50,

r: 40,

stroke: 'blue',

width: 4,

fill: 'yellow'

};

var svg = d3.select("svg");

svg.select("circle")

.attr("cx", circle.x)

.attr("cy", circle.y)

.attr("r", circle.r)

.style("stroke", circle.stroke)

.style("stroke-width", circle.width);

.style("fill", circle.fill);

</script>

SD4x-3.9 655

Property of Penn Engineering, Chris Murphy

<script>

var circle = {

x: 50,

y: 50,

r: 40,

stroke: 'blue',

width: 4,

fill: 'yellow'

};

var svg = d3.select("svg");

svg.select("circle")

.attr("cx", circle.x)

.attr("cy", circle.y)

.attr("r", circle.r)

.style("stroke", circle.stroke)

.style("stroke-width", circle.width);

.style("fill", circle.fill);

</script>

SD4x-3.9 656

Property of Penn Engineering, Chris Murphy

<script>

var circle = {

x: 50,

y: 50,

r: 40,

stroke: 'blue',

width: 4,

fill: 'yellow'

};

var svg = d3.select("svg");

svg.select("circle")

.attr("cx", circle.x)

.attr("cy", circle.y)

.attr("r", circle.r)

.style("stroke", circle.stroke)

.style("stroke-width", circle.width);

.style("fill", circle.fill);

</script>

SD4x-3.9 657

Property of Penn Engineering, Chris Murphy

<script>

var circle = {

x: 50,

y: 50,

r: 40,

stroke: 'blue',

width: 4,

fill: 'yellow'

};

var svg = d3.select("svg");

svg.select("circle")

.attr("cx", circle.x)

.attr("cy", circle.y)

.attr("r", circle.r)

.style("stroke", circle.stroke)

.style("stroke-width", circle.width);

.style("fill", circle.fill);

</script>

SD4x-3.9 658

Property of Penn Engineering, Chris Murphy

<script>

var circle = {

x: 50,

y: 50,

r: 40,

stroke: 'blue',

width: 4,

fill: 'yellow'

};

var svg = d3.select("svg");

svg.select("circle")

.attr("cx", circle.x)

.attr("cy", circle.y)

.attr("r", circle.r)

.style("stroke", circle.stroke)

.style("stroke-width", circle.width);

.style("fill", circle.fill);

</script>

SD4x-3.9 659

Property of Penn Engineering, Chris Murphy

<script>

var circle = {

x: 50,

y: 50,

r: 40,

stroke: 'blue',

width: 4,

fill: 'yellow'

};

var svg = d3.select("svg");

svg.select("circle")

.attr("cx", circle.x)

.attr("cy", circle.y)

.attr("r", circle.r)

.style("stroke", circle.stroke)

.style("stroke-width", circle.width);

.style("fill", circle.fill);

</script>

SD4x-3.9 660

Property of Penn Engineering, Chris Murphy

<script>

var circle = {

x: 50,

y: 50,

r: 40,

stroke: 'blue',

width: 4,

fill: 'yellow'

};

var svg = d3.select("svg");

svg.select("circle")

.attr("cx", circle.x)

.attr("cy", circle.y)

.attr("r", circle.r)

.style("stroke", circle.stroke)

.style("stroke-width", circle.width);

.style("fill", circle.fill);

</script>

SD4x-3.9 661

Property of Penn Engineering, Chris Murphy

<script>

var circle = {

x: 50,

y: 50,

r: 40,

stroke: 'blue',

width: 4,

fill: 'yellow'

};

var svg = d3.select("svg");

svg.select("circle")

.attr("cx", circle.x)

.attr("cy", circle.y)

.attr("r", circle.r)

.style("stroke", circle.stroke)

.style("stroke-width", circle.width);

.style("fill", circle.fill);

</script>

SD4x-3.9 662

Property of Penn Engineering, Chris Murphy

<script>

var circle = {

x: 50,

y: 50,

r: 40,

stroke: 'blue',

width: 4,

fill: 'yellow'

};

var svg = d3.select("svg");

svg.select("circle")

.attr("cx", circle.x)

.attr("cy", circle.y)

.attr("r", circle.r)

.style("stroke", circle.stroke)

.style("stroke-width", circle.width);

.style("fill", circle.fill);

</script>

SD4x-3.9 663

Property of Penn Engineering, Chris Murphy

<script>

var circle = {

x: 50,

y: 50,

r: 40,

stroke: 'blue',

width: 4,

fill: 'yellow'

};

var svg = d3.select("svg");

svg.select("circle")

.attr("cx", circle.x)

.attr("cy", circle.y)

.attr("r", circle.r)

.style("stroke", circle.stroke)

.style("stroke-width", circle.width);

.style("fill", circle.fill);

</script>

SD4x-3.9 664

Property of Penn Engineering, Chris Murphy

<script>

var circle = {

x: 50,

y: 50,

r: 40,

stroke: 'blue',

width: 4,

fill: 'yellow'

};

var svg = d3.select("svg");

svg.select("circle")

.attr("cx", circle.x)

.attr("cy", circle.y)

.attr("r", circle.r)

.style("stroke", circle.stroke)

.style("stroke-width", circle.width);

.style("fill", circle.fill);

</script>

SD4x-3.9 665

Property of Penn Engineering, Chris Murphy

<script>

var circle = {

x: 50,

y: 50,

r: 40,

stroke: 'blue',

width: 4,

fill: 'yellow'

};

var svg = d3.select("svg");

svg.select("circle")

.attr("cx", circle.x)

.attr("cy", circle.y)

.attr("r", circle.r)

.style("stroke", circle.stroke)

.style("stroke-width", circle.width);

.style("fill", circle.fill);

</script>

SD4x-3.9 666

Property of Penn Engineering, Chris Murphy

<script>

var circle = {

x: 50,

y: 50,

r: 40,

stroke: 'blue',

width: 4,

fill: 'yellow'

};

var svg = d3.select("svg");

svg.select("circle")

.attr("cx", circle.x)

.attr("cy", circle.y)

.attr("r", circle.r)

.style("stroke", circle.stroke)

.style("stroke-width", circle.width);

.style("fill", circle.fill);

</script>

SD4x-3.9 667

Property of Penn Engineering, Chris Murphy

<script>

var circle = {

x: 50,

y: 50,

r: 40,

stroke: 'blue',

width: 4

};

var svg = d3.select("svg");

svg.select("circle")

.attr("cx", circle.x)

.attr("cy", circle.y)

.attr("r", circle.r)

.style("stroke", circle.stroke)

.style("stroke-width", circle.width);

.style("fill", circle.fill);

</script>

SD4x-3.9 668

Property of Penn Engineering, Chris Murphy

<script>

var circle = {

x: 50,

y: 50,

r: 40,

stroke: 'blue',

width: 4

};

var svg = d3.select("svg");

svg.select("circle")

.attr("cx", circle.x)

.attr("cy", circle.y)

.attr("r", circle.r)

.style("stroke", circle.stroke)

.style("stroke-width", circle.width);

.style("fill", circle.fill);

</script>

SD4x-3.9 669

Property of Penn Engineering, Chris Murphy

<script>

var circle = {

x: 50,

y: 50,

r: 40,

stroke: 'blue',

width: 4

};

var svg = d3.select("svg");

svg.select("circle")

.attr("cx", circle.x)

.attr("cy", circle.y)

.attr("r", circle.r)

.style("stroke", circle.stroke)

.style("stroke-width", circle.width);

.style("fill", () => {

if (circle.r < 50) return 'yellow';

else return 'cyan'; })

</script>

SD4x-3.9 670

Property of Penn Engineering, Chris Murphy

<script>

var circle = {

x: 50,

y: 50,

r: 40,

stroke: 'blue',

width: 4

};

var svg = d3.select("svg");

svg.select("circle")

.attr("cx", circle.x)

.attr("cy", circle.y)

.attr("r", circle.r)

.style("stroke", circle.stroke)

.style("stroke-width", circle.width);

.style("fill", () => {

if (circle.r < 50) return 'yellow';

else return 'cyan'; })

</script>

SD4x-3.9 671

Property of Penn Engineering, Chris Murphy

<script>

var circle = {

x: 50,

y: 50,

r: 40,

stroke: 'blue',

width: 4

};

var svg = d3.select("svg");

svg.select("circle")

.attr("cx", circle.x)

.attr("cy", circle.y)

.attr("r", circle.r)

.style("stroke", circle.stroke)

.style("stroke-width", circle.width);

.style("fill", () => {

if (circle.r < 50) return 'yellow';

else return 'cyan'; })

</script>

SD4x-3.9 672

Property of Penn Engineering, Chris Murphy

<script>

var circle = {

x: 50,

y: 50,

r: 40,

stroke: 'blue',

width: 4

};

var svg = d3.select("svg");

svg.select("circle")

.attr("cx", circle.x)

.attr("cy", circle.y)

.attr("r", circle.r)

.style("stroke", circle.stroke)

.style("stroke-width", circle.width);

.style("fill", () => {

if (circle.r < 50) return 'yellow';

else return 'cyan'; })

</script>

SD4x-3.9 673

Property of Penn Engineering, Chris Murphy

<script>

var circle = {

x: 50,

y: 50,

r: 40,

stroke: 'blue',

width: 4

};

var svg = d3.select("svg");

svg.select("circle")

.attr("cx", circle.x)

.attr("cy", circle.y)

.attr("r", circle.r)

.style("stroke", circle.stroke)

.style("stroke-width", circle.width);

.style("fill", () => {

if (circle.r < 50) return 'yellow';

else return 'cyan'; })

</script>

SD4x-3.9 674

Property of Penn Engineering, Chris Murphy

Summary

• We can render basic visual elements in HTML using Scalable Vector Graphics (SVG)

• We can use D3.js to programmatically generate HTML elements (including SVG) based on data

SD4x-3.9 675

Video 3.10

D3 Charts

Chris Murphy

SD4x-3.10 676

Property of Penn Engineering, Chris Murphy

Review

• D3.js allows us to programmatically generate HTML elements (including SVG) based on data

• The most common visual representation of data is in the form of a chart

SD4x-3.10 677

Property of Penn Engineering, Chris Murphy SD4x-3.10 678

Property of Penn Engineering, Chris Murphy SD4x-3.10 679

Property of Penn Engineering, Chris Murphy

<style>

rect {

fill: darkred;

}

rect:hover {

fill: darkblue;

}

.chart text {

fill: white;

font: 10px sans-serif;

text-anchor: end;

}

</style>

<svg class="chart" height="200">

<g transform="translate(0,160)">

<rect width="39" height="40"></rect><text x="25" y="10">4</text>

</g>

<g transform="translate(40,70)">

<rect width="39" height="130"></rect><text x="25" y="10">13</text>

</g>

<g transform="translate(80,125)">

<rect width="39" height="75"></rect><text x="25" y="10">7.5</text>

</g>

<g transform="translate(120,30)">

<rect width="39" height="170"></rect><text x="25" y="10">17</text>

</g>

</svg>

SD4x-3.10 680

Property of Penn Engineering, Chris Murphy

<style>

rect {

fill: darkred;

}

rect:hover {

fill: darkblue;

}

.chart text {

fill: white;

font: 10px sans-serif;

text-anchor: end;

}

</style>

<svg class="chart" height="200">

<g transform="translate(0,160)">

<rect width="39" height="40"></rect><text x="25" y="10">4</text>

</g>

<g transform="translate(40,70)">

<rect width="39" height="130"></rect><text x="25" y="10">13</text>

</g>

<g transform="translate(80,125)">

<rect width="39" height="75"></rect><text x="25" y="10">7.5</text>

</g>

<g transform="translate(120,30)">

<rect width="39" height="170"></rect><text x="25" y="10">17</text>

</g>

</svg>

SD4x-3.10 681

Property of Penn Engineering, Chris Murphy

<style>

rect {

fill: darkred;

}

rect:hover {

fill: darkblue;

}

.chart text {

fill: white;

font: 10px sans-serif;

text-anchor: end;

}

</style>

<svg class="chart" height="200">

<g transform="translate(0,160)">

<rect width="39" height="40"></rect><text x="25" y="10">4</text>

</g>

<g transform="translate(40,70)">

<rect width="39" height="130"></rect><text x="25" y="10">13</text>

</g>

<g transform="translate(80,125)">

<rect width="39" height="75"></rect><text x="25" y="10">7.5</text>

</g>

<g transform="translate(120,30)">

<rect width="39" height="170"></rect><text x="25" y="10">17</text>

</g>

</svg>

SD4x-3.10 682

Property of Penn Engineering, Chris Murphy

<style>

rect {

fill: darkred;

}

rect:hover {

fill: darkblue;

}

.chart text {

fill: white;

font: 10px sans-serif;

text-anchor: end;

}

</style>

<svg class="chart" height="200">

<g transform="translate(0,160)">

<rect width="39" height="40"></rect><text x="25" y="10">4</text>

</g>

<g transform="translate(40,70)">

<rect width="39" height="130"></rect><text x="25" y="10">13</text>

</g>

<g transform="translate(80,125)">

<rect width="39" height="75"></rect><text x="25" y="10">7.5</text>

</g>

<g transform="translate(120,30)">

<rect width="39" height="170"></rect><text x="25" y="10">17</text>

</g>

</svg>

SD4x-3.10 683

Property of Penn Engineering, Chris Murphy

<style>

rect {

fill: darkred;

}

rect:hover {

fill: darkblue;

}

.chart text {

fill: white;

font: 10px sans-serif;

text-anchor: end;

}

</style>

<svg class="chart" height="200">

<g transform="translate(0,160)">

<rect width="39" height="40"></rect><text x="25" y="10">4</text>

</g>

<g transform="translate(40,70)">

<rect width="39" height="130"></rect><text x="25" y="10">13</text>

</g>

<g transform="translate(80,125)">

<rect width="39" height="75"></rect><text x="25" y="10">7.5</text>

</g>

<g transform="translate(120,30)">

<rect width="39" height="170"></rect><text x="25" y="10">17</text>

</g>

</svg>

SD4x-3.10 684

Property of Penn Engineering, Chris Murphy

<style>

rect {

fill: darkred;

}

rect:hover {

fill: darkblue;

}

.chart text {

fill: white;

font: 10px sans-serif;

text-anchor: end;

}

</style>

<svg class="chart" height="200">

<g transform="translate(0,160)">

<rect width="39" height="40"></rect><text x="25" y="10">4</text>

</g>

<g transform="translate(40,70)">

<rect width="39" height="130"></rect><text x="25" y="10">13</text>

</g>

<g transform="translate(80,125)">

<rect width="39" height="75"></rect><text x="25" y="10">7.5</text>

</g>

<g transform="translate(120,30)">

<rect width="39" height="170"></rect><text x="25" y="10">17</text>

</g>

</svg>

SD4x-3.10 685

Property of Penn Engineering, Chris Murphy

<style>

rect {

fill: darkred;

}

rect:hover {

fill: darkblue;

}

.chart text {

fill: white;

font: 10px sans-serif;

text-anchor: end;

}

</style>

<svg class="chart" height="200">

<g transform="translate(0,160)">

<rect width="39" height="40"></rect><text x="25" y="10">4</text>

</g>

<g transform="translate(40,70)">

<rect width="39" height="130"></rect><text x="25" y="10">13</text>

</g>

<g transform="translate(80,125)">

<rect width="39" height="75"></rect><text x="25" y="10">7.5</text>

</g>

<g transform="translate(120,30)">

<rect width="39" height="170"></rect><text x="25" y="10">17</text>

</g>

</svg>

SD4x-3.10 686

Property of Penn Engineering, Chris Murphy

<style>

rect {

fill: darkred;

}

rect:hover {

fill: darkblue;

}

.chart text {

fill: white;

font: 10px sans-serif;

text-anchor: end;

}

</style>

<svg class="chart" height="200">

<g transform="translate(0,160)">

<rect width="39" height="40"></rect><text x="25" y="10">4</text>

</g>

<g transform="translate(40,70)">

<rect width="39" height="130"></rect><text x="25" y="10">13</text>

</g>

<g transform="translate(80,125)">

<rect width="39" height="75"></rect><text x="25" y="10">7.5</text>

</g>

<g transform="translate(120,30)">

<rect width="39" height="170"></rect><text x="25" y="10">17</text>

</g>

</svg>

SD4x-3.10 687

Property of Penn Engineering, Chris Murphy SD4x-3.10 688

Property of Penn Engineering, Chris Murphy SD4x-3.10 689

Property of Penn Engineering, Chris Murphy

<style>

rect {

fill: darkred;

}

rect:hover {

fill: darkblue;

}

.chart text {

fill: white;

font: 10px sans-serif;

text-anchor: end;

}

</style>

<svg class="chart" height="200">

<g transform="translate(0,160)">

<rect width="39" height="40"></rect><text x="25" y="10">4</text>

</g>

<g transform="translate(40,70)">

<rect width="39" height="130"></rect><text x="25" y="10">13</text>

</g>

<g transform="translate(80,125)">

<rect width="39" height="75"></rect><text x="25" y="10">7.5</text>

</g>

<g transform="translate(120,30)">

<rect width="39" height="170"></rect><text x="25" y="10">17</text>

</g>

</svg>

SD4x-3.10 690

Property of Penn Engineering, Chris Murphy

<style>

rect {

fill: darkred;

}

rect:hover {

fill: darkblue;

}

.chart text {

fill: white;

font: 10px sans-serif;

text-anchor: end;

}

</style>

<svg class="chart" height="200">

<g transform="translate(0,160)">

<rect width="39" height="40"></rect><text x="25" y="10">4</text>

</g>

<g transform="translate(40,70)">

<rect width="39" height="130"></rect><text x="25" y="10">13</text>

</g>

<g transform="translate(80,125)">

<rect width="39" height="75"></rect><text x="25" y="10">7.5</text>

</g>

<g transform="translate(120,30)">

<rect width="39" height="170"></rect><text x="25" y="10">17</text>

</g>

</svg>

SD4x-3.10 691

Property of Penn Engineering, Chris Murphy

<style>

rect {

fill: darkred;

}

rect:hover {

fill: darkblue;

}

.chart text {

fill: white;

font: 10px sans-serif;

text-anchor: end;

}

</style>

<svg class="chart" height="200">

<g transform="translate(0,160)">

<rect width="39" height="40"></rect><text x="25" y="10">4</text>

</g>

<g transform="translate(40,70)">

<rect width="39" height="130"></rect><text x="25" y="10">13</text>

</g>

<g transform="translate(80,125)">

<rect width="39" height="75"></rect><text x="25" y="10">7.5</text>

</g>

<g transform="translate(120,30)">

<rect width="39" height="170"></rect><text x="25" y="10">17</text>

</g>

</svg>

SD4x-3.10 692

Property of Penn Engineering, Chris Murphy

<style>

rect {

fill: darkred;

}

rect:hover {

fill: darkblue;

}

.chart text {

fill: white;

font: 10px sans-serif;

text-anchor: end;

}

</style>

<svg class="chart" height="200">

<g transform="translate(0,160)">

<rect width="39" height="40"></rect><text x="25" y="10">4</text>

</g>

<g transform="translate(40,70)">

<rect width="39" height="130"></rect><text x="25" y="10">13</text>

</g>

<g transform="translate(80,125)">

<rect width="39" height="75"></rect><text x="25" y="10">7.5</text>

</g>

<g transform="translate(120,30)">

<rect width="39" height="170"></rect><text x="25" y="10">17</text>

</g>

</svg>

SD4x-3.10 693

Property of Penn Engineering, Chris Murphy

<style>

rect {

fill: darkred;

}

rect:hover {

fill: darkblue;

}

.chart text {

fill: white;

font: 10px sans-serif;

text-anchor: end;

}

</style>

<svg class="chart" height="200">

<g transform="translate(0,160)">

<rect width="39" height="40"></rect><text x="25" y="10">4</text>

</g>

<g transform="translate(40,70)">

<rect width="39" height="130"></rect><text x="25" y="10">13</text>

</g>

<g transform="translate(80,125)">

<rect width="39" height="75"></rect><text x="25" y="10">7.5</text>

</g>

<g transform="translate(120,30)">

<rect width="39" height="170"></rect><text x="25" y="10">17</text>

</g>

</svg>

SD4x-3.10 694

160

Property of Penn Engineering, Chris Murphy

<style>

rect {

fill: darkred;

}

rect:hover {

fill: darkblue;

}

.chart text {

fill: white;

font: 10px sans-serif;

text-anchor: end;

}

</style>

<svg class="chart" height="200">

<g transform="translate(0,160)">

<rect width="39" height="40"></rect><text x="25" y="10">4</text>

</g>

<g transform="translate(40,70)">

<rect width="39" height="130"></rect><text x="25" y="10">13</text>

</g>

<g transform="translate(80,125)">

<rect width="39" height="75"></rect><text x="25" y="10">7.5</text>

</g>

<g transform="translate(120,30)">

<rect width="39" height="170"></rect><text x="25" y="10">17</text>

</g>

</svg>

SD4x-3.10 695

160

40

Property of Penn Engineering, Chris Murphy

<style>

rect {

fill: darkred;

}

rect:hover {

fill: darkblue;

}

.chart text {

fill: white;

font: 10px sans-serif;

text-anchor: end;

}

</style>

<svg class="chart" height="200">

<g transform="translate(0,160)">

<rect width="39" height="40"></rect><text x="25" y="10">4</text>

</g>

<g transform="translate(40,70)">

<rect width="39" height="130"></rect><text x="25" y="10">13</text>

</g>

<g transform="translate(80,125)">

<rect width="39" height="75"></rect><text x="25" y="10">7.5</text>

</g>

<g transform="translate(120,30)">

<rect width="39" height="170"></rect><text x="25" y="10">17</text>

</g>

</svg>

SD4x-3.10 696

160

Property of Penn Engineering, Chris Murphy

<style>

rect {

fill: darkred;

}

rect:hover {

fill: darkblue;

}

.chart text {

fill: white;

font: 10px sans-serif;

text-anchor: end;

}

</style>

<svg class="chart" height="200">

<g transform="translate(0,160)">

<rect width="39" height="40"></rect><text x="25" y="10">4</text>

</g>

<g transform="translate(40,70)">

<rect width="39" height="130"></rect><text x="25" y="10">13</text>

</g>

<g transform="translate(80,125)">

<rect width="39" height="75"></rect><text x="25" y="10">7.5</text>

</g>

<g transform="translate(120,30)">

<rect width="39" height="170"></rect><text x="25" y="10">17</text>

</g>

</svg>

SD4x-3.10 697

7040

Property of Penn Engineering, Chris Murphy

<style>

rect {

fill: darkred;

}

rect:hover {

fill: darkblue;

}

.chart text {

fill: white;

font: 10px sans-serif;

text-anchor: end;

}

</style>

<svg class="chart" height="200">

<g transform="translate(0,160)">

<rect width="39" height="40"></rect><text x="25" y="10">4</text>

</g>

<g transform="translate(40,70)">

<rect width="39" height="130"></rect><text x="25" y="10">13</text>

</g>

<g transform="translate(80,125)">

<rect width="39" height="75"></rect><text x="25" y="10">7.5</text>

</g>

<g transform="translate(120,30)">

<rect width="39" height="170"></rect><text x="25" y="10">17</text>

</g>

</svg>

SD4x-3.10 698

125

80

Property of Penn Engineering, Chris Murphy

<style>

rect {

fill: darkred;

}

rect:hover {

fill: darkblue;

}

.chart text {

fill: white;

font: 10px sans-serif;

text-anchor: end;

}

</style>

<svg class="chart" height="200">

<g transform="translate(0,160)">

<rect width="39" height="40"></rect><text x="25" y="10">4</text>

</g>

<g transform="translate(40,70)">

<rect width="39" height="130"></rect><text x="25" y="10">13</text>

</g>

<g transform="translate(80,125)">

<rect width="39" height="75"></rect><text x="25" y="10">7.5</text>

</g>

<g transform="translate(120,30)">

<rect width="39" height="170"></rect><text x="25" y="10">17</text>

</g>

</svg>

SD4x-3.10 699

Property of Penn Engineering, Chris Murphy

<style>

rect {

fill: darkred;

}

rect:hover {

fill: darkblue;

}

.chart text {

fill: white;

font: 10px sans-serif;

text-anchor: end;

}

</style>

<svg class="chart" height="200">

<g transform="translate(0,160)">

<rect width="39" height="40"></rect><text x="25" y="10">4</text>

</g>

<g transform="translate(40,70)">

<rect width="39" height="130"></rect><text x="25" y="10">13</text>

</g>

<g transform="translate(80,125)">

<rect width="39" height="75"></rect><text x="25" y="10">7.5</text>

</g>

<g transform="translate(120,30)">

<rect width="39" height="170"></rect><text x="25" y="10">17</text>

</g>

</svg>

SD4x-3.10 700

Property of Penn Engineering, Chris Murphy

Dynamic SVG with D3.js

• D3.js is specifically designed to allow us to manipulate HTML/SVG elements based on data

• We can dynamically render SVG elements by applying functionality to a set of data

SD4x-3.10 701

Property of Penn Engineering, Chris Murphy

<style>

<!-- same CSS as before -->

</style>

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<script>

var numbers = [40, 130, 75, 170];

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(numbers)

.enter().append("g")

.attr("transform", (d,i) => {

return "translate(" + 40*i + "," + (200-d) + ")"; });

selection.append("rect")

.attr("width", 39)

.attr("height", (d,i) => { return d; });

selection.append("text")

.attr("x", 25)

.attr("y", 25)

.text((d) => { return d/10; });

</script>

SD4x-3.10 702

Property of Penn Engineering, Chris Murphy

<style>

<!-- same CSS as before -->

</style>

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<script>

var numbers = [40, 130, 75, 170];

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(numbers)

.enter().append("g")

.attr("transform", (d,i) => {

return "translate(" + 40*i + "," + (200-d) + ")"; });

selection.append("rect")

.attr("width", 39)

.attr("height", (d,i) => { return d; });

selection.append("text")

.attr("x", 25)

.attr("y", 25)

.text((d) => { return d/10; });

</script>

SD4x-3.10 703

Property of Penn Engineering, Chris Murphy

<style>

<!-- same CSS as before -->

</style>

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<script>

var numbers = [40, 130, 75, 170];

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(numbers)

.enter().append("g")

.attr("transform", (d,i) => {

return "translate(" + 40*i + "," + (200-d) + ")"; });

selection.append("rect")

.attr("width", 39)

.attr("height", (d,i) => { return d; });

selection.append("text")

.attr("x", 25)

.attr("y", 25)

.text((d) => { return d/10; });

</script>

SD4x-3.10 704

Property of Penn Engineering, Chris Murphy

<style>

<!-- same CSS as before -->

</style>

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<script>

var numbers = [40, 130, 75, 170];

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(numbers)

.enter().append("g")

.attr("transform", (d,i) => {

return "translate(" + 40*i + "," + (200-d) + ")"; });

selection.append("rect")

.attr("width", 39)

.attr("height", (d,i) => { return d; });

selection.append("text")

.attr("x", 25)

.attr("y", 25)

.text((d) => { return d/10; });

</script>

SD4x-3.10 705

Property of Penn Engineering, Chris Murphy

<style>

<!-- same CSS as before -->

</style>

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<script>

var numbers = [40, 130, 75, 170];

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(numbers)

.enter().append("g")

.attr("transform", (d,i) => {

return "translate(" + 40*i + "," + (200-d) + ")"; });

selection.append("rect")

.attr("width", 39)

.attr("height", (d,i) => { return d; });

selection.append("text")

.attr("x", 25)

.attr("y", 25)

.text((d) => { return d/10; });

</script>

SD4x-3.10 706

Property of Penn Engineering, Chris Murphy

<style>

<!-- same CSS as before -->

</style>

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<script>

var numbers = [40, 130, 75, 170];

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(numbers)

.enter().append("g")

.attr("transform", (d,i) => {

return "translate(" + 40*i + "," + (200-d) + ")"; });

selection.append("rect")

.attr("width", 39)

.attr("height", (d,i) => { return d; });

selection.append("text")

.attr("x", 25)

.attr("y", 25)

.text((d) => { return d/10; });

</script>

SD4x-3.10 707

Property of Penn Engineering, Chris Murphy

<style>

<!-- same CSS as before -->

</style>

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<script>

var numbers = [40, 130, 75, 170];

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(numbers)

.enter().append("g")

.attr("transform", (d,i) => {

return "translate(" + 40*i + "," + (200-d) + ")"; });

selection.append("rect")

.attr("width", 39)

.attr("height", (d,i) => { return d; });

selection.append("text")

.attr("x", 25)

.attr("y", 25)

.text((d) => { return d/10; });

</script>

SD4x-3.10 708

Property of Penn Engineering, Chris Murphy

<style>

<!-- same CSS as before -->

</style>

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<script>

var numbers = [40, 130, 75, 170];

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(numbers)

.enter().append("g")

.attr("transform", (d,i) => {

return "translate(" + 40*i + "," + (200-d) + ")"; });

selection.append("rect")

.attr("width", 39)

.attr("height", (d,i) => { return d; });

selection.append("text")

.attr("x", 25)

.attr("y", 25)

.text((d) => { return d/10; });

</script>

SD4x-3.10 709

Property of Penn Engineering, Chris Murphy

<style>

<!-- same CSS as before -->

</style>

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<script>

var numbers = [40, 130, 75, 170];

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(numbers)

.enter().append("g")

.attr("transform", (d,i) => {

return "translate(" + 40*i + "," + (200-d) + ")"; });

selection.append("rect")

.attr("width", 39)

.attr("height", (d,i) => { return d; });

selection.append("text")

.attr("x", 25)

.attr("y", 25)

.text((d) => { return d/10; });

</script>

SD4x-3.10 710

Property of Penn Engineering, Chris Murphy

<style>

<!-- same CSS as before -->

</style>

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<script>

var numbers = [40, 130, 75, 170];

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(numbers)

.enter().append("g")

.attr("transform", (d,i) => {

return "translate(" + 40*i + "," + (200-d) + ")"; });

selection.append("rect")

.attr("width", 39)

.attr("height", (d,i) => { return d; });

selection.append("text")

.attr("x", 25)

.attr("y", 25)

.text((d) => { return d/10; });

</script>

SD4x-3.10 711

Property of Penn Engineering, Chris Murphy

<style>

<!-- same CSS as before -->

</style>

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<script>

var numbers = [40, 130, 75, 170];

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(numbers)

.enter().append("g")

.attr("transform", (d,i) => {

return "translate(" + 40*i + "," + (200-d) + ")"; });

selection.append("rect")

.attr("width", 39)

.attr("height", (d,i) => { return d; });

selection.append("text")

.attr("x", 25)

.attr("y", 25)

.text((d) => { return d/10; });

</script>

SD4x-3.10 712

Property of Penn Engineering, Chris Murphy

<style>

<!-- same CSS as before -->

</style>

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<script>

var numbers = [40, 130, 75, 170];

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(numbers)

.enter().append("g")

.attr("transform", (d,i) => {

return "translate(" + 40*i + "," + (200-d) + ")"; });

selection.append("rect")

.attr("width", 39)

.attr("height", (d,i) => { return d; });

selection.append("text")

.attr("x", 25)

.attr("y", 25)

.text((d) => { return d/10; });

</script>

SD4x-3.10 713

Property of Penn Engineering, Chris Murphy

<style>

<!-- same CSS as before -->

</style>

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<script>

var numbers = [40, 130, 75, 170];

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(numbers)

.enter().append("g")

.attr("transform", (d,i) => {

return "translate(" + 40*i + "," + (200-d) + ")"; });

selection.append("rect")

.attr("width", 39)

.attr("height", (d,i) => { return d; });

selection.append("text")

.attr("x", 25)

.attr("y", 25)

.text((d) => { return d/10; });

</script>

SD4x-3.10 714

Property of Penn Engineering, Chris Murphy SD4x-3.10 715

var numbers = [40, 130, 75, 170];

Property of Penn Engineering, Chris Murphy SD4x-3.10 716

var numbers = [40, 130, 75, 170];

Property of Penn Engineering, Chris Murphy SD4x-3.10 717

var numbers = [40, 130, 75, 170];160

Property of Penn Engineering, Chris Murphy SD4x-3.10 718

var numbers = [40, 130, 75, 170];160

d = 40, i = 0 x = 0, y = 160

Property of Penn Engineering, Chris Murphy SD4x-3.10 719

var numbers = [40, 130, 75, 170];70

d = 40, i = 0 x = 0, y = 160

d = 130, i = 1 x = 40, y = 70

40

Property of Penn Engineering, Chris Murphy SD4x-3.10 720

var numbers = [40, 130, 75, 170];125

d = 40, i = 0 x = 0, y = 160

d = 130, i = 1 x = 40, y = 70

d = 75, i = 2 x = 80, y = 125

80

Property of Penn Engineering, Chris Murphy SD4x-3.10 721

var numbers = [40, 130, 75, 170];

30

d = 40, i = 0 x = 0, y = 160

d = 130, i = 1 x = 40, y = 70

d = 75, i = 2 x = 80, y = 125

d = 170, i = 3 x = 120, y = 30

120

Property of Penn Engineering, Chris Murphy SD4x-3.10 722

var numbers = [40, 130, 75, 170];

d = 40, i = 0 x = 0, y = 160

d = 130, i = 1 x = 40, y = 70

d = 75, i = 2 x = 80, y = 125

d = 170, i = 3 x = 120, y = 30

Property of Penn Engineering, Chris Murphy SD4x-3.10 723

var numbers = [40, 130, 75, 170];

d = 40, i = 0 x = 0, y = 160

d = 130, i = 1 x = 40, y = 70

d = 75, i = 2 x = 80, y = 125

d = 170, i = 3 x = 120, y = 30

Property of Penn Engineering, Chris Murphy SD4x-3.10 724

var numbers = [40, 130, 75, 170];

d = 40, i = 0 x = 0, y = 160

d = 130, i = 1 x = 40, y = 70

d = 75, i = 2 x = 80, y = 125

d = 170, i = 3 x = 120, y = 30

Property of Penn Engineering, Chris Murphy

<style>

<!-- same CSS as before -->

</style>

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<script>

var numbers = [40, 130, 75, 170];

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(numbers)

.enter().append("g")

.attr("transform", (d,i) => {

return "translate(" + 40*i + "," + (200-d) + ")"; });

selection.append("rect")

.attr("width", 39)

.attr("height", (d,i) => { return d; });

selection.append("text")

.attr("x", 25)

.attr("y", 25)

.text((d) => { return d/10; });

</script>

SD4x-3.10 725

Property of Penn Engineering, Chris Murphy

<style>

<!-- same CSS as before -->

</style>

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<script>

var numbers = [40, 130, 75, 170];

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(numbers)

.enter().append("g")

.attr("transform", (d,i) => {

return "translate(" + 40*i + "," + (200-d) + ")"; });

selection.append("rect")

.attr("width", 39)

.attr("height", (d,i) => { return d; });

selection.append("text")

.attr("x", 25)

.attr("y", 25)

.text((d) => { return d/10; });

</script>

SD4x-3.10 726

Property of Penn Engineering, Chris Murphy

<style>

<!-- same CSS as before -->

</style>

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<script>

var numbers = [40, 130, 75, 170];

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(numbers)

.enter().append("g")

.attr("transform", (d,i) => {

return "translate(" + 40*i + "," + (200-d) + ")"; });

selection.append("rect")

.attr("width", 39)

.attr("height", (d,i) => { return d; });

selection.append("text")

.attr("x", 25)

.attr("y", 25)

.text((d) => { return d/10; });

</script>

SD4x-3.10 727

Property of Penn Engineering, Chris Murphy

<style>

<!-- same CSS as before -->

</style>

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<script>

var numbers = [40, 130, 75, 170];

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(numbers)

.enter().append("g")

.attr("transform", (d,i) => {

return "translate(" + 40*i + "," + (200-d) + ")"; });

selection.append("rect")

.attr("width", 39)

.attr("height", (d,i) => { return d; });

selection.append("text")

.attr("x", 25)

.attr("y", 25)

.text((d) => { return d/10; });

</script>

SD4x-3.10 728

Property of Penn Engineering, Chris Murphy

<style>

<!-- same CSS as before -->

</style>

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<script>

var numbers = [40, 130, 75, 170];

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(numbers)

.enter().append("g")

.attr("transform", (d,i) => {

return "translate(" + 40*i + "," + (200-d) + ")"; });

selection.append("rect")

.attr("width", 39)

.attr("height", (d,i) => { return d; });

selection.append("text")

.attr("x", 25)

.attr("y", 25)

.text((d) => { return d/10; });

</script>

SD4x-3.10 729

Property of Penn Engineering, Chris Murphy

<style>

<!-- same CSS as before -->

</style>

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<script>

var numbers = [40, 130, 75, 170];

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(numbers)

.enter().append("g")

.attr("transform", (d,i) => {

return "translate(" + 40*i + "," + (200-d) + ")"; });

selection.append("rect")

.attr("width", 39)

.attr("height", (d,i) => { return d; });

selection.append("text")

.attr("x", 25)

.attr("y", 25)

.text((d) => { return d/10; });

</script>

SD4x-3.10 730

Property of Penn Engineering, Chris Murphy

<style>

<!-- same CSS as before -->

</style>

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<script>

var numbers = [40, 130, 75, 170];

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(numbers)

.enter().append("g")

.attr("transform", (d,i) => {

return "translate(" + 40*i + "," + (200-d) + ")"; });

selection.append("rect")

.attr("width", 39)

.attr("height", (d,i) => { return d; });

selection.append("text")

.attr("x", 25)

.attr("y", 25)

.text((d) => { return d/10; });

</script>

SD4x-3.10 731

Property of Penn Engineering, Chris Murphy

<style>

<!-- same CSS as before -->

</style>

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<script>

var numbers = [40, 130, 75, 170];

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(numbers)

.enter().append("g")

.attr("transform", (d,i) => {

return "translate(" + 40*i + "," + (200-d) + ")"; });

selection.append("rect")

.attr("width", 39)

.attr("height", (d,i) => { return d; });

selection.append("text")

.attr("x", 25)

.attr("y", 25)

.text((d) => { return d/10; });

</script>

SD4x-3.10 732

Property of Penn Engineering, Chris Murphy

<style>

<!-- same CSS as before -->

</style>

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<script>

var numbers = [40, 130, 75, 170];

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(numbers)

.enter().append("g")

.attr("transform", (d,i) => {

return "translate(" + 40*i + "," + (200-d) + ")"; });

selection.append("rect")

.attr("width", 39)

.attr("height", (d,i) => { return d; });

selection.append("text")

.attr("x", 25)

.attr("y", 25)

.text((d) => { return d/10; });

</script>

SD4x-3.10 733

Property of Penn Engineering, Chris Murphy

<style>

<!-- same CSS as before -->

</style>

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<script>

var numbers = [40, 130, 75, 170];

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(numbers)

.enter().append("g")

.attr("transform", (d,i) => {

return "translate(" + 40*i + "," + (200-d) + ")"; });

selection.append("rect")

.attr("width", 39)

.attr("height", (d,i) => { return d; });

selection.append("text")

.attr("x", 25)

.attr("y", 25)

.text((d) => { return d/10; });

</script>

SD4x-3.10 734

Property of Penn Engineering, Chris Murphy

Dynamic Graphics with D3.js

• In addition to rendering HTML/SVG elements using JavaScript, D3.js also allows us to add elements based on any changes to the data

• This allows us to dynamically modify our chart and other graphics

SD4x-3.10 735

Property of Penn Engineering, Chris Murphy SD4x-3.10 736

Property of Penn Engineering, Chris Murphy SD4x-3.10 737

Property of Penn Engineering, Chris Murphy SD4x-3.10 738

Property of Penn Engineering, Chris Murphy SD4x-3.10 739

Property of Penn Engineering, Chris Murphy SD4x-3.10 740

Property of Penn Engineering, Chris Murphy

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<p>

<input id="inputField"></input>

<button onclick="insert();">Insert</button>

<script>

var numbers = [40, 130, 75, 170];

function insert() {

var value = document.getElementById('inputField').value;

numbers.push(value);

drawChart();

document.getElementById('inputField').value = '';

}

function drawChart() {

// same D3 code as before!

}

drawChart();

</script>

SD4x-3.10 741

Property of Penn Engineering, Chris Murphy

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<p>

<input id="inputField"></input>

<button onclick="insert();">Insert</button>

<script>

var numbers = [40, 130, 75, 170];

function insert() {

var value = document.getElementById('inputField').value;

numbers.push(value);

drawChart();

document.getElementById('inputField').value = '';

}

function drawChart() {

// same D3 code as before!

}

drawChart();

</script>

SD4x-3.10 742

Property of Penn Engineering, Chris Murphy

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<p>

<input id="inputField"></input>

<button onclick="insert();">Insert</button>

<script>

var numbers = [40, 130, 75, 170];

function insert() {

var value = document.getElementById('inputField').value;

numbers.push(value);

drawChart();

document.getElementById('inputField').value = '';

}

function drawChart() {

// same D3 code as before!

}

drawChart();

</script>

SD4x-3.10 743

Property of Penn Engineering, Chris Murphy

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<p>

<input id="inputField"></input>

<button onclick="insert();">Insert</button>

<script>

var numbers = [40, 130, 75, 170];

function insert() {

var value = document.getElementById('inputField').value;

numbers.push(value);

drawChart();

document.getElementById('inputField').value = '';

}

function drawChart() {

// same D3 code as before!

}

drawChart();

</script>

SD4x-3.10 744

Property of Penn Engineering, Chris Murphy

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<p>

<input id="inputField"></input>

<button onclick="insert();">Insert</button>

<script>

var numbers = [40, 130, 75, 170];

function insert() {

var value = document.getElementById('inputField').value;

numbers.push(value);

drawChart();

document.getElementById('inputField').value = '';

}

function drawChart() {

// same D3 code as before!

}

drawChart();

</script>

SD4x-3.10 745

Property of Penn Engineering, Chris Murphy

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<p>

<input id="inputField"></input>

<button onclick="insert();">Insert</button>

<script>

var numbers = [40, 130, 75, 170];

function insert() {

var value = document.getElementById('inputField').value;

numbers.push(value);

drawChart();

document.getElementById('inputField').value = '';

}

function drawChart() {

// same D3 code as before!

}

drawChart();

</script>

SD4x-3.10 746

Property of Penn Engineering, Chris Murphy

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<p>

<input id="inputField"></input>

<button onclick="insert();">Insert</button>

<script>

var numbers = [40, 130, 75, 170];

function insert() {

var value = document.getElementById('inputField').value;

numbers.push(value);

drawChart();

document.getElementById('inputField').value = '';

}

function drawChart() {

// same D3 code as before!

}

drawChart();

</script>

SD4x-3.10 747

Property of Penn Engineering, Chris Murphy

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<p>

<input id="inputField"></input>

<button onclick="insert();">Insert</button>

<script>

var numbers = [40, 130, 75, 170];

function insert() {

var value = document.getElementById('inputField').value;

numbers.push(value);

drawChart();

document.getElementById('inputField').value = '';

}

function drawChart() {

// same D3 code as before!

}

drawChart();

</script>

SD4x-3.10 748

Property of Penn Engineering, Chris Murphy

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<p>

<input id="inputField"></input>

<button onclick="insert();">Insert</button>

<script>

var numbers = [40, 130, 75, 170];

function insert() {

var value = document.getElementById('inputField').value;

numbers.push(value);

drawChart();

document.getElementById('inputField').value = '';

}

function drawChart() {

// same D3 code as before!

}

drawChart();

</script>

SD4x-3.10 749

Property of Penn Engineering, Chris Murphy

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<p>

<input id="inputField"></input>

<button onclick="insert();">Insert</button>

<script>

var numbers = [40, 130, 75, 170];

function insert() {

var value = document.getElementById('inputField').value;

numbers.push(value);

drawChart();

document.getElementById('inputField').value = '';

}

function drawChart() {

// same D3 code as before!

}

drawChart();

</script>

SD4x-3.10 750

Property of Penn Engineering, Chris Murphy

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<p>

<input id="inputField"></input>

<button onclick="insert();">Insert</button>

<script>

var numbers = [40, 130, 75, 170];

function insert() {

var value = document.getElementById('inputField').value;

numbers.push(value);

drawChart();

document.getElementById('inputField').value = '';

}

function drawChart() {

// same D3 code as before!

}

drawChart();

</script>

SD4x-3.10 751

Property of Penn Engineering, Chris Murphy

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<p>

<input id="inputField"></input>

<button onclick="insert();">Insert</button>

<script>

var numbers = [40, 130, 75, 170];

function insert() {

var value = document.getElementById('inputField').value;

numbers.push(value);

drawChart();

document.getElementById('inputField').value = '';

}

function drawChart() {

// same D3 code as before!

}

drawChart();

</script>

SD4x-3.10 752

Property of Penn Engineering, Chris Murphy

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<p>

<input id="inputField"></input>

<button onclick="insert();">Insert</button>

<script>

var numbers = [40, 130, 75, 170];

function insert() {

var value = document.getElementById('inputField').value;

numbers.push(value);

drawChart();

document.getElementById('inputField').value = '';

}

function drawChart() {

// same D3 code as before!

}

drawChart();

</script>

SD4x-3.10 753

Property of Penn Engineering, Chris Murphy

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<p>

<input id="inputField"></input>

<button onclick="insert();">Insert</button>

<script>

var numbers = [40, 130, 75, 170];

function insert() {

var value = document.getElementById('inputField').value;

numbers.push(value);

drawChart();

document.getElementById('inputField').value = '';

}

function drawChart() {

// same D3 code as before!

}

drawChart();

</script>

SD4x-3.10 754

Property of Penn Engineering, Chris Murphy

<script src="http://d3js.org/d3.v4.min.js"></script>

<svg class="chart" height="200"></svg>

<p>

<input id="inputField"></input>

<button onclick="insert();">Insert</button>

<script>

var numbers = [40, 130, 75, 170];

function insert() {

var value = document.getElementById('inputField').value;

numbers.push(value);

drawChart();

document.getElementById('inputField').value = '';

}

function drawChart() {

// same D3 code as before!

}

drawChart();

</script>

SD4x-3.10 755

Property of Penn Engineering, Chris Murphy

Summary

• D3.js is a powerful library for generating HTML and SVG elements based on data

• We can apply functions to data sets to generate graphical elements, e.g. charts

• And use D3.js to modify the elements when new data is added

SD4x-3.10 756

Video 3.11

More D3

Chris Murphy

SD4x-3.11 757

Property of Penn Engineering, Chris Murphy

Review

• D3.js allows us to generate HTML and SVG elements based on data

• We can apply functions to data sets to generate graphical elements, e.g. charts

SD4x-3.11 758

Property of Penn Engineering, Chris Murphy SD4x-3.11 759

Property of Penn Engineering, Chris Murphy

D3 and Data

• The data used in D3 can be objects, not just numbers

• We can then use the properties of these objects when deciding how to render the visualization (chart, SVG, etc.)

SD4x-3.11 760

Property of Penn Engineering, Chris Murphy

<html>

<head>

<script src="http://d3js.org/d3.v4.min.js"></script>

</head>

<body>

<svg class="chart" height="900" width="900">

</svg>

<script>

var values = [

{price: 700, sqft: 3000, br: 3, pets: [ 'cats', 'dogs' ] },

{price: 445, sqft: 1700, br: 2, pets: [] },

{price: 421, sqft: 1455, br: 2, pets: [ 'cats', 'dogs' ] },

{price: 411, sqft: 1314, br: 2, pets: [ 'dogs' ] },

{price: 275, sqft: 1200, br: 1, pets: [ 'cats' ]},

{price: 500, sqft: 650, br: 1, pets: [] },

];

. . .

SD4x-3.11 761

Property of Penn Engineering, Chris Murphy

<html>

<head>

<script src="http://d3js.org/d3.v4.min.js"></script>

</head>

<body>

<svg class="chart" height="900" width="900">

</svg>

<script>

var values = [

{price: 700, sqft: 3000, br: 3, pets: [ 'cats', 'dogs' ] },

{price: 445, sqft: 1700, br: 2, pets: [] },

{price: 421, sqft: 1455, br: 2, pets: [ 'cats', 'dogs' ] },

{price: 411, sqft: 1314, br: 2, pets: [ 'dogs' ] },

{price: 275, sqft: 1200, br: 1, pets: [ 'cats' ]},

{price: 500, sqft: 650, br: 1, pets: [] },

];

. . .

SD4x-3.11 762

Property of Penn Engineering, Chris Murphy

<html>

<head>

<script src="http://d3js.org/d3.v4.min.js"></script>

</head>

<body>

<svg class="chart" height="900" width="900">

</svg>

<script>

var values = [

{price: 700, sqft: 3000, br: 3, pets: [ 'cats', 'dogs' ] },

{price: 445, sqft: 1700, br: 2, pets: [] },

{price: 421, sqft: 1455, br: 2, pets: [ 'cats', 'dogs' ] },

{price: 411, sqft: 1314, br: 2, pets: [ 'dogs' ] },

{price: 275, sqft: 1200, br: 1, pets: [ 'cats' ]},

{price: 500, sqft: 650, br: 1, pets: [] },

];

. . .

SD4x-3.11 763

Property of Penn Engineering, Chris Murphy

<html>

<head>

<script src="http://d3js.org/d3.v4.min.js"></script>

</head>

<body>

<svg class="chart" height="900" width="900">

</svg>

<script>

var values = [

{price: 700, sqft: 3000, br: 3, pets: [ 'cats', 'dogs' ] },

{price: 445, sqft: 1700, br: 2, pets: [] },

{price: 421, sqft: 1455, br: 2, pets: [ 'cats', 'dogs' ] },

{price: 411, sqft: 1314, br: 2, pets: [ 'dogs' ] },

{price: 275, sqft: 1200, br: 1, pets: [ 'cats' ]},

{price: 500, sqft: 650, br: 1, pets: [] },

];

. . .

SD4x-3.11 764

Property of Penn Engineering, Chris Murphy

<html>

<head>

<script src="http://d3js.org/d3.v4.min.js"></script>

</head>

<body>

<svg class="chart" height="900" width="900">

</svg>

<script>

var values = [

{price: 700, sqft: 3000, br: 3, pets: [ 'cats', 'dogs' ] },

{price: 445, sqft: 1700, br: 2, pets: [] },

{price: 421, sqft: 1455, br: 2, pets: [ 'cats', 'dogs' ] },

{price: 411, sqft: 1314, br: 2, pets: [ 'dogs' ] },

{price: 275, sqft: 1200, br: 1, pets: [ 'cats' ]},

{price: 500, sqft: 650, br: 1, pets: [] },

];

. . .

SD4x-3.11 765

Property of Penn Engineering, Chris Murphy

<html>

<head>

<script src="http://d3js.org/d3.v4.min.js"></script>

</head>

<body>

<svg class="chart" height="900" width="900">

</svg>

<script>

var values = [

{price: 700, sqft: 3000, br: 3, pets: [ 'cats', 'dogs' ] },

{price: 445, sqft: 1700, br: 2, pets: [] },

{price: 421, sqft: 1455, br: 2, pets: [ 'cats', 'dogs' ] },

{price: 411, sqft: 1314, br: 2, pets: [ 'dogs' ] },

{price: 275, sqft: 1200, br: 1, pets: [ 'cats' ]},

{price: 500, sqft: 650, br: 1, pets: [] },

];

. . .

SD4x-3.11 766

Property of Penn Engineering, Chris Murphy

<html>

<head>

<script src="http://d3js.org/d3.v4.min.js"></script>

</head>

<body>

<svg class="chart" height="900" width="900">

</svg>

<script>

var values = [

{price: 700, sqft: 3000, br: 3, pets: [ 'cats', 'dogs' ] },

{price: 445, sqft: 1700, br: 2, pets: [] },

{price: 421, sqft: 1455, br: 2, pets: [ 'cats', 'dogs' ] },

{price: 411, sqft: 1314, br: 2, pets: [ 'dogs' ] },

{price: 275, sqft: 1200, br: 1, pets: [ 'cats' ]},

{price: 500, sqft: 650, br: 1, pets: [] },

];

. . .

SD4x-3.11 767

Property of Penn Engineering, Chris Murphy

<html>

<head>

<script src="http://d3js.org/d3.v4.min.js"></script>

</head>

<body>

<svg class="chart" height="900" width="900">

</svg>

<script>

var values = [

{price: 700, sqft: 3000, br: 3, pets: [ 'cats', 'dogs' ] },

{price: 445, sqft: 1700, br: 2, pets: [] },

{price: 421, sqft: 1455, br: 2, pets: [ 'cats', 'dogs' ] },

{price: 411, sqft: 1314, br: 2, pets: [ 'dogs' ] },

{price: 275, sqft: 1200, br: 1, pets: [ 'cats' ]},

{price: 500, sqft: 650, br: 1, pets: [] },

];

. . .

SD4x-3.11 768

Property of Penn Engineering, Chris Murphy

<html>

<head>

<script src="http://d3js.org/d3.v4.min.js"></script>

</head>

<body>

<svg class="chart" height="900" width="900">

</svg>

<script>

var values = [

{price: 700, sqft: 3000, br: 3, pets: [ 'cats', 'dogs' ] },

{price: 445, sqft: 1700, br: 2, pets: [] },

{price: 421, sqft: 1455, br: 2, pets: [ 'cats', 'dogs' ] },

{price: 411, sqft: 1314, br: 2, pets: [ 'dogs' ] },

{price: 275, sqft: 1200, br: 1, pets: [ 'cats' ]},

{price: 500, sqft: 650, br: 1, pets: [] },

];

. . .

SD4x-3.11 769

Property of Penn Engineering, Chris Murphy

<html>

<head>

<script src="http://d3js.org/d3.v4.min.js"></script>

</head>

<body>

<svg class="chart" height="900" width="900">

</svg>

<script>

var values = [

{price: 700, sqft: 3000, br: 3, pets: [ 'cats', 'dogs' ] },

{price: 445, sqft: 1700, br: 2, pets: [] },

{price: 421, sqft: 1455, br: 2, pets: [ 'cats', 'dogs' ] },

{price: 411, sqft: 1314, br: 2, pets: [ 'dogs' ] },

{price: 275, sqft: 1200, br: 1, pets: [ 'cats' ]},

{price: 500, sqft: 650, br: 1, pets: [] },

];

. . .

SD4x-3.11 770

Property of Penn Engineering, Chris Murphy

<html>

<head>

<script src="http://d3js.org/d3.v4.min.js"></script>

</head>

<body>

<svg class="chart" height="900" width="900">

</svg>

<script>

var values = [

{price: 700, sqft: 3000, br: 3, pets: [ 'cats', 'dogs' ] },

{price: 445, sqft: 1700, br: 2, pets: [] },

{price: 421, sqft: 1455, br: 2, pets: [ 'cats', 'dogs' ] },

{price: 411, sqft: 1314, br: 2, pets: [ 'dogs' ] },

{price: 275, sqft: 1200, br: 1, pets: [ 'cats' ]},

{price: 500, sqft: 650, br: 1, pets: [] },

];

. . .

SD4x-3.11 771

Property of Penn Engineering, Chris Murphy SD4x-3.11 772

Property of Penn Engineering, Chris Murphy SD4x-3.11 773

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

.enter()

.append("g")

.attr("transform", "translate(10,10)");

selection.append("circle")

.attr("cx", (d,i) => { return d.price / 2; })

.attr("cy", (d,i) => { return (4000 - d.sqft)/(4000/400) ; })

.attr("r", (d,i) => { return d.br * 10 ; })

.style("fill", (d,i) => { return color(d.pets); })

.style("opacity", "0.5")

.append("svg:title").text( (d,i) => { return print(d); });

function color(pets) {

var dogs = pets.indexOf('dogs') != -1;

var cats = pets.indexOf('cats') != -1;

if (dogs) return cats ? 'purple' : 'blue' ;

else return cats ? 'red' : 'gray';

}

function print(home) {

return `$${home.price}k, ${home.sqft}sqft, ${home.br} BRs`;

}

Property of Penn Engineering, Chris Murphy SD4x-3.11 774

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

.enter()

.append("g")

.attr("transform", "translate(10,10)");

selection.append("circle")

.attr("cx", (d,i) => { return d.price / 2; })

.attr("cy", (d,i) => { return (4000 - d.sqft)/(4000/400) ; })

.attr("r", (d,i) => { return d.br * 10 ; })

.style("fill", (d,i) => { return color(d.pets); })

.style("opacity", "0.5")

.append("svg:title").text( (d,i) => { return print(d); });

function color(pets) {

var dogs = pets.indexOf('dogs') != -1;

var cats = pets.indexOf('cats') != -1;

if (dogs) return cats ? 'purple' : 'blue' ;

else return cats ? 'red' : 'gray';

}

function print(home) {

return `$${home.price}k, ${home.sqft}sqft, ${home.br} BRs`;

}

Property of Penn Engineering, Chris Murphy SD4x-3.11 775

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

.enter()

.append("g")

.attr("transform", "translate(10,10)");

selection.append("circle")

.attr("cx", (d,i) => { return d.price / 2; })

.attr("cy", (d,i) => { return (4000 - d.sqft)/(4000/400) ; })

.attr("r", (d,i) => { return d.br * 10 ; })

.style("fill", (d,i) => { return color(d.pets); })

.style("opacity", "0.5")

.append("svg:title").text( (d,i) => { return print(d); });

function color(pets) {

var dogs = pets.indexOf('dogs') != -1;

var cats = pets.indexOf('cats') != -1;

if (dogs) return cats ? 'purple' : 'blue' ;

else return cats ? 'red' : 'gray';

}

function print(home) {

return `$${home.price}k, ${home.sqft}sqft, ${home.br} BRs`;

}

Property of Penn Engineering, Chris Murphy SD4x-3.11 776

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

.enter()

.append("g")

.attr("transform", "translate(10,10)");

selection.append("circle")

.attr("cx", (d,i) => { return d.price / 2; })

.attr("cy", (d,i) => { return (4000 - d.sqft)/(4000/400) ; })

.attr("r", (d,i) => { return d.br * 10 ; })

.style("fill", (d,i) => { return color(d.pets); })

.style("opacity", "0.5")

.append("svg:title").text( (d,i) => { return print(d); });

function color(pets) {

var dogs = pets.indexOf('dogs') != -1;

var cats = pets.indexOf('cats') != -1;

if (dogs) return cats ? 'purple' : 'blue' ;

else return cats ? 'red' : 'gray';

}

function print(home) {

return `$${home.price}k, ${home.sqft}sqft, ${home.br} BRs`;

}

Property of Penn Engineering, Chris Murphy SD4x-3.11 777

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

.enter()

.append("g")

.attr("transform", "translate(10,10)");

selection.append("circle")

.attr("cx", (d,i) => { return d.price / 2; })

.attr("cy", (d,i) => { return (4000 - d.sqft)/(4000/400) ; })

.attr("r", (d,i) => { return d.br * 10 ; })

.style("fill", (d,i) => { return color(d.pets); })

.style("opacity", "0.5")

.append("svg:title").text( (d,i) => { return print(d); });

function color(pets) {

var dogs = pets.indexOf('dogs') != -1;

var cats = pets.indexOf('cats') != -1;

if (dogs) return cats ? 'purple' : 'blue' ;

else return cats ? 'red' : 'gray';

}

function print(home) {

return `$${home.price}k, ${home.sqft}sqft, ${home.br} BRs`;

}

Property of Penn Engineering, Chris Murphy SD4x-3.11 778

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

.enter()

.append("g")

.attr("transform", "translate(10,10)");

selection.append("circle")

.attr("cx", (d,i) => { return d.price / 2; })

.attr("cy", (d,i) => { return (4000 - d.sqft)/(4000/400) ; })

.attr("r", (d,i) => { return d.br * 10 ; })

.style("fill", (d,i) => { return color(d.pets); })

.style("opacity", "0.5")

.append("svg:title").text( (d,i) => { return print(d); });

function color(pets) {

var dogs = pets.indexOf('dogs') != -1;

var cats = pets.indexOf('cats') != -1;

if (dogs) return cats ? 'purple' : 'blue' ;

else return cats ? 'red' : 'gray';

}

function print(home) {

return `$${home.price}k, ${home.sqft}sqft, ${home.br} BRs`;

}

Property of Penn Engineering, Chris Murphy SD4x-3.11 779

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

.enter()

.append("g")

.attr("transform", "translate(10,10)");

selection.append("circle")

.attr("cx", (d,i) => { return d.price / 2; })

.attr("cy", (d,i) => { return (4000 - d.sqft)/(4000/400) ; })

.attr("r", (d,i) => { return d.br * 10 ; })

.style("fill", (d,i) => { return color(d.pets); })

.style("opacity", "0.5")

.append("svg:title").text( (d,i) => { return print(d); });

function color(pets) {

var dogs = pets.indexOf('dogs') != -1;

var cats = pets.indexOf('cats') != -1;

if (dogs) return cats ? 'purple' : 'blue' ;

else return cats ? 'red' : 'gray';

}

function print(home) {

return `$${home.price}k, ${home.sqft}sqft, ${home.br} BRs`;

}

Property of Penn Engineering, Chris Murphy SD4x-3.11 780

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

.enter()

.append("g")

.attr("transform", "translate(10,10)");

selection.append("circle")

.attr("cx", (d,i) => { return d.price / 2; })

.attr("cy", (d,i) => { return (4000 - d.sqft)/(4000/400) ; })

.attr("r", (d,i) => { return d.br * 10 ; })

.style("fill", (d,i) => { return color(d.pets); })

.style("opacity", "0.5")

.append("svg:title").text( (d,i) => { return print(d); });

function color(pets) {

var dogs = pets.indexOf('dogs') != -1;

var cats = pets.indexOf('cats') != -1;

if (dogs) return cats ? 'purple' : 'blue' ;

else return cats ? 'red' : 'gray';

}

function print(home) {

return `$${home.price}k, ${home.sqft}sqft, ${home.br} BRs`;

}

Property of Penn Engineering, Chris Murphy SD4x-3.11 781

Property of Penn Engineering, Chris Murphy SD4x-3.11 782

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

.enter()

.append("g")

.attr("transform", "translate(10,10)");

selection.append("circle")

.attr("cx", (d,i) => { return d.price / 2; })

.attr("cy", (d,i) => { return (4000 - d.sqft)/(4000/400) ; })

.attr("r", (d,i) => { return d.br * 10 ; })

.style("fill", (d,i) => { return color(d.pets); })

.style("opacity", "0.5")

.append("svg:title").text( (d,i) => { return print(d); });

function color(pets) {

var dogs = pets.indexOf('dogs') != -1;

var cats = pets.indexOf('cats') != -1;

if (dogs) return cats ? 'purple' : 'blue' ;

else return cats ? 'red' : 'gray';

}

function print(home) {

return `$${home.price}k, ${home.sqft}sqft, ${home.br} BRs`;

}

Property of Penn Engineering, Chris Murphy SD4x-3.11 783

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

.enter()

.append("g")

.attr("transform", "translate(10,10)");

selection.append("circle")

.attr("cx", (d,i) => { return d.price / 2; })

.attr("cy", (d,i) => { return (4000 - d.sqft)/(4000/400) ; })

.attr("r", (d,i) => { return d.br * 10 ; })

.style("fill", (d,i) => { return color(d.pets); })

.style("opacity", "0.5")

.append("svg:title").text( (d,i) => { return print(d); });

function color(pets) {

var dogs = pets.indexOf('dogs') != -1;

var cats = pets.indexOf('cats') != -1;

if (dogs) return cats ? 'purple' : 'blue' ;

else return cats ? 'red' : 'gray';

}

function print(home) {

return `$${home.price}k, ${home.sqft}sqft, ${home.br} BRs`;

}

Property of Penn Engineering, Chris Murphy SD4x-3.11 784

Property of Penn Engineering, Chris Murphy SD4x-3.11 785

{price: 700, sqft: 3000, . . . },

{price: 445, sqft: 1700, . . . },

{price: 421, sqft: 1455, . . . },

{price: 411, sqft: 1314, . . . },

{price: 275, sqft: 1200, . . . },

{price: 500, sqft: 650, . . . },

Property of Penn Engineering, Chris Murphy SD4x-3.11 786

{price: 700, sqft: 3000, . . . },

{price: 445, sqft: 1700, . . . },

{price: 421, sqft: 1455, . . . },

{price: 411, sqft: 1314, . . . },

{price: 275, sqft: 1200, . . . },

{price: 500, sqft: 650, . . . },

Property of Penn Engineering, Chris Murphy SD4x-3.11 787

{price: 700, sqft: 3000, . . . },

{price: 445, sqft: 1700, . . . },

{price: 421, sqft: 1455, . . . },

{price: 411, sqft: 1314, . . . },

{price: 275, sqft: 1200, . . . },

{price: 500, sqft: 650, . . . },

350

Property of Penn Engineering, Chris Murphy SD4x-3.11 788

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

.enter()

.append("g")

.attr("transform", "translate(10,10)");

selection.append("circle")

.attr("cx", (d,i) => { return d.price / 2; })

.attr("cy", (d,i) => { return (4000 - d.sqft)/(4000/400) ; })

.attr("r", (d,i) => { return d.br * 10 ; })

.style("fill", (d,i) => { return color(d.pets); })

.style("opacity", "0.5")

.append("svg:title").text( (d,i) => { return print(d); });

function color(pets) {

var dogs = pets.indexOf('dogs') != -1;

var cats = pets.indexOf('cats') != -1;

if (dogs) return cats ? 'purple' : 'blue' ;

else return cats ? 'red' : 'gray';

}

function print(home) {

return `$${home.price}k, ${home.sqft}sqft, ${home.br} BRs`;

}

Property of Penn Engineering, Chris Murphy SD4x-3.11 789

{price: 700, sqft: 3000, . . . },

{price: 445, sqft: 1700, . . . },

{price: 421, sqft: 1455, . . . },

{price: 411, sqft: 1314, . . . },

{price: 275, sqft: 1200, . . . },

{price: 500, sqft: 650, . . . },

Property of Penn Engineering, Chris Murphy SD4x-3.11 790

{price: 700, sqft: 3000, . . . },

{price: 445, sqft: 1700, . . . },

{price: 421, sqft: 1455, . . . },

{price: 411, sqft: 1314, . . . },

{price: 275, sqft: 1200, . . . },

{price: 500, sqft: 650, . . . },

Property of Penn Engineering, Chris Murphy SD4x-3.11 791

{price: 700, sqft: 3000, . . . },

{price: 445, sqft: 1700, . . . },

{price: 421, sqft: 1455, . . . },

{price: 411, sqft: 1314, . . . },

{price: 275, sqft: 1200, . . . },

{price: 500, sqft: 650, . . . },

100

Property of Penn Engineering, Chris Murphy SD4x-3.11 792

{price: 700, sqft: 3000, . . . },

{price: 445, sqft: 1700, . . . },

{price: 421, sqft: 1455, . . . },

{price: 411, sqft: 1314, . . . },

{price: 275, sqft: 1200, . . . },

{price: 500, sqft: 650, . . . },

230

Property of Penn Engineering, Chris Murphy SD4x-3.11 793

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

.enter()

.append("g")

.attr("transform", "translate(10,10)");

selection.append("circle")

.attr("cx", (d,i) => { return d.price / 2; })

.attr("cy", (d,i) => { return (4000 - d.sqft)/(4000/400) ; })

.attr("r", (d,i) => { return d.br * 10 ; })

.style("fill", (d,i) => { return color(d.pets); })

.style("opacity", "0.5")

.append("svg:title").text( (d,i) => { return print(d); });

function color(pets) {

var dogs = pets.indexOf('dogs') != -1;

var cats = pets.indexOf('cats') != -1;

if (dogs) return cats ? 'purple' : 'blue' ;

else return cats ? 'red' : 'gray';

}

function print(home) {

return `$${home.price}k, ${home.sqft}sqft, ${home.br} BRs`;

}

Property of Penn Engineering, Chris Murphy SD4x-3.11 794

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

.enter()

.append("g")

.attr("transform", "translate(10,10)");

selection.append("circle")

.attr("cx", (d,i) => { return d.price / 2; })

.attr("cy", (d,i) => { return (4000 - d.sqft)/(4000/400) ; })

.attr("r", (d,i) => { return d.br * 10 ; })

.style("fill", (d,i) => { return color(d.pets); })

.style("opacity", "0.5")

.append("svg:title").text( (d,i) => { return print(d); });

function color(pets) {

var dogs = pets.indexOf('dogs') != -1;

var cats = pets.indexOf('cats') != -1;

if (dogs) return cats ? 'purple' : 'blue' ;

else return cats ? 'red' : 'gray';

}

function print(home) {

return `$${home.price}k, ${home.sqft}sqft, ${home.br} BRs`;

}

Property of Penn Engineering, Chris Murphy SD4x-3.11 795

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

.enter()

.append("g")

.attr("transform", "translate(10,10)");

selection.append("circle")

.attr("cx", (d,i) => { return d.price / 2; })

.attr("cy", (d,i) => { return (4000 - d.sqft)/(4000/400) ; })

.attr("r", (d,i) => { return d.br * 10 ; })

.style("fill", (d,i) => { return color(d.pets); })

.style("opacity", "0.5")

.append("svg:title").text( (d,i) => { return print(d); });

function color(pets) {

var dogs = pets.indexOf('dogs') != -1;

var cats = pets.indexOf('cats') != -1;

if (dogs) return cats ? 'purple' : 'blue' ;

else return cats ? 'red' : 'gray';

}

function print(home) {

return `$${home.price}k, ${home.sqft}sqft, ${home.br} BRs`;

}

Property of Penn Engineering, Chris Murphy SD4x-3.11 796

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

.enter()

.append("g")

.attr("transform", "translate(10,10)");

selection.append("circle")

.attr("cx", (d,i) => { return d.price / 2; })

.attr("cy", (d,i) => { return (4000 - d.sqft)/(4000/400) ; })

.attr("r", (d,i) => { return d.br * 10 ; })

.style("fill", (d,i) => { return color(d.pets); })

.style("opacity", "0.5")

.append("svg:title").text( (d,i) => { return print(d); });

function color(pets) {

var dogs = pets.indexOf('dogs') != -1;

var cats = pets.indexOf('cats') != -1;

if (dogs) return cats ? 'purple' : 'blue' ;

else return cats ? 'red' : 'gray';

}

function print(home) {

return `$${home.price}k, ${home.sqft}sqft, ${home.br} BRs`;

}

Property of Penn Engineering, Chris Murphy SD4x-3.11 797

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

.enter()

.append("g")

.attr("transform", "translate(10,10)");

selection.append("circle")

.attr("cx", (d,i) => { return d.price / 2; })

.attr("cy", (d,i) => { return (4000 - d.sqft)/(4000/400) ; })

.attr("r", (d,i) => { return d.br * 10 ; })

.style("fill", (d,i) => { return color(d.pets); })

.style("opacity", "0.5")

.append("svg:title").text( (d,i) => { return print(d); });

function color(pets) {

var dogs = pets.indexOf('dogs') != -1;

var cats = pets.indexOf('cats') != -1;

if (dogs) return cats ? 'purple' : 'blue' ;

else return cats ? 'red' : 'gray';

}

function print(home) {

return `$${home.price}k, ${home.sqft}sqft, ${home.br} BRs`;

}

Property of Penn Engineering, Chris Murphy SD4x-3.11 798

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

.enter()

.append("g")

.attr("transform", "translate(10,10)");

selection.append("circle")

.attr("cx", (d,i) => { return d.price / 2; })

.attr("cy", (d,i) => { return (4000 - d.sqft)/(4000/400) ; })

.attr("r", (d,i) => { return d.br * 10 ; })

.style("fill", (d,i) => { return color(d.pets); })

.style("opacity", "0.5")

.append("svg:title").text( (d,i) => { return print(d); });

function color(pets) {

var dogs = pets.indexOf('dogs') != -1;

var cats = pets.indexOf('cats') != -1;

if (dogs) return cats ? 'purple' : 'blue' ;

else return cats ? 'red' : 'gray';

}

function print(home) {

return `$${home.price}k, ${home.sqft}sqft, ${home.br} BRs`;

}

Property of Penn Engineering, Chris Murphy SD4x-3.11 799

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

.enter()

.append("g")

.attr("transform", "translate(10,10)");

selection.append("circle")

.attr("cx", (d,i) => { return d.price / 2; })

.attr("cy", (d,i) => { return (4000 - d.sqft)/(4000/400) ; })

.attr("r", (d,i) => { return d.br * 10 ; })

.style("fill", (d,i) => { return color(d.pets); })

.style("opacity", "0.5")

.append("svg:title").text( (d,i) => { return print(d); });

function color(pets) {

var dogs = pets.indexOf('dogs') != -1;

var cats = pets.indexOf('cats') != -1;

if (dogs) return cats ? 'purple' : 'blue' ;

else return cats ? 'red' : 'gray';

}

function print(home) {

return `$${home.price}k, ${home.sqft}sqft, ${home.br} BRs`;

}

Property of Penn Engineering, Chris Murphy SD4x-3.11 800

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

.enter()

.append("g")

.attr("transform", "translate(10,10)");

selection.append("circle")

.attr("cx", (d,i) => { return d.price / 2; })

.attr("cy", (d,i) => { return (4000 - d.sqft)/(4000/400) ; })

.attr("r", (d,i) => { return d.br * 10 ; })

.style("fill", (d,i) => { return color(d.pets); })

.style("opacity", "0.5")

.append("svg:title").text( (d,i) => { return print(d); });

function color(pets) {

var dogs = pets.indexOf('dogs') != -1;

var cats = pets.indexOf('cats') != -1;

if (dogs) return cats ? 'purple' : 'blue' ;

else return cats ? 'red' : 'gray';

}

function print(home) {

return `$${home.price}k, ${home.sqft}sqft, ${home.br} BRs`;

}

Property of Penn Engineering, Chris Murphy SD4x-3.11 801

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

.enter()

.append("g")

.attr("transform", "translate(10,10)");

selection.append("circle")

.attr("cx", (d,i) => { return d.price / 2; })

.attr("cy", (d,i) => { return (4000 - d.sqft)/(4000/400) ; })

.attr("r", (d,i) => { return d.br * 10 ; })

.style("fill", (d,i) => { return color(d.pets); })

.style("opacity", "0.5")

.append("svg:title").text( (d,i) => { return print(d); });

function color(pets) {

var dogs = pets.indexOf('dogs') != -1;

var cats = pets.indexOf('cats') != -1;

if (dogs) return cats ? 'purple' : 'blue' ;

else return cats ? 'red' : 'gray';

}

function print(home) {

return `$${home.price}k, ${home.sqft}sqft, ${home.br} BRs`;

}

Property of Penn Engineering, Chris Murphy SD4x-3.11 802

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

.enter()

.append("g")

.attr("transform", "translate(10,10)");

selection.append("circle")

.attr("cx", (d,i) => { return d.price / 2; })

.attr("cy", (d,i) => { return (4000 - d.sqft)/(4000/400) ; })

.attr("r", (d,i) => { return d.br * 10 ; })

.style("fill", (d,i) => { return color(d.pets); })

.style("opacity", "0.5")

.append("svg:title").text( (d,i) => { return print(d); });

function color(pets) {

var dogs = pets.indexOf('dogs') != -1;

var cats = pets.indexOf('cats') != -1;

if (dogs) return cats ? 'purple' : 'blue' ;

else return cats ? 'red' : 'gray';

}

function print(home) {

return `$${home.price}k, ${home.sqft}sqft, ${home.br} BRs`;

}

Property of Penn Engineering, Chris Murphy SD4x-3.11 803

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

.enter()

.append("g")

.attr("transform", "translate(10,10)");

selection.append("circle")

.attr("cx", (d,i) => { return d.price / 2; })

.attr("cy", (d,i) => { return (4000 - d.sqft)/(4000/400) ; })

.attr("r", (d,i) => { return d.br * 10 ; })

.style("fill", (d,i) => { return color(d.pets); })

.style("opacity", "0.5")

.append("svg:title").text( (d,i) => { return print(d); });

function color(pets) {

var dogs = pets.indexOf('dogs') != -1;

var cats = pets.indexOf('cats') != -1;

if (dogs) return cats ? 'purple' : 'blue' ;

else return cats ? 'red' : 'gray';

}

function print(home) {

return `$${home.price}k, ${home.sqft}sqft, ${home.br} BRs`;

}

Property of Penn Engineering, Chris Murphy SD4x-3.11 804

Property of Penn Engineering, Chris Murphy SD4x-3.11 805

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

.enter()

.append("g")

.attr("transform", "translate(10,10)");

selection.append("circle")

.attr("cx", (d,i) => { return d.price / 2; })

.attr("cy", (d,i) => { return (4000 - d.sqft)/(4000/400) ; })

.attr("r", (d,i) => { return d.br * 10 ; })

.style("fill", (d,i) => { return color(d.pets); })

.style("opacity", "0.5")

.append("svg:title").text( (d,i) => { return print(d); });

function color(pets) {

var dogs = pets.indexOf('dogs') != -1;

var cats = pets.indexOf('cats') != -1;

if (dogs) return cats ? 'purple' : 'blue' ;

else return cats ? 'red' : 'gray';

}

function print(home) {

return `$${home.price}k, ${home.sqft}sqft, ${home.br} BRs`;

}

Property of Penn Engineering, Chris Murphy SD4x-3.11 806

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

.enter()

.append("g")

.attr("transform", "translate(10,10)");

selection.append("circle")

.attr("cx", (d,i) => { return d.price / 2; })

.attr("cy", (d,i) => { return (4000 - d.sqft)/(4000/400) ; })

.attr("r", (d,i) => { return d.br * 10 ; })

.style("fill", (d,i) => { return color(d.pets); })

.style("opacity", "0.5")

.append("svg:title").text( (d,i) => { return print(d); });

function color(pets) {

var dogs = pets.indexOf('dogs') != -1;

var cats = pets.indexOf('cats') != -1;

if (dogs) return cats ? 'purple' : 'blue' ;

else return cats ? 'red' : 'gray';

}

function print(home) {

return `$${home.price}k, ${home.sqft}sqft, ${home.br} BRs`;

}

Property of Penn Engineering, Chris Murphy SD4x-3.11 807

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

.enter()

.append("g")

.attr("transform", "translate(10,10)");

selection.append("circle")

.attr("cx", (d,i) => { return d.price / 2; })

.attr("cy", (d,i) => { return (4000 - d.sqft)/(4000/400) ; })

.attr("r", (d,i) => { return d.br * 10 ; })

.style("fill", (d,i) => { return color(d.pets); })

.style("opacity", "0.5")

.append("svg:title").text( (d,i) => { return print(d); });

function color(pets) {

var dogs = pets.indexOf('dogs') != -1;

var cats = pets.indexOf('cats') != -1;

if (dogs) return cats ? 'purple' : 'blue' ;

else return cats ? 'red' : 'gray';

}

function print(home) {

return `$${home.price}k, ${home.sqft}sqft, ${home.br} BRs`;

}

Property of Penn Engineering, Chris Murphy SD4x-3.11 808

Property of Penn Engineering, Chris Murphy

var width = 400;

var height = 400;

// draw the x-axis

var xScale = d3.scaleLinear()

.domain([0, width*2])

.range([0, width]);

var xAxis = d3.axisBottom(xScale);

svg.append("g")

.attr("transform", "translate(10,410)")

.call(xAxis);

// draw the y-axis

var yScale = d3.scaleLinear()

.range([height,0]);

.domain([0, 4000]);

var yAxis = d3.axisRight(yScale);

svg.append("g").attr("transform", "translate(10, 10)")

.call(yAxis);

SD4x-3.11 809

Property of Penn Engineering, Chris Murphy

var width = 400;

var height = 400;

// draw the x-axis

var xScale = d3.scaleLinear()

.domain([0, width*2])

.range([0, width]);

var xAxis = d3.axisBottom(xScale);

svg.append("g")

.attr("transform", "translate(10,410)")

.call(xAxis);

// draw the y-axis

var yScale = d3.scaleLinear()

.range([height,0]);

.domain([0, 4000]);

var yAxis = d3.axisRight(yScale);

svg.append("g").attr("transform", "translate(10, 10)")

.call(yAxis);

SD4x-3.11 810

Property of Penn Engineering, Chris Murphy

var width = 400;

var height = 400;

// draw the x-axis

var xScale = d3.scaleLinear()

.domain([0, width*2])

.range([0, width]);

var xAxis = d3.axisBottom(xScale);

svg.append("g")

.attr("transform", "translate(10,410)")

.call(xAxis);

// draw the y-axis

var yScale = d3.scaleLinear()

.range([height,0]);

.domain([0, 4000]);

var yAxis = d3.axisRight(yScale);

svg.append("g").attr("transform", "translate(10, 10)")

.call(yAxis);

SD4x-3.11 811

Property of Penn Engineering, Chris Murphy

var width = 400;

var height = 400;

// draw the x-axis

var xScale = d3.scaleLinear()

.domain([0, width*2])

.range([0, width]);

var xAxis = d3.axisBottom(xScale);

svg.append("g")

.attr("transform", "translate(10,410)")

.call(xAxis);

// draw the y-axis

var yScale = d3.scaleLinear()

.range([height,0]);

.domain([0, 4000]);

var yAxis = d3.axisRight(yScale);

svg.append("g").attr("transform", "translate(10, 10)")

.call(yAxis);

SD4x-3.11 812

Property of Penn Engineering, Chris Murphy

var width = 400;

var height = 400;

// draw the x-axis

var xScale = d3.scaleLinear()

.domain([0, width*2])

.range([0, width]);

var xAxis = d3.axisBottom(xScale);

svg.append("g")

.attr("transform", "translate(10,410)")

.call(xAxis);

// draw the y-axis

var yScale = d3.scaleLinear()

.range([height,0]);

.domain([0, 4000]);

var yAxis = d3.axisRight(yScale);

svg.append("g").attr("transform", "translate(10, 10)")

.call(yAxis);

SD4x-3.11 813

Property of Penn Engineering, Chris Murphy

var width = 400;

var height = 400;

// draw the x-axis

var xScale = d3.scaleLinear()

.domain([0, width*2])

.range([0, width]);

var xAxis = d3.axisBottom(xScale);

svg.append("g")

.attr("transform", "translate(10,410)")

.call(xAxis);

// draw the y-axis

var yScale = d3.scaleLinear()

.range([height,0]);

.domain([0, 4000]);

var yAxis = d3.axisRight(yScale);

svg.append("g").attr("transform", "translate(10, 10)")

.call(yAxis);

SD4x-3.11 814

Property of Penn Engineering, Chris Murphy

var width = 400;

var height = 400;

// draw the x-axis

var xScale = d3.scaleLinear()

.domain([0, width*2])

.range([0, width]);

var xAxis = d3.axisBottom(xScale);

svg.append("g")

.attr("transform", "translate(10,410)")

.call(xAxis);

// draw the y-axis

var yScale = d3.scaleLinear()

.range([height,0]);

.domain([0, 4000]);

var yAxis = d3.axisRight(yScale);

svg.append("g").attr("transform", "translate(10, 10)")

.call(yAxis);

SD4x-3.11 815

Property of Penn Engineering, Chris Murphy

var width = 400;

var height = 400;

// draw the x-axis

var xScale = d3.scaleLinear()

.domain([0, width*2])

.range([0, width]);

var xAxis = d3.axisBottom(xScale);

svg.append("g")

.attr("transform", "translate(10,410)")

.call(xAxis);

// draw the y-axis

var yScale = d3.scaleLinear()

.range([height,0]);

.domain([0, 4000]);

var yAxis = d3.axisRight(yScale);

svg.append("g").attr("transform", "translate(10, 10)")

.call(yAxis);

SD4x-3.11 816

Property of Penn Engineering, Chris Murphy

var width = 400;

var height = 400;

// draw the x-axis

var xScale = d3.scaleLinear()

.domain([0, width*2])

.range([0, width]);

var xAxis = d3.axisBottom(xScale);

svg.append("g")

.attr("transform", "translate(10,410)")

.call(xAxis);

// draw the y-axis

var yScale = d3.scaleLinear()

.range([height,0]);

.domain([0, 4000]);

var yAxis = d3.axisRight(yScale);

svg.append("g").attr("transform", "translate(10, 10)")

.call(yAxis);

SD4x-3.11 817

Property of Penn Engineering, Chris Murphy

var width = 400;

var height = 400;

// draw the x-axis

var xScale = d3.scaleLinear()

.domain([0, width*2])

.range([0, width]);

var xAxis = d3.axisBottom(xScale);

svg.append("g")

.attr("transform", "translate(10,410)")

.call(xAxis);

// draw the y-axis

var yScale = d3.scaleLinear()

.range([height,0]);

.domain([0, 4000]);

var yAxis = d3.axisRight(yScale);

svg.append("g").attr("transform", "translate(10, 10)")

.call(yAxis);

SD4x-3.11 818

Property of Penn Engineering, Chris Murphy

var width = 400;

var height = 400;

// draw the x-axis

var xScale = d3.scaleLinear()

.domain([0, width*2])

.range([0, width]);

var xAxis = d3.axisBottom(xScale);

svg.append("g")

.attr("transform", "translate(10,410)")

.call(xAxis);

// draw the y-axis

var yScale = d3.scaleLinear()

.range([height,0]);

.domain([0, 4000]);

var yAxis = d3.axisRight(yScale);

svg.append("g").attr("transform", "translate(10, 10)")

.call(yAxis);

SD4x-3.11 819

Property of Penn Engineering, Chris Murphy SD4x-3.11 820

400

Property of Penn Engineering, Chris Murphy

var width = 400;

var height = 400;

// draw the x-axis

var xScale = d3.scaleLinear()

.domain([0, width*2])

.range([0, width]);

var xAxis = d3.axisBottom(xScale);

svg.append("g")

.attr("transform", "translate(10,410)")

.call(xAxis);

// draw the y-axis

var yScale = d3.scaleLinear()

.range([height,0]);

.domain([0, 4000]);

var yAxis = d3.axisRight(yScale);

svg.append("g").attr("transform", "translate(10, 10)")

.call(yAxis);

SD4x-3.11 821

Property of Penn Engineering, Chris Murphy

var width = 400;

var height = 400;

// draw the x-axis

var xScale = d3.scaleLinear()

.domain([0, width*2])

.range([0, width]);

var xAxis = d3.axisBottom(xScale);

svg.append("g")

.attr("transform", "translate(10,410)")

.call(xAxis);

// draw the y-axis

var yScale = d3.scaleLinear()

.range([height,0]);

.domain([0, 4000]);

var yAxis = d3.axisRight(yScale);

svg.append("g").attr("transform", "translate(10, 10)")

.call(yAxis);

SD4x-3.11 822

Property of Penn Engineering, Chris Murphy

var width = 400;

var height = 400;

// draw the x-axis

var xScale = d3.scaleLinear()

.domain([0, width*2])

.range([0, width]);

var xAxis = d3.axisBottom(xScale);

svg.append("g")

.attr("transform", "translate(10,410)")

.call(xAxis);

// draw the y-axis

var yScale = d3.scaleLinear()

.range([height,0]);

.domain([0, 4000]);

var yAxis = d3.axisRight(yScale);

svg.append("g").attr("transform", "translate(10, 10)")

.call(yAxis);

SD4x-3.11 823

Property of Penn Engineering, Chris Murphy SD4x-3.11 824

Property of Penn Engineering, Chris Murphy

var width = 400;

var height = 400;

// draw the x-axis

var xScale = d3.scaleLinear()

.domain([0, width*2])

.range([0, width]);

var xAxis = d3.axisBottom(xScale);

svg.append("g")

.attr("transform", "translate(10,410)")

.call(xAxis);

// draw the y-axis

var yScale = d3.scaleLinear()

.range([height,0]);

.domain([0, 4000]);

var yAxis = d3.axisRight(yScale);

svg.append("g").attr("transform", "translate(10, 10)")

.call(yAxis);

SD4x-3.11 825

Property of Penn Engineering, Chris Murphy

var width = 400;

var height = 400;

// draw the x-axis

var xScale = d3.scaleLinear()

.domain([0, width*2])

.range([0, width]);

var xAxis = d3.axisBottom(xScale);

svg.append("g")

.attr("transform", "translate(10,410)")

.call(xAxis);

// draw the y-axis

var yScale = d3.scaleLinear()

.range([height,0]);

.domain([0, 4000]);

var yAxis = d3.axisRight(yScale);

svg.append("g").attr("transform", "translate(10, 10)")

.call(yAxis);

SD4x-3.11 826

Property of Penn Engineering, Chris Murphy

var width = 400;

var height = 400;

// draw the x-axis

var xScale = d3.scaleLinear()

.domain([0, width*2])

.range([0, width]);

var xAxis = d3.axisBottom(xScale);

svg.append("g")

.attr("transform", "translate(10,410)")

.call(xAxis);

// draw the y-axis

var yScale = d3.scaleLinear()

.range([height,0]);

.domain([0, 4000]);

var yAxis = d3.axisRight(yScale);

svg.append("g").attr("transform", "translate(10, 10)")

.call(yAxis);

SD4x-3.11 827

Property of Penn Engineering, Chris Murphy

var width = 400;

var height = 400;

// draw the x-axis

var xScale = d3.scaleLinear()

.domain([0, width*2])

.range([0, width]);

var xAxis = d3.axisBottom(xScale);

svg.append("g")

.attr("transform", "translate(10,410)")

.call(xAxis);

// draw the y-axis

var yScale = d3.scaleLinear()

.range([height,0]);

.domain([0, 4000]);

var yAxis = d3.axisRight(yScale);

svg.append("g").attr("transform", "translate(10, 10)")

.call(yAxis);

SD4x-3.11 828

Property of Penn Engineering, Chris Murphy

var width = 400;

var height = 400;

// draw the x-axis

var xScale = d3.scaleLinear()

.domain([0, width*2])

.range([0, width]);

var xAxis = d3.axisBottom(xScale);

svg.append("g")

.attr("transform", "translate(10,410)")

.call(xAxis);

// draw the y-axis

var yScale = d3.scaleLinear()

.range([height,0]);

.domain([0, 4000]);

var yAxis = d3.axisRight(yScale);

svg.append("g").attr("transform", "translate(10, 10)")

.call(yAxis);

SD4x-3.11 829

Property of Penn Engineering, Chris Murphy SD4x-3.11 830

Property of Penn Engineering, Chris Murphy

Accessing Data with D3.js

• D3.js can easily access data on the Web that is available through RESTful APIs

SD4x-3.11 831

var values = [];

var URL = . . .

d3.json(URL, (response) => {

// populate the values from the data in

// response that comes back from request

. . .

});

// now use values with D3 functions

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

. . .

Property of Penn Engineering, Chris Murphy

Accessing Data with D3.js

• D3.js can easily access data on the Web that is available through RESTful APIs

SD4x-3.11 832

var values = [];

var URL = . . .

d3.json(URL, (response) => {

// populate the values from the data in

// response that comes back from request

. . .

});

// now use values with D3 functions

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

. . .

Property of Penn Engineering, Chris Murphy

Accessing Data with D3.js

• D3.js can easily access data on the Web that is available through RESTful APIs

SD4x-3.11 833

var values = [];

var URL = . . .

d3.json(URL, (response) => {

// populate the values from the data in

// response that comes back from request

. . .

});

// now use values with D3 functions

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

. . .

Property of Penn Engineering, Chris Murphy

Accessing Data with D3.js

• D3.js can easily access data on the Web that is available through RESTful APIs

SD4x-3.11 834

var values = [];

var URL = . . .

d3.json(URL, (response) => {

// populate the values from the data in

// response that comes back from request

. . .

});

// now use values with D3 functions

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

. . .

Property of Penn Engineering, Chris Murphy

Accessing Data with D3.js

• D3.js can easily access data on the Web that is available through RESTful APIs

SD4x-3.11 835

var values = [];

var URL = . . .

d3.json(URL, (response) => {

// populate the values from the data in

// response that comes back from request

. . .

});

// now use values with D3 functions

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

. . .

Property of Penn Engineering, Chris Murphy

Accessing Data with D3.js

• D3.js can easily access data on the Web that is available through RESTful APIs

SD4x-3.11 836

var values = [];

var URL = . . .

d3.json(URL, (response) => {

// populate the values from the data in

// response that comes back from request

. . .

});

// now use values with D3 functions

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

. . .

Property of Penn Engineering, Chris Murphy

Accessing Data with D3.js

• D3.js can easily access data on the Web that is available through RESTful APIs

SD4x-3.11 837

var values = [];

var URL = . . .

d3.json(URL, (response) => {

// populate the values from the data in

// response that comes back from request

. . .

});

// now use values with D3 functions

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

. . .

Property of Penn Engineering, Chris Murphy

Accessing Data with D3.js

• D3.js can easily access data on the Web that is available through RESTful APIs

SD4x-3.11 838

var values = [];

var URL = . . .

d3.json(URL, (response) => {

// populate the values from the data in

// response that comes back from request

. . .

});

// now use values with D3 functions

var svg = d3.select("svg");

var selection = svg.selectAll("g")

.data(values)

. . .

Property of Penn Engineering, Chris Murphy

Summary

• D3.js allows us to generate HTML and SVG elements based on data

• We can apply functions to data sets to generate graphical elements, e.g. charts

• The data used by D3.js can include objects

• You can easily access data online using D3.js functions

SD4x-3.11 839

Property of Penn Engineering, Chris Murphy

Review: Week 3

• React

• library and framework for creating reusable, modular components

• can render themselves based on their state

• can be combined and work together

• D3.js

• library for generating HTML and SVG based on data

• ES6: more recent version of JavaScript

SD4x-3.11 840

Recommended