Commit 928486a6 authored by Yoon, Daeki's avatar Yoon, Daeki 😅
Browse files

chart 시작

parent bff0b7f5
import React from "react";
import { arc, DefaultArcObject, PieArcDatum } from "d3-shape";
// import { DefaultArcObject } from "d3";
interface Props {
arcData: DefaultArcObject & PieArcDatum<any>;
label?: string;
[rest: string]: any;
}
export const Arc = ({ arcData, label, ...rest }: Props) => {
console.log("rest:", rest);
const arcGenerator = arc();
arcGenerator.cornerRadius(5.2);
const centroid = arcGenerator.centroid({
...arcData,
// startAngle: arcData.startAngle,
// endAngle: arcData.endAngle,
});
const pathData = arcGenerator(arcData);
// console.log("arcdata:", arcData, "path data:", pathData);
return (
<>
<path d={pathData ?? ""} {...rest}></path>
{label && (
<text x={centroid[0]} y={centroid[1]} dy={"0.33em"}>
{label}
</text>
)}
</>
);
};
import { scaleLinear } from "d3-scale";
import { arc, pie } from "d3-shape";
import React from "react";
import { Arc } from "./Arc";
type Props = {
data: any;
};
export const Pie = ({ data }: Props) => {
const width = 300;
const height = 300;
const pieGenerator = pie();
const arcs = pieGenerator.padAngle(0.1)(data);
console.log(arcs);
return (
<div>
<h1>Pie</h1>
<svg width={width} height={height}>
<g
transform={`translate(${width / 2},${height / 2})`}
textAnchor="middle"
stroke="white"
>
{arcs.map((arc, i) => (
<Arc
key={i}
arcData={{ ...arc, innerRadius: 0, outerRadius: 100 }}
label={String(arc.value)}
fill={"blue"}
stroke={"red"}
strokeWidth={2}
/>
))}
</g>
</svg>
</div>
);
};
import React, { useRef, useState } from "react";
import { generateDataset1D } from "../helpers";
import { Pie } from "./Pie";
const initDataset = [50, 30, 12, 5, 3];
const nextDataset = [21, 16, 6, 18, 10];
export const PieExample = () => {
const [dataset, setDataset] = useState(initDataset);
const toggle = useRef(true);
const handleClick = () => {
setDataset(generateDataset1D());
};
const handleToggle = () => {
toggle.current ? setDataset(nextDataset) : setDataset(initDataset);
toggle.current = !toggle.current;
};
return (
<div>
<p onClick={handleClick}>새 데이터로 차트를 갱신하려면 클릭하세요</p>
<p onClick={handleToggle}>데이터 토글</p>
<Pie data={dataset} />
</div>
);
};
export { PieExample } from "./PieExample";
import { max, min } from "d3";
import { scaleLinear } from "d3-scale";
import React, { useState } from "react";
import { AxisScaleLinear, AxisVerticalScaleLinear } from "../axes";
import { CirclesWithG } from ".";
import { generateRandomDataset } from "../helpers";
import { TextsWithG } from "../texts";
export const ChartV0 = () => {
const pad = 30;
const margin = { top: 20, right: 30, bottom: 20, left: 30 };
const width = window.innerWidth - margin.left - margin.right;
const height = 300 - margin.bottom - margin.top;
const [dataset, setDataset] = useState(generateRandomDataset());
const xMin = min(dataset, (d) => d[0]) || 0;
const xMax = max(dataset, (d) => d[0]) || 100;
const yMin = min(dataset, (d) => d[1]) || 0;
const yMax = max(dataset, (d) => d[1]) || 100;
const xScale = scaleLinear()
.domain([0, xMax + 5])
.nice()
.range([0, width]);
const yScale = scaleLinear()
.domain([0, yMax + 5])
.nice()
.range([height, 0]);
const scaledDataset = dataset.map((d) => [xScale(d[0]), yScale(d[1])]);
// console.log("dataset:", dataset, "scaled dataset:", scaledDataset);
return (
<svg
width={width + margin.left + margin.right}
height={height + margin.bottom + margin.top}
>
<g transform={`translate(${margin.left}, ${margin.top})`}>
<CirclesWithG dataset={scaledDataset} />
<TextsWithG dataset={dataset} xScale={xScale} yScale={yScale} />
<AxisVerticalScaleLinear x={0} y={0} scale={yScale} />
<AxisScaleLinear x={0} y={height} scale={xScale} />
</g>
</svg>
);
};
import { ScaleLinear } from "d3-scale";
import React from "react";
type Props = {
dataset: number[][];
xScale: ScaleLinear<number, number>;
yScale: ScaleLinear<number, number>;
};
export const Circles = ({ dataset, xScale, yScale }: Props) => {
return (
<g>
{dataset.map((d) => (
<circle key={d[0]} cx={xScale(d[0])} cy={yScale(d[1])} r={3}></circle>
))}
</g>
);
};
import React, { useEffect, useRef, useState } from "react";
import { select } from "d3-selection";
import { generateDataset } from "../helpers";
export const CirclesWithD3 = () => {
const [dataset, setDataset] = useState(generateDataset());
const ref = useRef(null);
useEffect(() => {
const svg = select(ref.current);
svg
.selectAll("circle")
.data(dataset)
.join("circle")
.attr("cx", (d) => d[0])
.attr("cy", (d) => d[1])
.attr("r", 3);
}, [dataset]);
return <svg viewBox="0 0 100 50" ref={ref} />;
};
import React from "react";
type Props = {
dataset: number[][];
};
export const CirclesWithG = ({ dataset }: Props) => {
return (
<g>
{dataset.map((d) => (
<circle key={d[0]} cx={d[0]} cy={d[1]} r={3}></circle>
))}
</g>
);
};
import React, { useState } from "react";
import { generateDataset, generateRandomDataset } from "../helpers";
export const CirclesWithSvg = () => {
const [dataset, setDataset] = useState(generateRandomDataset());
return (
<div>
<svg viewBox="0 0 100 50" style={{ backgroundColor: "red" }}>
{dataset.map((d) => (
<circle key={d[0]} cx={d[0]} cy={d[1]} r={3}></circle>
))}
</svg>
</div>
);
};
import React, { useState } from "react";
import { scaleLinear } from "d3-scale";
import { max, min } from "d3";
import { generateRandomDataset } from "../helpers";
export const ScaledCircles = () => {
const [dataset, setDataset] = useState(generateRandomDataset(30, 1));
console.log(`dataset:`, dataset);
const width = 100,
height = 50,
r = 1;
const xPad = 3,
yPad = 3;
const xMin = min(dataset, (d) => d[0]) || 0;
const xMax = max(dataset, (d) => d[0]) || 100;
const yMin = min(dataset, (d) => d[1]) || 0;
const yMax = max(dataset, (d) => d[1]) || 50;
const xScale = scaleLinear()
.domain([xMin, xMax])
.range([0 + xMin, width - xPad]);
const yScale = scaleLinear()
.domain([yMin, yMax])
.range([yMin, height - yPad]);
const rScale = scaleLinear()
.domain([xMin + yMin, xMax + yMax])
.range([0, height / 10]);
return (
<div style={{ backgroundColor: "gray" }}>
<svg viewBox={`0 0 ${width + xMin} ${height + 3}`}>
{dataset.map((d) => (
<circle
key={d[0]}
cx={xScale(d[0])}
cy={yScale(d[1])}
r={rScale(d[0] + d[1])}
></circle>
))}
</svg>
</div>
);
};
import { max, min } from "d3";
import { scaleLinear } from "d3-scale";
import React, { useState } from "react";
import {
Axis,
AxisScaleLinear,
AxisVerticalScaleLinear,
Orient,
} from "../axes";
import { CirclesWithG } from ".";
import { generateRandomDataset } from "../helpers";
import { TextsWithG } from "../texts";
import { Circles } from "./Circles";
type Props = {
dataset: number[][];
dimensions: DOMRect | undefined;
};
export const ScatterChart = ({ dataset, dimensions }: Props) => {
const margin = { top: 20, right: 30, bottom: 20, left: 30 };
const width = dimensions?.width || 600;
const height = dimensions?.height || 300;
const innerWidth = width - margin.left - margin.right;
const innerHeight = height - margin.bottom - margin.top;
const xMin = min(dataset, (d) => d[0]) || 0;
const xMax = max(dataset, (d) => d[0]) || 100;
const yMin = min(dataset, (d) => d[1]) || 0;
const yMax = max(dataset, (d) => d[1]) || 100;
const xScale = scaleLinear()
.domain([0, xMax + 5])
.nice()
.range([0, innerWidth]);
const yScale = scaleLinear()
.domain([0, yMax + 5])
.nice()
.range([innerHeight, 0]);
// console.log("dataset:", dataset, "scaled dataset:", scaledDataset);
return (
<svg width={width} height={height}>
<g transform={`translate(${margin.left}, ${margin.top})`}>
<Circles dataset={dataset} xScale={xScale} yScale={yScale} />
<TextsWithG dataset={dataset} xScale={xScale} yScale={yScale} />
</g>
<g transform={`translate(${margin.left},${margin.top})`}>
<Axis scale={yScale} orient={Orient.left} />
</g>
<g transform={`translate(${width - margin.right},${margin.top})`}>
<Axis scale={yScale} orient={Orient.right} />
</g>
<g transform={`translate(${margin.left},${height - margin.bottom})`}>
<Axis scale={xScale} orient={Orient.bottom} />
</g>
<g transform={`translate(${margin.left},${margin.top})`}>
<Axis scale={xScale} orient={Orient.top} />
</g>
</svg>
);
};
import React, { useRef, useState } from "react";
import { Button, Comment } from "../commons";
import { generateDataset, generateRandomDataset } from "../helpers";
import { useSize } from "../hooks";
import { ChartV0 } from "./ChartV0";
import { ScatterChart } from "./ScatterChart";
export const ScatterExamples = () => {
const [dataset, setDataset] = useState(generateRandomDataset(20, 200));
const target = useRef(null);
const size = useSize(target);
const handleClick = () => {
setDataset(generateDataset());
};
// console.log("dataset", dataset);
return (
<div>
<h1>Scatter Chart Examples</h1>
<Button className="mr-4" onClick={handleClick}>
새로운 무작위 데이터로 차트를 갱신하려면 클릭하세요.
</Button>
<Comment>고정된 데이터에 대해서 scatter plot. 이전 축 적용</Comment>
<ChartV0 />
<Comment>resizable이 적용된 scatter plot. 새로운 축 적용.</Comment>
<div ref={target}>
<ScatterChart dataset={dataset} dimensions={size} />
</div>
</div>
);
};
export { CirclesWithD3 } from "./CirclesWithD3";
export { CirclesWithG } from "./CirclesWithG";
export { CirclesWithSvg } from "./CirclesWithSvg";
export { ScatterExamples } from "./ScatterExamples";
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment