Resium - Adding a new entity within Viewer/Scene causes the entire scene to re-render - cesiumjs

I want to dynamically add / remove entities from a scene but doing so causes the entire scene to re-render.
On pure cesium, calling viewer.entities.add does not have the same effect. Is this possible to achieve with Resium as well?
In the notional example below I have added a button that switches an Entity containing a point graphic with an identical one. Upon clicking the button, the whole scene reloads:
export default function Test() {
const [swapped, setSwapped] = React.useState(false);
return (
<>
<div
onClick={() => {
setSwapped(!swapped);
}}
style={{ position: "absolute", top: 25, left: 25, zIndex: 2 }}
>
swap pins
</div>
<Resium.Viewer
full
style={{
zIndex: 1,
}}
>
<Resium.Scene debugShowFramesPerSecond={true}>
{swapped ? (
<Resium.Entity
point={{ pixelSize: 10 }}
position={Cartesian3.fromDegrees(
longitude,
latitude,
altitude
)} />
) : (
<Resium.Entity
point={{ pixelSize: 10 }}
position={Cartesian3.fromDegrees(
longitude,
latitude,
altitude
)} />
)}
</Resium.Scene>
</Resium.Viewer>
</>
}

Related

How to Override MUI CSS in a React Custom Component which uses MUI Component in it?

Below is the Custome Component which i created in Reactjs and used in different component :
function SearchBox({ handle, placeholder, inputType, ...props}) {
return (
<Box
sx={{
display: 'flex',
alignItems: 'flex-end',
margin: 1,
marginTop: 0,
maxHeight: '30px'
}}
>
<TextField
sx={{
fontSize: '12px',
width: '100%'
}}
variant={inputType || 'standard'}
InputProps={{
startAdornment: (
<InputAdornment position='start'>
<SearchIcon
sx={{
color: 'action.active',
mb: 0.2,
display: 'flex',
alignItems: 'flex-end'
}}
/>
</InputAdornment>
),
placeholder: placeholder || 'Search'
}}
onChange={handle}
/>
</Box>
);
}
I am using this Component in Some Other Component <SearchBox handle={Keyword}/>
so how to override css for TexField and Box of the SearchBox component? i don't want to touch the SearchBox need to override css properties from the place where i am using this component.
When i did Inspect on the Browser i saw something like this <div class="MuiBox-root css-1uqe0j">...</div>
what is css-luqe0j ?
Can Anyone Help me out with this.
If you don't want to modify the SearchBox component at all, you have a few options, the most reasonable of which (IMO) is to just wrap the SearchBox component in a styled component that then targets elements contained within the SearchBox (it's child), for example:
const SearchBoxStyleOverrides = styled("div")({
".MuiBox-root": {
padding: "2rem",
backgroundColor: "green"
},
".MuiSvgIcon-root": {
color: "red"
},
".MuiInput-input": {
backgroundColor: "yellow"
}
});
export default function YourApp() {
return (
<SearchBoxStyleOverrides>
<SearchBox />
</SearchBoxStyleOverrides>
);
}
Which produces: (ugliness is for effect)
Working CodeSandbox: https://codesandbox.io/s/peaceful-dubinsky-wjthtt?file=/demo.js
And to answer your secondary question ("what is css-luqe0j ?"), that is the generated css class name for the component -- you don't want to target an element using those because they will frequently change.

Add conditional CSS property in React

I want to add conditional CSS property to a div in such a way that if particular condition is true then only it will applied. Below is my code.
const Select = ({
handleClick,
title,
permission,
}: SelectProps) => {
return (
<div
onClick={handleClick}
style={{
marginTop: '16px',
cursor: 'pointer',
pointerEvents <-- make this property conditional
${({ permission }) => permission && `pointerEvents: none;`} <-- tried this but not working
}}
>
<Title>{title}</Title>
</div>
);
};
export const RenderSelectBlock = () => {
const checkUserPermission = checkUserPermission();
return (
<Select
handleClick={() => setSelectType('Google')}
title="Google"
checkUserPermission={checkUserPermission}
/>
<Select
handleClick={() => setSelectType('Microsoft')}
title="Microsoft"
checkUserPermission={checkUserPermission}
/>
<Select
handleClick={() => setSelectType('Apple')}
title="Apple"
checkUserPermission={checkUserPermission}
/>
<Select
handleClick={() => setSelectType('Facebook')}
title="Facebook"
checkUserPermission={checkUserPermission}
/>
)
);
};
So here in the last Select where title is Facebook, I want to disable it if the user don't have permission i.e. permission = false. Basically pointerEvents property should only be added for title= Facebook and should be set to none if permission = false.
You best option is to avoid style entirely and use className, then include a second class (maybe no-pointer-events) for the pointer-events you want to optionally include:
<div
className={`main-class ${permission ? "no-pointer-events" : ""}`}
But if you want to do it with style, you could use undefined for when you don't want to specify it:
<div
style={{
marginTop: '16px',
cursor: 'pointer',
pointerEvents: permission ? "none" : undefined,
}}
You could also define the style object before reaching this point in the code:
const style = {
marginTop: '16px',
cursor: 'pointer',
};
if (permission) {
style.pointerEvents = "none";
}
Then use it:
<div
style={style}
Sometimes you'll see people do this with multiple properties via spread syntax:
<div
style={{
marginTop: '16px',
cursor: 'pointer',
...(permission ? {pointerEvents: "none"} : undefined),
}}
...undefined is fine in an object literal (it doesn't add any properties).

How do I display charts in the hyperion tool container

after playing around with the Data Visualization API for autodesk forge (https://forge.autodesk.com/en/docs/dataviz/v1/developers_guide/advanced_topics/integrate_bim360/) I've added an additional button to the HyperionToolContainer which shows on the left side of the application, when clicked the button shows a list of all the different types of information that the sensors in the application detect.
I'd like to set it up so that when the user clicks on one of these information types a popup window is created which displays the relevant charts for every sensor which can detect that info type, ideally arranged in a grid.
Anyone know how I could get this to work? I believe it probably mean having some way to import the chart data over from the dashboard.
Here's the code I've added to HyperionToolContainer.jsx to make the button
<IconButton
className="viewer-button"
onClick={handleViewerButtonClick}
ref={props.data.length > 0 ? setViewerButtonAnchor : null}
>
<LayersIcon id="layers-icon" />
</IconButton>
<ClickAwayListener onClickAway={handleClickAway}>
<Popper
className="popper"
open={showViewer}
anchorEl={viewerButtonAnchor}
placement="left-start"
disablePortal={false}
modifiers={{
flip: {
enabled: true,
},
preventOverflow: {
enabled: true,
boundariesElement: "scrollParent",
},
arrow: {
enabled: true,
element: arrowRef,
},
}}
>
<React.Fragment>
<span className="arrow" ref={setArrowRef} />
<Typography id="viewer-typography" component="div">
{props.data.forEach((floor) => {
floor.children.forEach((child) => {
child.propIds.forEach((property) => {
let alreadyAdded = false;
let newProperty = {
children:[],
id: property,
name: property,
}
propertyHolder.forEach((propId) => {
if (propId.id == property) {
alreadyAdded = true;
}
});
if (!alreadyAdded) {
propertyHolder.push(newProperty);
}
});
});
})}
{propertyHolder.length > 0 ? (
<div id="viewer-tree-view">
<BasicTree
data={propertyHolder}
onMouseOver={onMouseOver}
onMouseOut={onMouseOut}
onLabelClick={onLabelClick}
onIconClick={onIconClick}
expanded={expandNodeId}
selectedNodeId={selectedNodeId}
onLabelRequest={createLabel}
/>
</div>
) : (
<span>No property data found.</span>
)}
</Typography>
</React.Fragment>
</Popper>
</ClickAwayListener>

React-Google-Map multiple Info window open

I am currently building a google map api using react-google-maps and I would like to create multiple markers to display info of cities around the world on the info window. But since they are all from the html object. Whenever I clicked on one marker, all info windows will be opened. If there a way to fix this? Sample code:
<GoogleMap
defaultZoom={3}
defaultCenter={{ lat: 40.452906, lng: 190.818206 }}
>
<Marker id = "mark1"
options={{icon: Mark1}}
position={{ lat: 34.4076645, lng: 108.742099 }}
onClick={props.onToggleOpen}
>
{props.isOpen && <InfoWindow id = "info1"
onCloseClick={props.onToggleOpen}
>
<div> content1 </div>
</InfoWindow>}
</Marker>
<Marker
options={{icon: Mark2}}
position={{ lat: 35.6958783, lng: 139.6869534 }}
onClick={props.onToggleOpen}
>
{props.isOpen && <InfoWindow
onCloseClick={props.onToggleOpen}
>
<div> content2 </div>
</InfoWindow>}
</Marker>
</GoogleMap>
In your code, onClick of Marker you just call {props.onToggleOpen}, which i hope toggles a flag. Here you should send which marker you are clicking so you need to modify your onClick to something like below
onClick={() => { props.onToggleOpen("mark1"); }}
In the above line, Mark1 should be a unique value that you can use to identify the respective Marker. You can replace this with the marker id or of something that will be unique to the respective Marker.
Second, you need to modify onToggleOpen to toggle the flag for the respective marker which is identified by the argument it receives(the unique value you send from `onClick). You can use an array like data structure to store this value.
Then you need to show your InfoWindow based on the flag respective to the Marker. Considering isOpen will be an array of flags(after incorporating the above changes), one would show InfoWindow using condition something like below
<Marker id = "mark1"
options={{icon: Mark1}}
position={{ lat: 34.4076645, lng: 108.742099 }}
onClick={() => { props.onToggleOpen("mark1"); }}
>
{props.isOpen["mark1"] && <InfoWindow id = "info1"
onCloseClick={() => { props.onToggleOpen("mark1"); }}
>
<div> content1 </div>
</InfoWindow>}
</Marker>
Hope that leads you to a right direction.

ReactNative viewport change with GoogleMaps geolocation search

I'm using ReactNative with the GoogleMaps API (by Airbnb). I implemented the GoogleMaps geolocation search, and am receiving a lat/long response back as json.
Now I'm having trouble re-rendering the map to display at the searched lat/long.
So far to fix this I have tried:
Changing the state of the region attribute of MapView
Changing the state of the initialRegion attribute of MapView
Different combinations of onChange and region, none of which have worked.
Would appreciate hearing suggestions of what to try next - you can find my complete code here.
you can change your code to be like this
render() {
return (
<View style={styles.container}> // add a container view with absolute position same as map
<MapView
provider={ PROVIDER_GOOGLE }
style={styles.container}
region={this.state.locationCoordinates} // change from initialRegion to region
zoomEnabled={true}
scrollEnabled={true}
>
<MapView.Marker
coordinate={{
latitude: 37.7749,
longitude: -122.4194,
}}
/>
</MapView>
<View style={styles.inputContainer}> // remove input container from inside the MapView
<TextInput
placeholder="Where to?"
style={ styles.input }
onChangeText={this.handleLocationInput}
value={this.state.locationInput}
onSubmitEditing={this.handleSubmit.bind(this)}
/>
</View>
</View>
);
}