SimpleDataFlow
SimpleDataFlow copied to clipboard
A simple tool demonstrating the DPG node editor.
SimpleDataFlow (not ready yet)
A simple tool used to analyze data flow.
| Minimal Example - Data Sets - Tools - Modifiers - Inspectors |
|---|
Minimal Example
Although not very useful, below is the minimal code required to start:
import simple_data_flow as sdf
app = sdf.App()
app.start()
Basics
A Simple Data Flow application consists of a few components, namely:
- Data Graph - the center region that contains nodes
- Data sets - data of any form that can be dropped onto the data graph
- Modifiers - components that take in data and performs operation on it, outputting another data set.
- Inspectors - components that take in data and takes measurements but does not affect the data set.
- Tools - similar to Inspectors but these components do not have an output.
Data Sets
Data sets are the roots in node graph. The data itself can be any form. Below is a simple example of adding data sets:
import simple_data_flow as sdf
app = sdf.App()
app.add_data_set("New Data", [-5.0, -5.0, -3.0, -3.0, 0.0, 0.0, 3.0, 3.0, 5.0, 5.0])
app.start()
Custom Tools
Creating a new tool requires the developer to create a new class derived from Node. It is the developers responsibility to create a factory static method and override the execute method. The constructor will add however many input attributes are required to perform its operation. Most tools will also need to add a static attribute. The typical steps involved within the execute method are as follows:
- Retrieve data from input attributes.
- Retrieve local data.
- Perform operations.
- Set some values in the static attributes.
- Call
finish.
Below is a simple tool that displays the length of the incoming data:
import simple_data_flow as sdf
from simple_data_flow import dpg
class NewNode(sdf.Node):
@staticmethod
def factory(name, data):
node = NewNode(name, data)
return node
def __init__(self, label: str, data):
super().__init__(label, data)
# add input attributes
self.add_input_attribute(sdf.InputNodeAttribute("input"))
self.custom_id = dpg.generate_uuid()
def custom(self):
dpg.add_input_int(label="Length", width=150, id=self.custom_id, readonly=True, step=0)
def execute(self):
# input data
input_data_1 = self._input_attributes[0].get_data()
# perform operations
result = len(input_data_1)
# set values
dpg.set_value(self.custom_id, result)
# call finish
self.finish()
app = sdf.App()
app.add_tool("New Tool", NewNode.factory)
app.start()
Custom Modifiers
Creating a new modifier requires the developer to create a new class derived from Node. It is the developers responsibility to create a factory static method and override the execute method. The constructor will add however many input attributes are required to perform its operation. The constructor will also add the required number of output attributes. Most tools will also need to add a static attribute. The typical steps involved within the execute method are as follows:
- Retrieve data from input attributes.
- Retrieve local data.
- Perform operations.
- Call
executemethod of each output attribute, passing in output data. - Call
finish.
Below is a simple example of a modifier that subtracts some value from each value in the data set:
import simple_data_flow as sdf
from simple_data_flow import dpg
class NewNode(sdf.Node):
@staticmethod
def factory(name, data):
node = NewNode(name, data)
return node
def __init__(self, label: str, data):
super().__init__(label, data)
# add input attributes
self.add_input_attribute(sdf.InputNodeAttribute("input"))
self.custom_id = dpg.generate_uuid()
# add output attributes
self.add_output_attribute(sdf.OutputNodeAttribute("output"))
def custom(self):
dpg.add_input_int(label="Subtract Value", width=150, id=self.custom_id, step=0)
def execute(self):
# input data
input_data_1 = self._input_attributes[0].get_data()
# static attribute value
subtract_value = dpg.get_value(self.custom_id)
# perform operations
new_data = []
for value in input_data_1:
new_data.append(value - subtract_value)
# call execute on output attributes with data
self._output_attributes[0].execute(new_data)
# call finish
self.finish()
app = sdf.App()
app.add_modifier("New Modifier", NewNode.factory)
app.start()
Custom Inspectors
Creating a new inspector requires the developer to create a new class derived from Node. It is the developers responsibility to create a factory static method and override the execute method. The constructor will add however many input attributes are required to perform its operation. The constructor will also add the required number of output attributes. Most tools will also need to add a static attribute. The typical steps involved within the execute method are as follows:
- Retrieve data from input attributes.
- Retrieve local data.
- Perform operations.
- Call
executemethod of each output attribute, passing in output data. - Call
finish.
Below is a simple example of an inspector that finds the maximum value of a data set:
import simple_data_flow as sdf
from simple_data_flow import dpg
class NewNode(sdf.Node):
@staticmethod
def factory(name, data):
node = NewNode(name, data)
return node
def __init__(self, label: str, data):
super().__init__(label, data)
# add input attributes
self.add_input_attribute(sdf.InputNodeAttribute("input"))
# add output attributes
self.add_output_attribute(sdf.OutputNodeAttribute("output"))
def execute(self):
# input data
input_data_1 = self._input_attributes[0].get_data()
# perform operations
max_value = input_data_1[0]
for value in input_data_1:
if value > max_value:
max_value = value
# call execute on output attributes with data
self._output_attributes[0].execute(max_value)
# call finish
self.finish()
app = sdf.App()
app.add_inspector("New Inspector", NewNode.factory)
app.start()