Graphviz: how to make a timeline / rank in one row - layout
I am trying to create a timeline of mergers in the Dutch energy sector. I am using rank=same to force nodes to remain on the same year. However, the timeline backs up on itself, so that nodes in the "past" are in the same column as "1993".
How can I force the years to remain neatly in one row and the corresponding nodes in separate columns?
digraph energy_mergers {
ranksep=0.05
rankdir=LR
{
node [shape=plaintext, fontsize=8];
/* the time-line graph */
{past [shape=plaintext, fontsize=26]}
-> 1987 -> 1988 -> 1989
-> {1990 [shape=plaintext, fontsize=26]} -> 1991 -> 1992 -> 1993
-> 1994 -> 1995 -> 1996
-> 1997 -> 1998 -> 1999
-> {2000 [shape=plaintext, fontsize=26]} -> 2001 -> 2002
-> 2003 -> 2004
-> 2005 -> 2006 -> 2007
-> {2008 [shape=plaintext, fontsize=26]}
}
node [shape=box];
{ rank=source; past; "Obragas"; "Haarlemmermeer"; "NRE"; "SEP"; "EZH"; "GEB Den Haag"; "GEB Dordrecht"; "GEB Rotterdam"; "Vlaardingen/Maassluis"; "ERL"; "Delfland" ; "Weert"; "EMH"; "GZO"; "GMK"; "EZK"; "GNOF"; "Amstelland"; "ONS"; "GCN"; "PUEM"; "GEB Utrecht"; "PEGUS"; "PEN"; "GEB Amsterdam"; "GKNH"; "EZW"; "GEB Haarlem"; "REGEV"; "GAMOG"; "GGR"; "EWR"; "Centraal Overijssel"; "RENDO"; "VNB"; "ZGN"; "PEB Friesland"; "PGEM"; "EGD"; "Ijsselmij"; "Salland"; "GAZO"; "Frigem"; "Westergo"; "Westland"; "Maastricht"; "Heerlen"; "Limagas" ; "PLEM"; "RNH"; "PNEM"; "PZEM"; "Intergas"}
{ rank=same; 1987; "REMU"; "EPON"; "EPZ"}
{ rank=same; 1988; "EZH_1988" [label="EZH"]; "UNA"}
{ rank=same; 1991; "DELTA" [label="DELTA"]}
{ rank=same; 1992; "Ijsselmij_1992" [label="Ijsselmij"];
"MEGA"}
{ rank=min; 1993; "NUON_1993" [label="NUON"];
"EDON";
"PNEM"}
{ rank=same; 1994; "NUON_1994" [label="NUON"]}
{ rank=same; 1995; "ENECO_1995" [label="ENECO"];
"ENW"}
{ rank=same; 1997; "PNEM/MEGA"}
{ rank=same; 1998; "TenneT_1998" [label="TenneT"];
"ENW_1998" [label="ENW"];
"EDON_1998" [label="EDON"];
}
{ rank=same; 1999; "TZH_1999" [label="TZH"];
"Preussen_1999" [label="Preussen\nElektra"];
"REMU_1999" [label="REMU"];
"Electrabel";
"Essent_1999" [label="Essent"];
"NUON_1999" [label="NUON"];
}
{ rank=same; 2000; "RWE_2000" [label="RWE"]; "E.On_2000" [label="E.On"];
"ENECO_2000" [label="ENECO"];
"Reliant" [label="Reliant Energy"];
"Essent_2000" [label="Essent"]}
{ rank=same; 2003; "ENECO_2003" [label="ENECO"];
"NUON_2003" [label="NUON"];}
{ rank=same; 2005; "E.On_2005" [label="E.On"];
}
{ rank=same; 2006; "Electrabel_2006" [label="Electrabel"]}
{ rank=same; 2008; "RWE_2008" [label="RWE"]; "NRE/ObN-NetH";
"TenneT_2008" [label="TenneT"];
"E.On_2008" [label="E.On"];
"ENECO_2008" [label="ENECO"];
"Stedin_2008" [label="Stedin"];
"Liander_2008" [label="Liander"];
"NUON_2008" [label="NUON"];
"Cogas_2008" [label="Cogas"];
"RENDO_2008" [label="RENDO"];
"Electrabel_2008" [label="Electrabel"];
"Essent Netwerk_2008" [label="Essent Netwerk"];
"Essent_2008" [label="Essent"];
"EPZ_2008" [label="EPZ"];
"DELTA_2008" [label="Delta"];
"DELTA Netwerkbeheer_2008" [label="Delta\nNetwerkbeheer"];
"Intergas_2008" [label="Intergas"];
"DONG_2008" [label="DONG"];
}
//Splitsingspunten zonder naam
node [shape=point];
{ rank = same; 1997; "EDON_1997" [label=""];}
{ rank = same; 1998; "EZH_1998" [label=""];
"ENECO_1998" [label=""];
"PNEM/MEGA_1998" [label="PNEM/MEGA"]}
{ rank = same; 2000; "EPZ_2000" ;}
{ rank = same; 2001; "NUON_2001" ;}
{ rank = same; 2003; "TenneT_2003" [label=""];}
{ rank = same; 2005; "NRE_2005" [label=""];
"Intergas_2005" [label=""];
"Essent_2005" [label=""];}
{ rank = same; 2006; "Cogas_2006" [label=""];
"RENDO_2006"; "EN_2006"; "Essent_2006"}
{ rank = same; 2007; "RWE_2007" [label=""];
"ENECO_2007" [label=""];
"NUON_2007" [label=""];
"DELTA_2007" [label=""]}
/* Wellicht anders dan origineel 1 lijn voor combinatie levering/netbeheer */
/* Beheer van gas- en/of elektriciteitsnetten */
edge [color=blue];
"Obragas" -> "RWE_2000"
"Haarlemmermeer" -> "RWE_2000"
"RWE_2000" -> "RWE_2007"
"RWE_2007" -> "NRE/ObN-NetH"
"NRE" -> "NRE/ObN-NetH"
"EZH" -> "EZH_1988" [label="150 kV-net Zuid-Holland"]
"EZH_1988" -> "EZH_1998" -> "TZH_1999" -> "TenneT_2003"
//ENECO/Stedin
"GEB Den Haag" -> "ENECO_1995"
"GEB Dordrecht" -> "ENECO_1995"
"GEB Rotterdam" -> "ENECO_1995"
"Vlaardingen/Maassluis" -> "ENECO_1995"
"ERL" -> "ENECO_1998"
"ENECO_1995" -> "ENECO_1998" -> "ENECO_2000" -> "ENECO_2003" -> "ENECO_2007"
"ENECO_2007" -> "Stedin_2008"
"Delfland" -> "ENECO_2000"
"Weert" -> "ENECO_2000"
"EMH" -> "ENECO_2000"
"GZO" -> "ENECO_2000"
"GMK" -> "ENECO_2000"
"EZK" -> "ENECO_2000"
"GNOF" -> "ENECO_2000"
"Amstelland" -> "ENECO_2000"
"ONS" -> "ENECO_2007"
"GCN" -> "REMU_1999"
"PUEM" -> "REMU"
"GEB Utrecht" -> "REMU" -> "REMU_1999" -> "ENECO_2003"
//NUON
"PEN" -> "ENW"
"GEB Amsterdam" -> "ENW"
"GKNH" -> "ENW"
"EZW" -> "ENW"
"GEB Haarlem" -> "ENW" -> "ENW_1998"
"REGEV" -> "ENW_1998" -> "NUON_1999"
"GAMOG" -> "NUON_1999"
"GGR" -> "NUON_2001"
"EWR" -> "NUON_1999"
"VNB" -> "NUON_1994"
"ZGN" -> "NUON_1994"
"PEB Friesland" -> "NUON_1993"
"PGEM" -> "NUON_1993" -> "NUON_1994" -> "NUON_1999" -> "NUON_2001" -> "NUON_2003"
"NUON_2003" -> "NUON_2007" -> "Liander_2008"
//Overig
"Centraal Overijssel" -> "Cogas_2008"
"RENDO" -> "RENDO_2008"
"Intergas" -> "Intergas_2005" -> "Intergas_2008"
"PZEM" -> "DELTA" -> "DELTA_2007" -> "DELTA Netwerkbeheer_2008"
//RWE/Essent
"EGD" -> "EDON" -> "EDON_1997" -> "EDON_1998" -> "Essent_1999" -> "Essent_2000"
"Essent_2000" -> "Essent_2005" -> "EN_2006" -> "Essent Netwerk_2008"
"Ijsselmij" -> "Ijsselmij_1992"
"Salland" -> "Ijsselmij_1992"
"GAZO" -> "Ijsselmij_1992" -> "EDON"
"Frigem" -> "EDON_1997"
"Westergo" -> "EDON_1998"
"Westland" -> "EN_2006"
"Maastricht" -> "Essent_2000"
"Heerlen" -> "PNEM/MEGA_1998"
"Limagas" -> "MEGA"
"PLEM" -> "MEGA" -> "PNEM/MEGA" -> "PNEM/MEGA_1998" -> "Essent_1999"
"RNH" -> "PNEM_1993" -> "PNEM/MEGA"
"PNEM" -> "PNEM_1993"
edge [color=blue,style=bold];
"SEP" -> "TenneT_1998" [label="Landelijk koppelnet (220kV/380kV)"]
"TenneT_1998" -> "TenneT_2003" -> "TenneT_2008"
/* Levering (verkoop) van gas- en/of elektriciteit aan particulieren */
edge [color=green];
"Obragas" -> "RWE_2000"
"Haarlemmermeer" -> "RWE_2000"
"RWE_2000" -> "RWE_2007"
"RWE_2007" -> "RWE_2008"
"NRE" -> "NRE_2005" -> "E.On_2005"
"E.On_2005" -> "E.On_2008"
//ENECO/Stedin
"GEB Den Haag" -> "ENECO_1995"
"GEB Dordrecht" -> "ENECO_1995"
"GEB Rotterdam" -> "ENECO_1995"
"Vlaardingen/Maassluis" -> "ENECO_1995"
"ERL" -> "ENECO_1998"
"ENECO_1995" -> "ENECO_1998" -> "ENECO_2000" -> "ENECO_2003" -> "ENECO_2007"
"ENECO_2007" -> "ENECO_2008"
"Delfland" -> "ENECO_2000"
"Weert" -> "ENECO_2000"
"EMH" -> "ENECO_2000"
"GZO" -> "ENECO_2000"
"GMK" -> "ENECO_2000"
"EZK" -> "ENECO_2000"
"GNOF" -> "ENECO_2000"
"Amstelland" -> "ENECO_2000"
"ONS" -> "ENECO_2007"
"GCN" -> "REMU_1999"
"PUEM" -> "REMU"
"GEB Utrecht" -> "REMU" -> "REMU_1999" -> "ENECO_2003"
//NUON
"PEN" -> "ENW"
"GEB Amsterdam" -> "ENW"
"GKNH" -> "ENW"
"EZW" -> "ENW"
"GEB Haarlem" -> "ENW" -> "ENW_1998"
"REGEV" -> "ENW_1998" -> "NUON_1999"
"GAMOG" -> "NUON_1999"
"GGR" -> "NUON_2001"
"EWR" -> "NUON_1999"
"VNB" -> "NUON_1994"
"ZGN" -> "NUON_1994"
"PEB Friesland" -> "NUON_1993"
"PGEM" -> "NUON_1993" -> "NUON_1994" -> "NUON_1999" -> "NUON_2001" -> "NUON_2003"
"NUON_2003" -> "NUON_2007" -> "NUON_2008"
//RWE/Essent
"EGD" -> "EDON" -> "EDON_1997" -> "EDON_1998" -> "Essent_1999" -> "Essent_2000"
"Essent_2000" -> "Essent_2005" -> "Essent_2006"
"Ijsselmij" -> "Ijsselmij_1992"
"Salland" -> "Ijsselmij_1992"
"GAZO" -> "Ijsselmij_1992" -> "EDON"
"Frigem" -> "EDON_1997"
"Westergo" -> "EDON_1998"
"Westland" -> "Essent_2006" -> "Essent_2008"
"Maastricht" -> "Essent_2000"
"Heerlen" -> "PNEM/MEGA_1998"
"Limagas" -> "MEGA"
"PLEM" -> "MEGA" -> "PNEM/MEGA" -> "PNEM/MEGA_1998" -> "Essent_1999"
"RNH" -> "PNEM_1993" -> "PNEM/MEGA"
"PNEM" -> "PNEM_1993"
//Overig
"Centraal Overijssel" -> "Cogas_2006" -> "Electrabel_2006"
"RENDO" -> "RENDO_2006" -> "Electrabel_2006" -> "Electrabel_2008"
"Intergas" -> "Intergas_2005" -> "DONG_2008"
"PZEM" -> "DELTA" -> "DELTA_2008"
/* Grootschalige productie van elektriciteit in Nederland */
edge [color=red];
"GEB Den Haag" -> "EZH_1988"
"GEB Dordrecht" -> "EZH_1988"
"GEB Rotterdam" -> "EZH_1988"
"EZH_1988" -> "EZH_1998" -> "Preussen_1999" -> "E.On_2000" -> "E.On_2005" -> "E.On_2008"
"PEGUS" -> "UNA"
"PEN" -> "UNA"
"GEB Amsterdam" -> "UNA" -> "Reliant" -> "NUON_2003" -> "NUON_2007" -> "NUON_2008"
"PEB Friesland" -> "EPON"
"PGEM"-> "EPON"
"EGD"-> "EPON"
"Ijsselmij"-> "EPON" -> "Electrabel" -> "Electrabel_2006" -> "Electrabel_2008"
"PLEM" -> "EPZ"
"RNH" -> "EPZ"
"PNEM" -> "EPZ"
"PZEM" -> "EPZ" -> "EPZ_2000" -> "EPZ_2008"
"EPZ_2000" -> "Essent_2000" [label="Centrales van N-Brabant \nen Limburg naar\nEssent"]
"Essent_2000" -> "Essent_2008"
}
I found I could correct the problem by replacing:
{ rank=min; 1993; "NUON_1993" [label="NUON"];
"EDON";
"PNEM"}
... with:
{ rank=same; 1993; "NUON_1993" [label="NUON"];
"EDON";
"PNEM_1993" [label="PNEM"]}
It seems that because PNEM had the same rank as Past, using rank=min in along with PNEM moved 1993 back to the same rank as Past.
Related
wl_display#1.error(wl_display#1, 0, "invalid object 3")
I'm new to wayland, today I wrote a simple wayland server/client sample, but got some error, please help! what I expected is client draw a buffer and commit, then server got this buffer and present to screen by gl/egl. main part of server: wl_display_add_socket .... template <class T> void DestroyUserData(wl_resource* resource) { TakeUserDataAs<T>(resource); } void compositor_create_surface(wl_client* client, wl_resource* resource, uint32_t id) { wl_resource* surface_resource = wl_resource_create( client, &wl_surface_interface, wl_resource_get_version(resource), id); wl_resource_set_implementation(surface_resource, &surface_implementation, nullptr, DestroyUserData<T>); } const struct wl_compositor_interface compositor_implementation = { compositor_create_surface, compositor_create_region}; const uint32_t compositor_version = 3; void bind_compositor(wl_client* client, void* data, uint32_t version, uint32_t id) { wl_resource* resource = wl_resource_create(client, &wl_compositor_interface, std::min(version, compositor_version), id); wl_resource_set_implementation(resource, &compositor_implementation, data, nullptr); } wl_global_create(wl_display_.get(), &wl_compositor_interface, compositor_version, display_, bind_compositor); wl_event_loop_dispatch .... and others and main part of client: void Simple::Run(int frames, PresentationFeedback* feedback) { wl_callback_listener frame_listener = {FrameCallback}; wp_presentation_feedback_listener feedback_listener = { FeedbackSyncOutput, FeedbackPresented, FeedbackDiscarded}; Presentation presentation; int frame_count = 0; std::unique_ptr<wl_callback> frame_callback; bool frame_callback_pending = false; do { if (frame_callback_pending) continue; if (frame_count == frames) break; Buffer* buffer = DequeueBuffer(); if (!buffer) continue; SkCanvas* canvas = buffer->sk_surface->getCanvas(); static const SkColor kColors[] = {SK_ColorRED, SK_ColorBLACK}; canvas->clear(kColors[++frame_count % arraysize(kColors)]); if (gr_context_) { gr_context_->flush(); glFinish(); } wl_surface_set_buffer_scale(surface_.get(), scale_); wl_surface_set_buffer_transform(surface_.get(), transform_); wl_surface_damage(surface_.get(), 0, 0, surface_size_.width(), surface_size_.height()); wl_surface_attach(surface_.get(), buffer->buffer.get(), 0, 0); // Set up the frame callback. frame_callback_pending = true; frame_callback.reset(wl_surface_frame(surface_.get())); wl_callback_add_listener(frame_callback.get(), &frame_listener, &frame_callback_pending); // Set up presentation feedback. Frame frame; frame.feedback.reset( wp_presentation_feedback(globals_.presentation.get(), surface_.get())); wp_presentation_feedback_add_listener(frame.feedback.get(), &feedback_listener, &presentation); frame.submit_time = base::TimeTicks::Now(); presentation.submitted_frames.push_back(std::move(frame)); wl_surface_commit(surface_.get()); wl_display_flush(display_.get()); } while (wl_display_dispatch(display_.get()) != -1); if (feedback) *feedback = presentation.feedback; } set WAYLAND-DEBUG on, then start server and client, client report an error, and all the debug info: [137355.232] -> wl_display#1.get_registry(new id wl_registry#2) [137355.241] -> wl_display#1.sync(new id wl_callback#3) [137355.527] wl_display#1.delete_id(3) [137355.550] wl_registry#2.global(1, "wl_compositor", 3) [137355.558] -> wl_registry#2.bind(1, "wl_compositor", 3, new id [unknown]#4) [137355.575] wl_registry#2.global(2, "wl_shm", 1) [137355.589] -> wl_registry#2.bind(2, "wl_shm", 1, new id [unknown]#5) [137355.619] wl_registry#2.global(3, "zwp_linux_dmabuf_v1", 2) [137355.624] -> wl_registry#2.bind(3, "zwp_linux_dmabuf_v1", 1, new id [unknown]#6) [137355.628] wl_registry#2.global(4, "wl_subcompositor", 1) [137355.633] -> wl_registry#2.bind(4, "wl_subcompositor", 1, new id [unknown]#7) [137355.638] wl_registry#2.global(5, "wl_shell", 1) [137355.675] -> wl_registry#2.bind(5, "wl_shell", 1, new id [unknown]#8) [137355.697] wl_registry#2.global(6, "wl_output", 2) [137355.702] wl_registry#2.global(7, "zcr_vsync_feedback_v1", 1) [137355.726] wl_registry#2.global(8, "wp_presentation", 1) [137355.732] -> wl_registry#2.bind(8, "wp_presentation", 1, new id [unknown]#9) [137355.770] wl_registry#2.global(9, "zcr_alpha_compositing_v1", 1) [137355.781] wl_callback#3.done(0) [137355.943] -> wl_shm#5.create_pool(new id wl_shm_pool#3, fd 11, 262144) [137355.983] -> wl_shm_pool#3.create_buffer(new id wl_buffer#10, 0, 256, 256, 1024, 0) [137356.038] -> wl_shm#5.create_pool(new id wl_shm_pool#11, fd 12, 262144) [137356.045] -> wl_shm_pool#11.create_buffer(new id wl_buffer#12, 0, 256, 256, 1024, 0) [137356.081] -> wl_compositor#4.create_surface(new id wl_surface#13) [137356.096] -> wl_compositor#4.create_region(new id wl_region#14) [137356.100] -> wl_region#14.add(0, 0, 256, 256) [137356.106] -> wl_surface#13.set_opaque_region(wl_region#14) [137356.112] -> wl_region#14.destroy() [137356.114] -> wl_shell#8.get_shell_surface(new id wl_shell_surface#15, wl_surface#13) [137356.120] -> wl_shell_surface#15.set_title("Wayland Client") [137356.125] -> wl_shell_surface#15.set_toplevel() [137356.425] -> wl_surface#13.set_buffer_scale(1) [137356.431] -> wl_surface#13.set_buffer_transform(0) [137356.434] -> wl_surface#13.damage(0, 0, 256, 256) [137356.455] -> wl_surface#13.attach(wl_buffer#10, 0, 0) [137356.479] -> wl_surface#13.frame(new id wl_callback#16) [137356.498] -> wp_presentation#9.feedback(wl_surface#13, new id wp_presentation_feedback#17) [137356.518] -> wl_surface#13.commit() [137356.768] wl_display#1.error(wl_display#1, 0, "invalid object 3") wl_display#1: error 0: invalid object 3 [137356.871] -> wl_shm_pool#11.destroy() [137356.902] -> wl_buffer#12.destroy() [137356.913] -> wl_shm_pool#3.destroy() [137356.957] -> wl_buffer#10.destroy() [137356.965] -> wl_subcompositor#7.destroy() [137356.967] -> zwp_linux_dmabuf_v1#6.destroy() [137356.969] -> wp_presentation#9.destroy() [137356.972] -> wl_surface#13.destroy() server log: [3513445.412] wl_display#1.get_registry(new id wl_registry#2) [3513445.422] -> wl_registry#2.global(1, "wl_compositor", 3) [3513445.430] -> wl_registry#2.global(2, "wl_shm", 1) [3513445.434] -> wl_registry#2.global(3, "zwp_linux_dmabuf_v1", 2) [3513445.439] -> wl_registry#2.global(4, "wl_subcompositor", 1) [3513445.442] -> wl_registry#2.global(5, "wl_shell", 1) [3513445.446] -> wl_registry#2.global(6, "wl_output", 2) [3513445.450] -> wl_registry#2.global(7, "zcr_vsync_feedback_v1", 1) [3513445.454] -> wl_registry#2.global(8, "wp_presentation", 1) [3513445.457] -> wl_registry#2.global(9, "zcr_alpha_compositing_v1", 1) [3513445.461] wl_display#1.sync(new id wl_callback#3) [3513445.465] -> wl_callback#3.done(0) [3513445.467] -> wl_display#1.delete_id(3 [3513446.767] wl_registry#2.bind(1, "wl_compositor", 3, new id [unknown]#4) [3513446.786] wl_registry#2.bind(2, "wl_shm", 1, new id [unknown]#5) [3513446.794] -> wl_shm#5.format(875709016) [3513446.797] -> wl_shm#5.format(875708993) [3513446.799] -> wl_shm#5.format(1) [3513446.801] -> wl_shm#5.format(0) [3513446.803] wl_registry#2.bind(3, "zwp_linux_dmabuf_v1", 1, new id [unknown]#6) [3513446.808] -> zwp_linux_dmabuf_v1#6.format(909199186) [3513446.811] -> zwp_linux_dmabuf_v1#6.format(875709016) [3513446.813] -> zwp_linux_dmabuf_v1#6.format(875708993) [3513446.815] -> zwp_linux_dmabuf_v1#6.format(875713112) [3513446.817] -> zwp_linux_dmabuf_v1#6.format(875713089) [3513446.819] -> zwp_linux_dmabuf_v1#6.format(842094158) [3513446.821] -> zwp_linux_dmabuf_v1#6.format(842094169) [3513446.823] wl_registry#2.bind(4, "wl_subcompositor", 1, new id [unknown]#7) [3513446.829] wl_registry#2.bind(5, "wl_shell", 1, new id [unknown]#8) [3513446.840] wl_registry#2.bind(8, "wp_presentation", 1, new id [unknown]#9) [3513446.845] -> wp_presentation#9.clock_id(1) [3513446.848] wl_shm#5.create_pool(new id wl_shm_pool#3, fd 235, 262144) [3513446.855] -> wl_display#1.error(wl_display#1, 0, "invalid object 3")
how made token of || in alex
I'm new at Haskell and Alex. I'm trying to make tokens of operators in Lexer.x here is an example of my code \<= { \s -> TLE } \== { \s -> TEQ } \/= { \s -> TNEQ } \&& { \s -> TAND } but when I wrote \|| { \s -> TOR } I got a parse error on this line How I should make token for || ?
You can use string literals to prevent escaping all characters, so you can use: "||" { \s -> TOR }
Spring Integration Flow Log on Outbound success
how can I add logs if file is transferred successfully. I want to log file name and some values form my config object return IntegrationFlows.from(Sftp.inboundAdapter(inboundSftp) .localDirectory(this.getlocalDirectory(config.getId())) .deleteRemoteFiles(true) .autoCreateLocalDirectory(true) .remoteDirectory(config.getInboundDirectory()), e -> e.poller(Pollers.cron("0 */1 * ? * *").errorChannel(MessageHeaders.ERROR_CHANNEL).errorHandler((ex) -> { try { // exception handling here }))) .handle(Sftp.outboundAdapter(outboundSftp) .useTemporaryFileName(false) .autoCreateDirectory(true) .remoteDirectory(config.getOutboundDirectory()), c -> c.advice(startup.deleteFileAdvice()) ) .get(); Update after Gary Russell answer, my working code is return IntegrationFlows.from(Sftp.inboundAdapter(inboundSftp) .localDirectory(this.getlocalDirectory(config.getId())) .deleteRemoteFiles(true) .autoCreateLocalDirectory(true) .remoteDirectory(config.getInboundDirectory()), e -> e.poller(Pollers.cron("0 */1 * ? * *").errorChannel(MessageHeaders.ERROR_CHANNEL).errorHandler((ex) -> { // action on exceptions are here }))).publishSubscribeChannel(s -> s .subscribe(f -> f .handle(Sftp.outboundAdapter(outboundSftp) .useTemporaryFileName(false) .autoCreateDirectory(true) .remoteDirectory(config.getOutboundDirectory()), c -> c.advice(startup.deleteFileAdvice()) )) .subscribe(f -> f .handle(m -> { // all my custom logging logic is here }) )) .get();
Add a .publishSubscribeChannel() channel with 2 subflows. Docs here. .publishSubscribeChannel(s -> s .subscribe(f -> f .handle(...) .subscribe(f -> f .log())
implementation interfaces in golang
I want to implement the interface shown below. I don't know how to begin. Can someone show me how the functions should be implemented? package interval package main type Interval interface { contains(r float64) bool // if r is in x, then true average(Y Intervall) (Intervall, error) String() string //cast interval"[a,b]" to [a,b] completecontains(Y Intervall) bool //if y is completely in x, give true New(a, b float64) Intervall //var a int } type Complex struct { first int } func (c Complex) contains(r float64) bool { if a <= r <= b { return true } else { return false } } func (c Complex) String() string { return "a" } func (c Complex) length() float64 { return 2.3 } func main() { }
I can't really tell what you are actually trying to do here, but there were several issues with the code a and b were not defined, I added them to complex to get it to compile a <= r <= b is not valid in go, changed that You had a main, so I assume that you meant this to be the runnable app. Package needs to be called "main" for it to be directly runnable. May not be what you want, but it now compiles and runs (but doesn't do anything since main is empty) Here it is on play package main //import "fmt" type Intervall interface { contains(r float64) bool // if r is in x, then true average(Y Intervall) (Intervall, error) String() string //cast interval"[a,b]" to [a,b] completecontains(Y Intervall) bool //if y is completely in x, give true New(a, b float64) Intervall } type Complex struct { first int a float64 b float64 } func (c Complex) contains(r float64) bool { if c.a <= r && r <= c.b { return true } else { return false } } func (c Complex) String() string { return "a" } func (c Complex) length() float64 { return 2.3 } func main() { }
Not sure why the concrete interval is called "Complex" or what the average of two intervals might be, but this is as close as I can get. Also, not sure what the benefit of using an interface is here. http://play.golang.org/p/sxFRkJZCFa package main import "fmt" type Interval interface { Contains(r float64) bool Average(y Interval) (Interval, error) String() string CompletelyContains(y Interval) bool CompletelyContainedBy(y Interval) bool } type Complex struct { a, b float64 } func (c Complex) Contains(r float64) bool { return c.a <= r && r <= c.b } func (c Complex) Average(y Interval) (Interval, error) { return nil, fmt.Errorf("What the heck is the average of two intervals?") } func (c Complex) CompletelyContains(y Interval) bool { return y.CompletelyContainedBy(c) } func (c Complex) CompletelyContainedBy(y Interval) bool { return y.Contains(c.a) && y.Contains(c.b) } func (c Complex) String() string { return fmt.Sprintf("[%v,%v]", c.a, c.b) } func main() { var x Interval = Complex{a: 1, b: 5.1} var y Interval = Complex{a: 1.3, b: 5} fmt.Println("x contains 3:", x.Contains(3)) fmt.Println("x completely contains y:", x.CompletelyContains(y)) avg, err := x.Average(y) fmt.Println("Average of x and y:", avg, "with error:", err) fmt.Println("x:", x) } Edit: Here's a sillily complex way of implementing "Average" the way you want it. The complexity comes from avoiding directly accessing y.a and y.b, which would defeat the purpose of using an interface (if there is one). http://play.golang.org/p/Tc5YCciLWq
Force GraphViz force distance between nodes
I use GraphViz with the following dot file: digraph G { rankdir=LR; subgraph commits { "5c071a6b2c" -> "968bda3251" -> "9754d40473" -> "9e59700d33" -> "2a3242efa4"; } subgraph annotations { "V1.0" [shape=box]; "br/HEAD" [shape=box]; "V1.0" -> "9e59700d33" [weight=0]; "br/HEAD" -> "2a3242efa4" [weight=0]; } } It give me something like that: But I want something like that: V1.0 br/HEAD | | \/ \/ 5c071a6b2c -> 968bda3251 -> 9754d40473 -> 9e59700d33 -> 2a3242efa4 How can I do that? For your help, Thanks by advance.
This will align the annotations with the commits: digraph G { rankdir=LR; subgraph commits { "5c071a6b2c" -> "968bda3251" -> "9754d40473" -> "9e59700d33" -> "2a3242efa4"; } subgraph annotations1 { rank="same"; "V1.0" [shape=box]; "V1.0" -> "9e59700d33" [weight=0]; } subgraph annotations2 { rank="same"; "br/HEAD" [shape=box]; "br/HEAD" -> "2a3242efa4" [weight=0]; } } Since the rank="same"; effects the whole subgraph I had to split the annotations in two different subgraphs. Result is: