-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
226 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// LineChartExample.tsx | ||
import React, { useState } from 'react'; | ||
import LineChart from '../../src/LineChart'; // Assuming the path to the LineChart component | ||
import Line from '../../src/Line'; // Assuming the path to the Line component | ||
import CartesianGrid from '../../src/CartesianGrid'; | ||
import XAxis from '../../src/XAxis'; | ||
import YAxis from '../../src/YAxis'; | ||
import Tooltip from '../../src/Tooltip'; | ||
import Legend from '../../src/Legend'; | ||
import LineChartControls from '../utils/LineChartControls'; // Assuming the path to the LineChartControls component | ||
|
||
const data = [ | ||
{ name: 'Page A', uv: 4000, pv: 2400, amt: 2400 }, | ||
{ name: 'Page B', uv: 3000, pv: 1398, amt: 2210 }, | ||
{ name: 'Page C', uv: 2000, pv: 9800, amt: 2290 }, | ||
{ name: 'Page D', uv: 2780, pv: 3908, amt: 2000 }, | ||
{ name: 'Page E', uv: 1890, pv: 4800, amt: 2181 }, | ||
{ name: 'Page F', uv: 2390, pv: 3800, amt: 2500 }, | ||
{ name: 'Page G', uv: 3490, pv: 4300, amt: 2100 }, | ||
]; | ||
|
||
const LineChartExample: React.FC = () => { | ||
const [lines, setLines] = useState([ | ||
{ id: 1, dataKey: 'pv', stroke: '#8884d8' }, | ||
{ id: 2, dataKey: 'uv', stroke: '#82ca9d' }, | ||
]); | ||
|
||
return ( | ||
<div className="p-6"> | ||
<h1 className="text-2xl font-semibold mb-4">LineChart Example</h1> | ||
<div className="flex"> | ||
<LineChartControls lines={lines} setLines={setLines} /> | ||
<LineChart width={730} height={250} data={data} margin={{ top: 5, right: 30, left: 20, bottom: 5 }}> | ||
<CartesianGrid strokeDasharray="3 3" /> | ||
<XAxis dataKey="name" /> | ||
<YAxis /> | ||
<Tooltip /> | ||
<Legend /> | ||
{lines.map((line) => ( | ||
<Line key={line.id} type="monotone" dataKey={line.dataKey} stroke={line.stroke} /> | ||
))} | ||
</LineChart> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default LineChartExample; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// LineChartControls.tsx | ||
import React from 'react'; | ||
|
||
interface LineChartControlsProps { | ||
lines: Array<{ id: number; dataKey: string; stroke: string }>; | ||
setLines: React.Dispatch<React.SetStateAction<Array<{ id: number; dataKey: string; stroke: string }>>>; | ||
} | ||
|
||
const LineChartControls: React.FC<LineChartControlsProps> = ({ lines, setLines }) => { | ||
const handleLineChange = (index: number, key: keyof typeof lines[number], value: string) => { | ||
const updatedLines = [...lines]; | ||
updatedLines[index][key] = value; | ||
setLines(updatedLines); | ||
}; | ||
|
||
return ( | ||
<div className="bg-white p-6 shadow-lg rounded-lg mb-5 max-w-md"> | ||
<h2 className="text-2xl font-semibold mb-6 text-purple-600">Line Chart Settings</h2> | ||
<form className="space-y-6"> | ||
{lines.map((line, index) => ( | ||
<div key={line.id} className="bg-gray-100 p-4 rounded-lg mb-4"> | ||
<h3 className="text-lg font-medium text-purple-600 mb-2">Line {index + 1} Settings</h3> | ||
<div className="grid grid-cols-2 gap-4"> | ||
<div> | ||
<label className="block text-sm font-medium text-purple-600 mb-1">Data Key</label> | ||
<input | ||
type="text" | ||
value={line.dataKey} | ||
onChange={(e) => handleLineChange(index, 'dataKey', e.target.value)} | ||
className="w-full px-3 py-2 border border-purple-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500 transition duration-300 ease-in-out" | ||
/> | ||
</div> | ||
<div> | ||
<label className="block text-sm font-medium text-purple-600 mb-1">Stroke Color</label> | ||
<input | ||
type="color" | ||
value={line.stroke} | ||
onChange={(e) => handleLineChange(index, 'stroke', e.target.value)} | ||
className="w-full h-10 border-none rounded-lg" | ||
/> | ||
</div> | ||
</div> | ||
</div> | ||
))} | ||
</form> | ||
</div> | ||
); | ||
}; | ||
|
||
export default LineChartControls; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// Line.tsx | ||
import React from 'react'; | ||
|
||
interface LineProps { | ||
data: Array<{ [key: string]: any }>; | ||
dataKey: string; | ||
stroke: string; | ||
type?: 'monotone' | 'linear'; | ||
onMouseOver?: (event: React.MouseEvent, entry: { name: string; [key: string]: any }) => void; | ||
onMouseOut?: () => void; | ||
} | ||
|
||
const Line: React.FC<LineProps> = ({ | ||
data = [], | ||
dataKey, | ||
stroke, | ||
type = 'linear', | ||
onMouseOver = () => {}, | ||
onMouseOut = () => {}, | ||
}) => { | ||
if (!data.length) return null; | ||
|
||
const points = data | ||
.map((entry, index) => { | ||
const x = (index / (data.length - 1)) * 730; | ||
const y = 250 - (entry[dataKey] / Math.max(...data.map((d) => d[dataKey]))) * 250; | ||
return `${x},${y}`; | ||
}) | ||
.join(' '); | ||
|
||
return ( | ||
<polyline | ||
points={points} | ||
fill="none" | ||
stroke={stroke} | ||
strokeWidth={2} | ||
onMouseOver={(event) => onMouseOver(event, { name: dataKey })} | ||
onMouseOut={onMouseOut} | ||
style={{ transition: 'all 0.3s' }} | ||
/> | ||
); | ||
}; | ||
|
||
export default Line; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
// LineChart.tsx | ||
import React, { ReactNode, Children, cloneElement, useState, useRef, useEffect } from 'react'; | ||
import CartesianGrid from '../CartesianGrid'; | ||
import XAxis from '../XAxis'; | ||
import YAxis from '../YAxis'; | ||
import Tooltip from '../Tooltip'; | ||
import Legend from '../Legend'; | ||
import Line from '../Line'; | ||
|
||
interface LineChartProps { | ||
width: number; | ||
height: number; | ||
data: Array<{ [key: string]: any }>; | ||
margin?: { top?: number; right?: number; bottom?: number; left?: number }; | ||
children: ReactNode; | ||
} | ||
|
||
const LineChart: React.FC<LineChartProps> = ({ | ||
width, | ||
height, | ||
data, | ||
margin = { top: 20, right: 30, bottom: 20, left: 40 }, | ||
children, | ||
}) => { | ||
const chartWidth = width - (margin.left + margin.right); | ||
const chartHeight = height - (margin.top + margin.bottom); | ||
const [tooltipData, setTooltipData] = useState(null); | ||
const [position, setPosition] = useState({ x: 0, y: 0 }); | ||
const svgRef = useRef<SVGSVGElement>(null); | ||
|
||
useEffect(() => { | ||
if (svgRef.current) { | ||
// Add any adjustments based on rendered dimensions here if needed | ||
} | ||
}, [data]); | ||
|
||
const handleMouseOver = (event: React.MouseEvent, entry: { name: string }) => { | ||
const values = Children.toArray(children) | ||
.filter((child) => React.isValidElement(child) && child.type === Line) | ||
.map((child) => { | ||
const { dataKey, stroke } = child.props; | ||
const value = entry[dataKey]; | ||
return { key: dataKey, value, color: stroke }; | ||
}); | ||
|
||
setTooltipData({ name: entry.name, values }); | ||
setPosition({ x: event.clientX, y: event.clientY }); | ||
}; | ||
|
||
const handleMouseOut = () => { | ||
setTooltipData(null); | ||
}; | ||
|
||
return ( | ||
<div className="relative inline-block" style={{ padding: '10px' }}> | ||
<svg ref={svgRef} width={width} height={height} className="bg-white"> | ||
<g transform={`translate(${margin.left}, ${margin.top})`}> | ||
<CartesianGrid width={chartWidth} height={chartHeight} layout="horizontal" /> | ||
<XAxis data={data} width={chartWidth} height={chartHeight} dataKey="name" layout="horizontal" /> | ||
<YAxis height={chartHeight} maxValue={Math.max(...data.map((d) => d.pv))} minValue={0} layout="horizontal" /> | ||
{Children.map(children, (child) => | ||
React.isValidElement(child) && child.type === Line | ||
? cloneElement(child, { data, onMouseOver: handleMouseOver, onMouseOut: handleMouseOut }) | ||
: child | ||
)} | ||
</g> | ||
</svg> | ||
<Legend /> | ||
{tooltipData && <Tooltip tooltipData={tooltipData} position={position} />} | ||
</div> | ||
); | ||
}; | ||
|
||
export default LineChart; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters