Previously I made this question.
I try the solution linked in the similar question already made (using grid instead of flex) but I have some problems.
I have to build a grid of plots (bar charts). My dataset could be aggregated by Day or by Month.
Obviously if the data is aggregated by months, the number of bars is much smaller than the number of bars in case the data is aggregated by day.
The width of the plot is proportional to the number of bars.
To show my problem I created these simple images: each rectangle represents a bar chart (is like a placeholder).
The larger rectangles represent the bar charts in the case in which the data are aggregated by Day, the narrower bar charts instead represent the bar charts when the data are aggregated by Month.
In this example I suppose that my dataset is composed by 6 chart.
I know the width of the graph because it is simply the number of bars for the width of the bar.
I would like the data to be positioned automatically.
In each row there cannot be more than two graphs, between a graph and the other there must be some space and the final row (if it is not complete) must have the charts aligned to the left. The last request is the reason why use Flex is not correct, so I switched to Grid.
So, I want that if data are aggregated by Day, charts would like:
If data are aggregated by Month, charts would like:
I try CSS grid using this code:
<div
className="relative ba b--black"
style={{
display: 'grid',
gridTemplateColumns: `repeat(auto-fit, minmax(45%, 1fr))`,
gridAutoRows: SVG_HEIGHT,
gridGap: '10px 5px', // space h, space v
}}
>
{
data.map((plot, plotIdx) => {
return (
<div
key={plotIdx}
className="ba b--black overflow-x-auto"
onScroll={this.handleHorizontalScroll(plotIdx)}
>
<svg
width={SVG_WIDTH}
height={CHART_HEIGHT + MARGINS.bottom + MARGINS.top}
>
// other code...
</svg>
</div>
)
})
}
</div>
(Each chart can have a large width so there is a horizontal scroll).
The problem now is that the cell of each plot is always the same even if the real dimension if the chart is smaller than the container.
Data aggregated by Day:
Data aggregated by Month:
If I use SVG_WIDTH in place of 45% in the minmax statement, I get:
in case data are aggregated by day, and this one in case data are aggregated my month:
I didn't use px, thanks! Now it works in the case of aggregation by month but not the case of aggregation by day.
by day (doesn't work):
by month (works):
The problem is that every graph should have a horizontal scroll in fact if the SVG_WIDTH is greater than the size of the father div, then I need to add a scroll.
Here is the code I used:
<div
className="relative ba b--black"
style={{
display: 'grid',
gridTemplateColumns: `repeat(auto-fit, minmax(${SVG_WIDTH}px, 1fr))`,
gridAutoRows: PLOT_HEIGHT,
gridGap: '10px 5px', // space h, space v
}}
>
{data.map((plot, plotIdx) => {
const yScale = this.yScale(plot)
const yAxisTicks = yScale.ticks(4)
return (
<div
key={plotIdx}
ref={plotElem => (this.plots[plotIdx] = plotElem)}
className="ba b--black overflow-x-auto"
onScroll={this.handleHorizontalScroll(plotIdx)}
>
// ...
</div>
)}
)}
</div>
Use SVG_WIDTH in place of 45% in the minmax statement.
As for the overflow problem that show up for big values, there is a workaround described here, although it is a bit hacky. Adapted to your case, minimum two columns:
#media (max-width: ${SVG_WIDTH * 2 + 10}px) {
.container { grid-template-columns: repeat(2, 1fr); }
}
Where 10 is your grid-gap. And the .container takes full width of the page with body margin reset to 0. Otherwise also add the default margin of the body tag (8px left and right) and the sidebar width if you have one. You can also use CSS calc() if your sidebar or layout is adaptive, but the support for calc() in media queries is limited to very recent browsers currently.
Related
I am using react native 0.57. I want to make 2D Grid for non-fixed width and fixed height boxes by using Flatlist. Something like grid show be free to adjust the number of columns according to the screen size. I am unable to implement it.
I can use fixed column but I want my grid to ajust per the device width. The box width can be unpredictable depending upon the text between them. Thanks in advance
Example: In gmail:
You can use flex property , and a width of null.
assuming you have a renderitem function and a max of 4 columns, you will need to have some "dummy items" in your flatlist data
<FlatList
style={{flex:1}}
data={[1,2,3,4,dummy,dummy,3,4,1,2,dummy,dummy]}
renderItem={this.renderItem}
numColumns={4}
/>
renderItem = ({ item, index }) => {
if(item==='dummy'){return <View/>}
return (
<View style={{height:100,width:null,flex:1,backgroundcolor:'red'}}/>
);
};
use flex 1 to fill "dummy" space or flex 1/2 to fill half of the screen , etc.
I am using Fullcalendar Scheduler, and the problem is when i have many resources, it becomes not good, like this:
The live demo with litle resources: http://fullcalendar.io/js/fullcalendar-scheduler-1.3.3/demos/vertical-resource-view.html
I have an idea, it's adding an horizontal scroll, but i don't know the way, can you guys help me out ?
Thank you very much and have a great day.
.fc-view-container {
overflow-x: scroll;
}
.fc-view.fc-agendaDay-view.fc-agenda-view{
width: 500%;
}
/* **For 2 day view** */
.fc-view.fc-agendaTwoDay-view.fc-agenda-view{
width: 500%;
}
Use the combination of this configure options :
dayMinWidth: 150,
stickyFooterScrollbar : true,
dayMinWidth : guarantees your horizontal titles are visible.
stickyFooterScrollbar : guarantees horizontal scrollbar is visible.
Paresh's answer works for views with many columns, but has the limitation that views with few columns will have very wide columns.
Fullcalendar's render algorithm calculates equal column widths based on the view width, and there doesn't appear to be a simple way of setting the column widths using CSS.
Instead we need to enable scrolling on the x-axis:
.fc-view-container {
overflow-x: scroll;
}
then use jQuery to calculate the overall width of the view. Here I am using a minimum column width of 100px:
var columnCount = $('.fc-agendaDay-view th.fc-resource-cell').length;
var viewWidth = $('.fc-view-container').width();
var minViewWidth = 18 + columnCount * 100;
if (minViewWidth > viewWidth) {
$('.fc-view.fc-agendaDay-view.fc-agenda-view').css('width', minViewWidth + 'px');
}
We only change the width of the view and enable scrolling if it exceeds the current width of the view. This has the effect of setting a minimum column size of 100px.
The jQuery needs to run after the calendar.render(); call.
I want my columns to display in 3 columns per row on medium and larger screen sizes (col-md-4), 2 columns per row on smaller screen sizes, and 1 column per row on extra small (col-sm-6), but when I view my app on my tablet, I get floating columns in the 2 column rows. I know its possible to use a clearfix class with ng-if to tell it to make a column every so many rows, but if I use:
<div class='clearfix' ng-if='$index % 2 == 0'>
it will make my columns create a new row every 2 columns, even on larger screens, which isn't what I want. Is it possible to make ng-if only add the clearfix after 2 columns strictly on the col-sm class, and not on the col-md class?
Yes you can do it by listing to window resize event, Based on the screen inner width you can attach or detach the div.clearfix to the dom using ng-if.
EX:
Controller:
maintain a variable to represents the window width $scope.windowWidth
app.controller('MainCtrl', function($scope, $window, $timeout) {
$scope.windowWidth = $window.innerWidth;
$window.onresize = function(event) {
$timeout(function() {
$scope.windowWidth = $window.innerWidth;
});
};
});
View:
Attach the div IF windowWidth <= 768 ELSE Remove the div from the DOM.
<div class="tab-only clearfix" ng-if="windowWidth <= 768">
This will show only on min-width : 768px
</div>
here is a DEMO
Please search for if there is any css fixes for this.
Goal: to be able to animate a container-view's frame while it's subviews keep their original layout & scale in proportion to their container view.
Scenario:
Elements positioned via constraints/autolayout; within green container.
Green containerView's physical coordinates (frame/bounds) are adjusted per animation.
Members' compression & hugging properties are set to a low priority.
UIView.animateWithDuration(0, animations: {
self.bounds = myBounds
}) {(One) in
UIView.animateWithDuration(1, animations: {
self.frame = myFrame
}) {(Two) in
UIView.animateWithDuration(0.5, animations: {
self.frame = origFrame
// self.center = myCenter
}) {(Three) in
UIView.animateWithDuration(0.2, animations: {
self.frame = distantFrame
})
}
}
}
Here's the original layout:
I would like to have member element scale proportionally with their container view like this:
But the member elements (the one label 'Hello World!') don't adjust accordingly as their green containerView animates to a square in the upper left-hand corner:
How do I keep a UIView's members' layout in proportion to the prevailing their prevailing container view's frame?
Note: This would apply to any type of member (UIView, UITextView, ...etc.); for simple position/layout & transformation (pivot) animations.
In your example, you have a green background view (BG) and a hello world view (HW), and you want HW to scale in proportion to BG.
You can achieve this easily:
Open the Utilities pane in Xcode (top rightmost icon), and the Document outline (bottom left icon of storyboard).
Let’s assume that HW is already centered in BG, i.e. that you already set the alignment constraints for HW center horizontally and vertically in container.
Now, select BG as well as HW in the Document outline, and click the „Pin“ icon bottom right. It will offer the constraints „Equal widths“ and „Equal heights“. Activate both.
After these constraints have been created, open one of them in the Document outline. The utilities pane will then show the Equal Width constraint with the 2 views and a Multiplier field.
In the Multiplier field, you can enter the required proportions for the selected dimension, e.g. 1:3. This will fix the proportion for the selected dimension.
For the other dimension of course analogously. Of course you had then to update the frame of HW.
Here is an example:
I am also trying to positioning a node in a cell in grid layout as below
layout: { name: 'grid',
fit: true, // whether to fit the viewport to the graph
rows:5,
columns:12,
padding: 10, // the padding on fit
position: function( node )
{ console.log("Row : "+node.data('row') + ", COL : "+node.data('col'));
return {row:3, col:node.data('col')};
}
},
But node is always created in the middle of the canvas, even if I hardcode the row as above. Any suggestion, what is going on.
Thank you
If you're manually specifying positions, you shouldn't need to set the overall dimensions. Maybe you've overconstrained it (e.g. row beyond rows)?
Alternatively, you could set the dimensions and a sort function to indicate the ordering.