How to scale Highcharts height on window resize with React - javascript

I have this example https://stackblitz.com/edit/react-sjyuej?file=Chart1.jsx
where I'm trying to make the the two charts in the left container share the height and respond to window resizing.
I've made the width responsive by setting overflow: hidden, forcing the charts to rescale as far as I understand, but I don't know how to get the same effect with the height.
Setting height='100%' in the Chart component doesn't help.

Use the highcharts-react-official package (>= 2.1) and set containerProps={{ style: { height: "100%" } }}.
This will make the chart dynamically resize to fill its parent div. You can then set up parent divs using flexbox to get your desired layout.
For example your render method would look like this:
render() {
return (
<HighchartsReact
containerProps={{ style: { height: "100%" } }}
highcharts={ Highcharts }
options={ options }
/>
);
}
Here is a live demo
Make sure you are on version >= 2.1 of highcharts-react-official (see this github issue)

After setting the height, you need to use chart.reflow() method:
componentDidMount(){
const container = this.chartComponent.current.container.current;
const table = document.getElementsByClassName('table')[0];
container.style.height = table.clientHeight + 'px';
this.chartComponent.current.chart.reflow();
}
API: https://api.highcharts.com/class-reference/Highcharts.Chart#reflow
Live demo: https://stackblitz.com/edit/react-3jwwvt?file=ChartOfficial.jsx

Related

gridstack.js set grid-stack-item height auto based on inner content

Is there any option to use gridstack.js with each grid-stack-item height based on inner content like image.
In my scenario each images having different height so it's not showing correctly on card.
It gives scrollbar inside grid-stack-item to view image, that is wrong.
Any option or workaround or other JS plugin/library that will restrict fixed height based on any factor.
Current behavior
Expected behavior
Height will be 100% based on width so image aspect ratio preserves.
I managed to do by setting up cellHeight : 10 then get image in resizestop event and update updateWidget.
Below is sample code for that resizestop event.
$('.grid-stack').on('resizestop', function (e, item) {
let stackItem = me.findGridStackItem(item.element.find('img').data('Id'));
if (stackItem) {
setTimeout(() => {
stackItem.option.height = Math.ceil(($(stackItem.nativeElement).find('img').height() + 5) / 10);
me.gridStackMain.updateWidget(stackItem);
}, 200);
}
});
the problem you are facing is about creating "masonry layout". I think gridstack is not the tool you need to use to resolve this problem. Try https://masonry.desandro.com/ or any other masonry layout lib.

JQuery function in ReactJS for a dynamic viewport height

so I got some help in another question on making a table's height equal to the viewport's height. Meaning, if the user resizes the screen, the table height adjusts on-the-fly to occupy the entire height of the screen. My problem now is, this is a React App and I am having a hard time converting this jquery function to React.
My function looks like this:
$(document).ready(function() {
function setHeight() {
windowHeight = $(window).innerHeight();
$('.dynamicHeight').css('height', windowHeight + 'px');
};
setHeight();
$(window).resize(function() {
setHeight();
});
});
Here is a codepen showing the behavior
And here is a screen shot of what I am trying to do
How can I build this function in React? I'm assuming it will need some modification.
Thanks in advance
NOTE: this may look like another question I made, but it is not a duplicate. It's an entirely different question related to the same issue.
In the components lifecycle, you should add a componentDidMount method. In that method, simply add a resize handler
import React, { Component } from 'react';
class MyComponent extends Component {
constructor(props){
super(props);
this.state = {
width: $(window).width(),
height: $(window).height(),
}
this.resize = this.resize.bind(this);
}
resize(){
this.setState(() => {
return {
width: $(window).width(),
height: $(window).height()
}
});
}
componentDidMount(){
window.addEventListener('resize', this.resize);
}
render(){
return (
<div>
<MyComponent width={this.state.width} height={this.state.height} />
</div>
)
}
}
So what this does is, when your Component initializes, you set the state to the width and height of the viewport (using jQuery). Then you define a method to update the state, and when your component mounts you attach an resize event listener to it and call the resize method each time the screen resizes. This ensures that your state always contains the width and height of the viewport. Then you can define the width and height of your component by passing that state to your component as props and boom! All good, everytime you resize your screen your component will match it.
If you have any questions let me know. You might need to tinker with this to get it to work (specifically the lifecycle events might not update state as often as you need to) I just whipped it up and did not test it but in theory this is exactly what you need
edit: just a thought, if you want to change the style of your components I would use a style object. So in the child component, do something like this:
let style = {
width: this.props.width + 'px',
height: this.props.height + 'px'
}
And when you render that component
<ChildComponent style={style} />

Creating an overlay view and render it in a dynamic div in backbone

Here is the the framework I have:
....
var showChart = new showChartView({
el: this.$el.find("#my-chart-div");
// Other parameters passed in to build the chart
});
showChart.render();
The above view renders a chart graph on the browser.
The css for the div above looks like:
my-chart-div
{
height: 100,
width: 300
}
The html:
<div id="my-chart-div"></div>
What I want to do is that when I hover over the div (my-chart-div), there should be an overlaying chart rendered in a bigger size (rendered as an instance of the same view above - ShowChartView but with larger width and height), so the css of that would look something like:
overlay-chart-div
{
height: 200,
width: 500
}
Any ideas?
So you just want a slightly bigger chart when you hover over it?
If that is the case this should work perfectly for you:
#my-chart-div:hover {
transform: scale(1.1) translate(4%, 4%);
}
For bigger just up the scale() to 1.2.
You can use the mouse events(mouseenter, mouseleave) to perform this:
events: {
'mouseenter #my-chart-div' : 'show_overlay',
'mouseleave #' : 'hide_overlay',
},
show_overlay: function(event){
// show the overlay div, load/copy bigger chart...
},
hide_overlay: function(event){
// restore it here or simply call the render function
},
Regarding the overlay content, you can always use the same content or copy it from my-chart-div (jquery detach() function), or if the chart needs to be preloaded with the new dimensions, you just call the chart rendering function in the overlay element
So, for making the element "my-chart-div" 1.1 times larger on hover, simply add the following code to the css for the element:
#my-chart-div:hover {
transform: scale(1.1);
}
Above solution works to resolve the issue.

Expanding FLOT graph on click

I'm using flot library to plot some data. Flot uses height and width property of that div to draw the data plot like so
<div id="graph" style="width: 300px; height: 300px;"></div>
I would like to make this graph(div) clickable which expands to a bigger size say 500*500. Which means the width and height of the plot should be 500*500 but should be first visible in 300*300. Upon clicking, it should expand and reveal its original size. I guess setting initial height and width is required for flot to work. How can I achieve this ?
Techniques that I've tried :
1) Using jquery toggle which takes the parent class and animates its height and width like this
$(this).parent().animate({'height': '500px'},{'width': '500px'});
You can use your code to expand the graph but you also have to redraw it with the new size.
With this code you can redraw the graph after the expanding has finished:
$('#graph').on('click', function () {
$(this).animate({
'height': '600px',
'width': '600px'
}, function () {
plot.resize();
plot.setupGrid();
plot.draw();
});
})
for animation try like this:
$('#graph').animate({'height': '500px','width': '500px'});
demo
for click + animation:
$('#graph').on('click', function(){
$(this).animate({'height': '500px','width': '500px'});
})
Demo

Highcharts - how to have a chart with dynamic height?

I want to have a chart that resizes with the browser window, but the problem is that the height is fixed to 400px. This JSFiddle example has the same problem.
How can I do that? I tried using the chart.events.redraw event handler to resize the chart (using .setSize), but I guess it starts a never-ending loop (fire event handler, which calls setSize, which fires another event handler, etc.).
Just don't set the height property in HighCharts and it will handle it dynamically for you so long as you set a height on the chart's containing element. It can be a fixed number or a even a percent if position is absolute.
Highcharts docs:
By default the height is calculated from the offset height of the
containing element
Example: http://jsfiddle.net/wkkAd/149/
#container {
height:100%;
width:100%;
position:absolute;
}
What if you hooked the window resize event:
$(window).resize(function()
{
chart.setSize(
$(document).width(),
$(document).height()/2,
false
);
});
See example fiddle here.
Highcharts API Reference : setSize().
When using percentage, the height it relative to the width and will dynamically change along with it:
chart: {
height: (9 / 16 * 100) + '%' // 16:9 ratio
},
JSFiddle Highcharts with percentage height
Remove the height will fix your problem because highchart is responsive by design if you adjust your screen it will also re-size.
Alternatively, you can directly use javascript's window.onresize
As example, my code (using scriptaculos) is :
window.onresize = function (){
var w = $("form").getWidth() + "px";
$('gfx').setStyle( { width : w } );
}
Where form is an html form on my webpage and gfx the highchart graphics.
Another good option is, to pass a renderTo HTML reference.
If it is a string, the element by that id is used.
Otherwise you can do:
chart: {
renderTo: document.getElementById('container')
},
or with jquery:
chart: {
renderTo: $('#container')[0]
},
Further information can be found here:
https://api.highcharts.com/highstock/chart.renderTo
I had the same problem and I fixed it with:
<div id="container" style="width: 100%; height: 100%; position:absolute"></div>
The chart fits perfect to the browser even if I resize it. You can change the percentage according to your needs.

Categories

Resources