In my package dndTree I use htmlwidgets to render drag-and-drop diagonal trees as implemented here. I changed the original code to be one big function makeTree(treeData,el) where treeData is JSON (created from jsonlite) and el is the element passed in from HTMLWidgets.
In the examples I saw online the way for setting the size of the d3 block was:
var width = el.getBoundingClientRect().width;
var height = el.getBoundingClientRect().height;
var tree = d3.layout.tree()
.size([height, width]);
This method worked fine for making the graph in the RStudio viewer and even popping it out to the browser. However, when using the included Shiny hooks, the el.getBoundingClientRect().height returned 0 (I checked with a console.log(height);). The width responded appropriately using the shiny hooks but I couldn't do anything to get the height to respond to inputs.
I took it a step further back and in the file dndTree.js in the initialize step I included a console log:
initialize: function(el, width, height) {
console.log(height);
return{}
}
which also returned a 0 for height.
Ultimately I added another argument to the function that makes the tree, fHeight which, if the bounding rectangle reports a height of 0 sets the height to fHeight. This isn't a good solution though because now there are two apparent height controllers but only one works and it only works when supplying the number of pixels as a number.
Why does the el element have a height of 0 when using the default shiny hooks?
This is my first attempt at using htmlwidgets and I'll be very honest that I've never written d3 from scratch. I've been taking working examples and trying to make it into a usable widget. My package code is on github (https://github.com/bmewing/df2hjson), but hopefully the relevant nuggets here are enough to identify my mistakes.
Related
I'm trying to edit the data labels for a chart I'm writing on the slide. I can access the text of the datalabel using the methods available but as of yet the datalabel.fill is not existent. Any workarounds welcome if this is not planned on being added to the library in the future.
I've already gone through the source code in the github (https://github.com/scanny/python-pptx) but the datalabel class only has the font, has_text_frame, position, text_frame, _dLbl, _get_or_add_dLbl, _get_or_add_rich, _get_or_add_tx_rich, _get_or_add_txPr, and _remove_tx_rich methods. No fill or line fill methods is available.
The script I'm running does something similar for cells in a table:
cell.fill.solid()
cell.fill.fore_color.rgb = color_list[((col>0)*1)][i%2]
I'm looking at replicating the functionality on datalabels for chart series, with code that looks like this:
label.fill.solid()
label.fill.rgb = RGBColor(0x9B,0xBB,0x59)
label.fill.alpha = Alpha(.2)
label.line.fill.solid()
label.line.rgb = RGBColor(0xF0,0xF0,0x00)
The expected output xml should put the following for data labels:
<c:spPr>
<a:solidFill>
<a:srgbClr val="9BBB59">
<a:alpha val="80000"/>
</a:srgbClr>
</a:solidFill>
<a:ln>
<a:solidFill>
<a:schemeClr val="F0F000"/>
</a:solidFill>
</a:ln>
</c:spPr>
Actual output is non-existent as there is no method to do this directly.
This feature is not yet implemented, but if it was implemented it would be a .format property on the DataLabel object.
Typically users will work around an API gap like this by adding what we typically call a "workaround function" to the client code that manipulates the underlying XML directly, in this case, to add an <c:spPr> subtree in the right place.
python-pptx can generally get you close as far as a parent element is concerned. In this case, it can get you to the <c:dLbl> element like this:
data_label = chart.series[0].points[0].data_label
dLbl = data_label._dLbl
print(dLbl.xml)
The leading underscore in ._dLbl is your hint that you're getting into internals and if things don't go well it's something you're doing wrong, not an issue to be reported.
The dLbl object is an lxml.etree._Element object and can be manipulated with that API. If you have a search on "python-pptx workaround function" you'll find some examples for how to create new elements and put them where you want them.
The .xml property available on any python-pptx XML element object is handy for inspecting the results along the way. opc-diag can also be handy for inspecting PPTX files generated by PowerPoint or python-pptx for analysis or diagnostic purposes.
I am trying to understand how to use callbacks for the new Bokeh EditTools (e.g. BoxEditTool or similar).
Specifically, I would like to see on the server side the coordinates of the newly added rectangles, but I am not sure how to do this.
I am running the following server app
def app( curdoc ):
TOOLS = "tap"
p = figure(title="Some Figure", tools=TOOLS)
source = ColumnDataSource( {'xs':[1], 'ys':[1], 'width':[.1],'height':[.1]})
r = p.rect('xs','ys','width','height', source=source)
p.add_tools(BoxEditTool( renderers = [r]))
def cb( attr, old, new ):
print(r.data_source.data)
r.data_source.on_change("selected", cb)
curdoc.add_root(column(p))
I do get printout from the cb when I select different rectangles, but the r.data_source.data does not change
Thanks for the help!
The behaviour you're describing is actually a bug in the current distribution of Bokeh (0.13.0). You can read more in the google groups discussion. To summarize, there was a problem with the synchronization of the data at the server, it has been resolved and merged.
Note that the on_change method for the Rect glyph ColumnDataSource should watch the 'data' attribute and not 'selected'.
Other than that your snippet looks good, but if you want a working example you can look here. This code is under development but at this stage it reads images and allows drawing ROIs, as well as a simple mechanism for serializing and loading them.
Hope this helps!
In implementing an advanced shiny popup solution from K. Rohde, I've run into a problem using a navbarPage and tabPanels. Per the linked solution, the following code is in the appropriate tabPanel:
tabPanel("Multiple Locations",
uiOutput("script"),
tags$div(id="garbage"),
...rest of UI...
)
If Multiple Locations is the only tabPanel, or if navbarPage(selected="Multiple Locations") is set, everything works wonderfully (I have implemented nearly identically to the example in the linked solution). But if navbarPage(selected="someOtherPanel") is set, and the user subsequently navigates to the Multiple Locations tabPanel, the popups show up empty.
I've tried moving the uiOutput("script") and tags$div(id="garbage") lines into the other tabPanel (the one that's active on startup), I've tried moving it right under the navbarPage (before any tabPanel elements), and I've tried duplicating it in those locations as well, to no avail. Moving it right under the navbarMenu() appears to insert a div into the menu itself. Here's the setup that works:
ui<-navbarPage(id="page", selected="Multiple Locations",
tags$head(tags$link(href="myfavicon.ico", rel="icon"),
includeCSS("www/style.css"),
tags$script(type="text/javascript", src = "baranim.js")
),
navbarMenu("Explorer",
tabPanel("Single Location",
...UI elements...
),
tabPanel("Multiple Locations",
uiOutput("script"),
tags$div(id="garbage"),
...UI elements...
)
)
)
Though the app is not yet complete, I don't imagine I'll have users starting on the Multiple Locations tabPanel. But clearly, I'd still like the popups to function.
Many thanks to K. Rohde for the original solution.
First off, I really appreciate that you liked my post. This is very encouraging.
So I tried to reconstruct your situation and managed to reproduce the behavior you explained. My detective work showed, that you have another leaflet inside the Single Locations tab. Is that correct? The solution you linked was only designed for one single leaflet. It addresses the div of class leaflet-popup-pane, but if there are more than one, only the first one which is rendered, will be adressed. This explains the behavior with the tab choice in the beginning.
I have modified the script such that all available leaflet-popup-panes are addressed:
output$script <- renderUI({
tags$script(HTML('
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if(mutation.addedNodes.length > 0){
Shiny.bindAll(".leaflet-popup-content");
};
if(mutation.removedNodes.length > 0){
var popupNode = mutation.removedNodes[0].childNodes[1].childNodes[0].childNodes[0];
var garbageCan = document.getElementById("garbage");
garbageCan.appendChild(popupNode);
Shiny.unbindAll("#garbage");
garbageCan.innerHTML = "";
};
});
});
$(".leaflet-popup-pane").each(function() {
observer.observe(this, {childList: true});
});
'))
})
This should do the trick.
Some advice on placement: The garbage-div must only be placed once, to avoid duplicate Id problems. But it can be placed anywhere in the ui. If you have multiple leaflets with expanded popups, place one script output beneath each of those (or one beneath the last if there are several on the same page). Especially with tabPanels, this ensures that your leaflets have been fully rendered when the script is executed.
Please comment, if this doesn't solve your problem or if there is something I missed.
before mention, I Cant Speak Enginlish That very well
Recently I make Windows Desktop Application(On Windows7) using GDI+
I think Gdiplus::TextureBrush has a bug. I hope anyone found this bug like me.
that bug is like below
step1.
there is a image that has 500dpi, 6250 * 7819 size
step2
Loading the image by using Gdiplus::Image::FromStream()
the image name is "image1"
step3.
Creating Graphics graphics(HDC);
step3.
Creating Gdiplus::TextureBrush brush = Gdiplus::TextureBrush(image1);
step4
graphics.FillPath(brush);
currently everything is ok, you can see the right image on screen
step5
creating another Graphics from a bitmap
Graphics::Bitmap* bitmap = new Graphics::Bitmap(size.CX, size.CY), PixelFormat32bppARG);
Graphics* anotherGraphics = Gdiplus::Graphics::FromImage(bitmap);
step6 (Here Bug Occur)
anotherGraphics.DrawImage(image1);
and then detach the new image from anotherGraphics.
but new image is weird, new image like filled entirely by one pixel from the origin image
but next time, it never happens again..
only one time during the app life time
what is wrong....
Bitmap::FromStream method has second arg that is useEmbededColorManagement (not sure that is correct name anyway) I did put the True in it and then its working well. The arg looks like not related this bug.
I still don't know why its working but I solved this problem.
I generate an excel file using the great PHPExcel library. At this moment I need to show all the columns into a single page. You know the feeling when you have to scroll left and right up and down to see all the data. Basically I have 33 columns and I need to fit them on any display
I don't know if is my setup or where is the problem, but I can't make it work. This is the code I'm using
$objPHPExcel->getActiveSheet()->getPageSetup()->setFitToPage(true);
$objPHPExcel->getActiveSheet()->getPageSetup()->setFitToHeight(0);
$objPHPExcel->getActiveSheet()->getPageSetup()->setFitToWidth(1);
On MS Excel I select all thw colums then I choose View-> Zoom, then select Fit Selection. How can I do that programatically when excel file is generated with PHPExcel.
i hope i don't understand you wrong, here it goes:
phpExcel has an method called setZoomScalezoom(), however this does not auto fill the whole screen:
example:
$excel = new PHPExcel();
$sheet = $excel->getActiveSheet();
$sheet->getSheetView()->setZoomScale(300);
$writer = new PHPExcel_Writer_Excel5($excel);
$writer->save('test.xls');
got my information from:
source: http://typo3.org/extension-manuals/phpexcel_library/1.7.4/view/5/4/
Setting worksheet zoom level To set a worksheet’s zoom level, the
following code can be used:
$objPHPExcel->getActiveSheet()->getSheetView()->setZoomScale(75);
Note that zoom level should be in range 10 – 400.