Skip to content
Snippets Groups Projects
Unverified Commit 52979eb5 authored by darrylong's avatar darrylong Committed by GitHub
Browse files

Add Model Table Display into Readthedocs (#624)

* Added static page for model viewing and filtering

* Update model json data

* Update model js table

* Add generate model json python file for js table

* Reset filter input when clear filters button is selected
parent 60742110
No related branches found
No related tags found
No related merge requests found
import json
def get_key_val(part):
key_index_start = part.index('[')
key_index_end = part.index(']')
val_index_start = part.rindex('(')
val_index_end = part.rindex(')')
key = part[key_index_start + 1: key_index_end]
val = part[val_index_start + 1: val_index_end]
return key, val
# Read the content from README.md
with open('../README.md', 'r') as file:
content = file.read()
# Extract the relevant information from the content
models = []
lines = content.split('\n')
lines = lines[lines.index('## Models') + 4: lines.index('## Resources') - 2]
headers = []
headers = lines[0].split('|')[1:-1]
headers = [header.strip() for header in headers]
for line in lines[2:]:
parts = line.split('|')[1:-1]
parts = [part.strip() for part in parts]
model = dict(zip(headers, parts))
models.append(model)
year = None
for model in models:
# handle empty years
if model["Year"] == "":
model["Year"] = year
else:
year = model["Year"]
# handle model, docs and paper part
name_paper_str = model["Model and Paper"]
for i, part in enumerate(name_paper_str.split(', ')):
key, val = get_key_val(part)
if i == 0:
model["Name"] = key
model["Link"] = val
else:
model[key] = val
# handle environment part
env_part = model["Environment"].split(', ')[0]
search_dict = {
"PyTorch": "torch",
"TensorFlow": "tensorflow"
}
if "requirements" in env_part:
_, requirements_dir = get_key_val(env_part)
# read requirements file
with open(f'../{requirements_dir}', 'r') as file:
requirements = file.read()
for header, package in search_dict.items():
model[header] = package in requirements
else:
for header, _ in search_dict.items():
model[header] = False
# remove non required keys
model.pop("Model and Paper")
model.pop("Environment")
# Get package name
model_dir = model["Link"]
with open(f'../{model_dir}/__init__.py', 'r') as file:
init_data = file.read()
package_names = []
for row in init_data.split('\n'):
if "import" in row:
package_name = row[row.index("import") + len("import "):]
package_names.append(f"cornac.models.{package_name}")
model["packages"] = package_names
json_str = json.dumps(models, indent=4)
# Write the JSON object to a file
with open('source/_static/models/data.js', 'w') as file:
file.write(f"var data = {json_str};")
This diff is collapsed.
<html lang="en">
<head>
<script src="https://cdn.jsdelivr.net/npm/ag-grid-community/dist/ag-grid-community.min.js"></script>
</head>
<body>
<h3>Filters</h3>
<div>
<button onclick="clearFilters()">Clear Filters</button>
</div>
<div style="margin-top: 16px;">
<button onclick="filterModels('Collaborative Filtering')">Collaborative Filtering Models</button>
<button onclick="filterModels('Content-Based')">Content Based Models</button>
<button onclick="filterModels('Explainable')">Explainable Models</button>
<button onclick="filterModels('Next-Item')">Next-Item Models</button>
<button onclick="filterModels('Next-Basket')">Next-Basket Models</button>
<button onclick="filterModels('Baseline')">Baseline Models</button>
</div>
<div style="margin-top: 16px;">
<input type="text" id="filter-text-box" size="50" placeholder="Fliter" oninput="onFilterTextBoxChanged()" />
</div>
<br />
<div id="grid" class="ag-theme-quartz" style="height: 480px"></div>
</body>
</html>
<script type="text/javascript" src="data.js"></script>
<script type="text/javascript" src="_static/models/data.js"></script>
<script type="text/javascript">
function LinkRenderer(url, title) {
return `<a href="${url}" target="_blank">${title}</a>`
}
// Row Data Interface
const github_url = "https://github.com/PreferredAI/cornac/tree/master/";
// Grid API: Access to Grid API methods
let gridApi;
function onFilterTextBoxChanged() {
gridApi.setGridOption(
"quickFilterText",
document.getElementById("filter-text-box").value,
);
}
function filterModels(filter) {
gridApi.setColumnFilterModel("Type", {
type: "contains",
filter: filter,
})
.then(() => {
gridApi.onFilterChanged();
});
}
function clearFilters(){
gridApi.setColumnFilterModel("Type", null)
.then(() => {
gridApi.onFilterChanged();
});
// reset filter box
document.getElementById("filter-text-box").value="";
gridApi.setGridOption(
"quickFilterText",
"",
);
}
// Grid Options: Contains all of the grid configurations
const gridOptions = {
// Data to be displayed
rowData: data,
// Columns to be displayed (Should match rowData properties)
columnDefs: [
{ field: "Year" },
{
field: "Name",
headerName: "Model Name (Hover over for package name)",
flex: 4,
cellRenderer: params => LinkRenderer(params.data.docs, params.data.Name),
tooltipValueGetter: (params) => "Package Name: " + params.data.packages,
},
{ field: "Type", flex: 2 },
{
field: "PyTorch",
headerName: "PyTorch",
cellRenderer: params => params.value ? "" : "",
},
{
field: "TensorFlow",
headerName: "TensorFlow",
cellRenderer: params => params.value ? "" : "",
},
],
defaultColDef: {
flex: 1,
filter: true,
// floatingFilter: true,
},
pagination: true,
paginationAutoPageSize: true
};
// Create Grid: Create new grid within the #myGrid div, using the Grid Options object
gridApi = agGrid.createGrid(document.querySelector("#grid"), gridOptions);
</script>
\ No newline at end of file
...@@ -114,3 +114,9 @@ Quick Links ...@@ -114,3 +114,9 @@ Quick Links
:click-parent: :click-parent:
Contributor's Guide Contributor's Guide
Models Available
^^^^^^^^^^^^^^^^
.. raw:: html
:file: _static/models/models.html
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment