How do I render vertical victory native legend to the right of chart? - legend

I have the following code and the associated result. However, my goal is to render the pie chart to the left and the legend to the right. Sometimes, my categories are a lot, so I would like to make the legend scrollable.
In summary, what I need help with is displaying the two with 50-50 split of the screen
export default () => {
const { Layout } = useTheme()
return <View style={Layout.rowCenter}>
<VictoryContainer width={400} height={400} style={{ padding: 10 }}>
<VictoryLegend
standalone={false}
centerTitle
orientation="horizontal"
style={{ labels: { fontSize: 20, fill: "white" } }}
gutter={20}
width={400}
colorScale={colorScale || ["tomato", "lightgreen", "gold", "cyan", "navy", 'teal', 'magenta', 'green', 'orange', 'aqua', 'fuchsia', 'purple']}
data={[
{ name: "one" },
{ name: "Two", },
{ name: "Three", },
{ name: "four", },
{ name: "five", }
]}
/>
<VictoryPie
standalone={false}
margin={{
top: 20
}}
width={400}
height={400}
colorScale={colorScale || ["tomato", "lightgreen", "gold", "cyan", "navy", 'teal', 'magenta', 'green', 'orange', 'aqua', 'fuchsia', 'purple']}
labels={() => null}
data={[
{ x: "one", y: 35 },
{ x: "Two", y: 40 },
{ x: "Three", y: 25 },
{ x: "four", y: 55 },
{ x: "five", y: 55 }
]}
/>
</VictoryContainer>
</View>
}

use react native svg and adjust the height, width and distance from left and right using viewBox prop of react native svg, this way we can arrange and display the items in 50-50 split of the screen. Hope this answer helps.

Related

React native svg chart graphs

import React from 'react'
import { BarChart, Grid } from 'react-native-svg-charts'
import { Defs, LinearGradient, Stop } from "react-native-svg";
class ColorBarExample extends React.PureComponent {
render() {
const data = [
{
value: 50,
},
{
value: 10,
svg: {
fill: 'rgba(134, 65, 244, 0.5)',
},
},
{
value: 40,
svg: {
stroke: 'purple',
strokeWidth: 2,
fill: 'white',
strokeDasharray: [ 4, 2 ],
},
},
{
value: 95,
svg: {
fill: 'url(#gradient)',
},
},
{
value: 85,
svg: {
fill: 'green',
},
},
]
const Gradient = () => (
<Defs key={'gradient'}>
<LinearGradient id={'gradient'} x1={'0'} y={'0%'} x2={'100%'} y2={'0%'}>
<Stop offset={'0%'} stopColor={'rgb(134, 65, 244)'}/>
<Stop offset={'100%'} stopColor={'rgb(66, 194, 244)'}/>
</LinearGradient>
</Defs>
)
return (
<BarChart
style={{ height: 200 }}
data={data}
gridMin={0}
svg={{ fill: 'rgba(134, 65, 244, 0.8)' }}
yAccessor={({ item }) => item.value}
contentInset={{ top: 20, bottom: 20 }}
>
<Grid/>
<Gradient/>
</BarChart>
)
}
}
export default ColorBarExample
As this is giving me a simple gradient but i am need a gradient like this. How can i get it in this gradient .
Let me know how can i draw it like this image so that each gradient have some borderradius at the top and and have a custom gradient colors as per image and also can be of small width instead of long.
You can give vertical gradient by this x2={'0%'} y2={'100%'} in Gradient function and for rounded corners you can try this
To change width of bar you may try spacingInner property.
To give gradient to all bars, we should manage svg fill property of data array.
here is the link of your barchart code demo. Please check if it helps.

How to break line of multiple Text List Items when they exceeds it container size?

I am developing a react native app. In the app, I have a iterator mapping multiples types that are show inside a View. Each of these types have an specific color, so that is why I have an each tag for each type.
I have made a simplified example what I want and what is happening.
I want when the Text List Items exceeds its container, that they break to a new line. I tried many ways but don't discover how to do it.
The example: https://snack.expo.dev/#anschau/multiple-text-problem-not-breaking-line
The code:
import React from "react";
import { StyleSheet, Text, View } from "react-native";
const LabelTypes = [
{
styleType: "styleType1",
label: "Extensive Type 1",
},
{
styleType: "styleType2",
label: "Another Extensive Type 2",
},
{
styleType: "styleType3",
label: "Type 3",
},
{
styleType: "styleType4",
label: "Type 4",
},
{
styleType: "styleType5",
label: "Type 5",
},
{
styleType: "styleType6",
label: "Type 6",
},
];
const App = () => {
return (
<View style={[styles.container, {
flexDirection: "row"
}]}>
{
LabelTypes.map((item, index) => (
<>
{ index > 0 && <Text> - </Text>}
<Text style={[styles.label, styles[item.styleType] ]}>{item.label}</Text>
</>
))
}
</View>
);
};
const styles = StyleSheet.create({
container: {
maxWidth: "100%",
marginTop: 50,
marginLeft: 20,
marginRight: 20,
borderWidth: 1,
borderColor: "gray"
},
label: {
color: "black",
},
styleType1: {
color: "blue"
},
styleType2: {
color: "red"
},
styleType3: {
color: "green"
},
styleType4: {
color: "orange"
},
styleType5: {
color: "coral"
},
styleType6: {
color: "pink"
},
});
export default App;
Add to your container's (NOT individual labels') style:
flexWrap: 'wrap'
This will simply let items fill the container's width and fall into a new line when it doesn't fit.

I am using react-native-swiper-flatlist , but my image is not displaying i don't know error

// My deals
const Deals =[{
id:'1',
imageUrl:
'https://upload.wikimedia.org/wikipedia/commons/thumb/2/20/Spaghetti_Bolognese_mit_Parmesan_oder_Grana_Padano.jpg/800px-Spaghetti_Bolognese_mit_Parmesan_oder_Grana_Padano.jpg',
},
{
id:'2',
imageUrl:
'https://upload.wikimedia.org/wikipedia/commons/thumb/2/20/Spaghetti_Bolognese_mit_Parmesan_oder_Grana_Padano.jpg/800px-Spaghetti_Bolognese_mit_Parmesan_oder_Grana_Padano.jpg',
},
{
id:'3',
imageUrl:
'https://upload.wikimedia.org/wikipedia/commons/thumb/2/20/Spaghetti_Bolognese_mit_Parmesan_oder_Grana_Padano.jpg/800px-Spaghetti_Bolognese_mit_Parmesan_oder_Grana_Padano.jpg',
},
{
id:'4',
imageUrl:
'https://upload.wikimedia.org/wikipedia/commons/thumb/2/20/Spaghetti_Bolognese_mit_Parmesan_oder_Grana_Padano.jpg/800px-Spaghetti_Bolognese_mit_Parmesan_oder_Grana_Padano.jpg',
},
]
export default () => {
return (
<SwiperFlatList
autoplay
autoplayDelay={5}
index={3}
autoplayLoop
autoplayInvertDirection
data={Deals}
renderItem={ Deals => { return <Image style={styles.image} source={{uri:Deals.imageUrl}} />}}
showPagination
PaginationComponent={CustomPagination}
/>
);
};
const styles = StyleSheet.create ({
image: {
height: height * 0.5,
width,
},
});
I think your problem is with the image style.
instead of this:
image: {
height: height * 0.5,
width,
},
try setting fixed values, or window-size related values, like:
image: {
height: Dimensions.get('window').height * 0.5,
width: Dimensions.get('window').width,
}

Exporting an array to feed data to separate component

I have dataset, which looks like this:
var items = [
{
id: 1,
name: 'foo',
email: 'foo'
},
{
id: 2,
name: 'foo',
email: 'foo'
},
{
id: 3,
name: 'foo',
email: 'foo'
},
];
module.exports = items;
I'm feeding this data to searchable dropdown, so the data will be visible within the dropdown
The dropdown component, looks like this:
<SearchableDropdown
onItemSelect={(item) => {
const items = this.state.selectedItems;
items.push(item)
this.setState({ selectedItems: items });
}}
containerStyle={{ padding: 5 }}
onRemoveItem={(item, index) => {
const items = this.state.selectedItems.filter((sitem) => sitem.id !== item.id);
this.setState({ selectedItems: items });
}}
itemStyle={{
padding: 10,
marginTop: 2,
backgroundColor: '#ddd',
borderColor: '#bbb',
borderWidth: 1,
borderRadius: 5,
}}
itemTextStyle={{ color: '#222' }}
itemsContainerStyle={{ maxHeight: 140 }}
items={items}
defaultIndex={null}
resetValue={false}
textInputProps={
{
placeholder: "Choose priority level",
underlineColorAndroid: "transparent",
style: {
padding: 12,
borderWidth: 1,
borderColor: '#ccc',
borderRadius: 5,
},
onTextChange: text => console.log(text)
}
}
listProps={
{
nestedScrollEnabled: false,
}
}
/>
</Fragment>
And I imported the dataset with the following import:
import items from '../components/items';
However I'm getting that element type is invalid excepted a string but got object, I've tried previous threads from stackoverflow however nothing seems to solve my problem. Perhaps I'm missing something small that my eyes can't pick up? Any help appreciated.
First, you have to export the array as variable like
items.js
export const items = [
...
...
]
import it into your component.js like as
import {items} from '../path/to/items';
Just for confirmation log it inside your render method
console.log('Array Items', item);
Hope this will help you.

Victory-native's VictoryBar labels not displaying correctly

I cannot get my VictoryBar charts to display labels correctly in my React Native application. The x-axis represents days and y-axis represents values. I would like the chart to display
values above each bar, but it displays the day. I have set the labels property but it does nothing. Nothing happens when I console.log(d) as illustrated. The result of this code is below.
"react-native": "0.59.9"
"victory-native": "^32.0.2"
"react-native-svg": "^9.5.1",
Thanks
<VictoryChart domainPadding={70}>
<VictoryBar
data={bars}
x="label"
y="value"
// animate={{ onLoad: { duration: 1000 } }}
style={{ data: { width: 20, fill: (d) => d.x === 3 ? "#000000" : "#49C6B7" }}}
labels={(d)=>{console.log(d);return d.y}}
/>
<VictoryAxis
//x
tickLabelComponent={<VictoryLabel angle={45} />}
style={{
axis: {stroke: 'grey'},
ticks: {stroke: 'white'},
tickLabels: {fontSize: 12, padding: 3, marginLeft:10, stroke:"white", verticalAnchor: "middle", textAnchor:'start'}
}}
/>
<VictoryAxis
//y
tickFormat={(d)=> numeral(d).format('0.0a')}
dependentAxis
style={{
axis: {stroke: "grey"},
grid: {stroke:'grey'},
tickLabels: {fontSize: 0, padding: 0, stroke:'white'}
}}
/>
</VictoryChart>
labels={({ datum }) => `${datum.y}`}
import { VictoryBar,VictoryChart,VictoryAxis,VictoryTheme } from "victory-native";
<>
<VictoryChart
domainPadding={{ x: 20 }}
>
<VictoryBar
data={[
{ x: "Year 1", y: 150 },
{ x: "Year 2", y: 250 },
{ x: "Year 3", y: 100 },
{ x: "Year 4", y: 750 },
{ x: "Year 5", y: 100 }
]}
style={{
data: { fill: "black", width: 12 }
}}
animate={{
onExit: {
duration: 500,
before: () => ({
_y: 0,
fill: "orange",
label: "BYE"
})
}
}}
/>
</VictoryChart>
<VictoryChart
responsive={false}
animate={{
duration: 500,
onLoad: { duration: 200 }
}}
domainPadding={{ x: 0 }}
theme={VictoryTheme.material}
>
<VictoryAxis />
<VictoryBar
barRatio={1}
cornerRadius={0}
style={{ data: { fill: "#6DB65B" } }}
alignment="middle"
labels={({ datum }) => `${datum.y}`} // <-- important
data={[
{ x: "Year 1", y: 150 },
{ x: "Year 2", y: 250 },
{ x: "Year 3", y: 100 },
{ x: "Year 4", y: 750 },
{ x: "Year 5", y: 100 }
]}
/>
</VictoryChart>
</>