Mercurial > octave-nkf
diff scripts/plot/__go_draw_figure__.m @ 11198:9f080d23396f
Fix multi-parented legends with the gnuplot backend (fixes #30461 and #31522)
author | David Bateman <dbateman@free.fr> |
---|---|
date | Sun, 07 Nov 2010 22:35:40 +0100 |
parents | f0e9befd6a1c |
children | d2f3a904ac6b |
line wrap: on
line diff
--- a/scripts/plot/__go_draw_figure__.m Sun Nov 07 11:51:36 2010 +0100 +++ b/scripts/plot/__go_draw_figure__.m Sun Nov 07 22:35:40 2010 +0100 @@ -44,57 +44,139 @@ else bg_is_set = false; endif + for i = nkids:-1:1 type = get (kids(i), "type"); switch (type) case "axes" if (strcmpi (get (kids (i), "tag"), "legend")) - continue; - endif + ## This is so ugly. If there was a way of getting + ## gnuplot to give us the text extents of strings + ## then we could get rid of this mess. + lh = getfield (get (kids(i), "userdata"), "handle"); + if (isscalar (lh)) + ## We have a legend with a single parent. It'll be handled + ## below as a gnuplot key to the axis it corresponds to + continue; + else + ca = lh(1); + ## Rely upon listener to convert axes position + ## to "normalized" units. + legend_axes_units = get (kids(i), "units"); + legend_axes_position = get (kids(i), "position"); + legend_axes_outerposition = get (kids(i), "outerposition"); + legend_axes_box = get (kids(i), "box"); + legend_axes_ylim = get (kids(i), "ylim"); + orig_axes_units = get (ca, "units"); + hlgnd = get (kids(i)); + + unwind_protect + set (ca, "units", "normalized"); + set (kids(i), "units", "normalized", "box", "off", + "ylim", [-2, -1], "position", get (ca(1), "position"), + "outerposition", get (ca(1), "outerposition")); - ## Rely upon listener to convert axes position - ## to "normalized" units. - orig_axes_units = get (kids(i), "units"); - orig_axes_position = get (kids(i), "position"); - unwind_protect - set (kids(i), "units", "normalized"); - fg = get (kids(i), "color"); - if (isnumeric (fg) && strcmp (get (kids(i), "visible"), "on")) - fprintf (plot_stream, "set obj 2 rectangle from graph 0,0 to graph 1,1 behind fc rgb \"#%02x%02x%02x\"\n", 255 * fg); - fg_is_set = true; - else - fg_is_set = false; - endif - if (bg_is_set) - fprintf (plot_stream, "set border linecolor rgb \"#%02x%02x%02x\"\n", 255 * (1 - bg)); + ## Create a new set of lines with the appropriate + ## displaynames, etc + toberm = []; + hobj = get (kids(i), "children"); + for j = numel (hobj) : -1 : 1 + if (! strcmp (get (hobj(j), "type"), "text")) + continue; + endif + displayname = get (hobj(j), "string"); + ll = []; + lm = []; + for k = numel (hobj) : -1 : 1 + if (! strcmp (get (hobj(k), "type"), "line")) + continue; + endif + if (get (hobj(j), "userdata") + != get (hobj(k), "userdata")) + continue; + endif + if (! strcmp (get (hobj(k), "linestyle"), "none")) + ll = hobj(k); + endif + if (! strcmp (get (hobj(k), "marker"), "none")) + lm = hobj(k); + endif + endfor + + if (! isempty (ll)) + if (!isempty (lm)) + toberm = [toberm, line("xdata",[0,0],"ydata",[0,0], "color", get(lm,"color"), "linestyle", get(ll,"linestyle"), "marker", get(lm,"marker"), "markeredgecolor", get(lm,"markeredgecolor"), "markerfacecolor", get(lm,"markerfacecolor"), "markersize", get (lm, "markersize"), "displayname", displayname, "parent", kids(i))]; + else + toberm = [toberm, line("xdata",[0,0],"ydata",[0,0], "color", get(ll,"color"), "linestyle", get(ll,"linestyle"), "marker", "none", "displayname", displayname, "parent", kids(i))]; + endif + elseif (! isempty (lm)) + toberm = [toberm, line("xdata",[0,0],"ydata",[0,0], "color", get(lm,"color"), "linestyle", "none", "marker", get(lm,"marker"), "markeredgecolor", get(lm,"markeredgecolor"), "markerfacecolor", get(lm,"markerfacecolor"), "markersize", get (lm, "markersize"), "displayname", displayname, "parent", kids(i))]; + endif + endfor + if (bg_is_set) + fprintf (plot_stream, "set border linecolor rgb \"#%02x%02x%02x\"\n", 255 * (1 - bg)); + endif + __go_draw_axes__ (kids(i), plot_stream, enhanced, mono, + bg_is_set, hlgnd); + unwind_protect_cleanup + ## Return axes "units" and "position" back to + ## their original values. + set (ca, "units", orig_axes_units); + set (kids(i), "units", legend_axes_units, + "box", legend_axes_box, + "ylim", legend_axes_ylim, + "position", legend_axes_position, + "outerposition", legend_axes_outerposition); + delete (toberm); + bg_is_set = false; + end_unwind_protect endif - ## Find if this axes has an associated legend axes and pass it - ## to __go_draw_axes__ - hlegend = []; - fkids = get (h, "children"); - for j = 1 : numel(fkids) - if (ishandle (fkids (j)) - && strcmp (get (fkids (j), "type"), "axes") - && (strcmp (get (fkids (j), "tag"), "legend"))) - udata = get (fkids (j), "userdata"); - if (! isempty (intersect (udata.handle, kids (i)))) - hlegend = fkids (j); - break; - endif + else + ## Rely upon listener to convert axes position + ## to "normalized" units. + orig_axes_units = get (kids(i), "units"); + orig_axes_position = get (kids(i), "position"); + unwind_protect + set (kids(i), "units", "normalized"); + fg = get (kids(i), "color"); + if (isnumeric (fg) && strcmp (get (kids(i), "visible"), "on")) + fprintf (plot_stream, "set obj 2 rectangle from graph 0,0 to graph 1,1 behind fc rgb \"#%02x%02x%02x\"\n", 255 * fg); + fg_is_set = true; + else + fg_is_set = false; + endif + if (bg_is_set) + fprintf (plot_stream, "set border linecolor rgb \"#%02x%02x%02x\"\n", 255 * (1 - bg)); endif - endfor - __go_draw_axes__ (kids(i), plot_stream, enhanced, mono, - bg_is_set, hlegend); - unwind_protect_cleanup - ## Return axes "units" and "position" back to - ## their original values. - set (kids(i), "units", orig_axes_units); - set (kids(i), "position", orig_axes_position); - bg_is_set = false; - if (fg_is_set) - fputs (plot_stream, "unset obj 2\n"); - endif - end_unwind_protect + ## Find if this axes has an associated legend axes and pass it + ## to __go_draw_axes__ + hlegend = []; + fkids = get (h, "children"); + for j = 1 : numel(fkids) + if (ishandle (fkids (j)) + && strcmp (get (fkids (j), "type"), "axes") + && (strcmp (get (fkids (j), "tag"), "legend"))) + udata = get (fkids (j), "userdata"); + if (isscalar(udata.handle) + && ! isempty (intersect (udata.handle, kids (i)))) + hlegend = get (fkids (j)); + break; + endif + endif + endfor + __go_draw_axes__ (kids(i), plot_stream, enhanced, mono, + bg_is_set, hlegend); + unwind_protect_cleanup + ## Return axes "units" and "position" back to + ## their original values. + set (kids(i), "units", orig_axes_units); + set (kids(i), "position", orig_axes_position); + bg_is_set = false; + if (fg_is_set) + fputs (plot_stream, "unset obj 2\n"); + endif + end_unwind_protect + endif case "uimenu" ## ignore uimenu objects otherwise