I have used a grid template from BootStrap and the paging for that grid is showing as per the attached image 1. Now when i change the screen resolution of the browser the paging content gets break into two lines as per attached image 2 instead of in a single line.
But once i refresh the page it loads the paging correctly as the image 3. But i want that content right after changing of resolution.
Below is the code of JS by using React for that paging class
var ul = React.DOM.ul({className: 'pagination pagination-sm', role: 'menubar', 'aria-label': globalizationFactory.translate('STORMS_PAGER'), key: 'pager_container'}, [firstLi, prevLi, this.getPages(currentPageIndex + 1, totalPages), nextLi, lastLi]);
var mainClass = this.props.className ? 'container-fluid ' + this.props.className : 'container-fluid';
return React.DOM.div({className: mainClass,key: 'pager_wrapper'},
React.DOM.div({className: 'row',key: 'pager_wrapper_inner'},
React.DOM.div({className: 'col-sm-12', style: {textAlign: 'center'},key: 'pager_innerWrapper'}, ul)));
Any suggestion will be helpful.
Image 1:
Image 2:
Image 3:
I think all you need to do is listen for window resize events and have that trigger a render. In React, if you change state, your component will render. You can do something like this inside of your component that is doing the rendering.
getInitialState: function() {
return {
windowWidth: window.innerWidth,
windowHeight: window.innerHeight
};
},
componentDidMount: function() {
return window.addEventListener('resize', this._handleResize);
},
componentWillUnmount: function() {
return window.removeEventListener('resize', this._handleResize);
},
_handleResize: function() {
if (this.state.windowWidth !== window.innerWidth || this.state.windowHeight !== window.innerHeight) {
return this.setState({
windowWidth: window.innerWidth,
windowHeight: window.innerHeight
});
}
}
Related
I have four canvas in my screen, positioned two above and two below.
Each one have a button that makes possible to maximize the canvas, hiding the others.
This button is positioned above each canvas, with absolute position based on offsetTop and offsetLeft of the canvas.
However, when I maximize or minimize a canvas, the button formula updates only the width property.
The strange thing is that if I resize the screen, which also calls resize function, everything goes to the right place.
EDIT: Additional information: I am using VueJS and, in order to hide the other canvas, I apply v-show="false" to them parent divs, which only applies display: none.
Some snippets:
Initial resize and listener:
window.onload = function () {
resizeAll();
window.addEventListener('resize', resizeAll, false);
};
The resize hub:
function resizeAll () {
vue.$refs.panelOne.resizeDefault();
// ...
vue.$refs.panelN.resizeDefault();
}
The panel's resize default and resize method. The "expandStyles" is the css styles applied to the button:
resizeDefault() {
let dimensions;
if (this.expanded) {
dimensions = getScreenDimensions();
} else {
dimensions = getHalfScreenDimensions();
}
this.resize(dimensions.width, dimensions.height);
}
resize (width, height) {
this.canvas.width = width;
this.canvas.height = height;
this.expandStyles.top = (this.canvas.offsetTop + 10) + 'px';
this.expandStyles.left = (this.canvas.offsetLeft + this.canvas.width - 40) + 'px';
drawInterface.redraw();
}
And finally, the dimension getters:
function getScreenDimensions () {
return {
width: window.innerWidth - 310,
height: window.innerHeight * 0.92
};
}
function getHalfScreenDimensions () {
return {
width: (window.innerWidth - 310) / 2,
height: (window.innerHeight * 0.92) / 2
};
}
I agree with S.P.H.I.N.X , it seems like the problem lies with propagation of reactive properties in this.expandStyles to actual DOM. Would be useful if you can share the part of the template which has your canvases and positioning application.
Meanwhile, if setTimeOut doesn't feel right to you, you may do things more "Vue-way" by using Vue: nextTick to set order of operations (styles recalculation, redraw).
I am trying to use following code with React Native:
...
_getContentHeight() {
if (this.refs.AccordionContent) {
this.refs.AccordionContent.measure((ox, oy, width, height, px, py) => {
// Sets content height in state
this.setState({
height: this.props.expanded ? height : 0,
content_height: height
});
});
}
},
componentDidMount() {
// Gets content height when component mounts
// without setTimeout, measure returns 0 for every value.
// See https://github.com/facebook/react-native/issues/953
setTimeout(this._getContentHeight);
// tried setTimeout(this._getContentHeight.bind(this);
},
...
Now, when I debug the app in chrome, I see, that I never get to the _getContentHeight(). Now I am pretty sure that it has to do something with asynchronous calls etc. But is there a way to debug this, and see what values I get for height and content_height?
Help is needed, especially in understanding setTimeout/asynchronous function calls.
I'd suggest moving the call to measure inside componentDidMount to make sure your functionality works before abstracting it and dealing with any scoping or object reference issues that you might be facing now.
componentDidMount() {
this.refs.AccordionContent.measure((ox, oy, width, height, px, py) => {
// Sets content height in state
this.setState({
height: this.props.expanded ? height : 0,
content_height: height
});
});
}
Update:
I've wrapped your code in a react class and got the measure object to error out # https://jsfiddle.net/x7w62w99/
var Hello = React.createClass({
_getContentHeight() {
console.log(this.refs)
if (this.refs.AccordionContent) {
this.refs.AccordionContent.measure((ox, oy, width, height, px, py) => {
// Sets content height in state
this.setState({
height: this.props.expanded ? height : 0,
content_height: height
});
});
}
},
componentDidMount() {
setTimeout(this._getContentHeight);
},
render: function() {
return <div ref='AccordionContent'>
Hello {this.props.name}
<div id='AccordionContent'>
some stuff
</div>
</div>;
}
});
ReactDOM.render(
<Hello name="World" />,
document.getElementById('container')
);
Try this
setTimeout(function(){
this._getContentHeight.bind(this)
})
Use This:
setTimeout({
this._getContentHeight
}, the delay you want);
SetTimeout takes two parameteres.
http://www.w3schools.com/jsref/met_win_settimeout.asp
I have custom control inside TabPanel: {items: Panel: {items: customcontrol}}.
Inside control, i create dynamically in onRender handler image control with picture. Picture can be different sizes. How me refresh current container, that it took the right size? It happen automatically, then i switch to another tab and back. doLayout() not working, function updateLayout() violates the layout of the other tabs.
creating image:
onRender: function () {
var me = this;
me.callParent(arguments);
this.el.update(this.imageFieldTpl.apply(this));
var imageWrap = Ext.query('.image-ct', this.el.dom)[0];
this['image'] = Ext.create(Ext.Img, {
name: 'image',
height: "100%",
width: "100%",
renderTo: imageWrap
});
if (this.value != null) {
this.fireEvent('imageChange', this.value);
}
}
I am trying to use the pie chart from Chart.js (http://www.chartjs.org/docs/#pieChart-exampleUsage). Everything works smooth, but the animation happens as soon as the page loads, but since the user has to scroll down to see the chart, they won't see the animation. Is there anyway I can make the animation to start only when scrolled to that position? Also if possible, is it possible to animate everytime when that chart becomes into view?
My code is as follows:
<canvas id="canvas" height="450" width="450"></canvas>
<script>
var pieData = [
{
value: 30,
color:"#F38630"
},
{
value : 50,
color : "#E0E4CC"
},
{
value : 100,
color : "#69D2E7"
}
];
var myPie = new Chart(document.getElementById("canvas").getContext("2d")).Pie(pieData);
</script>
You can combine the check for whether something is viewable with a flag to keep track of whether the graph has been drawn since it appeared in the viewport (though doing this with the plugin bitiou posted would be simpler):
http://jsfiddle.net/TSmDV/
var inView = false;
function isScrolledIntoView(elem)
{
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return ((elemTop <= docViewBottom) && (elemBottom >= docViewTop));
}
$(window).scroll(function() {
if (isScrolledIntoView('#canvas')) {
if (inView) { return; }
inView = true;
new Chart(document.getElementById("canvas").getContext("2d")).Pie(data);
} else {
inView = false;
}
});
Best to use deferred plugin
https://chartjs-plugin-deferred.netlify.com/
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-deferred#1"></script>
new Chart(ctx, {
// ... data ...
options: {
// ... other options ...
plugins: {
deferred: {
xOffset: 150, // defer until 150px of the canvas width are inside the viewport
yOffset: '50%', // defer until 50% of the canvas height are inside the viewport
delay: 500 // delay of 500 ms after the canvas is considered inside the viewport
}
}
}
});
I don't know if you could do that, I had the same issue and resolved it without any plugin in this simple way, check out:
$(window).bind("scroll", function(){
$('.chartClass').each(function(i){
var dougData = [
{value: 100, color:"#6abd79"},
{value: 20, color:"#e6e6e6"}
];
var graphic = new Chart(document.getElementById("html-charts").getContext("2d")).Doughnut(dougData, options);
$(window).unbind(i);
});
});
I had the same problem with Chart.js and found a really great solution.
There is a package on GitHub that is called ChartNew.js by FVANCOP.
He expanded it and added several functions.
Look at the sample, the charts are drawn by scrolling down.
Responsible is the statement
dynamicDisplay : true
Using IntersectionObserver is the more modern approach, and gives you the ability to choose how much of the element must be visible before triggering an event.
A threshold of 0 means it will trigger if any part of the element is visible, while a threshold of 1 means the entire element must be visible.
It performs better than listening to scroll, and will only fire once when the element transitions from hidden to visible, even while you are continuously scrolling. And it also works if the page content changes due to other events, such as other content being hidden/shown, or window resize, etc.
This is how I made a radial chart that animates every time at least 20% of it appears into view:
const options = {
series: [75],
chart: {
type: 'radialBar',
},
};
const chart = new ApexCharts(document.querySelector("#chart"), options);
chart.render();
const observer = new IntersectionObserver(function(entries) {
if (entries[0].isIntersecting === true) {
chart.updateSeries([0], false); // reset data to 0, then
chart.updateSeries([75], true); // set original data and animate
// you can disconnect the observer if you only want this to animate once
// observer.disconnect();
}
}, { threshold: [0.2] });
observer.observe(document.querySelector("#chart"));
This is what you want:
Check if element is visible after scrolling
Next time please check if there's already an answer ;)
Alternatively: jquery.appear
I want to write my own layout.. (like vbox, border and so one)... What i want to do is to create layout that will place it's content in the middle (verticall - middle, horisontal - middle)..
Is there some one who could show me how this control will look like in extJs or can provide some links that may be usefull?
I have this example from
http://dev.sencha.com/deploy/dev/examples/layout-browser/layout-browser.html
Ext.ux.layout.CenterLayout = Ext.extend(Ext.layout.FitLayout, {
// private
setItemSize : function(item, size){
this.container.addClass('ux-layout-center');
item.addClass('ux-layout-center-item');
if(item && size.height > 0){
if(item.width){
size.width = item.width;
}
item.setSize(size);
}
}
});
Ext.Container.LAYOUTS['ux.center'] = Ext.ux.layout.CenterLayout;
But it gives me more questions than answers.. What is setItemSize How it works? When? Why? ect. What is item.setSize called for? How it works? When? Why? ect.
check the examples of ExtJS 3, there is an Ext.ux.Layout.CenterLayout under custom layouts there already, maybe a good point to start?
http://dev.sencha.com/deploy/dev/examples/layout-browser/layout-browser.html
Edit: Try this layout user extension, it centers an item in the horizontal and vertical center of it's container
Ext.ns('Ext.ux.layout');
Ext.ux.layout.CenterLayout = Ext.extend(Ext.layout.ContainerLayout, {
monitorResize:true,
type: 'ux.center',
getLayoutTargetSize : function() {
var target = this.container.getLayoutTarget();
if (!target) {
return {};
}
return target.getStyleSize();
},
onLayout : function(ct, target){
Ext.ux.layout.CenterLayout.superclass.onLayout.call(this, ct, target);
if(!ct.collapsed){
this.setItemSize(this.activeItem || ct.items.itemAt(0), this.getLayoutTargetSize());
}
},
setItemSize : function(item, size){
var left = (size.width - item.getWidth()) / 2;
var top = (size.height - item.getHeight()) / 2;
var pos = Ext.apply(item.getEl().getPositioning(), {
position : 'absolute',
left : left,
top : top
});
item.getEl().setPositioning(pos);
}
});
Ext.Container.LAYOUTS['ux.center'] = Ext.ux.layout.CenterLayout;
Ext.layout.ContainerLayout (the base class for layouts) has a doLayout method that triggers your container rendering.
In the case of FitLayout, its overriden and it calls a custom setItemSize function who calls the native setSize for the first container item (or the selected item if any), to fit the container size (maximize i guess).
Check also these custom layouts : http://layoutscroll.demo.revolunet.com/
Ext.create('Ext.container.Viewport', {
layout: {
type: 'hbox',
pack: 'center',
align: 'middle'
},
items: [
{
html: 'Hello World'
}
]
});