const user1 = [
{
id: 1,
orderDetails: [
{
id: 1,
custFN: 'Jon',
custLN: 'Smith',
serverDetails:
[{
id: 123,
sFN: 'Barack',
sLN: 'Obama',
}],
orderFinish: false,
}
],
shopF: [
{
maxPX: 10,
maxPY: 10,
}
],
furniture: [
{
id: 1,
type: 'table',
pX: 2,
pY: 0,
label: 'VIP Table',
color: 'green',
},
{
id: 2,
type: 'table',
pX: 2,
pY: 1,
label: 'VIP Table',
color: 'green',
},
{
id: 3,
type: 'chair',
pX: 1,
pY: 0,
label: 'VIP Chair',
color: 'brown',
},
{
id: 4,
type: 'chair',
pX: 1,
pY: 1,
label: 'VIP Chair',
color: 'pink',
},
],
}
];
My app is like a dining area where there are tables, chairs, plants etc. Think of it as tiles. So anyway,
Above is my sample data. shopF determines the maximum tiles that will be made(more like x and y coordinates). furniture consists of its position, type of furniture etc.
My problem is that I want to render an element that will serve as tiles and while looping it, determine if a furniture exists in x and y coordinates. I'm thinking of nested for loop.
return (
<React.Fragment>
{
// For loop y
// If furniture is equal to y then render also furniture else just render empty tiles
// For loop x
// If furniture is equal to x then render also furniture else just render empty tiles
}
</React.Fragment>
);
I've tried using map functionality but I don't know how to exactly do it.
Below image is the layout for the 'tiles' and its x and y coordinates.
Here's how I would do it, first create a Tilemap using this method:
const BuildTilesMap = (data, sizeX, sizeY) => {
let arr = new Array(sizeY).fill(null).map(() =>
new Array(sizeX).fill(null).map(() => ({
type: "empty" // chnage this to fit your need
}))
);
for (const item of data) {
console.log(item);
arr[item.posY][item.posX] = item;
}
return arr;
};
Then render a Row which would have a simple div which style set display: flex inside with an map of items like so:
const RenderRow = ({ data }) => {
return (
<div style={{ display: "flex" }}>
{data.map(e => (
<Tiles data={e} />
))}
</div>
);
};
const Tiles = ({ data }) => {
return (
<div style={{ height: 80, width: 80, border: "1px solid #555" }}>
{data.type}
</div>
);
};
Here's the codesandbox
Related
I would like to be able to provide a custom layer on each of my bars in a Nivo responsive bar chart. I have been using this guide as a reference. I am creating a warning level and would like to have a line representing that level set on each bar. The issue I have is that the level is moving around when resizing the page.
The expected response upon screen resizing is for the warning level line to retain its expected position on the chart. What I am getting instead is the warning line moving from its desired position.
"next": "~12.2.4",
"#nivo/bar": "~0.79.1",
"#nivo/core": "~0.78.0",
My chart component using mock data -
import CardComponent from '#components/CardComponent';
import NivoWrapper from '#components/NivoWrapper';
import {
ResponsiveBar,
} from '#nivo/bar';
import React from 'react';
const data = [
{
x: '0',
name: 'weight5',
current: 200,
warningLevel: 100,
},
{
x: '1',
name: 'weight2',
current: 300,
warningLevel: 150,
},
{
x: '2',
name: 'weight3',
current: 400,
warningLevel: 200,
},
{
x: '3',
name: 'weight4',
current: 500,
warningLevel: 250,
},
{
x: '4',
name: 'weight5',
current: 600,
warningLevel: 300,
},
];
const MarginTop = 0;
const Marginright = 24;
const Marginbottom = 24;
const Marginleft = 64;
function Line({ bars, xScale }) {
return (
{bars.map((bar: any) => {
return (
<line
key={bar.key}
y1={bar.absY}
y2={bar.absY + bar.height}
x1={xScale(bar.width - bar.data.data.warningLevel - bar.data.data.warningLevel)}
x2={xScale(bar.width - bar.data.data.warningLevel - bar.data.data.warningLevel)}
stroke="black"
/>
);
})}
);
}
function PackageStockLevelChart() {
return (
<NivoWrapper>
<ResponsiveBar
data={data}
indexBy="name"
keys={['current']}
layout="horizontal"
enableLabel={false}
axisLeft={{
tickValues: 7,
}}
margin={{
top: MarginTop, right: Marginright, bottom: Marginbottom, left: Marginleft,
}}
enableGridY={false}
colors="green"
legendLabel="legend label"
legends={[{
dataFrom: 'keys',
anchor: 'bottom-right',
direction: 'column',
itemWidth: 80,
itemHeight: 16,
translateY: -16,
}]}
layers={['axes', 'bars', Line, 'legends']}
/>
</NivoWrapper>
);
}
export default PackageStockLevelChart;
View before resizing -
View before resizing
During / After resizing
View during after reszing
Im using the e-charts libary for creating a bar chart for my data .
like so :
option.series = [
{
name: 'buy',
type: 'bar',
stack: 'one',
data: Object.values(chartData?.data || {}).map(elem => -elem.buy?.total),
color: colors.bought,
label: {
show: true,
position: "bottom",
formatter: (value) => Math.round(Math.abs(value.data))
},
tooltip: {
formatter: (data) => Math.abs(data.value).toString()
},
// barWidth:this.data
},
{
name: 'sell',
type: 'bar',
stack: 'one',
data: Object.values(chartData?.data || {}).map(elem =>elem.sell?.total),
color: colors.sold,
label: {
show: true,
position: "top",
formatter: (value) => Math.round(Math.abs(value.data))
},
tooltip: {
formatter: (data) => Math.abs(data.value).toString()
},
},
{
name: 'profite',
type: 'bar',
stack: 'two',
barGap: '-100%',
z: 100,
data: Object.values(chartData?.data || {}).map(elem => elem.sell?.profit),
color: colors.profit,
label: {
show: true,
position: "insideTop",
textBorderWidth: -1,
offset: [0, -20],
formatter: (value) => Math.round(Math.abs(value.data))
},
tooltip: {
formatter: (data) => Math.abs(data.value).toString()
},
},
]
im trying to set a different width for each bar depending on the value of each bar .
on data property i get a list of numbers rendering .
When i try to add a barWidth property all i can do is change all of the bars in the same chrts like so for example:
barWidth: ${getBarWidth((Object.values(chartData?.data || {}).map((elem) => elem.sell?.amount)))}%
so i returne a different value of my data each time but it didnt changed each bar according to its value (either buy, sell and so on).
Thanks in adavance.
As you pointed out, barWidth sets the width of all the bars of a bar series. And I don't think there is a way to set the width of each bar in the same bar series.
What you should use instead is a custom series.
Custom series have a parameter called renderItem, where you write the render logic of the chart. It's where you'll be able to display custom shapes (custom sized bar in your case), using graphics.
Here is an example I found on their website, doing pretty much what you're looking for.
var container = document.getElementById('main');
var chart = echarts.init(container);
const colorList = [
'#4f81bd',
'#c0504d',
'#9bbb59',
'#604a7b',
'#948a54',
'#e46c0b'
];
const data = [
[10, 16, 3, 'A'],
[16, 18, 15, 'B'],
[18, 26, 12, 'C'],
[26, 32, 22, 'D'],
[32, 56, 7, 'E'],
[56, 62, 17, 'F']
].map(function (item, index) {
return {
value: item,
itemStyle: {
color: colorList[index]
}
};
});
chart.setOption({
title: {
text: 'Profit',
left: 'center'
},
tooltip: {},
xAxis: {
scale: true
},
yAxis: {},
series: [
{
type: 'custom',
renderItem: function (params, api) {
var yValue = api.value(2);
var start = api.coord([api.value(0), yValue]);
var size = api.size([api.value(1) - api.value(0), yValue]);
var style = api.style();
return {
type: 'rect',
shape: {
x: start[0],
y: start[1],
width: size[0],
height: size[1]
},
style: style
};
},
label: {
show: true,
position: 'top'
},
dimensions: ['from', 'to', 'profit'],
encode: {
x: [0, 1],
y: 2,
tooltip: [0, 1, 2],
itemName: 3
},
data: data
}
]
});
#main {
width: 600px;
height: 400px;
}
<html>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.3.2/echarts.min.js"></script>
<div id="main"></div>
</body>
</html>
I want to get the filtered data from MUI DataGrid Table and want to send it to backend
Please suggest how should I save the filter condition data .
export default function MultiFilteringGrid() {
const { data } = useDemoData({
dataSet: 'Commodity',
rowLength: 200,
maxColumns: 6,
});
const [filterModel, setFilterModel] = React.useState({
items: [
{ id: 1, columnField: 'commodity', operatorValue: 'contains', value: 'rice' },
{ id: 2, columnField: 'quantity', operatorValue: '>=', value: '20000' },
],
});
return (
<div style={{ height: 400, width: '100%' }}>
<DataGridPro
{...data}
filterModel={filterModel}
onFilterModelChange={(model) => setFilterModel(model)}
/>
</div>
);
}
I am using react-flow to create a node graph. There are little dots that appear above and below each node to create new edges. The selection and drop zones for these edges are so pixel accurate that it makes it hard for users to link items. Is there any way to increase the connection zone? I want users to be able to drag an edge to anywhere on the node and it will link the two together.
import ReactFlow, { removeElements, addEdge, isNode, Background, Elements, BackgroundVariant, FlowElement, Node, Edge, Connection, OnLoadParams } from 'react-flow-renderer';
const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node);
const onElementClick = (_: MouseEvent, element: FlowElement) => console.log('click', element);
const initialElements: Elements = [
{ id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 }, className: 'light' },
{ id: '2', data: { label: 'Node 2' }, position: { x: 100, y: 100 }, className: 'light' },
{ id: '3', data: { label: 'Node 3' }, position: { x: 400, y: 100 }, className: 'light' },
{ id: '4', data: { label: 'Node 4' }, position: { x: 400, y: 200 }, className: 'light' },
{ id: 'e1-2', source: '1', target: '2', animated: true },
];
const BasicFlow = () =>
{
const [rfInstance, setRfInstance] = useState<OnLoadParams | null>(null);
const [elements, setElements] = useState<Elements>(initialElements);
const onElementsRemove = (elementsToRemove: Elements) => setElements((els) => removeElements(elementsToRemove, els));
const onConnect = (params: Edge | Connection) => setElements((els) => addEdge(params, els));
const onLoad = (reactFlowInstance: OnLoadParams) => setRfInstance(reactFlowInstance);
return (
<ReactFlow
elements={elements}
onLoad={onLoad}
onElementClick={onElementClick}
onElementsRemove={onElementsRemove}
onConnect={onConnect}
onNodeDragStop={onNodeDragStop}
>
<Background variant={BackgroundVariant.Lines} />
</ReactFlow>
);
};
export default BasicFlow;```
I did that passing a custom node with its own handles:
const NODE_TYPES = {
yourType: CustomNode,
};
...
<ReactFlow
nodeTypes={NODE_TYPES}
...
/>
Then, at the CustomNode, I used the Handle component with custom height and width:
import { Handle, Position } from 'react-flow-renderer';
const CustomNode = (...) => {
...
return <Box>
...
<Handle
type="target"
position={Position.Left}
style={{ // Make the handle invisible and increase the touch area
background: 'transparent',
zIndex: 999,
border: 'none',
width: '20px',
height: '20px',
}}
/>
<CircleIcon
style={{}} // Fix the position of the icon over here
/>
</Box>;
}
I think its a bit hacky, but that's the way I found to accomplish it.
Based on adding a width and height suggested by Leonardo, I added a class and this worked for me too. Background, border etc are optional possibilities as per your need.
I had to add !important as it wasn't overriding the default settings otherwise.
.node-custom-handle {
width: 15px!important;
height: 15px!important;
background: whitesmoke!important;
border: 1px solid black!important;
border-radius: 4px!important;
}
<Handle
type="target"
position="top"
id="t"
className="node-custom-handle"
onConnect={(params) => console.log("handle onConnect", params)}
/>
I'm new to React and trying to learn. My personal project is homebrewing display site.
I want to show some of the details in radial bar. I followed tutorial and made array data file, and index file where details show. Now I'm stuck getting single values to display in radial bar.
Also values need to be calculated from percent to numeric. I got that working. I tried some push functions but did not get it to work way I wanted. My coding skills are beginner level.
display example
data.js
import product1 from '../../images/product-1.png';
import product2 from '../../images/product-1.png';
export const productData = [
{
id: 1,
img: product1,
alt: 'Beer',
name: 'Lager',
desc: 'Saaz',
ibu: '35',
ebc: '40',
abv: '8.5',
},
{
id: 2,
img: product2,
alt: 'Beer',
name: 'IPA',
desc: 'Mango, Citrus',
ibu: '85',
ebc: '25',
abv: '5.5',
},
];
index.js
import React, { Component } from 'react';
import Chart from 'react-apexcharts';
import {
ProductsContainer,
ProductWrapper,
ProductsHeading,
ProductTitle,
ProductCard,
ProductImg,
ProductInfo,
ProductDesc,
ProductIbu,
ProductEbc,
ProductAbv,
} from './ProductsElements';
const max = 119;
function valueToPercent(value) {
return (value * 100) / max;
}
class IBU extends Component {
constructor(props) {
super(props);
this.state = {
series: [valueToPercent(15)],
options: {
plotOptions: {
radialBar: {
startAngle: -90,
endAngle: 90,
hollow: {
margin: 10,
size: '70%',
background: '#222222',
image: undefined,
imageOffsetX: 0,
imageOffsetY: 0,
position: 'front',
dropShadow: {
enabled: true,
top: 5,
left: 0,
blur: 4,
opacity: 0.9,
},
},
track: {
background: '#d42d2d',
strokeWidth: '67%',
margin: 0, // margin is in pixels
dropShadow: {
enabled: true,
top: 0,
left: 0,
blur: 4,
color: '#000',
opacity: 0.6,
},
},
dataLabels: {
show: true,
name: {
offsetY: -10,
show: true,
color: '#fff',
fontSize: '17px',
},
value: {
formatter: function (value) {
return (parseFloat(value) * max) / 100;
},
color: '#dadada',
fontSize: '36px',
show: true,
},
},
},
},
fill: {
colors: [
function ({ value, seriesIndex, w }) {
if (value < 55) {
return '#7E36AF';
} else if (value >= 55 && value < 80) {
return '#164666';
} else {
return '#D9534F';
}
},
],
},
stroke: {
lineCap: 'round',
},
labels: ['IBU'],
},
};
}
render() {
return <Chart options={this.state.options} series={this.state.series} type="radialBar" height={250} />;
}
}
const Products = ({ data }) => {
return (
<ProductsContainer>
<ProductsHeading>heading</ProductsHeading>
<ProductWrapper>
{data.map((product, index) => {
return (
<ProductCard key={index}>
<ProductImg src={product.img} alt={product.alt} />
<ProductInfo>
<ProductTitle>{product.name}</ProductTitle>
<ProductDesc>{product.desc}</ProductDesc>
<ProductIbu>{product.ibu}</ProductIbu>
<IBU></IBU>
<ProductEbc>{product.ebc}</ProductEbc>
<ProductAbv>{product.abv}</ProductAbv>
</ProductInfo>
</ProductCard>
);
})}
</ProductWrapper>
</ProductsContainer>
);
};
export default Products;