I'm trying to make a slider with restricted values with Material UI and React. I have copy the basic implementation from the documentation page and it seem's not to need CSS to function. But when I use it in my project, the labels appear overlapped as the color of the line representing the chosen value (with 0 value, the line is light blue, with 5 value, all the line is heavy blue).
This is the code I have implemented:
const useStyles = makeStyles({
root: {
width: 300,
},
});
const marks = [
{
value: 1,
label: 'Nada',
},
{
value: 2,
label: 'Un poco',
},
{
value: 3,
label: 'Moderado',
},
{
value: 4,
label: 'Bastante',
},
{
value: 5,
label: 'Totalmente'
}
];
function valuetext(value) {
return `${value}`;
}
function valueLabelFormat(value) {
return marks.findIndex((mark) => mark.value === value) + 1;
}
export default function DiscreteSlider() {
const classes = useStyles();
return (
<div className={classes.root}>
<Typography id="discrete-slider-restrict" gutterBottom>
Restricted values
</Typography>
<Slider
defaultValue={0}
valueLabelFormat={valueLabelFormat}
getAriaValueText={valuetext}
aria-labelledby="discrete-slider-restrict"
step={null}
valueLabelDisplay="auto"
marks={marks}
/>
</div>
);
}
And the Slider looks like that:
How can I change the overlapping and make it functional? Is there any Slider prop that I can use?
Thank you very much!
Set max for the Slider to 5 - currently it is defaulting to 100 (see docs for default value). Currently, your mark values are 1 to 5 so they are being squeezed in that tiny area
<Slider
max={5} // <-- set max
defaultValue={0}
valueLabelFormat={valueLabelFormat}
getAriaValueText={valuetext}
aria-labelledby="discrete-slider-restrict"
step={null}
valueLabelDisplay="auto"
marks={marks}
/>
and allocate more width to accomodate the labels
const useStyles = makeStyles({
root: {
width: 600
}
});
Related
I have a .js file containing the code for a context menĂ¹ component:
const ContextMenuDialog = (props) => {
// my state declaration, other const, etc...
const build_ITEMS_ContextMenu = () => {
const A = [
{
key: "0",
label: "AA123BB",
disabled: true
},
{
key: "1",
label: "Show"
},
{
key: "2",
label: "Edit"
},
{
key: "3",
label: "Save"
}
];
return A;
};
return (
<div>
{loading ? (
"Loading"
) : (
<Menu
title="Menu right click"
style={{ top: 10, left: 10 }}
onClick={my_onClick_function}
items={ build_ITEMS_ContextMenu }
/>
)}
</div>
)
}
export default ContextMenuDialog;
Just consider that I cannot simply past the code of const A directly inside the "items" element; if I do it,the code works properly. In the real life I need to build the const A with a my algorithm.
This code doesn't work, the context menĂ¹ is not shown!
How can I solve this problem?
the problem is that you are not calling the function.
try this items={ build_ITEMS_ContextMenu() }
I am writing some code for a ReactJS component to have an array of chips. I want each chip to be styled uniquely, so I set up a makeStyles class for each one. I was having trouble trying to figure out how to change the class for each tag. This is what I got so far:
const classes = useStyles();
const [chipData, setChipData] = React.useState([
{ key: 0, label: 'Heating' },
{ key: 1, label: 'Printing' },
{ key: 2, label: 'Resetting' },
{ key: 3, label: 'Idle' },
{ key: 4, label: 'Suspended' },
{ key: 5, label: 'Suspend in Progress' },
{ key: 6, label: 'Attention - Printer Connection Lost' },
{ key: 7, label: 'Attention - Filament Out' },
{ key: 8, label: 'Attention - Cooldown Failed' },
]);
return (
<Box display="flex" flexDirection="row" alignItems="flex-start" className={classes.container}>
{chipData.map((data) => {
return (
<div classes={classes.chipContainer}>
<li key={data.key}>
<Chip
label={data.label}
if (label === 'Heating') {
className={classes.heatingTag}
}
/>
</li>
</div>
);
})}
</Box>
);
}
export default PrinterStatusTags
So within the chip element, I have an if statement that is used to assign a specific class based on the label. My plan was to have an if statement for each label, but I am getting the following error:
Parsing error: Unexpected token
Any ideas how I can assign a class based on the chip?
Updated Answer
I would 2 things:
Add a new type property for every chip.
Create a mapper from the type (in the 1st point) to the classes
const classesMapper = {
first: classes.firstClass,
second: classes.secondClass
// ...
};
const [chipData, setChipData] = React.useState([
{ key: 0, label: 'Heating', type: 'first' },
{ key: 1, label: 'Printing', type: 'seocnd' },
// ....
]);
After you have the mapping between every chip to its type. Just render it:
return (
<Box display="flex" flexDirection="row" alignItems="flex-start" className={classes.container}>
{chipData.map((data) => {
return (
<div classes={classes.chipContainer}>
<li key={data.key}>
<Chip
label={data.label}
className={classesMapper[data.type]} />
</li>
</div>
);
})}
</Box>
);
Old Answer
You should write the code a little bit different:
Use className property and not the property class (nor classes)
Set the condition inside the className property. Please note that there are better ways to set the right class but for your case, that would be good enough.
This is the code as it should be:
<div classeName={classes.chipContainer}>
<li key={data.key}>
<Chip label={data.label} className={ label ==== 'Heating' && classes.heatingTag}/>
</li>
</div>
Whenever I change the value in my select, I have to show different graphs
if I choose bar, it should display bar chart
if I choose line, it should display line chart
Initially the value is zero so it displays bar chart, then when I change to line it works fine, but when I go back to bar it does not.
Code:
const [chart,setChart]=useState(0)
const [filterData, setFilterData] = useState([])
export const ChartTypes =[
{
value: 0,
label: 'Bar'
},
{
value: 1,
label: 'Line'
},
{
value: 2,
label: 'Scatter Plot'
},
// My select Component
const handleChartChange = (event) =>{
setChart(event.target.value)
}
<FormControl variant="filled" className={classes.formControl}>
<InputLabel htmlFor="filled-age-native-simple">Chart</InputLabel>
<Select
native
value={chart}
onChange={handleChartChange}
inputProps={{
name: 'Chart',
id: 'filled-age-native-simple',
}}
>
{ChartTypes.map((e,chart)=>{
return (
<option value={e.value} key={e}>
{e.label}
</option>
)
})}
</Select>
{/* </Col>
<Col> */}
</FormControl>
// conditional rendering the component
{chart === 0 ? <BarChart
graphData={filterData}
filterType={graphFilter}
/> : <LineChart
graphData={filterData}
filterType={graphFilter} />
}
Edit
Thanks, it worked with the support of the below answers
Your issue is that the value of event.target.value is going to be a string "0" instead of a number 0 which you check for in your chart === 0 check.
Your initial value works because you hard-coded a zero as a number.
Option 1
You can either change the check to not include the type by doing chart == 0
OR
Option 2
You can change the value in your ChartTypes array to a string:
export const ChartTypes = [
{
value: '0',
label: 'Bar'
},
{
value: '1',
label: 'Line'
},
{
value: '2',
label: 'Scatter Plot'
}
];
and make your initial value const [chart, setChart] = useState('0')
OR
Option 3
You can change your handleChartChange function to parse the value as a number:
const handleChartChange = (event) => {
setChart(parseInt(event.target.value));
}
try this way, it works for me.
//define the state in this way:
const [state,setSate]=useState({chart:0})
const handleChartChange = (e) => {
setState({...state, chart:e.target.value})
}
<Select
...
value={state.chart}
onChange={handleChartChange}
...
>
</Select>
I'm trying to display a barchart using React-Chartkick and Chart.js, and I'd like to customise the colours of the bars. Currently, I'm able to set all the bars to the same colour by passing a prop like this: <BarChart colours={["#fff"]} />.
Using LineCharts in React-Chartkick, you can set colours of the lines by passing an array of colours through that prop. BarCharts only seems to accept the first colour, however. Is this a limitation of React-Chartkick, or am I doing something wrong?
I've tried passing options (as described here: https://www.chartjs.org/docs/latest/charts/bar.html#styling ) through the library prop as that is how I've customised the colours of the axes and labels, but this doesn't seem to affect the bars.
Here's my current code:
state = {
chartLibraryOptions: {
borderColor: "#e34402", // does nothing here
backgroundColor: "#e34402", // nor this
scales: {
yAxes: [
{
ticks: { fontColor: "#fff", autoSkip: false }
}
],
xAxes: [
{
ticks: { fontColor: "#fff" }
}
]
}
}
};
render() {
return (
<BarChart
data={this.state.chartData}
library={this.state.chartLibraryOptions}
colors={["#e34402", "#e3b502"]} // All bars are the first colour
/>
);
}
I'm expecting to be able to change the colours of each bar, but after all this I'm not sure if that's possible through Chartkick?
Well, I used the same node package in a project with different approach kinda work for me. Almost all the charts take the same attributes.
Basically, this attribute dataset={{ backgroundColor: ['white', 'yellow' ], }}
is all you need to colour each bar. You can either pass string or array of string to backgroundColor.
The backgroundColor in dataset takes two types of data String and Array(object). Typical examples of passing data are below.
When you set backgroundColor to a string, it applied the same colour to each bar. e.g backgroundColor: 'red'
BarChart - <BarChart dataset={{ backgroundColor: 'red', }} />
When you set backgroundColor to an array, it applied each colour in the array to each bar. e.g backgroundColor: ['red', 'yellow'], then you create a loop of colours base on the data length.
column chart - <ColumnChart dataset={{ backgroundColor: ['red', 'yellow' ], }} />
React Implementation Below:
/* eslint-disable no-plusplus */
import React from 'react';
import { ColumnChart, BarChart } from 'react-chartkick';
import { chartOne } from '../common/chartData';
import 'chart.js';
const MonthlyGrowth = () => {
const handleBgColors = () => {
const firstColor = "#A00B16", secondColor = "#FAA226";
const arrOfBgColors = [];
for (let i = 1; i <= chartOne.length; i++) {
if (i % 2 === 0) {
arrOfBgColors.push(secondColor)
} else {arrOfBgColors.push(firstColor)}
}
return arrOfBgColors;
}
return (
<div className="bukka-card uk-card-default bg-white pt-4 pb-2 mr-1 pl-3 pr-2 pl-
lg-5">
<h2 className="mt-2">4,500,000</h2>
<BarChart
dataset={{ borderWidth: 0, width: 0, backgroundColor: handleBgColors(), }}
data={chartOne}
/>
</div>
)
}
export default MonthlyGrowth;
This is my first time using Material UI (I'm also a noob with react in general) and I cant seem to change the size of the toggle switch I'm using.
This is what I have so far -minus all the non related stuff:
import React, { Component } from "react";
import Switch from "#material-ui/core/Switch";
const styles = {
root: {
height: "500",
},
};
class ToggleActive extends Component {
state = {
checked: true,
};
handleChange = name => event => {
this.setState({ [name]: event.target.checked });
};
render() {
return (
<label htmlFor="normal-switch">
<Switch
classes={styles.root}
checked={this.state.checked}
onChange={this.handleChange("checked")}
/>
</label>
);
}
}
export default ToggleActive;
I just want to make it a bit larger, and change the color. Any help would be appreciated!
The change in the Switch component requires a little bit of detailed styling. I added some comments in parts that are not very obvious:
import {createStyles, makeStyles, Switch, Theme} from '#material-ui/core';
const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
width: 54,
height: 40,
padding: 0,
margin: theme.spacing(1),
},
switchBase: {
padding: 1,
'&$checked': {
// This is the part that animates the thumb when the switch is toggled (to the right)
transform: 'translateX(16px)',
// This is the thumb color
color: theme.palette.common.white,
'& + $track': {
// This is the track's background color (in this example, the iOS green)
backgroundColor: '#52d869',
opacity: 1,
border: 'none',
},
},
},
thumb: {
width: 36,
height: 36,
},
track: {
borderRadius: 19,
border: `1px solid ${theme.palette.grey[300]}`,
// This is the background color when the switch is off
backgroundColor: theme.palette.grey[200],
height: 30,
opacity: 1,
marginTop: 4,
transition: theme.transitions.create(['background-color', 'border']),
},
checked: {},
focusVisible: {},
})
);
You can implement this as a functional component:
import React, { useState } from 'react';
// import {createStyles, makeStyles, ...
// const useStyles = makeStyles((theme: Theme) => ...
export const ToggleItem: React.FC = () => {
const styles = useStyles();
const [toggle, setToggle] = useState<boolean>(false);
return (
<Switch
classes={{
root: styles.root,
switchBase: styles.switchBase,
thumb: styles.thumb,
track: styles.track,
checked: styles.checked,
}}
checked={toggle}
onChange={() => setToggle(!toggle)}
name={title}
inputProps={{'aria-label': 'my toggle'}}
/>
);
};
This is now even easier to accomplish because MUI has an official example in the documentation:
https://mui.com/material-ui/react-switch/#customization
Using that as an example, the minimum number of changes to accomplish making the switch bigger is actually just this:
export const MuiSwitchLarge = styled(Switch)(({ theme }) => ({
width: 68,
height: 34,
padding: 7,
"& .MuiSwitch-switchBase": {
margin: 1,
padding: 0,
transform: "translateX(6px)",
"&.Mui-checked": {
transform: "translateX(30px)",
},
},
"& .MuiSwitch-thumb": {
width: 32,
height: 32,
},
"& .MuiSwitch-track": {
borderRadius: 20 / 2,
},
}));
Here is the link to a forked sandbox with just a bigger switch:
https://codesandbox.io/s/customizedswitches-material-demo-forked-4m2t71
Consider this: I am not a front-end developer and did not develop in
Material-UI framework for years now. so just look for a different answer or send
me an edit version which works.
For changing the size of the switch component you should use size props that can be in two size 'small' || 'medium'.For example:
<Switch
size="small"
checked={this.state.checked}
onChange={this.handleChange("checked")}
color='primary'
/>
If it doesn't work for you then You need to change CSS style at root class:
const styles = {
root: {
height: 500,
width: 200},
};
Due to material-UI component API for changing the color of a switch you need to add a color props into you Switch JSX tag and choose from these enum:
enum: 'primary' |'secondary' | 'default'
your Switch should be like this:
<Switch
classes={styles.root}
checked={this.state.checked}
onChange={this.handleChange("checked")}
color='primary'
/>
Material-UI for switch size prop