The Context
Working on a database schema editor in SVG which may have
lot of records in some table , i am looking to add scrollbars to
the table. The whole thing is coded in SVG and integrated in a ReactJS
app within a container as a SVG document.
The Question
How could i get scrollbars like for instance scrolling the children
of a where bounds would tell the viewport size and
the children would determine the scrollable area?
I don't think this make much sense in SVG which is about 'painting' , however due to its increased popularity maybe something has been implemented about this?
Any ideas?
Regards
Philippe
I tried overflow='auto' on but it did not do the trick.
See code below in ReactJS
<svg>
<g overflow={'auto'} width={100} height={100} id={'test1'}>
<DivSvg top={255} left={25} width={100} height={100} backgroundColor={'green'}/>
</g>
</svg>
I thought maybe overflow='auto' would make evaluate its size based on width/height and scroll the DivSvg ( i.e. ) which otherwise does not fit into the
someone in our company found the right approach.
Actually svg can integrate HTML within rectangular areas known as ''
Thanks to this i can draw my diagram in SVG while keeping table display coded in HTML and they work properly alltogether to rely both on SVG graphical skills VS HTML table content styling , scrolling , ...
Related
I am quite new to coding and building my first React app. I have made good progress in styling and solving my other problems on my own, but I just cannot figure out this one: my rendered map obscures something else on the page. For styling I am using v5 of Material-UI.
To be clear, the map renders and I have no issue seeing my map in my app (sometimes), as well as having it geographically positioned to specific coordinates. The code looks like this for its specific grid:
<Grid container direction="row" rowSpacing={150}>
<Grid item xs={12} position="relative">
<MapsContainer />
</Grid>
</Grid>
Depending on the grid position property of the MapsContainer, the map either disappears completely (absolute and fixed), or just a sliver shows above the page footer unless rowSpacing is as obscene as the example code, and I lose footer functionality (no set property). When position is relative, I lose both header and footer functionality.
Regardless of the footer component position property, the map does not push it further down.
I hope this is not too convoluted to understand
*Edit: The problem came from the google-maps-react module. After pouring over it for 3 hours with a more skilled developer, not even he could figure it out, so we just broke it less by trying to reign in the div the rendered map would throw around itself. Is it fixed? Yes. Is it fixed in the proper way? Probably not. If you have the proper way to fix it, by all means share!
I want to render around 1200 items with images carousel in react native like shown on the screen below
FlatList works works so slow. Surprisingly, in case with images, ScrollView works better, but when it goes up 1200 elements, it works slow as hell.
Does somebody know how is that possible to render such amount of elements. Thanks.
Try these few props that help control the amount of items rendered like windowSize, maxToRenderPerBatch , and initialNumToRender .
It might helps with the performance
I have the following requirements to my table:
Table should have fixed header
It needs to autosize: for infinite scroll to work the first fetch should get sufficient amount of data for scroll to appear at all.
table body should work as infinite loader: when scrolled to the end of the list table body should show loading indicator and load more rows
My assumptions are as follows:
as user will scroll through possibly large sets of data I should virtualize lists (react-virtualized seems to be the only good option for me)
as we currently have react-table I want to keep it (it has great mechanism of declaring table rows, columns, accessing data and filtering + sorting)
As we use material ui I need to use material ui react components
Because react-virtualized has own Table component I could use it, but react-table has different way of rendering rows and columns, therefore I have to use List component. (react-table separates rows and columns while react-virtualized uses columns directly as children of Table component)
I saw that react-virtualized works with HOC component called InfiniteLoader, so I should use that as well
Finally I need my columns to not be messed up just because it has more text (i.e. have dynamic height). So I tried to use CellMeasurer for this.
What I was able to achieve can be seen in this sandbox
https://codesandbox.io/s/react-table-infinite-mzkkp?file=/src/MuiTable.js
(I cannot provide code here because it is quite large)
So, in general I could make Autosizer, CellMeasurer and List components from react-virtualized to work.
I am stuck at inifinite scroll part. I saw the example on official docs, but it seems to be a little bit anti pattern (mutation state directly is not a good thing at all)
So I tried to achieve similar result, however if you could see, my loadMore function fires too early for some reason. It leads to requests being sent on nearly every scroll event.
Any help is much appreciated.
What I tried already:
Using react-window instead of react-virtualized
It works only for simple use cases, and fails with dynamic size of cells.
Using react-inifnite-scrollcomponent (https://www.npmjs.com/package/react-infinite-scroll-component)
It is working for entire page (unable to make "sticky" header, unable to render loading indicators as part of table body, it odes not have any optimization for long lists)
Using Table component from react-virtualized.
I was unable to make it work with react-table (as Table component from react-virtualized seems to render Cells directly as children of Table component. I know it has renderRow function, but it means two separate places while react-table has
<TableRow
{...row.getRowProps({
style
})}
component="div"
>
{row.cells.map((cell) => {
return (
<TableCell {...cell.getCellProps()} component="div">
{cell.render("Cell")}
</TableCell>
);
})}
</TableRow>
Also, it is not clear how to render custom filters this way.
I know this is not the answer you were looking for, but I recommend using an IntersectionObserver instead of the virtualize library. react-virtualized is not great for dynamic/responsive sized elements. IntersectionObserver is a native browser api that can detect when an element enters the viewport, without providing it with element sizes.
You can easily use it with a react library like react-intersection-observer which has an InView component and a useInView hook, though that would require wrapping every table cell with InView. The performance of an IntersectionObserver tends to be better than a scroll event-based solution like react-virtualized, though that might degrade if you have 1000s of observers.
You could also use something like intersection-observer-admin, which will pool all your observers into one instance similar to the react SyntheticEvent. You'd want to integrate that into something like React.useContext or redux.
I've found the Virtuso package to be a great help for this. Works better out the box for dynamically sized list items.
I don't have a complete solution for you, but here are a few things that might help you in your quest:
Consider a static header instead of using position: sticky to keep the header row at the top.
(If you could get everything else in
react-inifnite-scrollcomponent to work, this would solve the sticky
header problem.)
A method I've used is to adjust for the size of the scrollbar and always include it (even if not needed) - this may or may not work in all cases:
// Header div
<div
style={{ width: 'calc(100% - 0.9em)' }} // accomodate for the width of the scrollbar
>
// header stuff
</div>
// list (simplified for clarity) - here I used react-window
<div>
<AutoSizer>
{({ height, width }) => (
<List
style={{
overflowX: 'hidden',
overflowY: 'scroll', // always display scrollbar
}}
>
{RenderRow} // function to return a complete react-table row
</List>
)}
</AutoSizer>
</div>
And here are some other ideas if that one doesn't work for you:
https://stackoverflow.com/a/63412885/6451307.
If you need horizontal scrolling, you might consider the above plus a wrapper to provide the horizontal scrolling separately.
Consider the table as a list of rows for virtualization purposes.
It sounds like you've already tried this some, but I definitely found it easiest to use the list virtualization tools and then render a row of cells for each list item.
You can see an example of that in my code above, too.
Consider an overlay for the loading indicator.
If it works with your UI needs, create a separate element for the loading indicator that overlays the table body (using absolute positioning and turning it on only when it's needed). It could be solid to hide the table data completely or have a translucent background. This would prevent it from causing problems with whatever is going on in the table/list itself.
(Some accessibility actions might need to be taken, too. Like hiding the table data from screen readers when the overlay is up, giving the overlay role="alert" or similar, etc. so consider that if you go this route.)
If you're not already doing it, consider using div's instead of trying to use table elements to allow for easier styling and more flexible element structure.
react-table adds the correct table roles so you can use div's and your table should still have the correct semantics as long as you apply the react-table functions properly - like {...getTableBodyProps()} and similar.
Hopefully, one or more of those will help you get closer to your goal. Good luck!
I have a working vertical column drag and drop React app using react-beautiful-dnd, but would like to 'invert' it so that Draggable items fall to the bottom of the Droppable div instead of floating to the top. Is this possible?
If I'm understanding you correctly, you'd like to have a list where when the container is not full, the items within that list are aligned to the bottom of the container?
If so, then yes - I would utilize flexbox.
Here is a good resource for flex - https://css-tricks.com/snippets/css/a-guide-to-flexbox/
There are multiple different ways to implement this with flex. Pick your poison.
edit
Based on the code sandbox:
I would add a wrapper div to the bay component with the same height as what you have now. On the child div, add a dynamic height field that is dependent on how many tables the bay contains.
Users won't be able to drop into the entire column but you could style it to show the user where they need to drop when the column is empty.
I ended up just creating another invisible strip with flexGrow = 1 to push everything to the bottom.
As I read, embedding an svg in another SVG leads to create another document and therefore complexify a lot the styling of those svg ...
Is there a way to use the css property transform : rotate(90Deg) easily on only 1 of the embbed svg ?
I'm trying to rotate the background only and not the front svg which needs to stay vertically ...
This example will help you a lot to understand what I'm trying :
https://codesandbox.io/s/example-rotate-svg-mucs3
Edit
Its seems that it works on Firefox but not in Chrome ... Does anyone know a solution for this in Chrome ?
Chrome's overview:
Firefox (and wanted) overview:
I've submitted this problem. Its has been merged here
As a work-around while waiting for this "bug" to be corrected. ( Should take some time as it's been reported since 2013... )
I've added a transform porperty with rotate(90) translate(0, -600) directly ON the <g> inside of the "background.svg".
The translate thing is here beacause the center used for rotating is by default [0,0]. It's clearly explained HERE