Skip to content

Commit

Permalink
fix: graph node seq
Browse files Browse the repository at this point in the history
  • Loading branch information
fearlessfe committed Aug 25, 2024
1 parent 9be6217 commit cbd1e1c
Show file tree
Hide file tree
Showing 3 changed files with 226 additions and 49 deletions.
9 changes: 4 additions & 5 deletions src/components/Charts/ClaimChart/ChartBase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import EChartsReact from "echarts-for-react";
type ChartBaseProps = {
options: EChartOption;
compact?: boolean;
depth?: number;
};

const COMMON_OPTIONS: EChartOption = {
Expand All @@ -18,13 +19,11 @@ const COMMON_OPTIONS: EChartOption = {
},
};



export const ChartBase: FC<ChartBaseProps> = function ({
options,
compact = false,
depth = 0,
}) {

const processedSeries = useMemo(
() =>
options.series?.map((series) => {
Expand All @@ -39,8 +38,8 @@ export const ChartBase: FC<ChartBaseProps> = function ({
[options]
);

const len = options?.series ? (options?.series[0]?.data?.length || 0) : 0
const height = len === 2 ? (len * 250) : (len * 150)
// const len = options?.series ? options?.series[0]?.data?.length || 0 : 0;
const height = depth * 200;

return (
<EChartsReact
Expand Down
9 changes: 5 additions & 4 deletions src/components/Charts/ClaimChart/ChartCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ import Skeleton from "react-loading-skeleton";
import { ChartSkeleton } from "@/components/ChartSkeleton";
import { ChartBase } from "./ChartBase";
import { Card } from "@/components/Cards/Card";
import { depth } from "@/utils";

type ChartCardProps = {
title?: ReactNode;
options: EChartOption;
depth?: number;
};

function getSeriesDataState(series: EChartOption.Series[] | undefined) {
Expand All @@ -27,6 +29,7 @@ function getSeriesDataState(series: EChartOption.Series[] | undefined) {
export const ChartCard: FC<ChartCardProps> = function ({
title,
options,
depth,
}) {
const { isEmpty, isLoading } = getSeriesDataState(options.series);

Expand All @@ -36,9 +39,7 @@ export const ChartCard: FC<ChartCardProps> = function ({
{title ?? <Skeleton width={150} />}
</div>
<div className="flex h-full flex-col gap-2">
<div
className="h-full"
>
<div className="h-full">
{isEmpty ? (
<div className="flex h-full items-center justify-center">
<div className="text-sm font-thin uppercase text-contentSecondary-light dark:text-contentSecondary-dark">
Expand All @@ -50,7 +51,7 @@ export const ChartCard: FC<ChartCardProps> = function ({
<ChartSkeleton itemsCount={6} />
</div>
) : (
<ChartBase options={options} />
<ChartBase options={options} depth={depth} />
)}
</div>
</div>
Expand Down
257 changes: 217 additions & 40 deletions src/components/Charts/ClaimChart/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ const genNodesAndLinks = (data: ClaimData[]): any => {
const nodes: any[] = [];
const links: any[] = [];

// key: tree deep, value: nums of nodes at this level
const levelMap = new Map<number, number>();
let maxDepth = 1;

const root = data[0];
nodes.push({
Expand All @@ -35,46 +34,60 @@ const genNodesAndLinks = (data: ClaimData[]): any => {
y: yBase,
});

for (let i = 1; i < data.length; i++) {
const current = data[i];
const parent = data[current.parent_index];
const deep = depth(current.position);
const deepCount = levelMap.get(deep) || 0;
const node = {
name: current.event_id.toString(),
claim: current.claim,
position: current.position,
value: `${current.position}⚔️ ${shortenAddress(current.claim, 3)}`,
itemStyle: {
color: "red",
},
x: (-deep + deepCount) * xGap,
y: yBase + deep * yGap,
};
const link = {
source: parent.event_id.toString(),
target: current.event_id.toString(),
lineStyle: {
color: "red",
},
label: {
show: true,
formatter: "attack",
},
};
if (!isAttack(current.position, parent.position)) {
node.itemStyle.color = "blue";
link.lineStyle.color = "blue";
link.label.formatter = "defend";
const queue: number[] = [0];
// key: tree deep, value: nums of nodes at this level
const levelMap = new Map<number, number>();

while (queue.length) {
const parentIndex = queue.shift()!;
const parent = data[parentIndex];
for (let i = 1; i < data.length; i++) {
const current = data[i];
if (current.parent_index !== parentIndex) {
continue;
}
queue.push(i);
const deep = depth(current.position);
if (deep > maxDepth) {
maxDepth = deep;
}
const deepCount = levelMap.get(deep) || 0;
const node = {
name: current.event_id.toString(),
claim: current.claim,
position: current.position,
value: `${current.position}⚔️ ${shortenAddress(current.claim, 3)}`,
itemStyle: {
color: "red",
},
x: (-deep + deepCount) * xGap,
y: yBase + deep * yGap,
};
const link = {
source: parent.event_id.toString(),
target: current.event_id.toString(),
lineStyle: {
color: "red",
},
label: {
show: true,
formatter: "attack",
},
};
if (!isAttack(current.position, parent.position)) {
node.itemStyle.color = "blue";
link.lineStyle.color = "blue";
link.label.formatter = "defend";
}
nodes.push(node);
links.push(link);
levelMap.set(deep, deepCount + 1);
}
nodes.push(node);
links.push(link);
levelMap.set(deep, deepCount + 1);
}
console.log(nodes);
return {
nodes,
links,
maxDepth,
};
};

Expand Down Expand Up @@ -192,8 +205,57 @@ const ClaimChart: FC<{ claimData: ClaimData[] }> = ({ claimData }) => {
// output_block: 16288209,
// event_id: 14818,
// },
// {
// id: 7606,
// created_at: "2024-08-23T06:32:25Z",
// updated_at: "2024-08-23T06:32:25Z",
// game_contract: "0x2ed2a8c32bbe31e55dd03f31c85bd45138a1181f",
// data_index: 6,
// parent_index: 5,
// countered_by: "0x0000000000000000000000000000000000000000",
// claimant: "0xffb026F67DA0869EB3ABB090cB7F015CE0925CdF",
// bond: 95908800000000000,
// claim: "bef852721eceb6b7da05920bf3c7ce8291cb1d673e93409e79da26106fff3a5a",
// position: 6,
// clock: 1724393700,
// output_block: 16288209,
// event_id: 148181,
// },
// {
// id: 7606,
// created_at: "2024-08-23T06:32:25Z",
// updated_at: "2024-08-23T06:32:25Z",
// game_contract: "0x2ed2a8c32bbe31e55dd03f31c85bd45138a1181f",
// data_index: 6,
// parent_index: 3,
// countered_by: "0x0000000000000000000000000000000000000000",
// claimant: "0xffb026F67DA0869EB3ABB090cB7F015CE0925CdF",
// bond: 95908800000000000,
// claim: "bef852721eceb6b7da05920bf3c7ce8291cb1d673e93409e79da26106fff3a5a",
// position: 6,
// clock: 1724393700,
// output_block: 16288209,
// event_id: 148182,
// },
// {
// id: 7606,
// created_at: "2024-08-23T06:32:25Z",
// updated_at: "2024-08-23T06:32:25Z",
// game_contract: "0x2ed2a8c32bbe31e55dd03f31c85bd45138a1181f",
// data_index: 6,
// parent_index: 1,
// countered_by: "0x0000000000000000000000000000000000000000",
// claimant: "0xffb026F67DA0869EB3ABB090cB7F015CE0925CdF",
// bond: 95908800000000000,
// claim: "bef852721eceb6b7da05920bf3c7ce8291cb1d673e93409e79da26106fff3a5a",
// position: 6,
// clock: 1724393700,
// output_block: 16288209,
// event_id: 148184,
// },
// ];
const { nodes, links } = genNodesAndLinks(claimData);
// const data = genTreeData(claimData);
const { nodes, links, maxDepth } = genNodesAndLinks(claimData);
const options: EChartOption<EChartOption.SeriesGraph> = {
tooltip: {
trigger: "item",
Expand Down Expand Up @@ -221,7 +283,9 @@ const ClaimChart: FC<{ claimData: ClaimData[] }> = ({ claimData }) => {
data: nodes,
type: "graph",
layout: "none",
symbolSize: 90,
symbolSize: 80,
// top: "20%",
// bottom: "20%",
force: {
// 设置link长度
edgeLength: 100, // 固定长度
Expand All @@ -242,7 +306,120 @@ const ClaimChart: FC<{ claimData: ClaimData[] }> = ({ claimData }) => {
},
],
};
return <ChartCard title="Fault Dispute Game Graph" options={options} />;
// const options: EChartOption<EChartOption.SeriesTree> = {
// tooltip: {
// trigger: "item",
// formatter: (params: any) => {
// if (params.dataType === "node") {
// return `${params.data.claim}`;
// }
// return "";
// },
// },
// grid: {
// left: "5%",
// right: "5%",
// },
// xAxis: {
// type: "category",
// show: false,
// },
// yAxis: {
// type: "value",
// show: false,
// },
// series: [
// {
// data: [data],
// type: "tree",
// symbolSize: 70,
// orient: "vertical",
// left: "2%",
// right: "2%",
// top: "20%",
// bottom: "20%",
// expandAndCollapse: false,
// // force: {
// // // 设置link长度
// // edgeLength: 100, // 固定长度
// // // repulsion: 300,
// // },
// label: {
// show: true,
// formatter: (params: any) => {
// return params.data.value;
// },
// },
// // edgeSymbol: ["circle", "arrow"],
// // edgeSymbolSize: [4, 10],
// // links,
// lineStyle: {
// color: "red",
// },
// symbol: "circle", // 节点形状为圆形
// itemStyle: {
// color: "red",
// },
// },
// ],
// };
return (
<ChartCard
title="Fault Dispute Game Graph"
options={options}
depth={maxDepth}
/>
);
};

const genTreeData = (data: ClaimData[]): any => {
const root = data[0];
const rootNode = {
index: 0,
name: root.event_id.toString(),
claim: root.claim,
position: root.position,
value: `${root.position}👑 ${shortenAddress(root.claim, 2)}`,
itemStyle: {
color: "yellow",
},
children: [] as any[],
};
const queue = [rootNode] as any[];
while (queue.length) {
const parent = queue.shift()!;
const parentIndex = parent!.index;
for (let i = 1; i < data.length; i++) {
const current = data[i];
if (current.parent_index === parentIndex) {
const node = {
index: i,
name: current.event_id.toString(),
claim: current.claim,
position: current.position,
value: `${current.position}⚔️ ${shortenAddress(current.claim, 2)}`,
itemStyle: {
color: "red",
},
lineStyle: {
color: "red",
},
children: [],
};
if (!isAttack(current.position, parent.position)) {
node.itemStyle.color = "blue";
node.lineStyle.color = "blue";
node.value = `${current.position}🏁 ${shortenAddress(
current.claim,
2
)}`;
}
parent!.children.push(node);
queue.push(node);
}
}
}
return rootNode;
};

export default ClaimChart;

0 comments on commit cbd1e1c

Please sign in to comment.