Custom Tooltip for Recharts StackedBarChart - javascript

In my application, I would like to have a StackBarChart component that clearly breaks down the data: https://recharts.org/en-US/examples/StackedBarChart and with any additional information in the tooltip as seen here: https://recharts.org/en-US/examples/CustomContentOfTooltip.
How can I add custom info in the tooltip and show the proper breakdown of data?
When I tried to incorporate code from Typescript Interface for Recharts Custom Tooltip, the only information that would show up in the tooltip would be the Text, not the breakdown of the data (aka A and B which are calls to an API). See code below:
const CustomTooltip = ({ active }: TooltipProps<ValueType, NameType>) => {
if( active ){
return (
<div className = "custom-tooltip">
<p className="Text"> Text: </p>
</div>
);
}
return null;
}
//more code
return (
<>
<Tooltip content = {<CustomTooltip />} labelStyle={{ color: "black" }} />
<Bar dataKey="other" />
<Bar dataKey="A" />
<Bar dataKey="B" />
);
See behavior in code sandbox: https://codesandbox.io/s/stacked-bar-chart-s47i2?file=/src/App.tsx

Related

How to add an emoji button in react?

So I already did this basically 1 year ago but I forgot how to do it, and its not working now though. Here is the LINK
basically I have a like a "smile emoji icon button" and then when I click it I will pass the emoji in my text but it giving me now an error undefined. In the link you can see that it has same thing here.
import './App.scss';
import React, { useState } from 'react'
import 'bootstrap/dist/css/bootstrap.min.css';
import Picker from 'emoji-picker-react';
function App() {
const [chosenEmoji, setChosenEmoji] = useState(null);
const onEmojiClick = (event, emojiObject) => {
setChosenEmoji(emojiObject);
console.log(emojiObject)
};
return (
<div className="App">
<header className="App-header">
{/* {isLogin && user ? <LoginTrue/> : <LoginFalse/>} */}
{chosenEmoji ? (
<span>You chose: {chosenEmoji.emoji}</span>
) : (
<span>No emoji Chosen</span>
)}
<Picker onEmojiClick={onEmojiClick} />
</header>
</div>
);
}
export default App;
but the new update of emoji-picker-react did get different...Is anyone can give me an idea of it? or is there another source of importing emojis..I don't want to use Input-emoji-react its too ugly.
You may find it helpful but the way I personally did it on my project were I also used emoji-picker-react and MaterialUI is through native materialUI emoji icon button like this:
<div className="chat_footer">
{!emojiPicker ? (
<InsertEmoticonIcon onClick={() => setEmojiPicker((prev) => !prev)} />
) : (
<>
<InsertEmoticonIcon
onClick={() => setEmojiPicker((prev) => !prev)}
/>
<EmojiPicker
searchDisabled="true"
previewConfig={{ showPreview: false }}
emojiStyle="google"
onEmojiClick={(e) => setInput((input) => input + e.emoji)}
height={400}
width="40%"
/>
</>
)}
As I said, InsertEmoticonIcon is a MaterialUI icon which I import
Code sandbox link:
This link may help:
https://codesandbox.io/s/emoji-picker-react-4-forked-h846rd?file=/src/App.tsx
Onclick handler has to be Emoji and Event, not Event and then emoji

Component's prop value isn't showing in React.js

I'm trying to make a clone of Spotify where I'm using Spotify-web-API to access all the user data (id, name, playlist info, etc.) And to avoid prop drilling all these data are getting stored in Datalayer with the help of React-Context-api. I have a component Sidebar.js where all the playlist names are getting pulled from the API and will be shown in the sidebar. Inside this component, I also have another component SidebarOption.js to show names of playlists. Although I'm getting the playlist names from the API but when I passed those in the SidebarOption.js component as title prop it isn't showing there. I also console logged the names to be sure. The names are showing in my console but not through the mapping function in SidebarOption component. I've attached a screenshot of what I'm getting in this link Screenshot of console log.
You'll see that outside the mapping function any prop value passed in the SidebarOption component is showing but not the ones inside the mapping function. So any help would be appreciated.
Sidebar.js
function SideBar() {
const [{ playlists }, dispatch] = UseDataLayerValue();
console.log("user playlist from sidebar.js", playlists);
return (
<div className="sidebar">
<img
className="sidebar__logo"
src="https://getheavy.com/wp-content/uploads/2019/12/spotify2019-830x350.jpg"
alt="spotify-logo"
/>
<SidebarOption Icon={HomeIcon} title="Home" />
<SidebarOption Icon={SearchIcon} title="Search" />
<SidebarOption Icon={LibraryMusicIcon} title="Your Library" />
<br />
<strong className="sidebar__title">PLAYLISTS</strong>
<hr />
{playlists?.items?.map((playlist) => {
console.log(playlist.name);
<h2>hi</h2>;
<SidebarOption title={playlist.name} />;
})}
</div>
);
}
SidebarOption.js
function SidebarOption({ title, Icon }) {
return (
<div className="sidebarOption">
{Icon && <Icon className="sidebarOption__icon" />}
{Icon ? <h4>{title}</h4> : <p>{title}</p>}
</div>
);
}
The main problem is, you're using a map. But, you're not returning the value.
You have:
{playlists?.items?.map((playlist) => {
console.log(playlist.name);
<h2>hi</h2>;
<SidebarOption title={playlist.name} />;
})}
Should be:
{playlists?.items?.map((playlist) => {
console.log(playlist.name);
<h2>hi</h2>;
return <SidebarOption title={playlist.name} />;
})}
Here is the Codesandbox to notice:
https://codesandbox.io/s/wizardly-sun-iku99?file=/src/App.js
the problem here is that you are not returning the SidebarOption in the map function you instead can do it like that
{playlists?.items?.map((playlist) => {
console.log(playlist.name);
return (
<>
<h2>hi</h2>;
<SidebarOption title={playlist.name} />;
</>
);
})}
or
{playlists?.items?.map((playlist) => (
<>
<h2>hi</h2>;
<SidebarOption title={playlist.name} />;
</>
))}

How to use mapping in React JS for Image

Hi guys so I'm trying to make some web page about hotel room information using React JS and I wanted to change the name, description, image of the page depending on the room type the user choose. But I don't know how to map the image, can somebody help me to do the mapping ?
I haven't make the button tag to change the room type yet.
Here's my room.js code:
import React from 'react'
import {Row, Col, Container} from "react-bootstrap"
const RoomInfo = [
{
MainPhoto:"",
RoomType:"Superior Twin",
RoomDescription:"",
LittlePhoto:'Photo1.jpg'
},
{
MainPhoto:"",
RoomType:"Double Room Twin",
RoomDescription:"",
LittlePhoto:'Photo1.jpg'
},
]
const Room = () => {
return (
<>
<Container fluid={true} className="p-0">
<Row>
<Col>
<h1 className="text-center"> Check out our room</h1>
</Col>
</Row>
</Container>
</>
)
}
export default Room
I hope I understand your question correctly.
you can do <img src={variable} /> and than assign the variable the link to the picture.
You can using map array like this to render element from an array:
...
<h1 className="text-center"> Check out our room</h1>
{
RoomInfo.map((item, i) => {
return (
<div key={i}>
<img src={item.LittlePhoto} />
</div>
);
});
}
...

Each child in a list should have a unique key prop

Here is a link to a working example of the site: https://codesandbox.io/s/eloquent-kapitsa-kk1ls
The issue I am having is with Buttons.js:
import React, { Component } from "react";
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
import registerIcons from "./FontAwesome";
registerIcons();
const DATA = [
{
href: "https://github.com/",
icon: ["fab", "github"],
label: "Github"
},
{
href: "https://www.linkedin.com/in//",
icon: ["fab", "linkedin"],
label: "LinkedIn"
},
{
href: "...",
icon: ["fas", "file-alt"],
label: "Resume"
},
{
href: "mailto:",
icon: ["fas", "paper-plane"],
label: "Email me"
}
];
const Icon = ({ href, icon, label }) => {
return (
<span className="button">
<a href={href} target="_self" rel="noopener noreferrer">
<FontAwesomeIcon className="icon" icon={icon} size="3x" />
<span className="icon_title">{label}</span>
</a>
</span>
);
};
class Buttons extends Component {
render() {
return (
<div>
{DATA.map(props => (
<Icon {...props} />
))}
</div>
);
}
}
export default Buttons;
I have looked through the other topics related to this issue and none are analogous to my case. I am not passing parameters to the render method - just taking an existing variable and mapping it to produce my output.
I have tried changing the Buttons render method to the code below in addition to a few other permutations of the DATA array without much progress.
<div key={DATA.label}>
{DATA.map(props => (
<Icon {...props} />
))}
</div>
I have also read through the React documentation on keys with no success.
you should change the code with this:
<div>
{DATA.map((props,i) => (
<Icon key={i} {...props} />
))}
</div>
As it is advised not to use index as a key for component. I would say add a random number and do something like below
<div>
{DATA.map((props,i) => (
<Icon key={Math.random()*1000*i} {...props} />
))}
</div>
This is rather a generic approach if you don't have any unique key in your object.
Try
<Icon {...props} key={props.href} />
From react documentation
A good rule of thumb is that elements inside the map() call need keys.
Please take a look to this documentation
https://reactjs.org/docs/lists-and-keys.html#extracting-components-with-keys
The key needs to go on like this:
<div key={DATA.label}>
{DATA.map(props => (
<Icon key={props.label} {...props} />
))}
</div>
As you probably saw in the React documentation on keys you reference, they say
The best way to pick a key is to use a string that uniquely identifies a list item among its siblings.
Each of the objects in your DATA array have unique strings and you can use any of them key={props.href} or key={props.icon[1]}. I used props.label in the answer above but the point is it doesn't have to be totally unique in all the world, it just needs to be unique compared to the other items in the list.

How do I pass a component as a prop in React and Typescript?

I am new to React and am building a tab component using Material UI's Tabs component. I'd like to place the Material UI badge component within the Tab component's label prop, but I'm not sure how to go about this.
The Tab component looks as such:
<Tab
key={i}
label={label}
{...globalTabProps}
{...tabProps}
classes={{
wrapper: cx('MuiTab-wrapper'),
}}
/>
I'm trying to add the badge as such:
const label = {
<Badge
color="primary"
className={
badgeProps.badgeContent === ''
? classNames(classes.MuiBadge, classes.MuiBadgeDotted)
: classNames(classes.MuiBadge, classes.MuiBadgeNumber)
}
badgeContent={''}
invisible={false}
{...globalBadgeProps}
{...badgeProps}
></Badge>
};
Of course, this errors out (parsing error), but I don't think this is the correct way to handle this anyway.
Would anyone be able to point me in the right direction?
Many thanks!
You should wrap it with (), like so.
const label = (
<Badge
color="primary"
className={
badgeProps.badgeContent === ''
? classNames(classes.MuiBadge, classes.MuiBadgeDotted)
: classNames(classes.MuiBadge, classes.MuiBadgeNumber)
}
badgeContent={''}
invisible={false}
{...globalBadgeProps}
{...badgeProps}
></Badge>
)
Note the () wrapping it.
Then do it like so:
<Tab
key={i}
label={label}
{...globalTabProps}
{...tabProps}
classes={{
wrapper: cx('MuiTab-wrapper'),
}}
/>
What it is done inside:
const WhateverComponent = (props) => (
<div>
...
{props.label}
</div>
);

Categories