Tree Navigator
A powerful Flutter library for navigating and managing complex JSON tree data structures with support for conditional logic, script engine, and multiple navigation strategies.
✨ Key Features
- 🌳 JSON Tree Navigation: Easily traverse through nodes in JSON data trees
- 🎯 Smart Navigation: Support for both static and dynamic navigation based on conditions
- 🔧 Script Engine: Execute complex logic with built-in script engine
- 📊 State Management: Track and manage navigation state
- 📝 Navigation History: Record and trace selection history
- 🎨 Multiple Strategies: Support for JSON Rule Engine and Strategy Pattern
- 🔄 Flexible: Easily extensible with custom functions and strategies
🚀 Installation
Add the dependency to your pubspec.yaml file:
dependencies:
  tree_navigator: ^1.0.0
Then run:
flutter pub get
📖 Usage
Basic Initialization
import 'package:tree_navigator/tree_navigator.dart';
// Initialize TreeNavigator with JSON file
var navigator = TreeNavigator('/path/to/assets', 'tree_data.json');
// Get current node information
print('Current node: ${navigator.current().key}');
print('Label: ${navigator.current().label}');
JSON File Structure
{
  "key": "ROOT",
  "label": "Home",
  "options": [
    {
      "key": "STATIC-NODE",
      "label": "Static Navigation",
      "leadsTo": "TARGET-NODE"
    },
    {
      "key": "DYNAMIC-NODE", 
      "label": "Dynamic Navigation",
      "script": "age >= 18 ? ADULT : CHILD"
    }
  ],
  "children": [
    {
      "key": "TARGET-NODE",
      "label": "Target Node",
      "options": [],
      "children": []
    },
    {
      "key": "ADULT",
      "label": "Adult",
      "options": [],
      "children": []
    },
    {
      "key": "CHILD", 
      "label": "Child",
      "options": [],
      "children": []
    }
  ]
}
Basic Navigation
// Set selection for current node
navigator.set('ROOT', 'STATIC-NODE');
// Move to next node
try {
  var nextNode = navigator.next();
  print('Moved to: ${nextNode?.key}');
} catch (e) {
  print('Navigation error: $e');
}
// Go back to previous node
navigator.prev();
// Reset to root
navigator.reset();
Conditional Navigation
// Set state
navigator.set('age', 25);
navigator.set('ROOT', 'DYNAMIC-NODE');
// Script will automatically evaluate: age >= 18 ? ADULT : CHILD
var nextNode = navigator.next(); // Will go to "ADULT" node
Registering Custom Functions
// Register custom function
navigator.registerScriptFunction('checkAge', (
  Map<String, dynamic> context,
  List<String> params,
  Map<String, dynamic>? extraParams
) {
  Map<String, dynamic> state = context['state'] ?? {};
  int age = state['age'] ?? 0;
  
  return age >= 18 ? 'ADULT' : 'CHILD';
});
// Use in JSON
{
  "key": "AGE-CHECK",
  "label": "Age Check",
  "script": "checkAge()"
}
JSON Rule Engine
// Define rule
Map<String, dynamic> ageRule = {
  "type": "condition",
  "field": "age", 
  "operator": ">=",
  "value": 18,
  "true": "ADULT",
  "false": "CHILD"
};
// Execute rule
navigator.set('age', 20);
String? result = navigator.executeJsonRule(ageRule);
print('Result: $result'); // Output: ADULT
Strategy Pattern
import 'package:tree_navigator/script_engine.dart';
// Create strategy
var ageStrategy = ConditionalStrategy(
  condition: 'age >= 18',
  trueNode: 'ADULT',
  falseNode: 'CHILD',
);
// Execute strategy
navigator.set('age', 16);
String? result = navigator.executeStrategy(ageStrategy);
print('Result: $result'); // Output: CHILD
Utility Functions
// Get navigation history
List<String> history = navigator.history();
print('History: $history');
// Get journey (detailed selections)
List<TraceItem> journey = navigator.journey();
for (var trace in journey) {
  print('Selected: ${trace.key}, Params: ${trace.params}');
}
// Find all leaf nodes
List<TreeNode> leafs = navigator.getleafs(navigator.current());
for (var leaf in leafs) {
  print('Leaf: ${leaf.key} - ${leaf.label}');
}
// Get last selection
TraceItem? lastChoice = navigator.lastsel();
print('Last choice: ${lastChoice?.key}');
🎯 Real-world Examples
Example 1: Survey System
// Initialize with survey file
var survey = TreeNavigator('/assets', 'survey.json');
// Set user information
survey.set('age', 25);
survey.set('gender', 'male');
survey.set('income', 50000);
// Navigate through questions
survey.set('Q1', 'YES');
var nextQuestion = survey.next();
// Check final result
if (survey.getleafs(survey.current()).isNotEmpty) {
  print('Survey completed!');
}
Example 2: Dynamic Menu System
// Menu changes based on user permissions
var menu = TreeNavigator('/assets', 'menu.json');
menu.set('userRole', 'admin');
menu.set('permissions', ['read', 'write', 'delete']);
// Script in JSON will check permissions and display appropriate menu
var menuItems = menu.current().options;
📊 Demo Results
When running with test2.json file, the library will execute the following scenarios:
Scenario 1: Static Navigation
📍 Current Node: ROOT
🎯 Options: STATIC-NODE, RULE-NODE
👆 Select: STATIC-NODE → Navigate to STATIC-18
Scenario 2: Script Navigation (age ≥ 18)
🎂 Set age = 25
👆 Select: RULE-NODE → Script evaluates → Navigate to OVER-18
Scenario 3: Script Navigation (age < 18)
🎂 Set age = 15  
👆 Select: RULE-NODE → Script evaluates → Navigate to UNDER-18
🔧 API Reference
TreeNavigator
| Method | Description | 
|---|---|
| current() | Get current node | 
| next([params]) | Move to next node | 
| prev() | Go back to previous node | 
| reset() | Reset to root node | 
| set(key, value) | Set state | 
| history() | Get navigation history | 
| journey() | Get detailed selections | 
| getleafs(node) | Find all leaf nodes | 
| lastsel() | Get last selection | 
Script Engine
| Method | Description | 
|---|---|
| registerFunction(name, fn) | Register custom function | 
| executeScript(script, context) | Execute script | 
| executeJsonRule(rule) | Execute JSON rule | 
| executeStrategy(strategy) | Execute strategy | 
🤝 Contributing
We welcome all contributions! Please:
- Fork the repository
- Create a feature branch (git checkout -b feature/amazing-feature)
- Commit your changes (git commit -m 'Add amazing feature')
- Push to the branch (git push origin feature/amazing-feature)
- Create a Pull Request
📄 License
This project is distributed under the MIT License. See the LICENSE file for more details.
🆘 Support
- 📧 Email: ducphan1311@gmail.com
- 🐛 Issues: GitHub Issues