graphview icon indicating copy to clipboard operation
graphview copied to clipboard

Questions on achieving a mindmap using graphview

Open beauduffy opened this issue 2 years ago • 3 comments

Hi, been trying to use graph view to create a mindmap, I have prototyped with the three algorithms and would like to hear your thoughts on which to use, as i believe all might be able to achieve but I have found hurdles with them. mind-map-graphic-e1642052584778

For context, I use Flutteflow and could be denoted as a novice when it comes to dart so I am probably overlooking some concepts, I am passing in a structured json which i believe graph view can accept, example below:

static const Map<String, dynamic> json = {
    'nodes': [
      {'id': 1, 'label': 'Fishing'},
      {'id': 2, 'label': 'Colours'},
      {'id': 3, 'label': 'Aquamarine'},
      {'id': 4, 'label': 'Turquoise'},
      {'id': 5, 'label': 'Cyan'},
      {'id': 6, 'label': 'Emotions'},
      {'id': 7, 'label': 'Excited'},
      {'id': 8, 'label': 'Intrigued'},
      {'id': 9, 'label': 'Adventurous'},
      {'id': 10, 'label': 'Objects'},
      {'id': 11, 'label': 'Rods'},
      {'id': 12, 'label': 'Reels'},
      {'id': 13, 'label': 'Lures'}
    ],
    'edges': [
      {'from': 1, 'to': 2},
      {'from': 2, 'to': 3},
      {'from': 2, 'to': 4},
      {'from': 2, 'to': 5},
      {'from': 1, 'to': 6},
      {'from': 6, 'to': 7},
      {'from': 6, 'to': 8},
      {'from': 6, 'to': 9},
      {'from': 1, 'to': 10},
      {'from': 10, 'to': 11},
      {'from': 10, 'to': 12},
      {'from': 10, 'to': 13}

    ]
  };

FruchtermanReingoldAlgorithm I believe this could work if repulsionRate and attractionRate could be directional and therefore each of the categories could have force exerting in different directions pulling it apart, below I think each category could be built independently with a different build below is the code I used to map each category based on the nodes edges to the center, however, I cant figure out how to achieve directional pull so it is just ends up being a standard Fruchterman graph.

  final Map<int, Graph> separateGraphs =
      {}; // Store separate graphs for each connected node
  final Map<int, Algorithm> builders = {}; // Store the builder for each graph

  @override
  void initState() {
    var edges = json['edges']!;

    // Find nodes connected to node with ID 1
    List<int> connectedNodes = [];
    for (var edge in edges) {
      if (edge['from'] == 1) {
        connectedNodes.add(edge['to']);
      } else if (edge['to'] == 1) {
        connectedNodes.add(edge['from']);
      }
    }

    // Create separate graphs for each connected node
    for (int connectedNode in connectedNodes) {
      Graph graph = Graph();
      separateGraphs[connectedNode] = graph;

      graph.addEdge(Node.Id(1), Node.Id(connectedNode));
      edges.forEach((element) {
        if ((element['from'] == connectedNode && element['to'] != 1) ||
            (element['to'] == connectedNode && element['from'] != 1)) {
          graph.addEdge(Node.Id(element['from']), Node.Id(element['to']));
        }
      });

      builders[connectedNode] = FruchtermanReingoldAlgorithm(
          iterations: 1500,
          repulsionRate: 0.2,
          attractionRate: 0.8,
          attractionPercentage: 0.5,
          repulsionPercentage: 0.25);
    }
  }
}

BuchheimWalkerConfiguration I think this could also achieve a mindmap like structure in a similar vain to my idea above in terms of mapping different individual mindmap orientations with the json. However, i think you run into the issue with collision between each of the independent mindmaps so I dont think this algo would be optimal.

  Widget build(BuildContext context) {
    List<GraphView> graphViews = [];
    var topLevelNodes = getTopLevelNodes();

    for (int i = 0; i < topLevelNodes.length; i++) {
      var currentNode = topLevelNodes[i];
      var subGraph = createSubGraph(currentNode);
      var currentOrientation;

      switch (i) {
        case 0:
          currentOrientation =
              BuchheimWalkerConfiguration.ORIENTATION_TOP_BOTTOM;
          break;
        case 1:
          currentOrientation =
              BuchheimWalkerConfiguration.ORIENTATION_LEFT_RIGHT;
          break;
        case 2:
          currentOrientation =
              BuchheimWalkerConfiguration.ORIENTATION_RIGHT_LEFT;
          break;
        default:
          currentOrientation =
              BuchheimWalkerConfiguration.ORIENTATION_TOP_BOTTOM;
      }

      graphViews.add(createGraphView(subGraph, currentOrientation));
    }

SugiyamaConfiguration This could be the more suitable algo for creating the mindmap becuase it is layered and the examples look very similar to what a mindmap should look like, however with amateur knowledge I can only seem to create a typical top-down model and cant mimic the edge creation I saw in the example which is shown below, but I am curious how it can be dynamically calculated.

class _LayerGraphPageFromJsonState extends State<LayerGraphPageFromJson> {
  var  json =   {
    "edges": [
      {
        "from": "254022114",
        "to": "435737192"
      },
      {
        "from": "102061118",
        "to": "435737192"
      },
      {
        "from": "864374573",
        "to": "676874082"
      },

Apologies for the long question, just wondering which algo to use and also looking for a general direction to go into to achieve a mindmap.

beauduffy avatar May 05 '23 11:05 beauduffy

Hi @Xander0x did you manage to create a mindmap?

I'm trying to build something like the image that you've showed but with no success

ManuelFEMartinho avatar Jun 21 '23 16:06 ManuelFEMartinho

Sadly, not.

The project I am working on depends on this so I moved away from Flutter and decided to use react native. Can achieve it with Reactflow with Webview, plus can use React native Skia as a wrapper for rendering.

I don't think it is doable with this repo, you could look into writing an algo for it if you are sticking with flutter.

beauduffy avatar Jul 02 '23 16:07 beauduffy

Duplicate of #65

Sternbach-Software avatar Jan 05 '24 21:01 Sternbach-Software