File size: 3,833 Bytes
b68f453
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import { Backdrop, CircularProgress, List, ListItem, Paper, Typography } from "@mui/material";
import * as d3 from "d3";
import React, { useCallback, useContext, useEffect, useRef, useState } from "react";
import { TopicsContext } from "./UploadFileContext";

const bunkaTopics = "bunka_topics.json";
const { REACT_APP_API_ENDPOINT } = process.env;

function TreemapView() {
  const svgRef = useRef(null);
  const [selectedTopic, setSelectedTopic] = useState({ name: "", content: [] });
  const { data: apiData, isLoading } = useContext(TopicsContext);

  const createTreemap = useCallback((data) => {
    const width = window.innerWidth * 0.6; // Adjust the width for the treemap
    const height = 800; // Adjust the height as needed

    const svg = d3.select(svgRef.current).attr("width", width).attr("height", height);

    const root = d3.hierarchy({ children: data }).sum((d) => d.size);

    const treemapLayout = d3.treemap().size([width, height]).padding(1).round(true);

    treemapLayout(root);

    const cell = svg
      .selectAll("g")
      .data(root.leaves())
      .enter()
      .append("g")
      .attr("transform", (d) => `translate(${d.x0},${d.y0})`)
      .on("click", (event, d) => {
        const topicName = d.data.name;
        const topicContent = d.data.top_doc_content || [];

        setSelectedTopic({ name: topicName, content: topicContent });
      });

    cell
      .append("rect")
      .attr("width", (d) => d.x1 - d.x0)
      .attr("height", (d) => d.y1 - d.y0)
      .style("fill", "lightblue")
      .style("stroke", "blue");

    cell
      .append("text")
      .selectAll("tspan")
      .data((d) => {
        const text = d.data.name.split(/(?=[A-Z][^A-Z])/g); // Split topic name on capital letters
        return text;
      })
      .enter()
      .append("tspan")
      .attr("x", 3)
      .attr("y", (d, i) => 13 + i * 10)
      .text((d) => d);

    svg.selectAll("text").attr("font-size", 13).attr("fill", "black");
  }, []);

  useEffect(() => {
    if (REACT_APP_API_ENDPOINT === "local" || apiData === undefined) {
      // Fetch the JSON data locally
      fetch(`/${bunkaTopics}`)
        .then((response) => response.json())
        .then((localData) => {
          createTreemap(localData);
        })
        .catch((error) => {
          console.error("Error fetching JSON data:", error);
        });
    } else {
      // Call the function with the data provided by TopicsContext
      createTreemap(apiData.topics);
    }
  }, [apiData, createTreemap]);

  return (
    <div>
      <h2>Treemap View</h2>
      {isLoading ? (
        <Backdrop open={isLoading} style={{ zIndex: 9999 }}>
          <CircularProgress color="primary" />
        </Backdrop>
      ) : (
        <div style={{ display: "flex" }}>
          <svg ref={svgRef} style={{ marginRight: "20px" }} />
          <div
            style={{
              width: window.innerWidth * 0.25,
              maxHeight: "800px",
              overflowY: "auto",
            }}
          >
            <Paper>
              <Typography
                variant="h4"
                style={{
                  position: "sticky",
                  top: 0,
                  backgroundColor: "white",
                  color: "blue",
                }}
              >
                {selectedTopic.name}
              </Typography>
              {selectedTopic.content.map((doc, index) => (
                <List key={doc.id}>
                  <ListItem>
                    <Typography variant="h5">{doc}</Typography>
                  </ListItem>
                </List>
              ))}
              {selectedTopic.content.length === 0 && <Typography variant="h4">Click on a Square.</Typography>}
            </Paper>
          </div>
        </div>
      )}
    </div>
  );
}

export default TreemapView;