Skip to content

Commit

Permalink
Finish initial situation table feature
Browse files Browse the repository at this point in the history
(Tauri feature parity, ...)
  • Loading branch information
aarkue committed Oct 24, 2024
1 parent 6ebf450 commit ed6ca50
Show file tree
Hide file tree
Showing 14 changed files with 189 additions and 105 deletions.
53 changes: 22 additions & 31 deletions backend/shared/src/binding_box/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,7 @@ pub mod expand_step;
#[cfg(test)]
pub mod test;

use std::{
collections::HashSet,
fs::File,
io::BufWriter,
time::Instant,
};
use std::{collections::HashSet, fs::File, io::BufWriter, time::Instant};

use chrono::DateTime;
use itertools::Itertools;
Expand Down Expand Up @@ -46,24 +41,23 @@ pub struct CheckWithBoxTreeRequest {

pub struct FilterExportWithBoxTreeRequest {
pub tree: BindingBoxTree,
pub export_format: ExportFormat,
pub export_format: ExportFormat,
}


#[derive(Serialize, Deserialize, Debug)]
pub enum ExportFormat {
XML,
JSON,
SQLITE
SQLITE,
}

impl ExportFormat {
pub fn to_extension(&self) -> &'static str {
match self {
ExportFormat::XML => "xml",
ExportFormat::JSON => "json",
ExportFormat::SQLITE => "sqlite",
}
pub fn to_extension(&self) -> &'static str {
match self {
ExportFormat::XML => "xml",
ExportFormat::JSON => "json",
ExportFormat::SQLITE => "sqlite",
}
}
}

Expand Down Expand Up @@ -116,7 +110,6 @@ pub fn evaluate_box_tree(
})
.collect_vec();


for (index, binding, viol) in evaluation_results_flat {
let r = &mut evaluation_results[index];
r.situations.push((binding, viol));
Expand All @@ -138,9 +131,7 @@ pub fn evaluate_box_tree(
}
}


pub fn filter_ocel_box_tree(tree: BindingBoxTree, ocel: &IndexLinkedOCEL) -> Option<OCEL> {

let now = Instant::now();
let evaluation_results_flat = tree.evaluate(ocel);
println!("Tree Evaluated in {:?}", now.elapsed());
Expand All @@ -157,7 +148,7 @@ pub fn filter_ocel_box_tree(tree: BindingBoxTree, ocel: &IndexLinkedOCEL) -> Opt
let mut o2o_rels_included: HashSet<(ObjectIndex, ObjectIndex, Option<String>)> = HashSet::new();
let mut o2o_rels_excluded: HashSet<(ObjectIndex, ObjectIndex, Option<String>)> = HashSet::new();

for (index, binding, viol) in evaluation_results_flat {
for (index, binding, _viol) in evaluation_results_flat {
for (var, label) in tree.nodes[index]
.as_box()
.iter()
Expand Down Expand Up @@ -302,12 +293,12 @@ pub fn filter_ocel_box_tree(tree: BindingBoxTree, ocel: &IndexLinkedOCEL) -> Opt
}
let mut ob = ob.clone();
ob.relationships.retain(|rel| {
check_o2o_inclusion(
**ob_index,
*ocel.object_index_map.get(&rel.object_id).unwrap(),
&rel.qualifier,
)
});
check_o2o_inclusion(
**ob_index,
*ocel.object_index_map.get(&rel.object_id).unwrap(),
&rel.qualifier,
)
});
filtered_ocel.objects.push(ob);
}
}
Expand All @@ -330,12 +321,12 @@ pub fn filter_ocel_box_tree(tree: BindingBoxTree, ocel: &IndexLinkedOCEL) -> Opt
}
let mut ev = ev.clone();
ev.relationships.retain(|rel| {
check_e2o_inclusion(
**ev_index,
*ocel.object_index_map.get(&rel.object_id).unwrap(),
&rel.qualifier,
)
});
check_e2o_inclusion(
**ev_index,
*ocel.object_index_map.get(&rel.object_id).unwrap(),
&rel.qualifier,
)
});
filtered_ocel.events.push(ev.clone());
}
}
Expand Down
2 changes: 1 addition & 1 deletion backend/shared/src/discovery/graph_discovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ impl CountConstraint {
ObjectVariable(inner_variable)
},
qualifier: None,
filter_label: None
filter_label: None,
},
},
}],
Expand Down
22 changes: 10 additions & 12 deletions backend/shared/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use binding_box::EvaluationResultWithCount;
use itertools::Itertools;
use preprocessing::linked_ocel::IndexLinkedOCEL;
use process_mining::{
ocel::ocel_struct::{OCELAttributeValue, OCELEvent, OCELObject, OCELType},
ocel::ocel_struct::{OCELEvent, OCELObject, OCELType},
OCEL,
};
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -113,7 +113,7 @@ impl Default for TableExportOptions {
pub fn export_bindings_to_csv_writer<W: std::io::Write>(
ocel: &IndexLinkedOCEL,
bindings: &EvaluationResultWithCount,
writer: W,
writer: &mut W,
options: &TableExportOptions,
) -> Result<(), csv::Error> {
let mut w = csv::WriterBuilder::new().from_writer(writer);
Expand All @@ -130,8 +130,7 @@ pub fn export_bindings_to_csv_writer<W: std::io::Write>(
.flat_map(|(b, _)| {
b.get_ev(ev_var, ocel)
.iter()
.map(|e| e.attributes.iter().map(|a| &a.name))
.flatten()
.flat_map(|e| e.attributes.iter().map(|a| &a.name))
.collect::<Vec<_>>()
})
.collect::<HashSet<_>>()
Expand All @@ -149,8 +148,7 @@ pub fn export_bindings_to_csv_writer<W: std::io::Write>(
.flat_map(|(b, _)| {
b.get_ob(ob_var, ocel)
.iter()
.map(|e| e.attributes.iter().map(|a| &a.name))
.flatten()
.flat_map(|e| e.attributes.iter().map(|a| &a.name))
.collect::<Vec<_>>()
})
.collect::<HashSet<_>>()
Expand All @@ -163,18 +161,18 @@ pub fn export_bindings_to_csv_writer<W: std::io::Write>(
// First object/event ID, then attributes, then next object/event ID, ..
for (ob, ob_attrs) in ob_vars.iter().zip(&ob_attrs) {
if options.include_ids {
w.write_field(format!("o{}", ob.0+1))?;
w.write_field(format!("o{}", ob.0 + 1))?;
}
for attr in ob_attrs {
w.write_field(format!("o{}.{}", ob.0+1, attr))?;
w.write_field(format!("o{}.{}", ob.0 + 1, attr))?;
}
}
for (ev, ev_attrs) in ev_vars.iter().zip(&ev_attrs) {
if options.include_ids {
w.write_field(format!("e{}", ev.0+1))?;
w.write_field(format!("e{}", ev.0 + 1))?;
}
for attr in ev_attrs {
w.write_field(format!("e{}.{}", ev.0+1, attr))?;
w.write_field(format!("e{}.{}", ev.0 + 1, attr))?;
}
}

Expand All @@ -186,7 +184,7 @@ pub fn export_bindings_to_csv_writer<W: std::io::Write>(

for (b, v) in &bindings.situations {
for (ob_v, ob_attrs) in ob_vars.iter().zip(&ob_attrs) {
if let Some(ob) = b.get_ob(&ob_v, ocel) {
if let Some(ob) = b.get_ob(ob_v, ocel) {
if options.include_ids {
w.write_field(&ob.id)?;
}
Expand All @@ -213,7 +211,7 @@ pub fn export_bindings_to_csv_writer<W: std::io::Write>(
}
}
for (ev_v, ev_attrs) in ev_vars.iter().zip(&ev_attrs) {
if let Some(ev) = b.get_ev(&ev_v, ocel) {
if let Some(ev) = b.get_ev(ev_v, ocel) {
if options.include_ids {
w.write_field(&ev.id)?;
}
Expand Down
6 changes: 4 additions & 2 deletions backend/shared/src/ocel_qualifiers/qualifiers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ pub fn get_qualifiers_for_event_types(
ocel.events
.iter()
.filter(|ev| ev.event_type == et.name)
.map(|ev| ev.relationships
.map(|ev| {
ev.relationships
.iter()
.filter_map(|r| {
let obj = ocel.objects.iter().find(|o| o.id == r.object_id);
Expand All @@ -34,7 +35,8 @@ pub fn get_qualifiers_for_event_types(
.fold(HashMap::new(), |mut acc, c| {
*acc.entry(c).or_insert(0) += 1;
acc
}))
})
})
.fold(HashMap::new(), |mut acc, c| {
c.into_iter().for_each(|(a, b)| {
let entry: &mut Vec<i32> = acc.entry(a).or_default();
Expand Down
2 changes: 1 addition & 1 deletion backend/shared/src/preprocessing/linked_ocel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ pub fn get_events_of_type_associated_with_objects(
}

pub fn get_event_relationships(ev: &OCELEvent) -> Vec<OCELRelationship> {
ev.relationships.clone()
ev.relationships.clone()
}

pub fn get_object_relationships(obj: &OCELObject) -> Vec<OCELRelationship> {
Expand Down
7 changes: 5 additions & 2 deletions backend/web-server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use tokio::net::TcpListener;
use std::{
collections::{HashMap, HashSet},
env,
io::{Cursor, Read},
io::Cursor,
sync::{Arc, RwLock},
};

Expand Down Expand Up @@ -99,7 +99,10 @@ async fn main() {
"/ocel/discover-constraints",
post(auto_discover_constraints_handler),
)
.route("/ocel/export-bindings-csv", post(export_bindings_csv).layer(DefaultBodyLimit::disable()))
.route(
"/ocel/export-bindings-csv",
post(export_bindings_csv).layer(DefaultBodyLimit::disable()),
)
.route("/ocel/event/:event_id", get(get_event_info_req))
.route("/ocel/object/:object_id", get(get_object_info_req))
.route("/ocel/get-event", post(get_event_req))
Expand Down
15 changes: 9 additions & 6 deletions frontend/src/BackendProviderContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ export type BackendProvider = {
"ocel/discover-constraints": (
autoDiscoveryOptions: DiscoverConstraintsRequest,
) => Promise<DiscoverConstraintsResponse>;
"ocel/export-bindings-csv": (bindings: EvaluationResultWithCount, options: TableExportOptions) => Promise<Blob | undefined>
"ocel/export-bindings-csv": (
bindings: EvaluationResultWithCount,
options: TableExportOptions,
) => Promise<Blob | undefined>;
"ocel/graph": (options: OCELGraphOptions) => Promise<{
nodes: (OCELEvent | OCELObject)[];
links: { source: string; target: string; qualifier: string }[];
Expand Down Expand Up @@ -89,8 +92,8 @@ export const API_WEB_SERVER_BACKEND_PROVIDER: BackendProvider = {
const type = ocelFile.name.endsWith(".json")
? "json"
: ocelFile.name.endsWith(".xml")
? "xml"
: "sqlite";
? "xml"
: "sqlite";
return await (
await fetch(BACKEND_URL + `/ocel/upload-${type}`, {
method: "post",
Expand Down Expand Up @@ -143,13 +146,13 @@ export const API_WEB_SERVER_BACKEND_PROVIDER: BackendProvider = {
).json();
},
"ocel/export-bindings-csv": async (bindings, options) => {
const res = (await fetch(BACKEND_URL + "/ocel/export-bindings-csv", {
const res = await fetch(BACKEND_URL + "/ocel/export-bindings-csv", {
method: "post",
headers: { "Content-Type": "application/json" },
body: JSON.stringify([bindings, options]),
}));
});
if (res.ok) {
return await res.blob()
return await res.blob();
} else {
throw new Error(res.status + " " + res.statusText);
}
Expand Down
Loading

0 comments on commit ed6ca50

Please sign in to comment.