Mentions légales du service

Skip to content
Snippets Groups Projects
Commit 40d07e35 authored by cha's avatar cha
Browse files

Merge branch 'refactoring/front' of gitlab.inria.fr:pydisk/examples/vizitig into refactoring/front

parents e993446e 0d853545
Branches
Tags v0.3-stable
No related merge requests found
......@@ -17,5 +17,4 @@
} */
.vizbody{
max-height: 50vh;
overflow-y: scroll;
}
......@@ -46,7 +46,7 @@
</form>
<div class="btn-group" style="max-height: 3em">
<button id="metadata-manager-button" class="btn btn-primary" data-bs-toggle="collapse" data-bs-target="#metadatamanagerholder" style="max-height:3em;" type="button">Metadata</button>
<button id="metadata_manager_button" class="btn btn-primary" style="max-height:3em;" type="button">Metadata</button>
<button id="filter_manager_button" class="btn btn-primary" style="max-height:3em;" type="button">Filters</button>
<button id="export_button" class="btn btn-primary" data-bs-toggle="collapse" data-bs-target="#exportmanagerholder" style="max-height:3em;" type="button">Export</button>
</div>
......@@ -59,8 +59,6 @@
<button id="add_filter_button" type="button" class="col-1 btn btn-primary">Add</button>
</div>
</div>
<div id="metadatamanagerholder" class="col collapse">
</div>
<div id="exportmanagerholder" class="col collapse">
<form id="export_form" class="form row">
<div class="row container-fluid">
......@@ -84,7 +82,10 @@
</div>
</div>
</nav>
<main class="container-fluid py-2 mx-0 px-0">
<div class="row w-100 mx-0 px-1 gx-3" id="main"></div>
</main>
......
......@@ -246,9 +246,15 @@ export class Graph{
_node_satisfy(ast, nodeid){
let that = this;
let keys = Object.keys(ast);
if (keys.length > 1)
throw new Error("AST should have at most one key");
let key = keys[0].toLowerCase();
let key;
let name = undefined;
if (keys.length > 1){
if (ast.name == undefined || ast.type == undefined)
throw new Error("AST should have at most one key");
name = ast.name.toLowerCase();
key = ast.type.toLowerCase();
} else
key = keys[0].toLowerCase();
if (key == "land" )
return ast.land.map((e) => that._node_satisfy(e, nodeid)).every(e=>e);
if (key == "lor")
......@@ -261,16 +267,17 @@ export class Graph{
return true;
if (key == "selection")
return this.#selection.has(nodeid);
let data = this.#nodes.get(nodeid);
if (data == PARTIALLY)
return key == "partial";
if (key == "degree")
return Object.keys(data.neighbors).length == ast[key];
for (const metadata of data.metadatas)
if (metadata.type.toLowerCase() == key && metadata.id.toLowerCase() == ast[key].toLowerCase())
if (key == "partial")
return data == PARTIALLY;
if (name == undefined)
name = ast[key].toLowerCase()
for (const metadata of this.#nodes.get(nodeid).metadatas)
if (metadata.type.toLowerCase() == key && metadata.id.toLowerCase() == name)
return true;
return false;
}
......
import { BaseViz } from "./visualisation.js";
import {autoResizeQueryField} from "./ui.js";
let debounceTimer;
let meta_id=0;
export class MetaViz extends BaseViz{
constructor(graph){
super();
this.graph = graph;
this.container = main;
this.id = meta_id;
meta_id += 1;
}
build(){
let G = this.graph
queryField.addEventListener("input", function() {
autoResizeQueryField();
});
let holder = document.createElement("div");
holder.classList.add("col-5", "card", "overflow-hidden", "p-0", "m-1");
holder.style = "height: 45vh; resize: both;";
holder.innerHTML = `
<div class="vizhead card-header p-1">
<div class="p-0 vizmenu_main">
<div class="container-fluid d-flex ">
<span>
<h5>Metadata</h5>
</span>
<span class="header-buttons ms-auto d-flex">
<button class="viz-close btn-close my-auto" aria-label="Close"></button>
</span>
</div>
<div class="vizbody">
<input type="text" id="metadata_field_${this.id}" class="form-control" placeholder="Filter metadata here">
<div class="form-floating">
<select name="metadata" id="metadata_selector_${this.id}" class="form-select metadata_selector">
<option value="">--Please choose a metadata type to explore--</option>
</select>
<label for="metadata_selector" class="form-label">Select a metadata type:</label>
</div>
</div>
<div class="vizfooter mt-3"></div>
</div>
`;
this.holder = holder;
let that = this;
holder.querySelector('.viz-close').addEventListener("click", function(){
G.delete_onready_callback(that.draw_callback);
holder.remove();
});
// closing the viz
//holder.querySelector('button[class="btn-close"]').addEventListener("click", function(){
// that.graph.delete_onready_callback(that.draw_callback);
// holder.remove();
// holder.remove();
//});
this.container.appendChild(holder);
let buttons_holder = document.createElement("div");
buttons_holder.classList.add("p-2", "overflow-y-auto");
holder.appendChild(buttons_holder);
G.metadata_types_list.forEach(function(type){
const option = document.createElement('option');
const metadataList = G.metadata_vars_values[type];
option.value = type;
option.innerHTML = type;
option.addEventListener("click", function() {
buttons_holder.innerHTML = "";
build_metadata_buttons(buttons_holder, metadataList)
});
document.querySelector(".metadata_selector").appendChild(option);
});
document.getElementById(`metadata_field_${this.id}`).addEventListener('input', function() {
clearTimeout(debounceTimer);
const filterText = this.value; // Get the current value of the textarea
// Rebuild the buttons with the filter applied
let type = document.querySelector(".metadata_selector").value;
const metadataList = G.metadata_vars_values[type];
debounceTimer = setTimeout(function() {
// Rebuild the buttons with the filter applied
build_metadata_buttons(buttons_holder, metadataList, filterText);
}, 200); // 1000 milliseconds = 1 second
});
}
}
// function build_metadata_buttons(container, metadataList) {
// for (const [key, element ] of Object.entries(metadataList)) {
// let button = document.createElement("button");
// button.classList.add("btn", "btn-primary");
// button.innerHTML = key;
// button.addEventListener("click", function(){
// queryField.value += element.type + '(' + key + ') ';
// autoResizeQueryField();
// })
// container.appendChild(button);
// }
// }
function build_metadata_buttons(container, metadataList, filterText = "") {
// Clear the container before adding buttons
container.innerHTML = "";
// Loop through the metadataList and create buttons for keys that match the filterText
for (const [key, element] of Object.entries(metadataList)) {
// Check if the key includes the filter text (case-insensitive)
if (key.toLowerCase().includes(filterText.toLowerCase())) {
let button = document.createElement("button");
button.classList.add("btn", "btn-outline-primary", "btn-sm", "m-1");
button.innerHTML = key;
button.addEventListener("click", function() {
queryField.value += element.type + `(${key})`;
autoResizeQueryField();
});
container.appendChild(button);
}
}
}
\ No newline at end of file
import { MetaViz } from "./metadata.js";
export function set_page(G){
for (const el of document.querySelectorAll("[gname]")){
el.innerHTML += G.gname;
......@@ -48,12 +50,8 @@ export function set_page(G){
link.remove();
})
});
const metadataselector = document.getElementById("metadata-manager-button");
metadataselector.addEventListener("click", function(event) {
console.log("Adding metadata event listener");
event.preventDefault();
add_viz(G, metadatamanagerholder, "metadata");
})
const metadataselector = document.getElementById("metadata_manager_button");
metadataselector.onclick = () => (new MetaViz(G)).build();
add_filter_button.addEventListener("click", function() {
G.add_filter_str(filterName.value, queryField.value.trim());
......
......@@ -68,7 +68,7 @@ export class BaseViz {
Show actions
</button>
<button class="viz-close btn-close my-auto" aria-label="Close"></button>
<span>
</span>
</div>
<div id="vizmenu_${this.viz_id}_actions" class="vizmenu setup_action_list container-fluid collapse border-top">
<form class="row py-1 list_action form">
......
import { BaseViz } from "../visualisation.js";
import { modal } from "../ui.js";
import {autoResizeQueryField} from "../ui.js";
export class MetaViz extends BaseViz{
get vizname(){
return "Metadata";
}
get vizlocation(){
return "."
}
draw(){
this.holder.classList.add("text-white");
this.body.innerHTML = `
<div class="card text-white" >
<label for="metadata_selector">Select a metadata type:</label>
<select name="metadata" id="metadata_selector">
<option value="">--Please choose a metadata type to explore--</option>
</select>
<div id = "metadata_table_container">
<table id="metadata_table">
<thead>
<tr>
<th>Metadata</th>
</tr>
</thead>
<tbody>
<!-- -->
</tbody>
</table>
</div>
</div>`;
const metadataSelector = this.body.querySelector('#metadata_selector');
const metadata_table = document.querySelector("#metadata_table tbody");
metadata_table.innerHTML = ''; // Clear existing data
let G = this.graph;
G.metadata_types_list.forEach(function(type){
const option = document.createElement('option');
const metadataList = G.metadata_vars_values[type];
option.value = type;
option.innerHTML = type;
// option.addEventListener('click',function(){
// for (const [key, element ] of Object.entries(metadataList)) {
// const tr = document.createElement('tr');
// const td = document.createElement('td');
// td.textContent = key;
// td.value = element;
// tr.appendChild(td);
// };
// });
option.addEventListener("click", function() {
let container = document.getElementById("metadatamanagerholder");
try {
document.getElementById("metadataButtonHolder").remove();
}
catch (error) {
;
}
let holder = document.createElement("div");
holder.id = "metadataButtonHolder"
holder.style = "max-height: 208px;";
holder.classList.add("overflow-auto", "d-flex", "align-content-start", "flex-wrap", "mb-3", "col-12", "col-md-6","white-text", "m-2", "border");
const metadataValues = G.metadata_vars
for (const [key, element ] of Object.entries(metadataList)) {
let button_container = document.createElement("div");
button_container.classList.add("w-25");
let button = document.createElement("button");
button.classList.add("p-2", "btn", "btn-primary", "w-100");
button.innerHTML = key;
button.addEventListener("click", function(){
queryField.value += element.type + '(' + key + ') ';
autoResizeQueryField();
})
button_container.appendChild(button);
holder.appendChild(button_container);
}
container.appendChild(holder);
});
metadataSelector.appendChild(option);
});
queryField.addEventListener("input", function() {
autoResizeQueryField();
});
}
build(){
let holder = document.createElement("div");
holder.classList.add("col-12", "col-md-5", "vizholder", "m-2", "border");
holder.innerHTML = `
<div class="vizhead">
<h2>
${this.vizname}
<button class="btn btn-danger"> Close </button>
</h2>
<div class="viz_menu"></div>
<div>
<form class="add_action">
<label> Apply a filter : </label>
<select class="filter_list" name="filter">
</select>
<label> action </label>
<select class="action_list">
</select>
<span class="action_params"></span>
<button type="submit"> apply </button>
</form>
</div>
<div class="filter_list">
<label> List of actions</label>
<ul></ul>
</div>
</div>
<div class="vizbody"></div>
<div class="vizfooter"></div>
`;
this.container.appendChild(holder);
this.holder = holder;
let that = this;
// build the filter list
this.update_filter();
// build the action list
let action_list = holder.querySelector(".action_list");
for (const act of this._actions.values()){
let opt = document.createElement("option");
opt.value = opt.innerHTML = act.name;
action_list.appendChild(opt);
}
// logic to expose form of each action
let action_params = this.holder.querySelector(".action_params");
action_list.onchange = function(){
action_params.innerHTML = "";
let act = that._actions.filter(e => e.name == this.value)[0]
that.current_action = act;
action_params.appendChild(act.form());
}
action_list.onchange();
// add_action logic
let add_action = document.querySelector(".add_action");
add_action.addEventListener("submit", function(event){
event.preventDefault();
const formData = new FormData(this);
let act_inst = new that.current_action(that.graph, formData);
that.add_action(act_inst);
});
// linking field with html nodes
this.head = holder.querySelector(".vizhead");
this.body = holder.querySelector(".vizbody");
this.footer= holder.querySelector(".vizfooter");
// closing the viz
holder.querySelector('button[class="btn btn-danger"]').addEventListener("click", function(){
// that.graph.delete_onready_callback(that.draw_callback);
// holder.remove();
document.getElementById("metadatamanagerholder").innerHTML = "";
});
// callback logic
this.draw_callback = () => that.draw();
this.update_filter_callback = () => that.update_filter();
this.graph.add_onready_callback(this.draw_callback);
this.graph.add_onupdate_filter_callback(this.update_filter_callback);
this.draw();
}
}
......@@ -156,7 +156,7 @@ GT : ">"
acgt : /[ACGT]+/i
integer : INT
ident : CNAME
ident : /[a-zA-Z_][\w\.\-\_]*/i
%import common.CNAME
%import common.INT
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment