Published
Edited
Sep 29, 2022
Insert cell
Insert cell
Insert cell

// The html for the input box and filter list, and the todo list, which is generated as items are added thru the text box
let wrapper = html`<div class="wrapper">
<div>
<input type="text" class="text" size="10">
</div>
<div class=visibilityFilterBoxDiv></div>
<div class=todoList></div>
</div>`

// update visible todo items
function updateData() {
// select items in the todo list
const item = d3.select('.todoList')
.selectAll('.item')
.data(store.getState().todos.filter(todo => {
// toggle which items are shown
switch (store.getState().visibilityFilter) {
case 'SHOW_ALL':
return todo
case 'SHOW_COMPLETED':
return todo.completed === true
case 'SHOW_ACIVE':
return todo.completed === false
default:
console.warn('Unexpected visibilityFilter state')
return todo
}
}), d => d.index)

// takes item you type into the text box and adds it to the html
const itemEnter = item.enter()
.append('div')
.attr('class', d => `item ${d.text}`)
.style('text-align', 'center')
.style('font-family', 'monospace')


// Add a check box before each list item
const itemBox = itemEnter.append('input')
.attr('class', 'itemBox')
.attr('type', 'checkbox')
.each(function(d) { if (d.completed) d3.select(this).attr('checked', true) })
.on('click', d => {
store.dispatch(toggleTodo(d.index))
updateData()
})

// Add the text of the list item as a label after the check box
const itemText = itemEnter.append('label')
.attr('class', 'itemText')
.attr('for', d => d.text)
.text(d => d.text)
const itemExit = item.exit().remove()
}

// these are the check boxes next to each item in the list
// set the visibility filters
const visibilityFilterBoxes = d3.select(wrapper)
.select('.visibilityFilterBoxDiv')
.selectAll('.visibilityFilters')
.data(Object.values(VisibilityFilters))
.join('div')


// when a visibility is chosen, change the state of store and update the output to show the change in the HTML
const visibilityCheckboxes = visibilityFilterBoxes.append('input')
.attr('class', 'visibilityCheckboxes')
.attr('type', 'radio')
.attr('name', 'visibilityCheckboxes')
.attr('id', d => d)
.attr('value', d => d)
.on('click', d => {
store.dispatch(setVisibilityFilter(d))
updateData()
})
.each(function(d) {
if (store.getState().visibilityFilter === d) d3.select(this).attr('checked', true)
})

// change the text in the filter options to be all lower case and remove under scores
const visibilityLabels = visibilityFilterBoxes.append('label')
.attr('class', 'visibilityLabels')
.attr('for', d => d)
.text(d => d.charAt(0) + d.replace('_', ' ').toLowerCase().slice(1))
.style('font-family', 'Helvetica')

// when a new list item is added, it is also updates the displayed list
d3.select(wrapper).select('.text')
.on('change', function() {
const index = store.getState().todos.length
store.dispatch(addTodo(this.value, index))
updateData()
this.value = ''
})

return wrapper
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// Initial state - show all of the todo items

initialState = {
return {
visibilityFilter: VisibilityFilters.SHOW_ALL,
todos: []
}
}
Insert cell
// ADD_TODO - Adds a todo item that is not completed
// toggle the completed state with TOGGLE_TODO

function todos(state = [], action) {
switch (action.type) {
case ADD_TODO:
return [
...state,
{
text: action.text,
completed: false,
index: action.index
}
]
case TOGGLE_TODO:
return state.map((todo, index) => {
if (index === action.index) {
return {
...todo,
completed: !todo.completed
}
}
return todo
})
default:
return state
}
}
Insert cell
// set the visibility filter

function visibilityFilter(state = VisibilityFilters.SHOW_ALL, action) {
switch (action.type) {
case SET_VISIBILITY_FILTER:
return action.filter
default:
return state
}
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more