• Hi All

    Please note that at the Chandoo.org Forums there is Zero Tolerance to Spam

    Post Spam and you Will Be Deleted as a User

    Hui...

  • When starting a new post, to receive a quicker and more targeted answer, Please include a sample file in the initial post.

Draw proper Bezier curves to contruct flow shapes for Sankey chart [ SOLVED ]

Abrasax

New Member
Hello everyone.

I am programmatically trying to build a Sankey diagram from scratch as my company has a policy of not allowing add-ins or other applications available from the Web, so I can’t use a readily provided relevant solution. I have managed to come close to a functioning result, but properly drawing the flows between the nodes is the tricky part and the one I need your help with.

More specifically, in the attached, by pressing the “One shape” button a flow shape is created between the first node (blue bar) and the node in the lower right (orange bar). In practice, the coordinates for a number of points and control points for these are estimated based on the relative positions of the two nodes and then these points are connected with each other using the shapes.Addcurve command to effectively draw a Bezier curve as a continuous freeform shape that represents the desired flow shape. I can provide the guides I have used to estimate the control points, but they link to another Excel forum and I am not sure if this is allowed by the rules of this forum. The guide I used to draw the Bezier lines is the following:

https://learn.microsoft.com/en-us/office/vba/api/excel.shapes.addcurve

Still, as you can see, once you press the button, the shape is drawn but with some “bumps” and the lower part of the shape is not drawn properly (possibly due to the shape inherently having an outline which messes the proper coordinates but I am not sure this is the case).

As such, I tried a slightly different method by drawing each part of the desired shape as a separate Bezier line (two curves and two straight lines). This can be achieved by pressing the “Separate lines” button. When this is done, a more properly shaped flow shape is created (using the exact same coordinates used by the “One shape” button), but the drawback in this case is that I cannot merge the 4 lines into a uniform shape which can then be filled with color and thus represent the flow shape that I am trying to achieve.
Therefore, I am looking for your help on two alternative solutions (either one will suffice):
  • Fix the resulting shape when the “One shape” button is pressed into a smooth one (no bumps).
  • Merge the 4 lines into a uniform shape that can properly filled with color when the “Separate lines” button is pressed.
The model used works as follows:
  • In cells I21 – M41 the coordinates for the existing manually drawn shapes are given. These are re-estimated each time a button is pressed (if the shapes are moved around).
  • In cells I43 – M69 the points for the four parts of the flow shape to be drawn are estimated. Each Bezier curve is made of 4 points (therefore 4 x’s and 4 y’s coordinates), lines only need two points.
  • The control points for each of the points estimated in the step above are calculated in the Sheets “Bezier curve A”, “Bezier line A”, “Bezier curve B” and “Bezier line B”.
  • Finally, in cells A28 – G52 the points and control points calculated in the steps above are collected for each part and then drawn onto the 1st sheet.
The buttons effectively perform steps 1. and 4.

Some notes to keep in mind:
  • The green flow shape already existing is manually drawn and only serves as a benchmark for the desired result.
  • You can move around the orange connector shape and then press either of the buttons that will dynamically provide a flow shape.
  • The file provided is reproduced from the original one I use at work. Therefore, the values in column N and the button “Initial Positions” were only used to try to reproduce the positions of the shapes from the original file, so you can ignore these.
  • In the original file, I managed to draw a shape with no bumps or other visible flows, as shown in the image attached but I could not reach the same result in the file provided and I am not sure why. Still, I provide this picture to show that the coordinates estimated by the model are correct and should not be the issue for any flaws in the drawing of the flow shape.
  • The values in column J are calculated manually to estimate the position of the points for the first Bezier curve and can be changed. Perhaps a different choice of values will fix the bumps of the flow.
Thank you so much in advance for your help, I am sorry for the long-windedness of the thread, I tried beforehand to address any possible questions you may had, I am at your disposal of course for any clarification needed.
 

Attachments

  • Sankey_FINAL.xlsm
    52.8 KB · Views: 2
  • IMG_20230409_170645.jpg
    IMG_20230409_170645.jpg
    37.6 KB · Views: 8
Abrasax
Please, reread and follow Forum Rules - those are for You too:
  • Cross-Posting. Generally, it is considered poor practice to cross post. That is to post the same question on several forums in the hope of getting a response quicker.
  • If you do cross-post, please put that in your post.
  • Also if you have cross-posted and get an Solution elsewhere, have the courtesy of posting the Solution here so other readers can learn from the answer also, as well as stopping people wasting their time on your answered question.
 
Abrasax
Please, reread and follow Forum Rules - those are for You too:
  • Cross-Posting. Generally, it is considered poor practice to cross post. That is to post the same question on several forums in the hope of getting a response quicker.
  • If you do cross-post, please put that in your post.
  • Also if you have cross-posted and get an Solution elsewhere, have the courtesy of posting the Solution here so other readers can learn from the answer also, as well as stopping people wasting their time on your answered question.

I apologize. It is my first time in general that I’m making threads in any forums and I was negligent in my inexperience to even assume this could be a problem.

The forums I have posted the question are the following:

VBFORUMS
EXCELFORUM
CHANDOO
MSOFFICEFORUMS
VBAEXPRESS

The reason I did the cross-posting was not to get results as fast as possible, but to get any result in general, as I assumed the problem I posed is a difficult one, considering the complex calculations needed to estimate proper control points. Just for reference, by the time I’m writing this message my posts have been viewed by almost 800 people across all forums and even though I have been offered some suggestions by some good people, of which I am grateful, I have yet to find a solution I can apply to my model.

I will also make sure to notify all the forums if anyone manages to suggest a practicable solution.

Please keep in mind the following which I believe holds some significance (at least to me): If a forum member manages to provide some solution I can apply to my model, I will be able to develop a Sankey diagram which more or less will be automated using only Excel, without the need of add-ins or other software and I will be more than happy to share this with the Excel/VBA community for further use by others.

Thank you for your interest and time.
 
Abrasax
Did You check my reply?

Each Forum has basic same kind of rules.
Those rules are good to read before the 1st posting.
Normally members puts links to those cross-posted threads - that no need to offer same reply than others.
Difficult - something could be more challenge for someone.
Your model - is it only possible way to solve it?
 
Abrasax
Could You use MSOAutoShapeType 76 or 103?

Thank you for your response vietm. If I understand the guide you provided correctly, the problem is whether I draw shapes 76 or 103 programatically, I can only manipulate the outer edges of the rectangle in which the shapes is in and not the actual points of the shape, as shown in the picture below:

83922

Additionally, I only know how to edit the actual points of the shape manually (as below), not programmatically, whic is what I need so that I may have an automated Sankey diagram based on the dynamic parameters it will have as inputs.

83923

Thank you.
 
Abrasax
Did You test it? ... or as You wrote ... understand?
If You overlap those above to shapes - what is difference? ... or if there are differences ... is it any/huge challenge?
... all shapes could do point-by-point - with some shapes, it could be smoother to use ready shapes.
One of Your challenge was that there were 'bumps' ... add more points, with using non rounded values.
 
Abrasax
Did You test it? ... or as You wrote ... understand?
If You overlap those above to shapes - what is difference? ... or if there are differences ... is it any/huge challenge?
... all shapes could do point-by-point - with some shapes, it could be smoother to use ready shapes.
One of Your challenge was that there were 'bumps' ... add more points, with using non rounded values.

I did try it. I can draw a shape 103 easily but because the coordinates I input affect the rectangle in which the actual shape is in and not the actual shape, this makes all the difefrence.

Consider the following: On the left part of the picture below is what I begin with, trying to connect the blue bar with the orange one using the green flow shape. Even if I manage to connect the right part of the flow shape to the orange bar propelry, as shown in the middle part of the picture, the left part of the flow shape is moved to a wrong position and no longer connects properly with the blue bar, because of its locked curvature. There is also the problem of how to do this programmatically considering the problem described above with the shape being placed in a rectangle. You can verify this using the file I attached in my initial post if you wish. My method solves this problem as shown in the right part of the picture, with the edges and the curvature of the flow shape properly manipulated to connect with both bars dynamically. The only issue are the bumps.

83924

What exactly do you mean when you say add more points, with using non rounded values? The model uses 4 points for each curved line: start, 2 mid points (for the curvature) and end. I have tried to introduce more mid points, but the problem with the bumps persists. A contributor from another forum has suggested that I should caluclate extra points/segments perpendicular to the problematic points to inverse the bumps, which makes sense but I don't know how to implement their idea with specific coordinates. I can provide a link to the post if you wish.

Thank you for your patience and time.
 
I apologize. It is my first time in general that I’m making threads in any forums and I was negligent in my inexperience to even assume this could be a problem.

The forums I have posted the question are the following:

VBFORUMS
EXCELFORUM
CHANDOO
MSOFFICEFORUMS
VBAEXPRESS

You are supposed to post links to the threads. Why links and not just a text list like you included above? To be courteous to people here who may otherwise waste their time and effort in duplicating help or advice you have already gotten elsewhere - like over on VBForums where your thread runs to about 15 posts, last I checked. This is basic courtesy and "I'm a novice..." only goes so far.

For others here:
 
Abrasax
I finally checked myself - how would #2 reply work with this?
> Please, if You need / would like to get answers then You should be ready to give answers too.
> You've skipped many questions.​
Seems that #2 won't be the best solution for this.​
... and I seems to missed Your used term Bezier curves
That's why my offer about add more points won't work with that term.​
... but it could use to draw smoother line around Your 'bezier-curve-shape'.​
Or it could use Excel's chart to do this.​

The Cross-Posting
  • If you do cross-post, please put that in your post.
In this case You ... means You Abrasax
(#5) Normally members puts links to those cross-posted threads - that no need to offer same reply than others.
I can provide a link to the post if you wish.​
> for me - Forum Rules and Common Sense - matters​
For me, in 90% of threads - Cross-Posting means delay to continue.​
Added one sample about 'more points' ...​
It shows - one way to improve bezier-curves-with-sankey-chart.​
There is also basic Excel-chart to show same.
Note: It won't show the way to solve those y-azes values.
 

Attachments

  • bezier.xlsb
    21.7 KB · Views: 7
Last edited:
Hi.

For anyone who may be interested in the problem I initially posted (automatically creating a Sankey diagram that represents a Profit and Loss Statement with VBA, by creating and manipulating wave shapes with the use of Bezier curves), I have managed to provide a solution, without directly using Bezier curves.

In the attached, the sheet Output provides the solution, by using the values in row 103 of the same sheet as the dimensions for each node and creating the proper link shapes that connect these nodes together, in the form of wave shapes. The code is run through Module1 and some comments are included in it in the form of steps (optionally Module2 can be run first which deletes all the existing shapes and then Module1 to create the Sankey diagram).

The sheet Graph simply contains an image of the result I got (given the values of my model) using the following website that provides a fully customizable solution, to compare it with my solution:


I think both results are very similar.

My solution can be customized to a certain extent (most importantly by allowing the height and the position of the nodes to be adjusted relatively easily), but the structure of the diagram (number of nodes and their hierarchy), as well as the way input values are structured (compared to the structure of values usually used for Sankey diagrams in the form of “Source” values and “Target” values) are not flexible. If anyone with more skill than me are willing they can improve the code (for example using loops and arrays to define each node and link dynamically) and perhaps even generalize it for any number of nodes and different hierarchies provided by a user. I might give it a try in the future.

In any case (and given the limitations of the methodology used), if anyone considers the code helpful I can provide some help if needed.

Thank you.
 

Attachments

  • Sankey v. FINAL.xlsm
    267.8 KB · Views: 0
I have posted in the msofficeforums forum about the solution, as for the rest of the forums on which I have cross-posted the problem (vbaexpress, excelforum and vbforums), they don't allow me to make new posts, so I can't inform them that the problem is solved.
 
Back
Top