google map Marker update on clicking on Div - angularjs

I am new to google maps. right now I'm using ng-map with angularjs. I am finding it difficult to put animations on the makers (like bounce) when I click on a div. Can anybody tell me how can I do that?

I've written an example of how to animate a marker by clicking on a Div element (See the div under the map which has the text "Div element - Click me to toggle marker animation!"). It can be found here:
http://plnkr.co/edit/KATXex?p=preview
The code to animate the marker is as follows:
if (marker.getAnimation() !== null) {
marker.setAnimation(null);
} else {
marker.setAnimation(google.maps.Animation.BOUNCE);
}
Note that to get this to work properly I had to set the marker's animation property to null in the "on" event e.g.
$scope.$on('mapInitialized', function(evt, evtMap) {
map = evtMap;
var mapMarker = map.markers[0];
mapMarker.setAnimation(null);
marker = mapMarker;
});
By default it is undefined, which means that without this step you'd normally have to click on the marker twice, once to set the animation to null, second to set the animation e.g. to BOUNCE. The issue with "undefined" may be an issue with the ng-maps library.

Related

Show PopupMenu in Ag-Grid

How can I show programmatically the column PopupMenu in Ag-Grid?
PopupMenu Ag-Grid
With the gridApi you can hide it, but not show it
gridApi.hidePopupMenu()
I try also with the FilterInstance and the columnApi, but I haven't found anything that works
gridApi.getFilterInstance(colKey)
gridColumnApi?.getColumn(colKey) ...
Thanks
you can add a little workaround to open the filter popup:
// find the header menu button for the desired column
const colElement = document.querySelector("div[col-id='" + desiredColumn.getColId() + "'] > .ag-cell-label-container > .ag-header-cell-menu-button");
colElement.dispatchEvent(new Event("click")); // simulate a click on the menu button
// the next part ist to switch to the filter tab:
setTimeout(() => { // give the browser some time to render the menu
const tabElement = document.querySelectorAll("div.ag-tabs-header > .ag-tab")[1]; // select the filter tab
if (!tabElement.classList.contains("ag-tab-selected")) { // if the filter tab is not selected already
tabElement.dispatchEvent(new Event("click")); // click the filter tab
}
}, 10);
Basically, you locate the button in the DOM and execute a virtual click on it. It's not pretty but it works well, maybe we'll get an API for this in the future.
What you're wanting to do is to access getFilterInstance() of the Ag Grid API. Here's the relevant documentation: https://www.ag-grid.com/javascript-grid/filter-api/
Here's one way of accessing, and setting the filter using the getFilterInstance method
var FilterComponent = gridOptions.api.getFilterInstance('Status');
FilterComponent.selectNothing(); //Cleared all options
FilterComponent.selectValue('Approved') //added the option i wanted
FilterComponent.onFilterChanged();
Here's a related Stackoverflow question: how to pre-set column filter in ag-grid

how to set a text for a group in vis.js using groupTemplate

I have an application and using vis.js to build timeline events.
I'm using React.
I want to add an icon near each event, so I using groupTemplate and I want to render there a component with group text and icon.
in the options I add:
groupTemplate: (item, element) => {
if (!item) return;
ReactDOM.render(<TimelineGroupComp item={item}/>, element);
}
TimelineGroupComp component render function:
return (
<div className="primary-wrapper" key={this.props.item.content}>
<div style="background-image:url(../images/myIcon.svg);"/>
</div>
);
I get the correct Icon but the text is the item.id instead item.content.
I try to add a span with the correct text in the TimelineGroupComp but it renders also the item.id, not only the correct text.
Also I have another problem: when I collapse/expaned the group, I have an error in the console:
Warning: render(...): It looks like the React-rendered content of this
container was removed without using React. This is not supported and will
cause errors. Instead, call ReactDOM.unmountComponentAtNode to empty a
container.
and the group is render normal, ignored my component.
I know this post is almost a year old, but I thought I'd post the answer to this question anyways for anyone who gets the same issue in the future. I've had the same issue and this is how I fixed it.
Starting with React 16, if you want to use React templates in Vis Timeline you'll have to use React.createPortal in the groupTemplate option, see https://jsfiddle.net/api/post/library/pure/.
For the code above, the correct groupTemplate would be:
groupTemplate: (item, element) => {
if (!item) return;
ReactDOM.createPortal(
ReactDOM.render(<TimelineGroupComp item={item}/>, element),
element
)
}

Change text when image is displayed on scroll react

I'm building a portfolio website with React with large full width vertically scrolling images. There is a single text box on the side of the webpage that I would like to display the title of each image as each image comes into view.
Any recommendations on how to change the text in a DIV when an image comes into view? I'm not even sure what to search to find an answer to this. Any help is much appreciated. Thanks!
You can attach an onscroll listener to detect when the user scrolls. Inside the listener, you need to do some math to calculate which element is currently viewed. The variables you can use for the calculation are scrollTop (on the container, used to determine the current scroll position) and the clientHeight of each element.
let nameDisplayDiv = document.getElementById('display')
let containerDiv = document.getElementById('container')
function refresh() {
let scrollTop = containerDiv.scrollTop + containerDiv.clientHeight / 2
let height = 0
for (let child of containerDiv.children) {
let top = height
let bottom = height += child.clientHeight
if (top < scrollTop && bottom > scrollTop) {
// Found the element that's currently viewed!
nameDisplayDiv.innerHTML = child.style.backgroundColor
break
}
}
}
containerDiv.onscroll = refresh
Here's a working fiddle:
https://jsfiddle.net/uxh91Leq/2/

React-slick Slider stays on same page if slides items are changed

I am stuck with an issue with react-slick. The subject line may not make sense, but I will try to explain the scenario in detail. See this example fiddle to see the issue in action.
var DemoSlider = React.createClass({
getSlides(count) {
var slides = [];
for(var i = 0; i < count; i++) {
slides.push((<img key={i} src='http://placekitten.com/g/400/200' />));
}
return slides;
},
render: function() {
var settings = {
dots: false,
infinite: false,
slidesToShow: 3,
slidesToScroll: 3
}
var slides = this.getSlides(this.props.count);
return (
<div className='container'>
<Slider {...settings}>
{ slides }
</Slider>
</div>
);
}
});
In this demo, initially the slider shows 20 slides (3 per page). The idea is that if you click the button, it will generate a random number, which would be the new number of slides. The code is fairly simple and self-explanatory.
To reproduce the problem,
1. keep on clicking Next arrow until you reach the last slide.
2. click on the button that says 'Click' to generate a new random number of slides.
My expectation was that the slide will go back to the first slide but not to stay on the page where it previously was. Even worse, if the new number of slides is lower than the previous number, the user will see a blank page with no slides. On clicking Previous error, he/she can go to the previous slides, and everything works normally but the initial display ruins the user experience.
Is there something I am missing to add in the code, or is this a bug?
Thanks,
Abhi.
I would say it is rather a buggy behavior, but still you can achieve what you want by forcing a redraw after new collection has been passed as props, by resetting react's key:
<DemoSlider key={Date.now()} count={this.state.count}/>
UPDATED FIDDLE
Quick workaround: When you change to a new set of slides, remove the component, and reconstruct it again. It would then start with the first slide. You can do this by incrementing the key attribute of DemoSlider.
For a proper fix, you'd need to tell the component to change the 'current slide', so that it's not looking at a slide index beyond the end, but a casual look at the source at https://cdnjs.cloudflare.com/ajax/libs/react-slick/0.11.0/react-slick.js suggests it currently does not allow this. A change would need to be made to InnerSlider.componentWillReceiveProps() to check state.currentSlide against props.slidesToShow and state.slideCount.
It would also benefit from allowing currentSlide to be passed as props.

react-highcharts how to call reflow?

I use kirjs/react-highcharts plugin for react but I have no idea how to get Highchart component in order to call reflow like: $('#container1').highcharts().reflow()
From docs its tells:
For access to methods & properties from the Highcharts library you can use ReactHighcharts.Highcharts. For example, the Highcharts options are available via ReactHighcharts.Highcharts.getOptions().
but I don't see there any reflow() method.
Any ideas?
Edit
its located under ReactHighcharts.Highcharts.charts so I can call
ReactHighcharts.Highcharts.charts[0].reflow()
but it has list of all highchart instances so I have no information what index is mine
I am using highcharts-react-official and highcharts. They are available via npm . Although I am using different packages, the working principle should be the same.
The way of using reflow() function in react-highchart is also Highcharts.charts[i].reflow(). I have prepared 2 code sandboxes for the demonstration. The first code sandbox shows the way of re-flowing every chart, and the second code sandbox shows the way of re-flowing a particular chart.
The first code sandbox link is here.
There is a button on App.js to hide and show highchart divs.
The child component is React.memo (for performance optimization), therefore the hidden highchart will not be auto resized after it becomes visible.
To let every chart window resize with respect to the window size. The following code is placed in App.js. It looks for all existing charts and re-flow them:
for (var i = 0; i < Highcharts.charts.length; i++) {
if (Highcharts.charts[i] !== undefined) {
Highcharts.charts[i].reflow();
}
}
The second code sandbox link is here.
Almost the same as the first code sandbox, but there is a ref array of referencing every chart.
The chart which needs re-flowing is placed with an id in its chart option.
Iterate every chart and get the index of the chart with that id e.g. "secondChart" for this example.
for (var i = 0; i < chartRef.current.length; i++) {
if (
chartRef.current[i].chart.userOptions.id !== undefined &&
chartRef.current[i].chart.userOptions.id === "secondChart"
)
Highcharts.charts[chartRef.current[i].chart.index].reflow();
}
Re-flow that chart.
The Reflow can be set with event load in options.
Workaround: You have to set reflow() using setTimeout() this will trigger the resizing. Time is set to 0 to avoid delay.
Solution
const options = {
chart: {
type: 'column',
style: {},
events: {
load() {
setTimeout(this.reflow.bind(this), 0);
},
},
},
title: 'Column Chart',
}
Usage
<HighchartsReact highcharts={Highcharts} options={options} />

Resources