React
by michaelnicol
HTML
<div id="app"></div>
CSS
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
li {
margin: 8px 0;
}
h2 {
font-weight: bold;
margin-bottom: 15px;
}
.done {
color: rgba(0, 0, 0, 0.3);
text-decoration: line-through;
}
input {
margin-right: 5px;
}
React
export const TodoApp = () => {
const data = useMemo(() => {
// The data to display will be vertical lines at certian dates.
return [
new Date("2022-01-01"),
new Date("2022-02-01"),
new Date("2022-03-01"),
new Date("2022-04-01"),
new Date("2022-05-01")
]
}, [])
const svgRef = useRef(null);
const width = 500
const height = 500
useEffect(() => {
if (svgRef.current) {
const svg = d3.select(svgRef.current);
// Remove all SVG
svg.selectAll("*").remove();
// Generate the width and domain of the x and y axis.
// The x-axis will be 500 px wide with a domain of lowest to highest date.
const xScale = d3.scaleTime().range([0, width]).domain(d3.extent(data));
// yScale will be a linear scale from 0 to 500 pixels.
const yScale = d3.scaleLinear().range([height, 0])
// Create the x-axis
svg.append("g")
.attr("transform", `translate(0,${height})`) // Move x-axis to bottom of graph
.call(
d3.axisBottom(xScale) // Generate an axis to place tick marks on.
.ticks(d3.timeMonth.every(1)) // The ticks will be spaced out every month
.tickFormat((d, i) => { // The text for each tick will be the month name
if (d instanceof Date) {
return d3.timeFormat("%B")(d)
} else {
return "" + d
}
}))
// Generate the y-axis, no ticks.
svg.append("g").call(d3.axisLeft(yScale))
}
}, [data])
return (
{<svg
ref={svgRef}
width={width}
height={height}
/>}
)
}
ReactDOM.render(<TodoApp />, document.querySelector("#app"))