Related
You can see in the example above that the bars are on top of the text. I am currently solving for this by adjusting the opacity of the bars, but I would really like to just have the text sit on top of the bars.
I have tried using props in the Bar/tick components, as well as using the style attributes, but neither have worked.
Here is my code:
import { FaLock } from "react-icons/fa";
import {
BarChart,
Bar,
Cell,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
Legend,
ResponsiveContainer,
Label,
} from "recharts";
export const MonthlyResults = ({ data }) => {
const CustomTick = (props) => {
const { x, y, payload } = props;
return (
<text
x={x + 20}
y={y + 5}
fontWeight={900}
fill="blue"
z={100}
style={{ fontSize: "1.5rem", zIndex: 100 }}
>
{payload.value.replace(/\w\S*/g, function (txt) {
return txt.charAt(0).toUpperCase() + txt.substring(1).toLowerCase();
})}{" "}
({data[payload.index].count})
</text>
);
};
return (
<div className="min-h-fit w-full justify-center bg-gray-200 rounded-md">
<h1 className="text-center text-2xl my-4 font-semibold">
Top 50 Restaurants in NYC
</h1>
<div className="h-[2000px] w-full">
<ResponsiveContainer>
<BarChart
data={data}
layout="vertical"
margin={{ top: 0, right: 0, left: -61, bottom: 0 }}
barCategoryGap="1"
>
<XAxis type="number" hide domain={[0, "dataMax"]} />
<YAxis
yAxisId={0}
type="category"
dataKey="name"
tick={<CustomTick />}
style={{
fontSize: "1rem",
fontWeight: "bold",
}}
/>
<Tooltip content={() => null} />
<Bar
dataKey="count"
onClick={(e) => {
console.log(e);
}}
style={{ zIndex: 50 }}
z={50}
>
{data.map((entry, index) => (
<Cell
cursor="pointer"
key={`cell-${index}`}
fill="rgba(112, 207, 250, 1)"
/>
))}
</Bar>
</BarChart>
</ResponsiveContainer>
</div>
</div>
);
};
I need help in setting correctly a Flatlist in my React Native app.
What I need is:
I have a View
Inside that view i have a title on top and a bottom below.
Between I want to insert a Flatlist that displays a list of elements, but i want a fixed height and scroll capability to see all elements from the list.
Part of my code:
return (
<Container theme={theme}>
<TitleContainer theme={theme}>
<Title theme={theme}>Destino da publicação:</Title>
</TitleContainer>
<ButtonContainer>
<Option theme={theme} onPress={() => setView('contacts')}>
<Texto theme={theme}>Contactos</Texto>
</Option>
<Option theme={theme} onPress={() => setView('groups')}>
<Texto theme={theme}>Grupos</Texto>
</Option>
</ButtonContainer>
<ContactContainer>
{view === 'contacts' && (
<FlatList
key="contactList"
data={contactListFiltered}
renderItem={renderItemContact}
ListEmptyComponent={() => (
<Text
style={{
color: `${theme.mainColor}`,
textAlign: 'center',
fontSize: VMHSize(811, 14),
}}
>
Sem contatos
</Text>
)}
keyExtractor={(item) => item.email}
/>
)}
{view === 'groups' && (
<FlatList
key="groupListShare"
data={groupListFiltered}
renderItem={renderItemGroup}
ListEmptyComponent={() => (
<Text
style={{
color: `${theme.mainColor}`,
textAlign: 'center',
fontSize: VMHSize(811, 14),
}}
>
Não existem grupos criados
</Text>
)}
keyExtractor={(item) => item}
/>
)}
<ButtonContainer>
<Option onPress={close} theme={theme}>
<MaterialCommunityIcons
name="cancel"
size={VMHSize(811, 25)}
color={theme.mainColor}
/>
<OptionText theme={theme}>Cancelar</OptionText>
</Option>
</ButtonContainer>
</ContactContainer>
</Container>
);
};
I already tried many suggestions I readed, but or the flatlist appears with the height I want but i cant scroll the content, or the flatlist renders all elements pushing the bellow content of the view to outside the view.
To explain the idea if the code:
I´m building a social media app, something alike facebook. I have a view Posts, where i have a flatlist that displays the posts from the feed for the user.
Then, each post have a Options button with many options, one is to share the post with another friend. In the code above, i need to show in a view with a fixed height, a list with the friends. If i have many friends, i need to scroll that list within the limited size view. I´m using another flatlist to list the friends.
Can anybody help me? Thanks!
Well, I resolved my problem with a ScrollView and nestedScrollEnabled prop.
<ScrollView style={{ height: VMHSize(811, 300) }} nestedScrollEnabled>
{view === 'contacts' && (
<FlatList
key="contactList"
data={contactListFiltered}
renderItem={renderItemContact}
ListEmptyComponent={() => (
<Text
style={{
color: `${theme.mainColor}`,
textAlign: 'center',
fontSize: VMHSize(811, 14),
}}
>
Sem contatos
</Text>
)}
keyExtractor={(item) => item.email}
/>
)}
{view === 'groups' && (
<FlatList
key="groupListShare"
data={groupListFiltered}
renderItem={renderItemGroup}
ListEmptyComponent={() => (
<Text
style={{
color: `${theme.mainColor}`,
textAlign: 'center',
fontSize: VMHSize(811, 14),
}}
>
Não existem grupos criados
</Text>
)}
keyExtractor={(item, index) => item + index}
/>
)}
</ScrollView>
I am trying to create multistep form using formik but i am not able to
set form value when on click serach button. when i click search button
then i am set the data and i want to auto field make and model field
how can i do ????
here is my stepper.js page--
const renderStep = (
step,
values,
SearchButtonClick,
setFieldValue,
vehicleData
) => {
switch (step) {
case 1:
return <Form1 values={values} />;
case 2:
return (
<Form2
values={values}
SearchButtonClick={SearchButtonClick}
setFieldValue={setFieldValue}
vehicleData={vehicleData}
/>
);
default:
return <Form1 values={values} />;
}
};
const Stepper = () => {
const [step, setStep] = useState(1);
const [vehicleData, setVehicleData] = useState({});
function SearchButtonClick(data) {
const value={
"vehicleId": "V1",
"rcNo": "OD01AB1234",
"chassisNo": "ODXYZ123",
"engineNo": "ENABC012",
"make": "HYUNDAI MOTOR INDIA LTD ",
"model": "HYUNDAI SANTRO",
"fuel": "PETROL",
"vehicle_type": "Motor Car",
"pollutionNorms": "Not Available",
"mfgYear": 2017
}
setVehicleData(value)
}
const formData = {
PolicystartDate: "",
PolicyendDate: "",
regNo: "OD01AB1234",
make: "",
model: "",
};
function handleSubmit(values) {
debugger;
setStep((step) => step + 1);
console.log({
...values,
PolicystartDate: moment(values.PolicystartDate).toISOString(),
PolicyendDate: moment(values.PolicyendDate).toISOString(),
});
}
return (
<MainWrapper>
<>
{/* <Header title="Multi Step Form using React And Formik" /> */}
<Formik
enableReinitialize
initialValues={{ ...formData }}
onSubmit={handleSubmit}
>
{({
errors,
touched,
isSubmitting,
setFieldValue,
setFieldTouched,
values,
...rest
}) => (
<Form>
{renderStep(
step,
values,
SearchButtonClick,
setFieldValue,
vehicleData
)}
<StepButton step={step} />
</Form>
)}
</Formik>
</>
</MainWrapper>
);
};
export default Stepper;
here is my first Form ----
function Form1(props) {
console.log(props);
return (
<>
<PageHeader
style={{
border: "1px solid rgb(235, 237, 240)",
}}
title="Cover"
/>
<div style={{ display: "flex", justifyContent: "space-between" }}>
<div
style={{
height: "100%",
width: "30%",
marginLeft: "15px",
}}
>
<Field
name="PolicystartDate"
label="Policy Start Date"
component={DatePicker}
isColumn
width={"100%"}
value={props.values.PolicystartDate}
inlineLabel
style={{
flexBasis: "80%",
height: "33px",
width: "100%",
marginTop: "4px",
}}
/>
<Spacer />
<Field
name="PolicyendDate"
label="Policy End Date"
component={DatePicker}
isColumn
width={"100%"}
value={props.values.PolicyendDate}
inlineLabel
style={{
flexBasis: "80%",
height: "33px",
width: "100%",
marginTop: "4px",
}}
/>
<Spacer />
</div>
</div>
</>
);
}
export default Form1;
here is my second form-------
function Form2(props) {
console.log(props);
return (
<>
<StyledLabel>Registration Number</StyledLabel>
<Field
name="regNo"
component={InputComponent}
isColumn
isColumn
style={{
height: "33px",
width: "80%",
}}
/>
<Button
style={{ marginTop: "21px" }}
onClick={() =>
props.SearchButtonClick(props.values.regNo, props.setFiledValue)
}
>
Search
</Button>
<Field
disabled="true"
name="make"
label="Make"
width={"100%"}
isRequired
isColumn
component={InputComponent}
style={{
flexBasis: "80%",
height: "33px",
marginTop: "4px",
}}
/>
<Field
disabled="true"
name="model"
label="Model"
width={"100%"}
isRequired
isColumn
component={InputComponent}
style={{
flexBasis: "80%",
height: "33px",
marginTop: "4px",
}}
/>
export default Form2
set Fields value on Form 2 from props , same as you have setted in Form1
function Form2(props) {
console.log(props);
return (
<>
<StyledLabel>Registration Number</StyledLabel>
<Field
name="regNo"
component={InputComponent}
isColumn
isColumn
style={{
height: "33px",
width: "80%",
}}
/>
<Button
style={{ marginTop: "21px" }}
onClick={() =>
props.SearchButtonClick(props.values.regNo, props.setFiledValue)
}
>
Search
</Button>
<Field
disabled="true"
name="make"
label="Make"
width={"100%"}
isRequired
isColumn
value={props.values.make}
component={InputComponent}
style={{
flexBasis: "80%",
height: "33px",
marginTop: "4px",
}}
/>
<Field
disabled="true"
name="model"
label="Model"
width={"100%"}
isRequired
isColumn
value={props.values.model}
component={InputComponent}
style={{
flexBasis: "80%",
height: "33px",
marginTop: "4px",
}}
/>
export default Form2
My app drop-downs are pretty slow. It especially takes a long time if i go into the Settings Screen and try to change my major. Or anything dealing with adding or editing a major in this specific screen. I really need to make adding or editing a major much faster. I am not sure the reason why editing or adding a major is taking too long. And I am not sure about how to go at making adding and editing a major much faster. So I am posting the entire component and I am commenting parts that deal with adding or editing a major. I am using react-native-material-dropdown.
Here is the entire component code:
import React from 'react';
import PropTypes from 'prop-types';
import { View, ScrollView, Text, TouchableOpacity } from 'react-native';
import { connect } from 'react-redux';
import { compose, withStateHandlers } from 'recompose';
import { Dropdown } from 'react-native-material-dropdown';
import { Icon } from 'react-native-material-ui';
import R from 'ramda';
import { ConnectivityRenderer } from 'react-native-offline';
import NetworkConnectivity from '../error/NetworkConnectivity';
import { toArray } from '../selectors';
import { Container, Switch, SwitchOption } from './common';
import { editStudent } from '../actions';
const propTypes = {
toolbar: PropTypes.elem,
loading: PropTypes.bool,
university: PropTypes.shape({
id: PropTypes.string,
name: PropTypes.string,
}),
universities: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.string,
name: PropTypes.string,
})
),
degrees: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.string,
name: PropTypes.string,
})
),
studentDegrees: PropTypes.arrayOf(
PropTypes.shape({
index: PropTypes.number,
track: PropTypes.string,
})
),
errors: PropTypes.shape({
university: PropTypes.string,
degree: PropTypes.string,
}),
year: PropTypes.string,
onUniversityChange: PropTypes.func,
onTermChange: PropTypes.func,
onDegreeChange: PropTypes.func,
onYearChange: PropTypes.func,
onTrackChange: PropTypes.func,
onAddDegree: PropTypes.func,
onDone: PropTypes.func,
};
const contextTypes = {
uiTheme: PropTypes.object.isRequired,
};
const validate = state => {
const result = {};
if (!state.university.id) {
result.university = 'You should select an university';
}
return result;
};
const enhance = compose(
connect(
({ user, universities, degrees }) => ({
studentId: user.id,
user,
universities: toArray(universities),
degrees: toArray(degrees),
}),
{ editStudent }
),
withStateHandlers(
props => {
return {
university: props.user.university || {},
year: props.user.academicClass || 'freshman',
studentDegrees: R.isEmpty(props.degrees)
? []
: R.isEmpty(props.user.studentDegrees)
? [{ degree_id: props.degrees[0].id, track: 'Major' }]
: R.values(props.user.studentDegrees),
errors: {},
};
},
{
onUniversityChange: () => (value, index, data) => ({
university: data[index],
}),
onYearChange: () => year => ({ year }),
onTrackChange: state => ({ idx, track }) => ({
studentDegrees: R.update(
idx,
R.assoc('track', track, state.studentDegrees[idx]),
state.studentDegrees
),
}),
// Fucntion dealing with degree change
onDegreeChange: (state, props) => ({ idx, index }) => ({
studentDegrees: R.update(
idx,
R.assoc(
'degree_id',
props.degrees[index].id,
state.studentDegrees[idx]
),
state.studentDegrees
),
}),
// Function dealing with degree adding
onAddDegree: (state, props) => () => ({
studentDegrees: R.append(
{
degree_id: props.degrees[0].id,
track: 'Major',
},
state.studentDegrees
),
}),
onRemoveDegree: state => idx => ({
studentDegrees: [
...state.studentDegrees.slice(0, idx),
...state.studentDegrees.slice(idx + 1),
],
}),
// When the user is done with settings.
// This function communicates with the back end to save things in the remote database
onDone: (state, { studentId, editStudent }) => () => {
const errors = validate(state);
if (Object.keys(errors).length !== 0) {
return { errors };
}
editStudent(
studentId,
state.year,
state.university.id,
state.studentDegrees
);
},
}
)
);
// The Settings Component
const FormUserSettings = (props, context) => {
const styles = getStyles(props, context);
return (
<ConnectivityRenderer>
{isConnected => (
isConnected ? (
<Container>
{React.cloneElement(props.toolbar, {
onRightElementPress: props.onDone,
})}
<ScrollView style={styles.container}>
<Text
style={[
styles.title,
props.errors.university ? styles.titleError : {},
]}
>
University
</Text>
// Selecting a university
<Dropdown
label="Select university..."
data={props.universities.map(u => ({ id: u.id, value: u.name }))}
onChangeText={props.onUniversityChange}
value={props.university.name}
/>
{props.errors.university &&
<Text style={styles.errorMessage}>
{props.errors.university}
</Text>}
<View style={{ height: 16 }} />
<Text style={styles.title}>Current Year</Text>
<View style={{ height: 8 }} />
<Switch
value={props.year}
onChange={props.onYearChange}
selectedColor={styles.switchSelectedColor}
unselectedColor={styles.switchUnselectedColor}
>
<SwitchOption text="Freshman" value="freshman" />
<SwitchOption text="Sophomore" value="sophomore" />
<SwitchOption text="Junior" value="junior" />
<SwitchOption text="Senior" value="senior" />
</Switch>
<View style={{ height: 16 }} />
<Text
style={[styles.title, props.errors.degree ? styles.titleError : {}]}
>
Major / Minors
</Text>
{!R.isEmpty(props.degrees) &&
props.studentDegrees.map((sd, idx) => {
const degree = R.find(R.propEq('id', sd.degree_id), props.degrees);
return (
<View
key={`sd-${idx}`}
style={{ flex: 1, height: 96, marginTop: 24 }}
>
<View
style={{
flex: 1,
flexDirection: 'row',
alignItems: 'flex-end',
}}
>
<View style={{ flex: 1 }}>
<Dropdown
style={{ flex: 1 }}
label="Select degree..."
data={props.degrees.map(d => ({
id: d.id,
value: d.name,
}))}
onChangeText={(value, index) =>
props.onDegreeChange({ idx, index })}
value={degree ? degree.name : ''}
/>
</View>
{props.studentDegrees.length !== 1 &&
<TouchableOpacity
style={{ marginBottom: 8, paddingLeft: 24 }}
onPress={() => props.onRemoveDegree(idx)}
>
<Icon name="delete" size={24} />
</TouchableOpacity>}
</View>
<Switch
value={sd.track}
onChange={track => props.onTrackChange({ idx, track })}
selectedColor={styles.switchSelectedColor}
unselectedColor={styles.switchUnselectedColor}
>
<SwitchOption text="Major" value="Major" />
<SwitchOption text="Minor" value="Minor" />
<SwitchOption text="Certificate" value="Cert" />
</Switch>
</View>
);
})}
<TouchableOpacity style={{ padding: 10 }} onPress={props.onAddDegree}>
<Text style={styles.addDegreeText}>+ Degree</Text>
</TouchableOpacity>
</ScrollView>
</Container>
) : (
<Container>
{React.cloneElement(props.toolbar, {
onRightElementPress: props.onDone,
})}
<NetworkConnectivity />
<ScrollView style={styles.container}>
<Text
style={[
styles.titleDisabled,
props.errors.university ? styles.titleError : {},
]}
>
University
</Text>
<Dropdown
label=""
data={props.universities.map(u => ({ id: u.id, value: u.name }))}
onChangeText={props.onUniversityChange}
value={props.university.name}
disabled={true}
editable={false}
/>
{props.errors.university &&
<Text style={styles.errorMessage}>
{props.errors.university}
</Text>}
<View style={{ height: 16 }} />
<Text style={styles.titleDisabled}>Current Year</Text>
<View style={{ height: 8 }} />
<Switch
value={props.year}
onChange={props.onYearChange}
selectedColor={styles.disabledSwitchSelectedColor}
unselectedColor={styles.switchUnselectedColor}
>
<SwitchOption text="Freshman" value="freshman" />
<SwitchOption text="Sophomore" value="sophomore" />
<SwitchOption text="Junior" value="junior" />
<SwitchOption text="Senior" value="senior" />
</Switch>
<View style={{ height: 16 }} />
<Text
style={[styles.titleDisabled, props.errors.degree ? styles.titleError : {}]}
>
Major / Minors
</Text>
// The problem of slowness starts here
// I feel like something here should be improved
{!R.isEmpty(props.degrees) &&
props.studentDegrees.map((sd, idx) => {
const degree = R.find(R.propEq('id', sd.degree_id), props.degrees);
return (
<View
key={`sd-${idx}`}
style={{ flex: 1, height: 96, marginTop: 24 }}
>
<View
style={{
flex: 1,
flexDirection: 'row',
alignItems: 'flex-end',
}}
>
<View style={{ flex: 1 }}>
<Dropdown
style={{ flex: 1 }}
label="Select degree..."
data={props.degrees.map(d => ({
id: d.id,
value: d.name,
}))}
disabled={true}
editable={false}
onChangeText={(value, index) =>
props.onDegreeChange({ idx, index })}
value={degree ? degree.name : ''}
/>
</View>
</View>
<Switch
value={sd.track}
onChange={track => props.onTrackChange({ idx, track })}
selectedColor={styles.disabledSwitchSelectedColor}
unselectedColor={styles.switchUnselectedColor}
>
<SwitchOption text="Major" value="Major" />
<SwitchOption text="Minor" value="Minor" />
<SwitchOption text="Certificate" value="Cert" />
</Switch>
</View>
);
})}
<TouchableOpacity disabled={true} style={{ padding: 10 }} onPress={props.onAddDegree} disabled={true}>
<Text style={styles.addDegreeTextDisabled}>+ Degree</Text>
</TouchableOpacity>
</ScrollView>
</Container>
)
)}
</ConnectivityRenderer>
);
};
FormUserSettings.contextTypes = contextTypes;
FormUserSettings.propTypes = propTypes;
export default enhance(FormUserSettings);
On Android 4.4, ListView separator lines are inconsistent in thickness, and some do not render.
I can't see how this can be a code issue, this is how I render them:
separator: {
height: 1,
backgroundColor: 'grey',
}
...
<ListView
renderSeparator={(sectionID, rowID) =>
<View key={`${sectionID}-${rowID}`} style={styles.separator} />
}
.../>
Here is a screenshot of a View with this problem:
This issue does not happen on iOS or Android 6.
Anyone had this problem before?
Update
I did a test, this is not Android4 issue. It happens on all API version when running on Nexus One device (in android emulator)
I had this issue on iOS and worked around it by adding a hairline margin, like so:
<View
style={{
...styles,
borderWidth: StyleSheet.hairlineWidth,
margin: StyleSheet.hairlineWidth,
}}
>
{// ...row content}
</View>
Just give the height:hairlineWidth in style
I had the same issue and solved changing the view height from a number to StyleSheet.hairlineWidth as some folks said before. Trying to be more visual/specific:
Before:
renderItemSeparator() {
return (
<View style={{ height: .2, backgroundColor: 'rgba(0,0,0,0.3)' }} />
);
}
After:
renderItemSeparator() {
return (
<View style={{ height: StyleSheet.hairlineWidth, backgroundColor: 'rgba(0,0,0,0.3)' }} />
);
}
Actually there is no fix. It's RN "render-canvas-bug".
But I found hack solution.
<ListView
style={Style.listView}
dataSource={data}
renderRow={(data) => this._renderRow(data)}
/>`
Style.listView: {
backgroundColor: '#fff',
}, // or another backgroundColor you need
Then:
_renderRow(goods) {
return (
<View key={'goods_' + goods.id} style={Style.listView_item}>
<TouchableOpacity or View or ...
style={[Style.flex, Style.flexRow, Style.separatorRow, Style.u_paddingVerticalS, Style.u_middle]}
onPress={() => this._xyz(goods)}>
<View>
<AppFont>{goods.name}</AppFont>
</View>
</TouchableOpacity or View or ...>
</View>
);
}
Only important TouchableOpacity style is Style.separatorRow to render your separator. This style should be inside listView_item, where you can use another styles.
listView: {
backgroundColor: '#fff',
},
listView_item: {
paddingHorizontal: em(1.5),
},
flex: {
flex: 1,
},
flexRow: {
flexDirection: 'row',
},
separatorRow: {
marginBottom: 1,
borderBottomWidth: 1,
borderBottomColor: Colors.canvasColor,
},
You can use StyleSheet.hairlineWidth instead of 1 but it's not a must.
I reported it on GitHub
My workaround was to style the containing view and text like this:
const styles = StyleSheet.create({
rowViewContainer: {
flex: 1,
paddingRight: 15,
paddingTop: 13,
paddingBottom: 13,
borderBottomWidth: 0.5,
borderColor: '#c9c9c9',
flexDirection: 'row',
alignItems: 'center',
},
rowText: {
marginLeft: 15,
},
});
This is the ListView:
<ListView
dataSource={this.state.dataSource}
renderRow={(data) => <View style={styles.rowViewContainer}>
<Text style={styles.rowText}>
{data.bb_first_name}
</Text>
</View>}
/>
Looks nice:
This happens because you have empty rows in your data source. You can style your separators to see it
To avoid this just filter your data.
I faced the same issue when trying to render a Divider with a width of 0.5.
It rendered properly on devices with pixel ratio of 2 (e.g. iPhone SE 2nd gen.) but rendered random width on devices with pixel ratio of 3 (e.g. iPhone 12).
As suggested by other answers, using Stylesheet.hairlineWidth fixes the random width issue but the problem was that the width was thinner than 0.5 on devices with pixel ratio of 3.
So this fixed my problem:
import { PixelRatio, View } from 'react-native';
...
export const Divider = () => {
const width = PixelRatio.roundToNearestPixel(0.5);
...
return <View style={{ width }} ... />
}