terrastruct / d2

D2 is a modern diagram scripting language that turns text to diagrams.
https://d2lang.com
Mozilla Public License 2.0
16.51k stars 414 forks source link

proposal: support shape of mind map #768

Open skyhee opened 1 year ago

skyhee commented 1 year ago

I think it's a important feature

alixander commented 1 year ago

related: https://github.com/terrastruct/d2/discussions/261

if someone wants to do this as a layout plugin (which we have good support for), I will help review and merge. But there's too many higher priority things to do for this to get a slot in a release cycle in the near or even medium-term future (unless some enterprise customer wants us to do it).

bo-ku-ra commented 1 year ago

uncool, but.. https://play.d2lang.com/?script=vFPNasQgEL7PUwzsuUs3yclCX6VoaqAgmBp7KCXvXibqNLVOAj3sTeab8ftx5GAVBnIPcHH6039EWKIOUeHXZkTh-BZGZ9dUxodnXKKdb-XQlUNfDgONkr5rDkfhI03b-SYinYj0ItLmgcumk_kAcfL-x83y7l6iNs4-YRqmfVEY7OsKiEaHRuuaLpHAOprr5H1dMjo0uqjK_kWlsrCmhwOlG3hIcjZ51mJ0OEkqW-f9yWn9KafEWt0yIl91OJNx2L9Lzbh_rf5-e5Xl8yfjtKpy8VfM_hpg4cP_1oykAPPwP2ctVZnovgMAAP__&layout=dagre&

alixander commented 1 year ago

lol damn that's not bad

bo-ku-ra commented 1 year ago

that's not bad

proposal: shape:mindmap

shape:mindmap

start +foo ++foo ++bar +++foo +++bar ++++foo ++++bar ++foobar ++foofoo ++barbar +++foobar ++foofoobarbar +bar +foobar ++foobarfoobar

+ step1

++ step2

+++ step3

++++ step4

++++....+++ stepX


d2(convert-> compile->output) -> (https://github.com/terrastruct/d2/issues/768#issuecomment-1420139034)

alixander commented 1 year ago

nah i don't think we need anything more than a shape: mind_map. just needs to force bezier curve connections and tune the spacing. can probably make ELK and TALA do this in a good session or so.

bo-ku-ra commented 1 year ago

okay but you may need to fix the problem with han-fonts.(#517, #513, #749) because double-byte characters (incl. japanese) can't use sql_table title.

bo-ku-ra commented 1 year ago

i didn't spend much time on making...

-- mindmap.txt ----------------------------------------- start +foo ++foo ++bar +++foo +++bar ++++foo ++++bar ++foobar ++foofoo ++barbar +++foobar ++foofoobarbar +bar +foobar ++foobarfoobar -- mindmap.txt -----------------------------------------

conv_mindmap.pl (perl_script)

# open ------------------------
open(FILE, "mindmap.txt");
@lines = <FILE>;
close(FILE);

my $max = 0;
my $d2_source = "direction:right\n";

foreach(@lines){
s/\x0d//g; s/\x0a//g;
my $container = $str = $_;
my $str = $_;
my $count = ($str =~ s/(\+)/$1/g); #('+' * n)
  if ($max < $count){ $max = $count; }

$container =~ s/^\++//;
$stl_table .= sprintf("%05d.%s\n",$count, $container);
}

# layout -------------------------
for (my $i = 0; $i <= $max; $i++){
$d2_source .= sprintf("%05d{style.opacity:0;}\n",$i);
$connector .= sprintf("%05d->",$i);
}
$connector =~ s/->$/{style.opacity:0;}\n/;
$d2_source .= "${connector}\n";

# mindmap ------------------------
my @step = ();
foreach( split("\n", $stl_table)){
  $_ =~ /([0-9]+)\.(.*)/;
  my $count = $1;
 @step[$count] = $_;
 if($count == 0){
   $d2_source .= sprintf("%s{shape:oval;}\n", $_);
   next;
 } else {
   $d2_source .= sprintf("%s{shape:sql_table;}\n", $_);
   $d2_source .= sprintf ("%s->%s\n", @step[($count - 1)], $_);
 }
}
# save ------------------------
open(FILE, ">mindmap.d2");
printf FILE "$d2_source";
close(FILE);

-- mindmap.d2 ------------------------------------- direction:right 00000{style.opacity:0;} 00001{style.opacity:0;} 00002{style.opacity:0;} 00003{style.opacity:0;} 00004{style.opacity:0;} 00000->00001->00002->00003->00004{style.opacity:0;} 00000.start{shape:oval;} 00001.foo{shape:sql_table;} 00000.start->00001.foo 00002.foo{shape:sql_table;} 00001.foo->00002.foo 00002.bar{shape:sql_table;} 00001.foo->00002.bar 00003.foo{shape:sql_table;} 00002.bar->00003.foo 00003.bar{shape:sql_table;} 00002.bar->00003.bar 00004.foo{shape:sql_table;} 00003.bar->00004.foo 00004.bar{shape:sql_table;} 00003.bar->00004.bar 00002.foobar{shape:sql_table;} 00001.foo->00002.foobar 00002.foofoo{shape:sql_table;} 00001.foo->00002.foofoo 00002.barbar{shape:sql_table;} 00001.foo->00002.barbar 00003.foobar{shape:sql_table;} 00002.barbar->00003.foobar 00002.foofoobarbar{shape:sql_table;} 00001.foo->00002.foofoobarbar 00001.bar{shape:sql_table;} 00000.start->00001.bar 00001.foobar{shape:sql_table;} 00000.start->00001.foobar 00002.foobarfoobar{shape:sql_table;} 00001.foobar->00002.foobarfoobar -- mindmap.d2 ------------------------------------- https://play.d2lang.com/?l=&script=jJJBC8IwDIXv-y-OufY0wb8iHehpMOyKl-F_lyZpu1SS1UvhmW8v77W52MnH8N0Qfzt8uKdU03D7gn4V9FHQjaBbQR8ud7DBY8TD4CEy_RacDzvUPa0ft6Rl-9e6kry9l0dw8_LkENnFQcyhIDBFix2A2fkWYHYeG1EcYIoyZwejODAgOVjFwRTAZgerODAgOUD8xtw4WbD2flnF7S2zok-q43XXe7bbHufpX5msnl5B1H3_H2x9G-d3kuNypPsFAAD__w%3D%3D&

bo-ku-ra commented 1 year ago

https://play.d2lang.com/?l=&script=jJJBC8IwDIXv-y-OufY0wb8iHehpMOyKl-F_lyZpu1SS1UvhmW8v77W52MnH8N0Qfzt8uKdU03D7gn4V9FHQjaBbQR8ud7DBY8TD4CEy_RacDzvUPa0ft6Rl-9e6kry9l0dw8_LkENnFQcyhIDBFix2A2fkWYHYeG1EcYIoyZwejODAgOVjFwRTAZgerODAgOUD8xtw4WbD2flnF7S2zok-q43XXe7bbHufpX5msnl5B1H3_H2x9G-d3kuNypPsFAAD__w%3D%3D&

playground 0.1.6 -> ok 0.2.0(now) -> api error

alixander commented 1 year ago

@bo-ku-ra D2 0.2.0 has a new keyword, which changes the encoding, which makes the previously encoded playground URLs not work anymore. That is unfortunate, but I'm okay with the loss of backwards compatibility of these links until 1.0.

The same script still works:

https://play.d2lang.com/?script=jJJBC8IwDIXv-y-OufY0wb8iHehpMOyKl-F_lyZpu1SS1UvhmW8v77W57MnHQroh_nb4cE8Zp-H2Bf0q6KOgG0G3gj5c7mCDx4iHwUNk-i04H3bofFo_bknL9q91JXl7L4_g5uXJIbKLg5hDQWCKFjsAs_MtwOw8NqI4wBRlzg5GcWBAcrCKgymAzQ5WcWBAcoD4jblxsmDt_bKK21tmRZ9Ux-uu92y3Pc7TvzJZPb2CqPv-P9j6Ns7vJMflSPcLAAD__w%3D%3D&

bo-ku-ra commented 1 year ago

https://play.d2lang.com/?script=jJJBC8IwDIXv-y-OufY0wb8iHehpMOyKl-F_lyZpu1SS1UvhmW8v77W5sMnHZN0Qfzt8vKd9p-H2Bf0q6KOgG0G3gj5c7mCDx4iHwUNk-i04H3ZocVo_bknL9q91JXl7L4_g5uXJIbKLg5hDQWCKFjsAs_MtwOw8NqI4wBRlzg5GcWBAcrCKgymAzQ5WcWBAcoD4jblxsmDt_bKK21tmRZ9Ux-uu92y3Pc7TvzJZPb2CqPv-P9j6Ns7vJMflSPcLAAD__w%3D%3D&

bo-ku-ra commented 1 year ago

mermaid is easy to write.

mindmap
  root((mindmap))
    foo
        foo
        bar
            foo
            bar
                foo
                bar
        foobar
        foofoo
        barbar
            foobar
        foofoobarbar
    bar
    foobar
        foobarfoobar
mindmap
  root((mindmap))
    foo
        foo
        bar
            foo
            bar
                foo
                bar
        foobar
        foofoo
        barbar
            foobar
        foofoobarbar
    bar
    foobar
        foobarfoobar

d2 sample (my perl script generated this.)

vars:"mindmap.pl" {
  d2-config: {theme-id: 0; dark-theme-id: 0; pad: 0; center: false; sketch: false; layout-engine: dagre}
}
# ----------------------------------------------------------------------
# COLORS
# ----------------------------------------------------------------------
classes: {
  PINK: {style.font-color: hotpink; style.stroke: hotpink; style.fill: lavenderblush; style.border-radius: 8;}
  BLUE: {style.font-color: blue; style.stroke: blue; style.fill: lightsteelblue; style.border-radius: 8;}
  PURPLE: {style.font-color: purple; style.stroke: purple; style.fill: lavender; style.border-radius: 8;}
  _RED: {style.font-color: red; style.stroke: red}
  _PINK: {style.font-color: hotpink; style.stroke: hotpink;}
  _BLUE: {style.font-color: blue; style.stroke: blue}
  _PURPLE: {style.font-color: purple; style.stroke: purple}
  ~RED: {style.font-color: mistyrose; style.stroke: mistyrose; style.fill: red; style.border-radius: 8;}
  ~PINK: {style.font-color: lavenderblush; style.stroke: lavenderblush; style.fill: hotpink; style.border-radius: 8;}
  ~BLUE: {style.font-color: lightsteelblue; style.stroke: lightsteelblue; style.fill: blue; style.border-radius: 8;}
  ~PURPLE: {style.font-color: lavender; style.stroke: lavender; style.fill: purple; style.border-radius: 8;}
  ~GRAY: {style.font-color: gainsboro; style.stroke: gainsboro; style.fill: dimgray; style.border-radius: 8;}
}
# ----------------------------------------------------------------------
style: {fill-pattern: lines;}
# ----------------------------------------------------------------------
direction:right
00000:""{ style.opacity:0 }
00001:""{ style.opacity:0 }
00002:""{ style.opacity:0 }
00003:""{ style.opacity:0 }
00004:""{ style.opacity:0 }
00000->00001->00002->00003->00004{ style.opacity:0 }

00000."start"{ shape:oval; style.bold: true; style.font-size: 16; style.stroke-width: 5; class:~GRAY }
00001."foo"{ height:1; style.bold: true; class:~BLUE }
00000."start" -- 00001."foo" {class:_BLUE}
00002."foo"{ height:1; class:BLUE }
00001."foo" -- 00002."foo" {class:_BLUE}
00002."bar"{ height:1; class:BLUE }
00001."foo" -- 00002."bar" {class:_BLUE}
00003."foo"{ height:1; class:BLUE }
00002."bar" -- 00003."foo" {class:_BLUE}
00003."bar"{ height:1; class:BLUE }
00002."bar" -- 00003."bar" {class:_BLUE}
00004."foo"{ height:1; class:BLUE }
00003."bar" -- 00004."foo" {class:_BLUE}
00004."bar"{ height:1; class:BLUE }
00003."bar" -- 00004."bar" {class:_BLUE}
00002."foobar"{ height:1; class:BLUE }
00001."foo" -- 00002."foobar" {class:_BLUE}
00002."foofoo"{ height:1; class:BLUE }
00001."foo" -- 00002."foofoo" {class:_BLUE}
00002."barbar"{ height:1; class:BLUE }
00001."foo" -- 00002."barbar" {class:_BLUE}
00003."foobar"{ height:1; class:BLUE }
00002."barbar" -- 00003."foobar" {class:_BLUE}
00002."foofoobarbar"{ height:1; class:BLUE }
00001."foo" -- 00002."foofoobarbar" {class:_BLUE}
00001."bar"{ height:1; style.bold: true; class:~PINK }
00000."start" -- 00001."bar" {class:_PINK}
00001."foobar"{ height:1; style.bold: true; class:~PURPLE }
00000."start" -- 00001."foobar" {class:_PURPLE}
00002."foobarfoobar"{ height:1; class:PURPLE }
00001."foobar" -- 00002."foobarfoobar" {class:_PURPLE}

https://play.d2lang.com/?l=&script=rJZNi9swEIbv_hWD9-yQxGkpYyj0YymloRtS9tBTUWIlMfEXsrMQTPLbiyQ7a9mS1muSi4nG8z6jmdeW-SK6SZSGCckneexC5QCEc2-bpbtoj1CVB5pQLwoRpgGEhB09ZSUn8rqlaUkZwo7EBQ2gONJye7j9jck5O5UeTfdRShFCsmf04lycB_Du8nMe4NvT8mn9536KtcdQNGT18_cvhEo0fvJqHIRDVuZRegxAhuSUesvcdAgxeaF8GJv4VByakGJuhE_BxQH4unx-1OI28Yl2We21GsSNWpSUxu2YlrR6Xq-WelZ-Ynnco6mr6saspH_rx-9aDqNhF8JoKFLGtl0kv7uJEjmuITz3atphEhXlmWVFL7cXkP1sdUTbyquxL1qLNTRtUBI7_dRTjQ3V--2G1UYl901_Xi3z6Nquu08VpU5PD_ux_vJXi9qTKC02Gcu6rF5AwsIo2TNyttDu-O4TDISqfczxtqe0CO6IuZ2vyPhEnSn_oetW9SbrIw6ncBGxmSU2t8R8S2xhiU29zwIrL3N58eVloUuSWRO3KAkruSw_jTF7IfHr3OIQoWQt2zafCgizj6oZ5NmM8CEAcXagsFPTjIm7yzK3AvkVgTMdok7jz1mzp6Y68Dxo6UAl7xUvubqlfYK8pyXXZNdic5vYhrD3ivEUjZg_oLImuxbzjZX5AyrrixkqWwyozFfFFsbKFgMq64sZKpOjGTGDOssoOc4jVpuMc4rVLANH3LfMW3sfV66Sq5Gf9UdvfLr52W15uhUCv7dd03CIODXtLxGVJBI63jMOQpFvqXVtaKL8DwAA__8%3D&

alixander commented 1 year ago

wow very nice.

i don't like mermaid's personally. tab-delimited syntax constrains how large and readable it is past a small example. won't handle multi-line nodes easily. makes no sense to me

bo-ku-ra commented 1 year ago

if it will be a huge mindmap, then it is a bad root theme. in any case, if you don't like tab-delimited syntax, i wait for others ideas.

mrsimb commented 10 months ago

We already have curly braces syntax for defining containers, it can be reused for mindmaps:

GamingDevices: {
  shape: mindmap

  Consoles: {
    Microsoft: {
      XSS
      XSX
    }
    Sony: {
      PS4
      PS5
    }
  }
  Handhelds: {
    Valve: {
      SteamDeck
    }
    ASUS: {
      RogAlly
    }
    GPD: {
      Win4
      WinMini
    }
  }
}

All sub-containers of a mindmap should inherit mindmap shape by default unless we specify otherwise