Published
Edited
Dec 2, 2020
1 fork
Insert cell
Insert cell
filtersForm()
Insert cell
function filtersForm(savedFilters) {
const activeFilters = savedFilters || [];
let newForm;

const removeAddFilterMenu = () => {
const selectedFilter = finalForm.querySelector('.pm-filter-selected');
selectedFilter.innerHTML = '';
newForm = null;

return selectedFilter;
};

const removeFilter = () => {};

const addFilter = filterName => {
// Clear the selected filter and prepare for a new one to be set.
const selectedFilter = removeAddFilterMenu();
newForm = filters[filterName].function;
selectedFilter.appendChild(newForm);

const submitFilter = e => {
if (newForm && newForm.value) {
activeFilters.push({
name: filterName,
value: newForm.value
});
}

console.debug(activeFilters);

removeAddFilterMenu();
};

// Submit the options for the form.
newForm.addEventListener('submit', submitFilter, {
once: true,
passive: true
});
};

const create_filter_html = (filterName, properties) => {
return html.fragment`
<li class="pm-filter-option pm-filter-time" onclick=${
e => {
// addFilter.removeEventListener();
addFilter(filterName);
} /* remove the listener thing here */
}>
<div class="pm-filter-title">${filterName}</div>
<div class="pm-filter-text">${properties.text}</div>
</li>
`;
};

const finalForm = html`
<div class="pm-filter-panel">
<div class="pm-filter-list">
<p class="pm-filter-list-title">Active filters</p>
<div class="pm-filter-active">
${activeFilters.map(activeFilter =>
create_active_filter_html(activeFilter)
)}
</div>
<!--div class="pm-filter-add" onclick=${addFilter}>click to add filter...</div-->
<ul class="pm-filter-options">
${Object.keys(filters).map(key =>
create_filter_html(key, filters[key])
)}
</ul>
</div>

<div class="pm-filter-selected"></div>
</div>
`;

return finalForm;
}
Insert cell
Insert cell
Insert cell
filters = ({
Timeframe: {
text: 'Filters by timestamp',
function: timeRangeFilter()
},
Variation: {
text: 'Filters variants',
function: variantsFilter()
},
Performance: {
text: 'Filters cases by performance',
function: performanceFilter()
},
Endpoints: {
text: 'Removes incomplete cases',
function: endpointsFilter()
},
Attribute: {
text: 'Filters events by attribute',
function: attributeFilter()
},
Follower: {
text: 'Filters by subsequences',
function: followerFilter()
}
})
Insert cell
Insert cell
function timeRangeFilter() {
const options = [
'contain',
'started_in',
'completed_in',
'intersecting',
'trim'
];

return formWithSubmit(html`<form><table style=${{ width: 'auto' }}>
<tbody>
<tr title="Start time (keeps all projects that have at least one date after this time)">
<td>Start time:</td>
<td><input name="start_time" type="date"></td>
</tr>
<tr title="End time (keeps all projects that have at least one date before this time)">
<td>End time:</td>
<td><input name="end_time" type="date"></td>
</tr>
<tr>
<td>Select time filter mode:</td>
<td>
<select name="time_filter_type">${arr_to_options(options)}</select>
</td>
<tr>
</tbody>
<tfoot>
<tr><td><input type="submit" value="Submit"></td></tr>
</tfoot>
</table></form>`);
}
Insert cell
function performanceFilter() {
return formWithSubmit(html`<form><table style=${{ width: 'auto' }}>
<tbody>
<tr title="Shortest time a project can take">
<td>Lower bound (days):</td>
<td><input name="min_case_performance" type="number" min="0" value="0"></td>
</tr>
<tr title="Longest time a project can take">
<td>Upper bound (days):</td>
<td><input name="max_case_performance" type="number" min="0"></td>
</tr>
</tbody>
<tfoot>
<tr><td><input type="submit" value="Submit"></td></tr>
</tfoot>
</table></form>`);
}
Insert cell
function variantsFilter() {
return formWithSubmit(html`<form><table style=${{ width: 'auto' }}>
<tbody>
</tbody>
<tfoot>
<tr><td><input type="submit" value="Submit"></td></tr>
</tfoot>
</table></form>`);
}
Insert cell
function followerFilter() {
return formWithSubmit(html`<form><table style=${{ width: 'auto' }}>
<tbody>
</tbody>
<tfoot>
<tr><td><input type="submit" value="Submit"></td></tr>
</tfoot>
</table></form>`);
}
Insert cell
function endpointsFilter() {
return formWithSubmit(html`<form><table style=${{ width: 'auto' }}>
<tbody>
</tbody>
<tfoot>
<tr><td><input type="submit" value="Submit"></td></tr>
</tfoot>
</table></form>`);
}
Insert cell
function attributeFilter() {
return formWithSubmit(html`<form><table style=${{ width: 'auto' }}>
<tbody>
</tbody>
<tfoot>
<tr><td><input type="submit" value="Submit"></td></tr>
</tfoot>
</table></form>`);
}
Insert cell
Insert cell
function create_active_filter_html(activeFilter) {
return html.fragment`
<li class="pm-filter-option pm-filter-time"
<div class="pm-filter-title">${activeFilter.name}</div>
</li>
`;
}
Insert cell
function arr_to_options(arr) {
return arr.map(
element => html.fragment`<option value="${element}">${element}</option>`
);
}
Insert cell
Insert cell
Insert cell
Insert cell
function formWithSubmit(form) {
const container = html`<div>${form}`;
form.addEventListener("submit", event => {
event.preventDefault();
container.value = formValue(form);
container.dispatchEvent(new CustomEvent("input"));
});
form.addEventListener("input", event => {
event.preventDefault();
// Need this, because otherwise the viewof Generator catches bubbling input events
event.stopPropagation();
});
return container;
}
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more