How may I change the text in a RaphaelJS-created text node? First, I am creating a new element with a text string with Raphael, and at some later point I would like to change this text. It's easier for me if I do not have to reinitialize the element as there will be a whole host of attributes attached that will be a pain to recreate. Is there a way to do this? I've got my logic below, but it doesn't work; it's there just to provide extra insight as to what I'm trying to achieve.
Thanks
var R = Raphael("graph-o-matic", 1000, 1000);
var title = R.text( 10, 10, 'original text');
...
title.text.innerHTML = 'nifty new text here';
Try this:
title.attr({text: 'nifty new text here'});
Related
I'm very new to Oracle Apex and currently I want to use and customize Gantt charts. What I want to achieve it to show line breaks in the row-labels. Currently every newline character gets cut out and I am not sure where this happens and how I can prevent this.
The marked text contains newline characters. Don't be confused by the <br>, I just tests if this does the trick.
I just want to show more some information in the for each row. If there is another more elegant way, it would be very nice to give a tip.
Update:
I did some research and found a very nice example on a similar topic, in this case to create a custom tooltip https://youtu.be/2rZAIR_0tNg?t=2532.
I wanted to do the same thing for the row_axis label renderer, but nothing gets visualized.
The render function I use:
function custom_row_axis_label_renderer(data_context){
var row_axis_label_elem = document.createElement("g");
$("row_axis_label_elem").addClass("custom_row_axis_label");
row_axis_label_elem.innerHTML = '<text font-size="14px">Hello World</text>';
console.log(row_axis_label_elem);
return row_axis_label_elem;
}
The rendered element kind of exists, but it's get the size 0x0 from somewhere.
Am I missing something here?
Regards,
Nik
Meanwhile I found the solution on how to build a custom renderer. The main part I didn't new is that you NEED to pass x and y coordinates to have the new label to be rendered correctly. I found a proper example the the oracle forum, but unfortunately I can't find the link anymore to give credit to the original example.
Here is my code. It creates two text elements below each other to achieve a mocked line break and it adds a yellow icon. Of course you can use the data_context object to access the actual label. Add this part in the "Function and Global Variable Declaration
" part of your page:
custom_row_axis_label_renderer = function (data_context){
var row_axis_label_elem = document.createElementNS("http://www.w3.org/2000/svg", "g");
var upper_text = document.createElementNS("http://www.w3.org/2000/svg", "text");
var lower_text = document.createElementNS("http://www.w3.org/2000/svg", "text");
var icon_node = document.createElementNS("http://www.w3.org/2000/svg", "circle");
upper_text.textContent = "Hello";
upper_text.setAttribute("dominant-baseline","text-before-edge");
upper_text.setAttribute("class","oj-gantt-row-label");
upper_text.setAttribute("font-size","14px");
upper_text.setAttribute("text-anchor","end");
upper_text.setAttribute("x","220");
upper_text.setAttribute("y","5");
lower_text.textContent = "World";
lower_text.setAttribute("dominant-baseline","text-before-edge");
lower_text.setAttribute("class","oj-gantt-row-label");
lower_text.setAttribute("font-size","14px");
lower_text.setAttribute("text-anchor","end");
lower_text.setAttribute("x","220");
lower_text.setAttribute("y","25");
icon_node.setAttribute("cx","240");
icon_node.setAttribute("cy","25");
icon_node.setAttribute("r","8");
icon_node.setAttribute("class","u-color-7");
row_axis_label_elem.appendChild(upper_text);
row_axis_label_elem.appendChild(lower_text);
row_axis_label_elem.appendChild(icon_node);
return row_axis_label_elem;
}
Also you need to set the renderer of the row-axis-label. I also made the rows and task a little bit bigger to have enough space for two lines of text in the label. Add this in the "JavaScript Initialization Code" in the attriutes of you chart:
function( options ){
options.rowAxis.label = {renderer : custom_row_axis_label_renderer};
options.rowDefaults = {height : 60};
options.taskDefaults = {height: 40};
return options;
}
Update 2:
I am still fighting to get the Icon save on the server.
Here what I am doing:
Item item = Sitecore.Context.Database.GetItem(imageId);
var imageIconUrl = Sitecore.Resources.Images.GetThemedImageSource(item.Appearance.Icon, ImageDimension.id32x32);
if (!string.IsNullOrEmpty(imageIconUrl))
{
// download the icon from the url
var iconFullPath = "e:\\pngIcons\\excelIcon.png";
var webClient = new System.Net.WebClient();
var downloadPath = "http://serverName/" + imageIconUrl;
webClient.DownloadFile(downloadPath, iconFullPath);
}
The variable downloadPath contains following string:
http://serverName/sitecore/shell/themes/standard/~/media/E503BA48C89B422D8400393F1C7086A7.ashx?h=32&thn=1&w=32&db=master
At the end what I can see is a png file but there is nothing in it. I also copy the string I get in variable downloadPath and pasted it in browser and I can see the Icon as follow:
Please let me know what I am doing wrong. Or How I can save the Icon. Thanks!!
Original Question:
The sitecore media item has a field "Media". I am talking about this:
I want to access this field. And the reason is:
If I access it with e.g. item.GetMediaStream() then I will get the complete file. I just want to save this little icon some how on the server. Is it possible ?
To get the icon/thumbnail you can use
var icon = Sitecore.Resources.Media.MediaManager.GetThumbnailUrl(mediaItem);
To get the url of the thumbnail.
If you want the stream of the thumbnail you need to use the MediaData object. Like this:
var mediaItem = new MediaItem(item)
var mediaData = new MediaData(mediaItem);
var iconStream = mediaData.GetThumbnailStream();
if (iconStream.Length < 0)
{
// The stream is empty, its probably a file that Sitecore can't
// generate a thumbnail for. Just use the Icon
var icon = item.Appearance.Icon;
}
This will get the icon or thumbnail of the actual media blob that is attached to the media item. If you just want the icon of the Sitecore item, then use Martins method.
If the stream is empty, then Sitecore can't generate a thumbnail for it, so you can just use the icon file for the media item template. item.Appearance.Icon
Appearance section (of Standard Template) has a field called Icon - this is where you can modify icon for the item. There is also a field called Thumbnail - your excel icon is sitting there
You can access the field programmatically, just mind that it starts with two underscores: __Icon:
var iconField = item.Fields["__Icon"];
var thumbnailField = item.Fields["__Thumbnail"];
Update: As you asked, below is the code that saves either of fields into the file on a drive. I have tested the code and confirm successfully stores icon from thumbnail field into the file:
string mediaItemPath = "/sitecore/media library/Files/ExcelFile";
string mediaFiedlName = "Thumbnail"; // also can be "__Icon"
var item = Sitecore.Context.Database.GetItem(mediaItemPath);
var iconField = item.Fields[mediaFiedlName];
if (iconField.HasBlobStream)
{
var thumb = (ImageField)iconField;
var bl = ((MediaItem)thumb.MediaItem).InnerItem.Fields["blob"];
Stream stream = bl.GetBlobStream();
byte[] buffer = new byte[8192];
using (FileStream fs = File.Create("D:\\you_file_name.ico")) // change your path
{
int length;
do
{
length = stream.Read(buffer, 0, buffer.Length);
fs.Write(buffer, 0, length);
}
while (length > 0);
fs.Flush();
fs.Close();
}
}
Update 2: If that does not help then I would advise to look around the way how that icon gets generated on Media field in Sitecore. In the worst case you may do the following - right click that icon and see its url. You will have something similar to what I assign to variable below:
string url = "http://test81/sitecore/shell/Applications/-/media/B4F61650CBE84EE396649602C0C48E1B.ashx?bc=White&db=master&h=128&la=en&mw=640&thn=1&vs=1&ts=b8046903-ae57-4f9d-9dd5-b626ee5eee90";
Of course your URL should have your hostname and media prefix and the rest of parameters. Then use Webclient with that modified URL:
WebClient webClient = new WebClient();
webClient.DownloadFile(url, "e:\\you_file_name.ico");
Not ideal, but may work. Note, that the code above should work in a context of already logged user, so you need to authorise you Webclient prior that (many articles on S.O. how to do that).
Please reply if that approach has worked for you (I've spent decent time writing and testing that code in debugger, so would want to know whether that helped)
Wondering if someone might help with another pair of eyes - as I am trying to work out why some of my Famo.us 'Views' are being displayed despite having an opacity StateModifier set to '0'.
Here is my code - My apologies for it not being standard - I have "Panels" instead of "Views" and a few other things..but happy to expand on the code if needed.
function _buildSidePanel() {
this._sidePanel = _createPanel.call(this);
this._sidePanel.setOptions(this.constructor.DEFAULT_OPTIONS.sideMenu);
this._sidePanel.position = this.cm(this.constructor.DEFAULT_OPTIONS.sideMenu.position);
this._container.add(this._sidePanel.position).add(this._sidePanel);
this._menuHolder = _createPanel.call(this); //My version of a View
this._menuHolder.setOptions(this.constructor.DEFAULT_OPTIONS.sideMenu.menuHolder);
// Create StateModifiers
this._menuHolder.position = this.cm({ align: [.5,.6], origin: [.5,.6], proportions: [.9,.8] });
this._menuHolder.fadeState = this.cm({ opacity: 0 });
this._menuHolder.sizeState = this.cm();
this._menuHolder.mC = new ModifierChain();
this._menuHolder.mC.addModifier(this._menuHolder.fadeState);
this._menuHolder.mC.addModifier(this._menuHolder.sizeState);
this._menuHolder.mC.addModifier(this._menuHolder.position);
/* Tried splitting it to just modifiers but getting the same thing
this._sidePanel._container.add(this._menuHolder.fadeState)
.add(this._menuHolder.sizeState)
.add(this._menuHolder.position)
.add(this._menuHolder);
*/
this._sidePanel._container.add(this._menuHolder.mC).add(this._menuHolder);
// this._menuHolder.fadeState.setOpacity(1,this.constructor.DEFAULT_OPTIONS.sideMenu.menuHolder.transition.in);
}
I have created a ModifierChain and added among other things an Opacity State of 0. When I add this and then add the modifier and 'View' to the container it displays the View even though the View has a StateModifier of '0' so should not be displayed.
The 'fadeState.setOpacity' command is meant to transition the fadeState to display the View but it is commented out, so the View should not be displayed.
I have this working in other areas so know the approach works. I am also (hopefully) not using the same variable names, so not using a StateModifier more than once. But still stuck as to why this is being displayed.
Any help or thoughts would be gratefully appreciated.
Thanks.
I want to set the line spacing of a QTextEdit.
It's no problem to get that information with
QFontMetrics::lineSpacing();
But how to set that?
I tried with StyleSheets, but that didn't work:
this->setStyleSheet("QTextEdit{ height: 200%; }");
or
this->setStyleSheet("QTextEdit{ line-height: 200%; }");
Partial solution:
Well, I've found a solution - not the way I wanted it, but at least it's simple and it gives nearly my intended behavior, enough for my proof of concept.
On every new line there's some linespacing. But if you just type until the text is automatically wrapped to a new line you wont have line-spacing between this two lines. This hack only works with text blocks, see the code.
Just keep in mind it's brute force and a ugly hack. But it provides some kind of line-spacing to your beautiful QTextEdit. Call it everytime your text changes.
void setLineSpacing(int lineSpacing) {
int lineCount = 0;
for (QTextBlock block = this->document()->begin(); block.isValid();
block = block.next(), ++lineCount) {
QTextCursor tc = QTextCursor(block);
QTextBlockFormat fmt = block.blockFormat();
if (fmt.topMargin() != lineSpacing
|| fmt.bottomMargin() != lineSpacing) {
fmt.setTopMargin(lineSpacing);
//fmt.setBottomMargin(lineSpacing);
tc.setBlockFormat(fmt);
}
}
}
The QFontMetrics contains (per the name) static properties that come from the font file. How wide a capital "C" is, etc. lineSpacing() gets you the natural distance in single-spacing that the person who designed the font encoded into the font itself. If you actually wanted to change that (you don't)...the somewhat complicated story of how is told here:
http://fontforge.sourceforge.net/faq.html#linespace
As for the line spacing in a QTextEdit...it looks (to me) like that is seen as one of the things that falls under Qt's extensibility model for specifying text "layouts":
http://doc.qt.io/qt-4.8/richtext-layouts.html
You would supply your own layout class to the QTextDocument instead of using the default. Someone tried it here but did not post their completed code:
http://www.qtcentre.org/threads/4198-QTextEdit-with-custom-space-between-lines
I know this is an old question, but I've spent a lot of time today trying to solve this for PyQt5 5.15.2. I'm posting my solution in case it is useful to others. The solution is for Python, but should be easily transferable.
The following code will change the line height to 150% for a populated QTextEdit widget in one go. Further editing will pick up the current block format, and continue applying it. I've found it to be very slow for large documents though.
textEdit = QTextEdit()
# ... load text into widget here ...
blockFmt = QTextBlockFormat()
blockFmt.setLineHeight(150, QTextBlockFormat.ProportionalHeight)
theCursor = textEdit.textCursor()
theCursor.clearSelection()
theCursor.select(QTextCursor.Document)
theCursor.mergeBlockFormat(blockFmt)
Applying blockformat to entire document rather than each line works.
QTextBlockFormat bf = this->textCursor().blockFormat();
bf.setLineHeight(lineSpacing, QTextBlockFormat::LineDistanceHeight) ;
this->textCursor().setBlockFormat(bf);
I have translated Jadzia626's code to C++ and it works. Here is the information about setLineHeight()
qreal lineSpacing = 35;
QTextCursor textCursor = ui->textBrowser->textCursor();
QTextBlockFormat * newFormat = new QTextBlockFormat();
textCursor.clearSelection();
textCursor.select(QTextCursor::Document);
newFormat->setLineHeight(lineSpacing, QTextBlockFormat::ProportionalHeight);
textCursor.setBlockFormat(*newFormat);
I have a weird problem that I can't seem to solve. I've got a JList which has to be able to scroll if there are more items in it then can be displayed. However if I put the JList in a JScrollPane, it doesn't utilise the full height of the EAST part of the BorderLayout it's in.
Example without JScrollPane:
public UsersPanel(){
String[] userList = new String[]{"Foo","Bar","Foo","Bar","Foo","Bar","Foo","Bar","Foo","Bar","Foo","Bar","Foo","Bar"};
JList users = new JList(userList);
add(users);
}
Example with JScrollPane:
public UsersPanel(){
String[] userList = new String[]{"Foo","Bar","Foo","Bar","Foo","Bar","Foo","Bar","Foo","Bar","Foo","Bar","Foo","Bar"};
JList users = new JList(userList);
JScrollPane sp = new JScrollPane(users);
add(sp);
}
I want a JList that utilises the full available height of the EAST part of the BorderLayout it's in. I've tried wrapping my JList inside another JPanel, but that doesn't solve my problem either.
use setVisibleRowCount() method to set number of visible rows in Jlist.
users.setVisibleRowCount(10);
One hack that I've used successfully before is to add a ComponentListener to parent component of the JList / JScrollPane, and as it changes reset the preferred size of the JList and/or Jscrollpane via (pseudo-code) setPreferredSize(getPreferredSize().width, parentHeight)