Git Product home page Git Product logo

Comments (18)

nabil6391 avatar nabil6391 commented on May 12, 2024 2

Thanks for the PR, I will publish to pub.dev soon.

I have also started looking into the New Algorithm you shared.

from graphview.

nabil6391 avatar nabil6391 commented on May 12, 2024 2

I am about 30% with the new EiglspergerAlgorithm

from graphview.

nabil6391 avatar nabil6391 commented on May 12, 2024 2

That sucks. Need to improve my test cases, thanks for exporting this . Will try in the week end

from graphview.

JulianBissekkou avatar JulianBissekkou commented on May 12, 2024 1

Any luck with the bugfix? @nabil6391

from graphview.

JulianBissekkou avatar JulianBissekkou commented on May 12, 2024 1

I went through the sources of the java lib and found no change that would be a potential bugfix. Maybe you can take a look as well.
The java lib has a few issues about overlapping that are still open. I send an E-Mail to the maintainers of that lib. Let's see if they fix this issue then we can add the fix to your lib as well.

It would still be good if you can analyze the problem because I don't know if and when they are going to respond.

from graphview.

JulianBissekkou avatar JulianBissekkou commented on May 12, 2024

I found some performance optimizations in this paper. Might be interesting.

https://jgaa.info/accepted/2005/EiglspergerSiebenhallerKaufmann2005.9.3.pdf

And it looks like this project implemented this:
https://github.com/tomnelson/jungrapht-visualization

from graphview.

JulianBissekkou avatar JulianBissekkou commented on May 12, 2024

Did you make any progress? :)

from graphview.

nabil6391 avatar nabil6391 commented on May 12, 2024

@JulianBissekkou Highly suggest you to update to 1.1.0. There are some major improvements to Sugiyama Algorithm. Do have a look

from graphview.

JulianBissekkou avatar JulianBissekkou commented on May 12, 2024

Thanks! Improvements are looking really good, but we saw some nodes that are overlapping horizontally.

I exported the tree as JSON so you can easily reproduce this issue.
https://gist.github.com/JulianBissekkou/9e2a6a7dccb437b0e781352f7665b99d

from graphview.

JulianBissekkou avatar JulianBissekkou commented on May 12, 2024

Thanks a lot. If you need any help then let me know :)

from graphview.

nabil6391 avatar nabil6391 commented on May 12, 2024

@JulianBissekkou try out 1.1.1. Should be ok now but let me know if there are any other issues or not

from graphview.

JulianBissekkou avatar JulianBissekkou commented on May 12, 2024

@nabil6391 I checked out 1.1.1 and I found some overlapping issues. I also added some tests that are failing so you have some data to work with.
You can find that data in my PR #63

If you need some more details let me know. I can also improve the test suite to include more examples and details.

from graphview.

nabil6391 avatar nabil6391 commented on May 12, 2024

Thanks for the tests, I had a brief look. looks like the issues is not with the new code as the tests failed for Old Sugiyama Algorithm as well. I will have to dig deeper to see how to fix that.

from graphview.

JulianBissekkou avatar JulianBissekkou commented on May 12, 2024

@nabil6391
Did you have the time to check into that issue?

from graphview.

nabil6391 avatar nabil6391 commented on May 12, 2024

I did sat one day, found the place which should have taken into account the width (placeBlockWidth) but could not solve it yet

from graphview.

CicadaCinema avatar CicadaCinema commented on May 12, 2024

Today I had a go at tackling the issue of overlapping nodes, with almost no success.

Minimal test cases

I produced two minimal test cases - small graphs which result in overlapping nodes. Substitute these in place of this object.

This graph is disconnected:

var json = {
  'edges': [
    {'from': '1', 'to': '2'},
    {'from': '1', 'to': '3'},
    {'from': '4', 'to': '7'},
    {'from': '4', 'to': '5'},
    {'from': '9', 'to': '6'},
    {'from': '6', 'to': '4'},
    {'from': '8', 'to': '1'},
  ],
};

image

This graph is connected:

var json = {
  'edges': [
    {'from': '1', 'to': '2'},
    {'from': '1', 'to': '3'},
    {'from': '7', 'to': '8'},
    {'from': '7', 'to': '9'},
    {'from': '10', 'to': '6'},
    {'from': '6', 'to': '7'},
    {'from': '5', 'to': '1'},
    {'from': '5', 'to': '10'},
    {'from': '4', 'to': '1'},
  ],
};

image

I made the nodes translucent to be able to see overlaps more clearly:

 Widget rectangleWidget(String? a, Node node) {
   return Container(
-    color: Colors.amber,
     child: InkWell(
       onTap: () {
         print('clicked');
       },
       child: Container(
           padding: EdgeInsets.all(16),
           decoration: BoxDecoration(
             borderRadius: BorderRadius.circular(4),
             boxShadow: [
-              BoxShadow(color: Colors.blue[100]!, spreadRadius: 1),
+              BoxShadow(color: Colors.blue[500]!.withOpacity(0.3), spreadRadius: 1),
             ],
           ),
           child: Text('${a}')),
     ),
   );
 }

Debugging

It was difficult to debug this issue, and I found it difficult to make any sense of the data structures in the SugiyamaAlgorithm class. Without any evidence I claim that the bug might lie in one of these two methods:

void coordinateAssignment() {

By the time they are populated, the following data structures...

// each node points to the root of the block.;
final root = <Map<Node, Node>>[];
// each node points to its aligned neighbor in the layer below.;
final align = <Map<Node, Node>>[];
final sink = <Map<Node, Node>>[];
final x = <Map<Node, double>>[];
// minimal separation between the roots of different classes.;
final shift = <Map<Node, double>>[];
// the width of each block (max width of node in block);
final blockWidth = <Map<Node?, double>>[];

...are arrays of 4 elements, which might correspond to the 'alignment' of nodes in 4 directions. Here...

final k = 2 * downward + leftToRight;

... k ranges between 0 and 3 (inclusive) due to the two nested loops.

I claim that a logic error could arise at index 3 (k=3).

I experimented with making the following modification to this block of code:

for (var i = 0; i < 4; i++) {
values[i] = x[i][n]!;
}
values.sort();
var average = (values[1] + values[2]) * 0.5;
coordinates[n] = average;

  for (var i = 0; i < 4; i++) {
    values[i] = x[i][n]!;
  }
  values.sort();
  var average = (values[1] + values[2]) * 0.5;
- coordinates[n] = average;
+ if (values[1] != x[3][n]! && values[2] != x[3][n]!) {
+   coordinates[n] = average;
+ } else if (values[1] != x[3][n]!) {
+   coordinates[n] = values[1];
+ } else {
+   // here, values[2] != x[3][n]! is true
+   coordinates[n] = values[2];
+ }

It looks like this location in the algorithm is where the x coordinates of the nodes are set, and my logic above "avoids" x[3][n]! while attempting to retain the original behaviour if possible.

This change produces the following renderings of my test cases above:

image

image

This approach performs poorly for other examples, such as this one:

image

This modification fails the following tests:

Click to expand
PS C:\Users\Atom\Downloads\graphview> flutter test
00:02 +0: C:\Users\Atom\Downloads\graphview\test\buchheim_walker_algorithm_test.dart: Buchheim Graph Buchheim Node positions are correct for Top_Bottom
Timetaken 8
00:02 +1: C:\Users\Atom\Downloads\graphview\test\buchheim_walker_algorithm_test.dart: Buchheim Graph Buchheim Performance for 100 nodes to be less than 2.5s
Timetaken 21 12
00:02 +3: C:\Users\Atom\Downloads\graphview\test\graph_test.dart: Graph Node Hash Implementation is performant
Timetaken 5 Node{position: Offset(0.0, 0.0), key: [<5.6>], _size: Size(0.0, 0.0)}
00:02 +4: C:\Users\Atom\Downloads\graphview\test\sugiyama_algorithm_test.dart: Sugiyama Graph Sugiyama Node positions are correct for Top_Bottom
Timetaken 37
00:02 +4 -1: C:\Users\Atom\Downloads\graphview\test\sugiyama_algorithm_test.dart: Sugiyama Graph Sugiyama Node positions are correct for Top_Bottom [E]
  Expected: Offset:<Offset(1045.0, 815.0)>
    Actual: Offset:<Offset(2195.0, 815.0)>
  
  package:test_api                                    expect
  package:flutter_test/src/widget_tester.dart 460:16  expect
  test\sugiyama_algorithm_test.dart 112:7             main.<fn>.<fn>
  

To run this test again: C:\Software\flutter\bin\cache\dart-sdk\bin\dart.exe test C:\Users\Atom\Downloads\graphview\test\sugiyama_algorithm_test.dart -p vm --plain-name 'Sugiyama Graph Sugiyama Node positions are correct for Top_Bottom'
00:02 +4 -1: C:\Users\Atom\Downloads\graphview\test\sugiyama_algorithm_test.dart: Sugiyama Graph Sugiyama Node positions correct for LEFT_RIGHT
Timetaken 10
00:02 +4 -2: C:\Users\Atom\Downloads\graphview\test\sugiyama_algorithm_test.dart: Sugiyama Graph Sugiyama Node positions correct for LEFT_RIGHT [E]
  Expected: Offset:<Offset(815.0, 745.0)>
    Actual: Offset:<Offset(815.0, 1595.0)>

  package:test_api                                    expect
  package:flutter_test/src/widget_tester.dart 460:16  expect
  test\sugiyama_algorithm_test.dart 142:7             main.<fn>.<fn>


To run this test again: C:\Software\flutter\bin\cache\dart-sdk\bin\dart.exe test C:\Users\Atom\Downloads\graphview\test\sugiyama_algorithm_test.dart -p vm --plain-name 'Sugiyama Graph Sugiyama Node positions correct for LEFT_RIGHT'
00:02 +6 -3: C:\Users\Atom\Downloads\graphview\test\sugiyama_algorithm_test.dart: Sugiyama Graph Sugiyama for a cyclic graph [E]
  Expected: Offset:<Offset(10.0, 17.5)>
    Actual: Offset:<Offset(10.0, 10.0)>

  package:test_api                                    expect
  package:flutter_test/src/widget_tester.dart 460:16  expect
  test\sugiyama_algorithm_test.dart 239:7             main.<fn>.<fn>


To run this test again: C:\Software\flutter\bin\cache\dart-sdk\bin\dart.exe test C:\Users\Atom\Downloads\graphview\test\sugiyama_algorithm_test.dart -p vm --plain-name 'Sugiyama Graph Sugiyama for a cyclic graph'
00:02 +6 -3: C:\Users\Atom\Downloads\graphview\test\sugiyama_algorithm_test.dart: Sugiyama for a complex graph with 140 nodes
Timetaken 37 140
00:02 +6 -4: C:\Users\Atom\Downloads\graphview\test\sugiyama_algorithm_test.dart: Sugiyama for a complex graph with 140 nodes [E]
  Expected: Offset:<Offset(10.0, 397.5)>
    Actual: Offset:<Offset(10.0, 210.0)>

  package:test_api                                    expect
  package:flutter_test/src/widget_tester.dart 460:16  expect
  test\sugiyama_algorithm_test.dart 276:5             main.<fn>


To run this test again: C:\Software\flutter\bin\cache\dart-sdk\bin\dart.exe test C:\Users\Atom\Downloads\graphview\test\sugiyama_algorithm_test.dart -p vm --plain-name 'Sugiyama for a complex graph with 140 nodes'
00:05 +7 -4: C:\Users\Atom\Downloads\graphview\test\sugiyama_algorithm_test.dart: Sugiyama Performance for 100 nodes to be less than 2.5s
Timetaken 2013 200
00:05 +8 -4: Some tests failed.

The good news is that all these look like golden tests, and that the tests for overlapping actually pass. The bad news is that the graphs resulting from this algorithm are probably wildly space-inefficient (like the example above).

Conclusion

This is all I know. Oh well, I can't be bothered to work on this issue any longer, maybe someone else can pick up the torch. It looks like this is the most fully-fledged graph-drawing package on pub.dev, which is a shame because it was very difficult for me to work with something which is essentially a twice-translated Java library.

from graphview.

CicadaCinema avatar CicadaCinema commented on May 12, 2024

Pinging @nabil6391 @JulianBissekkou

from graphview.

nabil6391 avatar nabil6391 commented on May 12, 2024

Try out 1.2.0 , fixed overlapping nodes and the tests are not failing as well

from graphview.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.