Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

통계 뷰어 컴포넌트 작성하기 #238

Open
BEOKS opened this issue Apr 5, 2022 · 4 comments
Open

통계 뷰어 컴포넌트 작성하기 #238

BEOKS opened this issue Apr 5, 2022 · 4 comments
Assignees

Comments

@BEOKS
Copy link
Owner

BEOKS commented Apr 5, 2022

Description

주어지는 데이터는 환자의 정보를 다루고 있는 메타데이터입니다. 이 데이터를 영상의학과 선생님들과 머신러닝 엔지니어들이 쉽게 확인하기 위해서는 시각화가 필요합니다. 주어진 메타데이터를 props로 입력받아 시각화 자료를 보여주는 Component를 생성해주세요.

Json Data

사용해야 할 데이터는 레포지토리에 저장되어 있습니다.
Json 데이터는 아래와 같이 한 명의 메타데이터가 리스트 형태로 주어져 있습니다.
내부의 데이터는 크게 Number,String형태로 나뉘어 있습니다. 이 중, String 데이터의 경우 카테고리화가 적용되어 있습니다.
또 한, 각각의 메타데이터는 동일한 key를 보유하고 있습니다. value의 경우 데이터가 존재하지 않는 경우가 존재합니다.

카테고리화는 전체 데이터가 몇 개의 분류로 나뉘어 있는 것을 의미합니다.

[
  {
   "stored_dicom_id": 145125,
    "anonymized_id": 1028011,
    "age": 53,
    "modality": "MG",
    "manufacturer": "HOLOGIC, Inc.",
    "manufacturerModelName": "Lorad Selenia",
    "class\nnon-pCR: 0 pCR: 1": 0,
    "left: 0\nright: 1": 1,
    "ER": 1,
    "PR": 1,
    "HER2": 1,
    "non-IDC: 0\nIDC: 1": 1,
    "compressionForce": 173.5019
  },
  {
   "stored_dicom_id": 145135,
    "anonymized_id": 1106526,
    "age": 56,
    "modality": "MG",
    "manufacturer": "HOLOGIC, Inc.",
    "manufacturerModelName": "Lorad Selenia",
    "class\nnon-pCR: 0 pCR: 1": 1,
    "left: 0\nright: 1": 0,
    "ER": 0,
    "PR": 0,
    "HER2": 0,
    "non-IDC: 0\nIDC: 1": 1,
    "compressionForce": 115.6019
  },
...
...

Result

아래는 다른 툴을 통해서 만든 시각화 예시입니다. 더 유용하거나 적절한 표현방식이 있다면 이를 적용해도 됩니다.

  1. Number 시각화 예시
    Json에서 숫자 형태로 데이터가 존재하는 경우 아래와 같이 히스토그램을 작성하도록 합니다.
    image
  2. String 시각화 예시
    위에서 언급했든, String 형태의 데이터는 카테고리화가 적용되어 있습니다. 비율이 어느정도인지 파악하기 위한 그래프를 작성하도록 합시다.
    image

Condition

  1. 작성할 컴포넌트는 json 데이터를 props로 받아서 처리해야 합니다.
<VisualTable data={metadataJson}/>
  1. 컴포넌트와 관련된 코드는 src/VisualTable 폴더를 만들어 내부에 작성합니다.
  2. 컴포넌트 코드는 VisualTable.js를 만들어 작성합니다.
  3. 작성된 컴포넌트는 다른 사용자가 쉽게 import 할 수 있어야 합니다.
//example in App.js
import VisualTable  from './VisualTable/VisualTable'
function(metadataJson){
    return <VisualTable data={metadataJson}/>
}

After

코드 작성을 모두 마친 후에는 카톡으로 연락해주세요

Tip

이미 React에는 좋은 디자인으로 구현된 라이브러리들이 많습니다. 구글링을 통해서 유용한 라이브러리들을 참고하는 것을 추천합니다. 아래는 참고하기 좋은 링크를 일부 첨부합니다.

  1. https://devexpress.github.io/devextreme-reactive/react/chart/docs/guides/zoom-and-pan/
  2. https://www.chartjs.org/docs/latest/getting-started/usage.html
@BEOKS BEOKS assigned BEOKS and doheez Apr 5, 2022
@doheez
Copy link
Collaborator

doheez commented Apr 7, 2022

상황

GET api로 받아온 metaData에서 실제 데이터는 body 안에 들어있다.

[
    {
        "metadataId": "624e76c18dcde84f6aac05ea",
        "projectId": "624e76a88dcde84f6aac05e9",
        "body": {
            "StudyInstanceUID": "",
            "image_name": "name",
            "anonymized_id": "5b42edb0-754f-56c9-9666-6c8f7ce712f3",
            "age": "53",
            "modality": "MG",
            "manufacturer": "HOLOGIC, Inc.",
            "manufacturerModelName": "Lorad Selenia",
            "class non-pCR: 0 pCR: 1": "0",
            "left: 0 right: 1": "1",
            "ER": "1",
            "PR": "1",
            "HER2": "1",
            "non-IDC: 0 IDC: 1": "1",
            "compressionForce": "173.5019"
        }
    },
    {
        "metadataId": "624e76c18dcde84f6aac05eb",
        "projectId": "624e76a88dcde84f6aac05e9",
        "body": {
            "StudyInstanceUID": "1.2.70.122170.4.14.1018932208290001",
            "image_name": "name",
            "anonymized_id": "97628259-dce6-5bdb-a065-b65cf27b5b40",
            "age": "56",
            "modality": "MG",
            "manufacturer": "HOLOGIC, Inc.",
            "manufacturerModelName": "Lorad Selenia",
            "class non-pCR: 0 pCR: 1": "1",
            "left: 0 right: 1": "0",
            "ER": "0",
            "PR": "0",
            "HER2": "0",
            "non-IDC: 0 IDC: 1": "1",
            "compressionForce": "115.6019"
        }
    },
    ...
]

하려고 하는 것

VisualTablemetaData를 props로 넘겨준 후
body만 뽑아내서 실제 데이터 부분만 사용하고자 한다.

const data = metaData.map(e => e.body);

(이후엔 이를 다시 key별 데이터로 나누어 각 key에 대한 차트를 만들고자 한다.)

문제 발생

타입스크립트를 사용 중이기 때문에 props의 타입을 지정해주어야 한다.

  1. props로 받아온 metaData 타입을 단순히 object array로 정의했을 경우
type VisualTableProps = {
    metaData: object[]
};

image

  1. any array로 정의했을 경우
type VisualTableProps = {
    metaData: any[]
};

image

질문

위와 같이 array element에 대한 타입만을 지정하지 않고 메타데이터의 전체 column 타입을 일일이 정해주자니,
테이블마다 컬럼 수와 타입이 제각각이라 타입 지정 방법이 떠오르지 않는다.
어떻게 하는 게 좋을까?

@BEOKS

@BEOKS
Copy link
Owner Author

BEOKS commented Apr 8, 2022

가장 간단한 해결방법은 아래와 같이 타입을 아예 any로 주면
자바스크립트 처럼 동작하기에 컴파일 레벨에서 에러가 발생하지 않을거야.

type VisualTableProps = {
    metaData: any
};

두 번째 방법은 Json 내부에 string값들이 동적으로 할당될 수 있는 인터페이스를 만드는거야 (type으로 해도 상관없어)
그럼 해당 인터페이스로 정의된 변수는 내부에 string 값의 키와 값 쌍을 넣는 경우는 모두 허락하기 때문에, body 내부에 있는 데이터를 수용할 수 있을 거야. 아래를 보면 메타데이터를 넣어도 컴파일 에러가 발생하지 않아
image

결론은 아래와 같이 선언하는게 이상적

interface Metadata{
    [name : string] : string
}
type VisualTableProps = {
    metaData: Metadata[]
};

@doheez
Copy link
Collaborator

doheez commented Apr 8, 2022

설명 고마워! 그런데 props의 타입을 이렇게 설정하면

type Body = {
    [key : string] : string
}

type MetaData = {
    metadataId: string,
    projectId: string,
    body: Body
}

type VisualTableProps = {
    metaData: MetaData[]
};

map 메서드를 쓰는 부분에서 이런 에러가 나.

const data = metaData.map(e => e.body);

image

구글링해보니 array가 아닌 object에 map 메서드를 썼을 때 주로 발생하는 에러라는데, metaData는 원소 각각이 MetaData 타입으로 이루어진 array거든. 왜 이런 에러가 뜨는지 모르겠다...

@doheez
Copy link
Collaborator

doheez commented Apr 8, 2022

해결

const data = Array.from(metaData).map(e => e.body);

doheez added a commit that referenced this issue Apr 8, 2022
Add
메타 데이터에 대한 통계 차트를 생성합니다.
숫자 데이터인 age는 Bar Chart로,
문자열 데이터인 나머지는 Doughnut Chart로 시각화합니다.
각 차트는 percent를 표시하는 tooltip을 포함합니다.

After
1. 차트에서 각 데이터의 값을 표시해야 합니다.
2. Bar Chart의 x축을 정렬해야 합니다.

Task: #238
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants