What is the best way of showing a very long text (in MBs) using ui-scroll ? The text is available in the form of an array but needs to be displayed as a long text document just like a textarea. I'm using ui-scroll as each word in the text is a clickable anchor tag.
Is ui-scroll-td to display each word as a column and lines as row the only way ?
More Information
I have a large array containing > 2000 elements (words) which can be
changed by user dynamically (both the number of elements and the
element itself).
I need to display these elements as a single document where each element (word) is a hyperlink which when clicked performs certain action.
I need it to look like a simple scrollable div which has these words displayed as long free flowing clickable text.
I was using $compile earlier to create html dynamically but the initial compile time and the compile upon element change is very significant (seconds) as I have to compile/render the whole list of elements every single time.
So I thought of using ui-scroll to display which virtualizes and renders only the displayed content.
But ui-scroll always display each element in a separate line like a row which is not the desired behavior for my use case.
Input:
myList = ["Hello", "World", "This", "is", "my", "first", "dream"].
desired Output (each word in same line with auto wrap just like a div):
<div>
<span ng-repeat="w in myList">
<a ng-click="someAction()">myList[$index]</a>
</span>
</div>
Hello World This is my first dream
ui-scroll:
<div>
<span ui-scroll="at in info">
<a id="at-{{$index}}" ng-click="someAction($index, $event)">
myList[$index]}}
</a>
</span>
</div>
ui-scroll output (each word in separate line):
Hello
World
This
is
my
first
dream
Kindly note that each word above is a clickable anchor.
Thanks.
Unfortunately, this is completely impossible with the angular-ui-scroll as it does not support inline/floating elements. There were some attempts to implement this feature in 2015, but now it seems frozen forever.
Infinite approach
The case you are developing is very interesting. As a possible workaround I would advise to try "infinite" approach instead of "virtualizing" one. Infinite scroll could be implemented with no additional libraries, the idea could be broken into following steps:
add N words into the viewport initially
if viewport's scrollHeight === clientHeight, add N more words; make a loop until the scrollbar appears
listen for viewport's scrollTop changing, invoke following when scroll happens
if scrollTop + clientHeight === scrollHeight add N more words; also in a loop until the height of the viewport (scrollHeight) increases or until words are over
This should drastically reduce the cost of the initial render, but since the elements out of the view are not being destroyed, the overall performance will decrease per each new elements injection.
Virtualization
After the "infinite" approach is implemented, I think you may try to turn this particular infinite scroll case into virtual one. Let's think what might be required. First, you'll need two additional elements, say, top and bottom padding elements, which will emulate virtual words. Then you will need to extend the last step of the "infinite" approach by following:
look into the opposite direction and find the first element that is visible in the viewport; this could be done in multiple ways (here and hundreds of other links)
remember scrollHeight, clip off all the elements before the found one, set the height of the top padding element into remembered value to make the the result scrollHeight the same as before clipping
depends on the environment/requirements you also might need to correct scroll position as it might jump up during clipping; I would like not to discuss back-jumping here, just be happy with the default overflow-anchor behaviour (though you'll have to forget about Edge and other sad guys)
the condition scrollTop + clientHeight === scrollHeight in our handler (say, "if we are at the very bottom") should be reconsidered as we may have non-zero bottom padding element; so it should be like "if we are at the very bottom OR if the bottom padding element becomes visible"
if the condition above is fulfilled, you need to add N words again and again until the bottom padding becomes invisible again, and each injection should be accomplished with decreasing of the bottom padding element's height by the value the viewport's scrollHeight is increased with; and only the edge case when "we are at the very bottom" will cause the irrevocable increasing of the viewport's scrollHeight
This way we will properly cover downward scrolling. You obviously will need to take into account upward scrolling and run the similar procedure when "the top padding becomes visible OR we are at the very top". Also the "we are at very top/bottom" and "element becomes visible" conditions could be extended with some UX-friendly deltas, say, "we are almost at..." and "the element is almost visible".
I don't think this plan covers or should cover all possible edge cases and requirements, it's just an idea how this could be done from scratch, and my guess is it's the only way you have, I mean the complete implementation by yourself. I would be happy if I'm wrong and would love to look at someone's ready-made solution.
Related
I am working on a page where there are two rows in the header.
The first row has a "My Account" icon, Company Logo, and Logout.
The second row has a navigation bar.
When the Focus Ring/Focus Indicator highlights an item on the first row, the bottom of the focus ring is cut off by the navigation bar in the second row.
I am not allowed to change the spacing of the elements on the DOM.
Is there a way I can change the layering so that all of the elements on the page are not changed in size or location, but the Focus Ring is not cut off by the navigation bar?
The site built with React.
I've tried googling a number of things, but haven't turned up much specific to this issue.
I'm a little new to programming (my first job, first year). I'm not totally sure where to even start.
You are looking for z-index. The second element is positioned in front of the first element and so it covers the focus indicator.
This allows you to specify how far 'forward' elements are on the page.
Assuming nothing is using fixed or absolute position within the <div>s you are working on this should solve your issue.
i.e.
<div class="container">
<div id="behind" z-index="1"></div>
<div id="infront" z-index="0"></div> <!--The z-index is not really needed here so try without it first, it is to illustrate that the item in front at the moment should have a lower z-index than the one at the back-->
</div>
You may need to play with the z-index in order to get this to work (you can go to 999999 without a problem, but try and use as low a number as possible).
You may also have to fiddle with heights of elements if the site is poorly designed but without a code example I can only offer general advice and gotcha's
Without a code example it is difficult to suggest a solution, but it sounds like your two rows are overlapping, and thereby hiding part of the focus indicator.
Three different solutions come to mind,
Change the height and placement of the two rows to avoid the overlap in the first place
Try using the CSS z-index property to control which element is rendered foremost
Using the CSS outline-offset property, with a negative value, i.e. -5px, to shrink the focus indicator and hopefully making it visible
I'm using the SpanLabel Component, but on the screen the text content does not occupying the full width when text size is lower
Someone can help please?
This can happen if the width isn't deterministic. The SpanLabel won't be able to reflow and at best will cause only its own Container to resize. There are two solutions:
Deterministic hierarchy - this is generally best but not always possible
Use TextArea - sometimes this works around the issue by reducing the hierarchy depth.
Deterministic layout means that the size of the elements is determined in a clear way by the hierarchy. E.g. BoxLayout.Y is deterministic on the X axis as it gives the components on the X axis all available space. FlowLayout isn't deterministic as it gives components their preferred size.
Some layouts can go back and forth and vary in determinism based on their axis.
This is important because when we layout the components we go from top down. So we go through the Form to its children asking each for their preferred size. If at this point the SpanLabel doesn't know its size it can give the wrong value and we can't really fix that later as we don't reflow the UI. Reflow would create a potential infinite loop and a performance problem at best.
We try to workaround some of this behavior by making a revalidate() call within TextArea but that has its limits. If the hierarchy is too deep the preferred size is already set and won't adapt. SpanLabel is just a Container with a TextArea and a Label (for the icon). So by only using a TextArea you'd slightly simplify the hierarchy and it sometimes might be enough. E.g.
TextArea t = new TextArea(myText);
t.setEditable(false);
t.setFocusable(false);
t.setUIID("Label");
I am currently attempting to write a control(s) that will display a collection of elements, each of which have a start time between 0 and 1. The desired visual look we're aiming for is something akin to a simple timeline.
I've already created a FrameworkElement that renders an individual element as a line (this line represents the transition between one element and the next, e.g. y(x) = x) and my intention is to use this element as part of the DataTemplate for my custom ItemsControl. By flipping the odd elements horizontally and butting them together in a panel, it should be possible to see a continuous series of transitions between the elements. I'm having difficulty in deciding how to implement this panel, in particular with filling 'dead space' that might occur at the start of the panel.
The collection of elements that I'm trying to draw represents a looping effect, but the first element may not start at time T=0. Because the effect loops back on itself this means that the gap between T=0 and the first effect's start time is actually made up of the final part of the last element in the collection. This means I have to find a way of chopping up the last visual element in the panel so that the front part sits at the end of the panel and the back part sits at the start.
Another way to think of this is in terms of a circle/pie chart - if element A starts at 15% and element B starts at 50%, element B would occupy the regions 50-100% and 0%-15% continuously.
I'm really looking for a way to get this done in WPF visually rather than by modifying the collection of items (e.g. by adding a fake 'padding' element between 0 and the first element) as this would create complications down the line when it comes to things like modifying/selecting items, etc.
Someone has suggested drawing this as a 0-1 effect (removing any offset on the first element if there is one) then recreating the offset using a pair of cameras/viewports, which is something I'm not familiar with and seems a bit overkill. Can anyone suggest a simpler or more elegant way?
The 3D XAML question posed below contains code that achieves the kind of effect I was looking for, with some modifications. I set it up as an orthographic camera and made the position and texture co-ordinates of the MeshGeometry3D into dependency properties:
Why does TextureCoordinates work as expected for a Viewport2DVisual3D, but not for a GeometryModel3D?
I am using www.responsivegridsystem.com for my columns and here is what I've come up with: ux.stoicdigital.com/#intro-message.
I'd like the list to work like this one: http://doyouimpress.com/#uses-list
The biggest problems are that, above a certain amount of px (can't remember exact), the three column grid is centered, but doesn't LOOK centered due to cell widths, etc. and that below that amount of px (when list is in one-column mode), the off-center problem is even worse.
Again, I realize that this has to do with cell widths, etc. but I can't figure out where to make the changes I need to do the following at both sizes:
Align text and bullets left
Center the list itself on the page
Any advice would be appreciated. Would especially appreciate any details you can give re: changes to make to CSS.
PS: If there is another way to achieve this outside of Responsive Grid System, I'm open to that too.
The text doesn't look centered because it isn't. The container div is centered, but since you align the text to the left its all scewed to the left, just like it'd be scewed to the right if you aligned the text to the right.
You could align the text to the middle, but then your checkbox icons wouldn't be lined up. If you want the text to be centered but still have the icons lined up you need to attach the icons so something else but the text. You could display them as pseudo-elements to the <li>, but the drawback is that there would be varying amounts of space between the text and the icons.
What I'm coming at is basically that you can't center the columns this way (as long as you don't make sure that the text in each <li> is equally wide) - however you can fake it and that's what they do on that site you're referring to.
To fake it, simply give each column div a unique class name (or target them with :nth-child), then move each column manually to make it look like the content is centered. You could give them different width-values (this is what they do in your example), different padding-values or similar. That's entirely up to you.
As for the one-column layout, do something similar where you add a padding-value to push them closer to the center, but obviously use the same value for all column divs.
I am new in WPF if there is something wrong please co-operate.Here i require some idea from experts.
I am working on one application in which i have to show some content on WPF form after filling the fields present on the form.On the same form i also have a print option.
Check this image.This is my form here part in the red block is generated at runtime.When i click on the print button it only show the visible part on the paper and skip the remaining part.
Problem :
How i can move the remaining part of the form which is under scroll to next page when i click on print.
For example in the given image we can see only 2 bulls eye completely and next 2 partially.How i can shift this remaining part to next page only when i click on print.
The answer is quite easy : don't rely on your window to do the printing, but build the visual you want then print it.
For instance, you must have a function that creates dynamically the circles and so on, then adds them to a Panel. What you might do is to print the Panel.
Or if you prefer, you might build Dynamically a new window, where you put all the Data you want printed as you want, then print the window. The advantage of this method is that it is more flexible for the content (if you want a header/footer) and also you can watch the content easily for debug. Note that even if the Window content is dynamic, you can have a base window for printing that avoids you to do too much xaml with code (expl : you might have TextBox bound to a PrintTitle property that you setup in the constructor of the Print Window...).
Notice that visual that were not rendered on screen will not print. Be sure, to avoid the common issues, to have a look at this article from this great site, switch on the code, here :
http://www.switchonthecode.com/tutorials/printing-in-wpf
Edit (reply to the question in comment):
1) If you have fixed number of bulls eyes, just make one Window for that number and Print it, this is waaaay easier.
2) To put Visuals in pages instead of rows, you'll have to rely on page Width/Height. What matters is the size of your control vs size of page. In the example, they build (in OnRender) Controls having LineHeight, LineWidth as size. Do the same : Try to put as many line of control as you can such as
(Control Height + margin )*NumberOfControlPerPage < Page Height.
Then you have to change OnRender to render controls instead of Rows made with rectangle+text. Pack your controls two by two in Horizontal StackPanels Then pack those StackPanel into a vertical StackPanel, then render. You have to keep track for each page which control was rendered last, then resume rendering at the following control.
Please follow this link.This is the basic which i got after searching in web world.Using this basic detail you can do any thing with print in WPF