Skip to content
This repository has been archived by the owner on Dec 28, 2021. It is now read-only.

Commit

Permalink
Show visualization available for node output type only. (#1384)
Browse files Browse the repository at this point in the history
  • Loading branch information
farmaazon authored Mar 30, 2021
1 parent ebf5c4f commit d4cc824
Show file tree
Hide file tree
Showing 12 changed files with 140 additions and 68 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@
with a browser of your choice.
- [JS visualizations have consistent gestures with the IDE][1291]. Panning and
zooming now works just as expected on trackpad and mouse.
- [The `inputType` field of visualizations is actually taken into consideration]
[1384]. The visualization chooser shows entries accepting the node's output's
type only.
- [Fix applying selected node output to the expression of new node][1385]. For
example, having selected node with Table output and adding a new node with
expression `at "x" == "y"` the selected node was applied to the right side of
Expand Down Expand Up @@ -104,6 +107,7 @@ you can find their release notes
[1341]: https://github.com/enso-org/ide/pull/1341
[1348]: https://github.com/enso-org/ide/pull/1348
[1353]: https://github.com/enso-org/ide/pull/1353
[1384]: https://github.com/enso-org/ide/pull/1384
[1385]: https://github.com/enso-org/ide/pull/1385
[1393]: https://github.com/enso-org/ide/pull/1393
[1392]: https://github.com/enso-org/ide/pull/1392
Expand Down
4 changes: 3 additions & 1 deletion src/rust/ensogl/lib/components/src/drop_down_menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,10 +226,13 @@ impl DropDownMenu {

let menu_height = DEPRECATED_Animation::<f32>::new(&network);


eval menu_height.value ([model](height) {
model.selection_menu.frp.resize.emit(Vector2::new(MENU_WIDTH,*height));
if *height <= 0.0 {
model.hide_selection_menu();
} else if *height > 0.0 {
model.show_selection_menu();
}
});

Expand Down Expand Up @@ -268,7 +271,6 @@ impl DropDownMenu {
show_menu <- source::<()>();

eval_ hide_menu (model.selection_menu.deselect_entries.emit(()));
eval_ show_menu (model.show_selection_menu());

frp.source.menu_visible <+ hide_menu.constant(false);
frp.source.menu_visible <+ show_menu.constant(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ const makeId = makeGenerator()
* TODO: Make 2-finger panning behave like in IDE, and RMB zooming. [#1368]
*/
class GeoMapVisualization extends Visualization {
static inputType = 'Any'
static inputType = 'Standard.Table.Data.Table.Table'
static label = 'Geo Map'

constructor(api) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const BUTTON_HEIGHT = 25
}
*/
class Histogram extends Visualization {
static inputType = 'Any'
static inputType = 'Standard.Table.Data.Table.Table | Standard.Base.Data.Vector.Vector'
static label = 'Histogram'

constructor(data) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const BUTTONS_HEIGHT = 25
* }
*/
class ScatterPlot extends Visualization {
static inputType = 'Any'
static inputType = 'Standard.Table.Data.Table.Table | Standard.Base.Data.Vector.Vector'
static label = 'Scatter Plot'

constructor(data) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ loadScript('https://cdnjs.cloudflare.com/ajax/libs/sql-formatter/4.0.2/sql-forma
class SqlVisualization extends Visualization {
// TODO Change the type below once #837 is done:
// 'Standard.Database.Data.Table.Table | Standard.Database.Data.Column.Column'
static inputType = 'Any'
static inputType = 'Standard.Database.Data.Table.Table | Standard.Database.Data.Column.Column'
static label = 'SQL Query'

constructor(api) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub mod fullscreen;

use crate::prelude::*;

use crate::data::enso;
use crate::visualization;
use crate::component::visualization::instance::PreprocessorConfiguration;

Expand Down Expand Up @@ -129,23 +130,26 @@ pub mod overlay {

ensogl::define_endpoints! {
Input {
set_visibility (bool),
toggle_visibility (),
set_visualization (Option<visualization::Definition>),
set_data (visualization::Data),
select (),
deselect (),
set_size (Vector2),
enable_fullscreen (),
disable_fullscreen (),
set_visibility (bool),
toggle_visibility (),
set_visualization (Option<visualization::Definition>),
cycle_visualization (),
set_data (visualization::Data),
select (),
deselect (),
set_size (Vector2),
enable_fullscreen (),
disable_fullscreen (),
set_vis_input_type (Option<enso::Type>),
}

Output {
preprocessor (PreprocessorConfiguration),
visualisation (Option<visualization::Definition>),
size (Vector2),
is_selected (bool),
visible (bool),
preprocessor (PreprocessorConfiguration),
visualisation (Option<visualization::Definition>),
size (Vector2),
is_selected (bool),
visible (bool),
vis_input_type (Option<enso::Type>)
}
}

Expand Down Expand Up @@ -420,6 +424,20 @@ impl ContainerModel {
fn is_this_target(&self, target:scene::PointerTarget) -> bool {
self.view.overlay.is_this_target(target)
}

fn next_visualization
(&self, current_vis:&Option<visualization::Definition>, input_type:&Option<enso::Type>)
-> Option<visualization::Definition> {
let input_type_or_any = input_type.clone().unwrap_or_else(enso::Type::any);
let vis_list = self.registry.valid_sources(&input_type_or_any);
let next_on_list = current_vis.as_ref().and_then(|vis| {
let mut from_current = vis_list.iter().skip_while(
|x| vis.signature.path != x.signature.path
);
from_current.nth(1)
});
next_on_list.or_else(|| vis_list.first()).cloned()
}
}

impl display::Object for ContainerModel {
Expand Down Expand Up @@ -468,10 +486,28 @@ impl Container {
frp::extend! { network
eval frp.set_visibility ((v) model.set_visibility(*v));
eval_ frp.toggle_visibility (model.toggle_visibility());
eval frp.set_data ((t) model.set_visualization_data(t));
frp.source.size <+ frp.set_size;
frp.source.visible <+ frp.set_visibility;
frp.source.visible <+ frp.toggle_visibility.map(f!((()) model.is_active()));
let preprocessor = &frp.source.preprocessor;
frp.source.visualisation <+ frp.set_visualization.map(f!(
}


// === Cycling Visualizations ===

frp::extend! { network
vis_after_cycling <- frp.cycle_visualization.map3(&frp.visualisation,&frp.vis_input_type,
f!(((),vis,input_type) model.next_visualization(vis,input_type))
);
}


// === Switching Visualizations ===

frp::extend! { network
new_vis_definition <- any(frp.set_visualization,vis_after_cycling);
let preprocessor = &frp.source.preprocessor;
frp.source.visualisation <+ new_vis_definition.map(f!(
[model,action_bar,scene,logger,preprocessor](vis_definition) {

if let Some(definition) = vis_definition {
Expand All @@ -488,15 +524,12 @@ impl Container {
}
vis_definition.clone()
}));
}

eval frp.set_data ((t) model.set_visualization_data(t));
eval_ frp.enable_fullscreen (model.enable_fullscreen());
eval_ frp.disable_fullscreen (model.disable_fullscreen());
fullscreen_enabled_weight <- frp.enable_fullscreen.constant(1.0);
fullscreen_disabled_weight <- frp.disable_fullscreen.constant(0.0);
fullscreen_weight <- any(fullscreen_enabled_weight,fullscreen_disabled_weight);
frp.source.size <+ frp.set_size;

// === Selecting Visualization ===

frp::extend! { network
mouse_down_target <- scene.mouse.frp.down.map(f_!(scene.mouse.target.get()));
selected_by_click <= mouse_down_target.map(f!([model] (target){
let vis = &model.visualization;
Expand All @@ -522,6 +555,18 @@ impl Container {
(new != old).as_some(new)
});
frp.source.is_selected <+ is_selected_changed;
}


// === Fullscreen View ===

frp::extend! { network
eval_ frp.enable_fullscreen (model.enable_fullscreen());
eval_ frp.disable_fullscreen (model.disable_fullscreen());
fullscreen_enabled_weight <- frp.enable_fullscreen.constant(1.0);
fullscreen_disabled_weight <- frp.disable_fullscreen.constant(0.0);
fullscreen_weight <- any(fullscreen_enabled_weight,fullscreen_disabled_weight);
frp.source.size <+ frp.set_size;

_eval <- fullscreen_weight.all_with3(&frp.size,scene_shape,
f!([model] (weight,viz_size,scene_size) {
Expand All @@ -544,6 +589,7 @@ impl Container {


// === Visualisation chooser frp bindings ===

frp::extend! { network
selected_definition <- action_bar.visualisation_selection.map(f!([registry](path)
path.as_ref().map(|path| registry.definition_from_path(path) ).flatten()
Expand All @@ -561,10 +607,15 @@ impl Container {
frp.source.visualisation <+ selected_definition;
on_selected <- selected_definition.map(|d|d.as_ref().map(|_|())).unwrap();
eval_ on_selected ( action_bar.hide_icons.emit(()) );
frp.source.vis_input_type <+ frp.set_vis_input_type;
eval frp.set_vis_input_type (
(tp) model.action_bar.visualization_chooser().frp.set_vis_input_type(tp)
);
}


// === Action bar actions ===

frp::extend! { network
eval_ action_bar.on_container_reset_position(model.drag_root.set_position_xy(Vector2::zero()));
drag_action <- app.cursor.frp.scene_position_delta.gate(&action_bar.container_drag_state);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,9 @@ impl ActionBar {
}
self
}

/// Visualization Chooser component getter.
pub fn visualization_chooser(&self) -> &VisualizationChooser { &self.model.visualization_chooser }
}

impl display::Object for ActionBar {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,17 @@ ensogl::define_endpoints! {
hide_selection_menu (),
set_selected (Option<visualization::Path>),
set_menu_offset_y (f32),
set_vis_input_type (Option<enso::Type>),
}

Output {
menu_visible (bool),
menu_closed (),
chosen_entry (Option<visualization::Path>),
mouse_over (),
mouse_out (),
entries (Rc<Vec<visualization::Path>>)
menu_visible (bool),
menu_closed (),
chosen_entry (Option<visualization::Path>),
mouse_over (),
mouse_out (),
entries (Rc<Vec<visualization::Path>>),
vis_input_type (Option<enso::Type>)
}
}

Expand All @@ -62,10 +64,9 @@ impl Model {
Self{selection_menu,registry}
}

pub fn entries(&self) -> Vec <visualization::Path> {
// TODO[ao]: The returned visualizations should take the current type on node into account.
// See https://github.com/enso-org/ide/issues/837
let definitions_iter = self.registry.valid_sources(&enso::Type::any()).into_iter();
pub fn entries(&self, input_type:&Option<enso::Type>) -> Vec<visualization::Path> {
let input_type_or_any = input_type.clone().unwrap_or_else(enso::Type::any);
let definitions_iter = self.registry.valid_sources(&input_type_or_any).into_iter();
definitions_iter.map(|d| d.signature.path).collect_vec()
}
}
Expand Down Expand Up @@ -119,17 +120,6 @@ impl VisualizationChooser {
eval set_selected_ix ((ix) menu.set_selected.emit(ix));


// === Showing Entries ===


frp.source.entries <+ menu.menu_visible.gate(&menu.menu_visible).map(f_!([model] {
let entries = Rc::new(model.entries());
let provider = list_view::entry::AnyModelProvider::from(entries.clone_ref());
model.selection_menu.set_entries(provider);
entries
}));


// === Output Processing ===

frp.source.mouse_over <+ menu.icon_mouse_over;
Expand All @@ -152,6 +142,20 @@ impl VisualizationChooser {
analytics::remote_log_value(event,field,data);
}
});
frp.source.vis_input_type <+ frp.set_vis_input_type;


// === Showing Entries ===

menu_appears <- menu.menu_visible.gate(&menu.menu_visible).constant(());
input_type_changed <- frp.set_vis_input_type.gate(&menu.menu_visible).constant(());
refresh_entries <- any(menu_appears,input_type_changed);
frp.source.entries <+ refresh_entries.map2(&frp.vis_input_type,f!([model] ((),input_type){
let entries = Rc::new(model.entries(input_type));
let provider = list_view::entry::AnyModelProvider::from(entries.clone_ref());
model.selection_menu.set_entries(provider);
entries
}));
}
self
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ impl Registry {
pub fn add(&self, class:impl Into<visualization::Definition>) {
let class = class.into();
let sig = &class.signature;
self.type_map.borrow_mut().entry(sig.input_type.clone()).or_default().push(class.clone_ref());
for tp in sig.input_type.alternatives() {
self.type_map.borrow_mut().entry(tp).or_default().push(class.clone_ref());
}
self.path_map.borrow_mut().entry(sig.path.clone()).insert(class);
}

Expand All @@ -65,7 +67,14 @@ impl Registry {
/// Return all `visualization::Class`es that can create a visualization for the given datatype.
pub fn valid_sources(&self, tp:&enso::Type) -> Vec<visualization::Definition>{
let type_map = self.type_map.borrow();
type_map.get(tp).cloned().unwrap_or_default()
let any_type = enso::Type::any();
let mut result:Vec<visualization::Definition> = type_map.get(tp).cloned().unwrap_or_default();
if tp != &any_type {
if let Some(vis_for_any) = type_map.get(&any_type) {
result.extend(vis_for_any.iter().cloned());
}
}
result
}

/// Return the `visualization::Definition` registered for the given `visualization::Path`.
Expand Down
4 changes: 4 additions & 0 deletions src/rust/ide/view/graph-editor/src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,9 @@ pub mod enso {
pub fn any() -> Self {
"Any".into()
}

pub fn alternatives<'a>(&'a self) -> impl Iterator<Item=Type> + 'a {
self.content.split('|').map(str::trim).map(Type::new)
}
}
}
Loading

0 comments on commit d4cc824

Please sign in to comment.