행위

"DigitalSinology(2026) NetworkGraph 02.lst"의 두 판 사이의 차이

CNUDH

(JSH CNUGrad (토론)의 31631판 편집을 되돌림)
(태그: 편집 취소)
(연구 결과)
90번째 줄: 90번째 줄:
 
:또한 '인력거'가 출현하지 않은 문장은 각각 '낙타', '돈', '결혼' 등의 요소로 내용을 이끌고 있다. <br/>
 
:또한 '인력거'가 출현하지 않은 문장은 각각 '낙타', '돈', '결혼' 등의 요소로 내용을 이끌고 있다. <br/>
 
</div>
 
</div>
 
+
<br/>
 +
[[파일:인력거시각화1.png]]
 
-----
 
-----
 +
<br/>
 
===='''<span style="color:#006400">연구 결과 02</span>'''====
 
===='''<span style="color:#006400">연구 결과 02</span>'''====
 
<div style="border:1px solid #000;">
 
<div style="border:1px solid #000;">
99번째 줄: 101번째 줄:
 
:다만, 아직 초반 부분이며 전체 장을 마크업하면 흥미로운 결과가 나올 듯 하다..<br/>
 
:다만, 아직 초반 부분이며 전체 장을 마크업하면 흥미로운 결과가 나올 듯 하다..<br/>
 
</div>
 
</div>
 
+
<br/>
 +
<div style="text-align:center;"><big><b><che> 속성 공간 분포 (마이크로 닷 히트맵)</b><big> <br/>
 +
<small>각 격자는 하나의 단락을 의미하며, 한 줄에 15개씩 출력되도록 줄바꿈 되었습니다.</small><br/>
 +
<small>격자 좌상단의 작은 숫자는 단락의 순번입니다.</small></div><br/>
 +
<div style="text-align:center;">[[파일:인력거시각화2-1.png]]</div>
 +
<br/>
 +
<div style="text-align:center;">[[파일:인력거시각화2-2.png]]</div>
 
-----
 
-----
 +
<br/>
 
===='''<span style="color:#006400">연구 결과 03</span>'''====
 
===='''<span style="color:#006400">연구 결과 03</span>'''====
 
<div style="border:1px solid #000;">
 
<div style="border:1px solid #000;">
108번째 줄: 117번째 줄:
 
:연구결과02에서 언급했듯, 작품의 후반부까지 마크업하면 샹즈와 연결된 '발생-희망'의 비율이 어떻게 달라질 것인가? 역전할 것인가?
 
:연구결과02에서 언급했듯, 작품의 후반부까지 마크업하면 샹즈와 연결된 '발생-희망'의 비율이 어떻게 달라질 것인가? 역전할 것인가?
 
</div>
 
</div>
 +
<html lang="ko">
 +
<head>
 +
    <meta charset="UTF-8">
 +
    <title>낙타샹즈 상태-주체 생키 다이어그램</title>
 +
    <script src="https://d3js.org/d3.v7.min.js"></script>
 +
    <script src="https://unpkg.com/d3-sankey@0.12.3/dist/d3-sankey.min.js"></script>
 +
    <style>
 +
        body { font-family: 'Malgun Gothic', sans-serif; background-color: #f8f9fa; margin: 0; padding: 20px; display: flex; flex-direction: column; align-items: center; }
 +
        h1 { color: #2c3e50; margin-bottom: 10px; }
 +
        .desc { color: #666; margin-bottom: 30px; font-size: 14px; text-align: center; }
 +
        .chart-box { background: #fff; padding: 30px; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.1); }
 +
       
 +
        .node rect { cursor: move; fill-opacity: 0.9; shape-rendering: crispEdges; stroke: #333; stroke-width: 1px; }
 +
        .node text { pointer-events: none; text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, 0 -1px 0 #fff, -1px 0 0 #fff; font-weight: bold; font-size: 14px; }
 +
       
 +
        .link { fill: none; stroke-opacity: 0.4; transition: stroke-opacity 0.2s; }
 +
        .link:hover { stroke-opacity: 0.8 !important; }
 +
       
 +
        .tooltip { position: absolute; text-align: center; padding: 10px; font-size: 13px; background: rgba(0,0,0,0.85); color: #fff; border-radius: 6px; pointer-events: none; opacity: 0; transition: opacity 0.2s; z-index: 10; box-shadow: 0 4px 6px rgba(0,0,0,0.2); }
 +
    </style>
 +
</head>
 +
<body>
 +
    <div style="text-align:center;"><small><h1>&lt;che&gt; 속성 교차 흐름 (상태 → 주체)</h1></small></div>
 +
    <div class="desc">
 +
        1~5장에 등장하는 전체 &lt;che&gt; 마크업의 속성값을 바탕으로 작성된 생키 다이어그램입니다.<br>
 +
        선의 두께는 동시 출현 빈도(결합 강도)에 비례하며, 노드에 마우스를 올리면 상세 수치를 확인할 수 있습니다.
 +
    </div>
 +
 +
    <div class="chart-box" id="sankey-container"></div>
 +
    <div class="tooltip" id="tooltip"></div>
 +
 +
    <script>
 +
        const data = {"nodes": [{"name": "\ubc1c\uc0dd", "category": "state"}, {"name": "\ud76c\ub9dd", "category": "state"}, {"name": "\uae30\ud0c0", "category": "state"}, {"name": "\uc0f9\uc988", "category": "subject"}, {"name": "\ud0c0\uc778", "category": "subject"}, {"name": "\uc0ac\ubb3c", "category": "subject"}], "links": [{"source": 0, "target": 4, "value": 47}, {"source": 2, "target": 5, "value": 35}, {"source": 1, "target": 4, "value": 8}, {"source": 0, "target": 3, "value": 127}, {"source": 1, "target": 3, "value": 68}, {"source": 2, "target": 4, "value": 6}, {"source": 2, "target": 3, "value": 24}, {"source": 0, "target": 5, "value": 16}, {"source": 1, "target": 5, "value": 4}]};
 +
        const tooltip = d3.select("#tooltip");
 +
 +
        const margin = {top: 30, right: 150, bottom: 30, left: 150};
 +
        const width = 1000 - margin.left - margin.right;
 +
        const height = 600 - margin.top - margin.bottom;
 +
 +
        const svg = d3.select("#sankey-container").append("svg")
 +
            .attr("width", width + margin.left + margin.right)
 +
            .attr("height", height + margin.top + margin.bottom)
 +
            .append("g")
 +
            .attr("transform", `translate(${margin.left},${margin.top})`);
 +
 +
        // 색상 스케일
 +
        const colorScale = d3.scaleOrdinal()
 +
            .domain(["발생", "희망", "기타", "샹즈", "타인", "사물"])
 +
            .range(["#ff7f0e", "#2ca02c", "#7f7f7f", "#1f77b4", "#9467bd", "#8c564b"]);
 +
 +
        // 생키 레이아웃 설정
 +
        const sankey = d3.sankey()
 +
            .nodeWidth(30)
 +
            .nodePadding(60)
 +
            .extent([[0, 0], [width, height]]);
 +
 +
        const {nodes, links} = sankey(data);
 +
 +
        // 링크(흐름선) 그리기
 +
        const link = svg.append("g")
 +
            .attr("fill", "none")
 +
            .selectAll(".link")
 +
            .data(links)
 +
            .enter().append("path")
 +
            .attr("class", "link")
 +
            .attr("d", d3.sankeyLinkHorizontal())
 +
            .attr("stroke", d => colorScale(d.source.name))
 +
            .attr("stroke-width", d => Math.max(1, d.width))
 +
            .on("mouseover", function(event, d) {
 +
                d3.selectAll(".link").style("stroke-opacity", 0.1);
 +
                d3.select(this).style("stroke-opacity", 0.8);
 +
               
 +
                tooltip.style("opacity", 1)
 +
                      .html(`<strong>${d.source.name} → ${d.target.name}</strong><br>빈도: ${d.value}건`)
 +
                      .style("left", (event.pageX + 15) + "px")
 +
                      .style("top", (event.pageY - 15) + "px");
 +
            })
 +
            .on("mouseout", function() {
 +
                d3.selectAll(".link").style("stroke-opacity", 0.4);
 +
                tooltip.style("opacity", 0);
 +
            });
 +
 +
        // 노드(막대) 그리기
 +
        const node = svg.append("g")
 +
            .selectAll(".node")
 +
            .data(nodes)
 +
            .enter().append("g")
 +
            .attr("class", "node")
 +
            .attr("transform", d => `translate(${d.x0},${d.y0})`)
 +
            .call(d3.drag()
 +
                .subject(d => d)
 +
                .on("start", function() { this.parentNode.appendChild(this); })
 +
                .on("drag", dragmove));
  
 +
        node.append("rect")
 +
            .attr("height", d => d.y1 - d.y0)
 +
            .attr("width", sankey.nodeWidth())
 +
            .attr("fill", d => colorScale(d.name))
 +
            .on("mouseover", function(event, d) {
 +
                // 하이라이트 연결된 링크
 +
                link.style("stroke-opacity", l => (l.source === d || l.target === d) ? 0.8 : 0.1);
 +
               
 +
                tooltip.style("opacity", 1)
 +
                      .html(`<strong>${d.name}</strong><br>총합: ${d.value}건`)
 +
                      .style("left", (event.pageX + 15) + "px")
 +
                      .style("top", (event.pageY - 15) + "px");
 +
            })
 +
            .on("mouseout", function() {
 +
                link.style("stroke-opacity", 0.4);
 +
                tooltip.style("opacity", 0);
 +
            });
 +
 +
        // 노드 텍스트 라벨
 +
        node.append("text")
 +
            .attr("x", d => d.x0 < width / 2 ? 40 : -10)
 +
            .attr("y", d => (d.y1 - d.y0) / 2)
 +
            .attr("dy", "0.35em")
 +
            .attr("text-anchor", d => d.x0 < width / 2 ? "start" : "end")
 +
            .text(d => `${d.name} (${d.value})`);
 +
 +
        // 드래그 앤 드롭 함수 (위아래 이동)
 +
        function dragmove(event, d) {
 +
            d.y0 = Math.max(0, Math.min(height - (d.y1 - d.y0), event.y));
 +
            d.y1 = d.y0 + (d.y1 - d.y0);
 +
            d3.select(this).attr("transform", `translate(${d.x0},${d.y0})`);
 +
            sankey.update(data);
 +
            link.attr("d", d3.sankeyLinkHorizontal());
 +
        }
 +
       
 +
        // 컬럼 라벨 (상태, 주체)
 +
        svg.append("text")
 +
            .attr("x", 15)
 +
            .attr("y", -10)
 +
            .attr("text-anchor", "middle")
 +
            .style("font-size", "16px")
 +
            .style("font-weight", "bold")
 +
            .style("fill", "#2c3e50")
 +
            .text("상태 (State)");
 +
           
 +
        svg.append("text")
 +
            .attr("x", width - 15)
 +
            .attr("y", -10)
 +
            .attr("text-anchor", "middle")
 +
            .style("font-size", "16px")
 +
            .style("font-weight", "bold")
 +
            .style("fill", "#2c3e50")
 +
            .text("주체 (Subject)");
 +
 +
    </script>
 +
</body>
 +
</html>
  
 
<br/>
 
<br/>
 
<br/>
 
<br/>
 
<br/>
 
<br/>
 +
 
==='''<span style="color:#006400">나가며</span>'''===
 
==='''<span style="color:#006400">나가며</span>'''===
 
<br/>
 
<br/>

2026년 6월 18일 (목) 15:53 판





샹즈와 인력거


중어중문학과 정선한


문제의식

  • 『낙타상자』에서 '인력거'라는 중심 사물이 차지하는 비중은 어느 정도인가?
  • 샹즈가 인력거를 '실제'로 가지고 있는 정도가 많을 것인가, '희망'하는 정도가 많을 것인가?


연구 목적

01. 전체 문장에서 '車(인력거)'가 언급된 분포 시각화
02. 샹즈의 현실과 비현실 속 인력거의 등장 양상 확인

연구 방법

01. 전체 문장에서 '車, 인력거'가 언급된 양상과 분포는 어떻게 나타나는가?

<Sentence> 단위에서 '車'와 '인력거' 전체 마크업 다시 4가지 태그로 분류한다.

  1. che: 인력거
  2. cheRen: 인력거와 관련된 사람
  3. chePlace: 인력거와 관련된 장소
  4. cheMoney: 인력거와 관련된 돈




02. 샹즈는 '인력거'를 현실에서 접하는가, 희망으로 접하는가?

<che>태그 내에서 속성으로 현실과 희망을 구분한다.

<che 상태="발생/희망/기타" 주체="샹즈/타인/사물">
상태
주체

발생: 현재 발생한 사건, 샹즈에게 이미 일어난 일, 실제로 일어난 것
희망: 실제로 일어나지는 않았지만 실현되길 바라는 사건, 할 것임을 다짐하는 문장
기타: 발생/희망에 해당하지 않음

샹즈: 발생/희망/기타 사건의 동작을 하는 주체가 샹즈
타인: 발생/희망/기타 사건의 동작을 하는 주체가 타인
사물: 발생/희망/기타 사건의 동작을 하는 주체가 사람이 아님




03. <che> 속성의 상태와 주체의 교차 흐름은 어떻게 되는가?

이는 인력거가 존재하는 방식과 그 시점에서의 인력거 소유 주체를 보기 위함이다.
각 속성값을 생키 다이어그램으로 비율과 흐름을 확인한다.

연구 결과


연구 결과 01

  • 전체 문장 1807개 중, 346개만이 '인력거'와 관련이 있다. 비율은 19.15% 이다.
『낙타상자』에서 '인력거'는 가장 주된 사물이지만, 라오서가 서술한 비율은 크지 않다.
또한 '인력거'가 출현하지 않은 문장은 각각 '낙타', '돈', '결혼' 등의 요소로 내용을 이끌고 있다.


인력거시각화1.png



연구 결과 02

  • 1장 1단락부터 5장 7단락까지의 데이터다.
샹즈는 인력거를 얻기 위해, 그리고 인력거를 찾기 위해 고군분터하는 인물이다.
따라서 인력거를 희망하며 노력하는 시간이 많을 것으로(<che 상태="희망">이 많을 것으로) 예상했는데 그렇지 않았다.
다만, 아직 초반 부분이며 전체 장을 마크업하면 흥미로운 결과가 나올 듯 하다..


<che> 속성 공간 분포 (마이크로 닷 히트맵)

각 격자는 하나의 단락을 의미하며, 한 줄에 15개씩 출력되도록 줄바꿈 되었습니다.

격자 좌상단의 작은 숫자는 단락의 순번입니다.

인력거시각화2-1.png


인력거시각화2-2.png


연구 결과 03

  • <che> 속성의 상태와 주체의 교차 흐름의 결과, 주체는 샹즈가 단연 제일 큰 비중이었다.
샹즈 중심의 서술이므로 샹즈의 발생-희망 비율(53.5%)이 타인의 발생-희망(17.0%)보다 높은 수치를 보였다.
이때, '타인'을 각 인물명으로 세분화하면 여전히 발생-희망 비율이 유사하게 나타날 것인가? 인물별로 달라지리라 예상한다.
연구결과02에서 언급했듯, 작품의 후반부까지 마크업하면 샹즈와 연결된 '발생-희망'의 비율이 어떻게 달라질 것인가? 역전할 것인가?

낙타샹즈 상태-주체 생키 다이어그램

<che> 속성 교차 흐름 (상태 → 주체)

1~5장에 등장하는 전체 <che> 마크업의 속성값을 바탕으로 작성된 생키 다이어그램입니다.
선의 두께는 동시 출현 빈도(결합 강도)에 비례하며, 노드에 마우스를 올리면 상세 수치를 확인할 수 있습니다.




나가며


추후 진행되어야 할 작업과 남아 있는 질문은 다음과 같다.

전체 데이터의 마크업이 완료되면,
<che 상태="발생/희망/기타"> 마크업 샹즈는 '인력거를 끄는' 인물이 될 것인가, '인력거를 갈하는' 인물이 될 것인가?
<che 상태="발생/희망/기타"> 마크업 서사의 진행에 따라 '인력거'가 샹즈의 현실과 비현실에 존재하는 모습은 어떤 변화를 보일 것인가?
<che 주체="타인"> 구체화 각 인물별로 인력거를 소유하고, 바라는 비율은 어떻게 될 것인가?
<che 주체="타인"> 구체화 직업(신분)별로 어떠한 양상을 보일 것인가? 인력거꾼들과, 샹즈의 비율을 유사한 수치를 보일 것인가?
'인력거' 외 주요 사물 마크업 서사를 진행하는 중심 사물은 무엇으로 이동하는가? 라오서가 사용한 주요 매개체가 '인력거'가 정말 맞을 것인가?

이 작품의 첫 문장이다.

我們所要介紹的是祥子,不是駱駝, 내가 소개하고자 하는 이는 샹즈祥子이지 낙타駱駝가 아니다.
'샹즈'에 관한 소개인 『낙타상자』에서 각각의 사물은 언제 등장하며, '낙타'는 무엇의 시발점이 되는가?