Browse / github.com/storytold/vectorcraft / patch
Graph: add Data to the selected chart's context menu (#3462)
Graph: add Data to the selected chart's context menu A user reports that editing a created chart's data requires Object > Graph > Data; the canvas context menu provides no shortcut. Source: https://discord.com/channels/1359579021108842617/1557517495470915686/1562540461565153281 (2026-10-21 18:57 UTC). App version and OS were not specified. Expected behavior: - With an editable graph selected, offer Data… in its canvas context menu. - Open the existing Graph Data worksheet using the existing command/dialog path. - Preserve editing and undo behavior; do not offer an enabled action for unsupported selections. Current default-branch context_items
- Status
- open
- Score
- 0.00
- Adopters
- 0 other operators
- Author
- dennisklappe (imported from pull request #3472, open)
- Base
19c7d61f8af95e257ad2b422ce40db99ce12eabf- Size
- +30 −0 in 2 files
- Review
- pending
- Shared
- 2026-10-28
- Id
ac61a397ca063e2557074a7c
How it went
No other operator has reported using it yet.
Diff
raw · crates/ui-egui/src/menus.rs crates/ui-egui/src/tests_contextmenu.rs
@@ -3256,6 +3256,13 @@ pub fn context_items(app: &VectorcraftApp) -> Vec<Item> { if any(|k| matches!(k, NodeKind::Compound { .. })) { v.push(c("Release Compound Path", "object.compoundPath.release")); }+ // A graph, or art inside one, selected: its Graph Data worksheet, as Object › Graph › Data… opens.+ let in_graph = |id: vectorcraft_doc::NodeId| {+ std::iter::successors(Some(id), |c| st.doc.parent_of(*c)).any(|c| st.doc.node(c).is_some_and(|n| n.extras().graph.is_some()))+ };+ if st.selection.objects.iter().any(|id| in_graph(*id)) {+ v.push(c("Data…", "graph.setData"));+ } v.extend([ c("Make Guides", "view.guides.make"), Sep,@@ -246,3 +246,26 @@ fn every_context_label_is_a_menu_string() { assert!(shown.contains(label), "`{label}` is listed but the context menu never shows it"); } }++/// A selected graph (or art inside one) offers Data…, which opens the Graph Data worksheet as+/// Object › Graph › Data… does; other selections do not.+#[test]+fn a_selected_graph_offers_data() {+ let mut app = app();+ let a = rect(&mut app, 0.0, 0.0);+ app.run("select.set", json!({"ids": [a.0]})).unwrap();+ assert!(!labels(&menus::context_items(&app)).contains(&"Data…"));+ let g = app.run("graph.create", json!({"type": "column", "x": 20, "y": 20, "width": 200, "height": 120, "csv": ",a,b\nQ1,1,2"})).unwrap()["id"]+ .as_u64()+ .unwrap();+ app.run("select.set", json!({"ids": [g]})).unwrap();+ let items = menus::context_items(&app);+ assert!(labels(&items).contains(&"Data…"), "{:?}", labels(&items));+ menus::invoke(&mut app, "graph.setData", json!({}));+ assert_eq!(app.ui.dialog.as_ref().map(|d| d.kind.as_str()), Some(crate::dialogs::graph_data::KIND));+ app.ui.dialog = None;+ // Art inside the graph counts as the graph.+ let inner = app.session.doc().unwrap().doc.children(Some(NodeId(g))).and_then(|c| c.first()).map(|n| n.id).unwrap();+ app.run("select.set", json!({"ids": [inner.0]})).unwrap();+ assert!(labels(&menus::context_items(&app)).contains(&"Data…"));+}