feat: add option to show dislike
This commit is contained in:
		
							
								
								
									
										29
									
								
								analysis.py
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								analysis.py
									
									
									
									
									
								
							@@ -49,13 +49,10 @@ def sociogram_json():
 | 
				
			|||||||
    return JSONResponse({"nodes": nodes, "links": links})
 | 
					    return JSONResponse({"nodes": nodes, "links": links})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def sociogram_data():
 | 
					def sociogram_data(dislike: bool | None = False):
 | 
				
			||||||
    nodes = []
 | 
					 | 
				
			||||||
    links = []
 | 
					 | 
				
			||||||
    G = nx.DiGraph()
 | 
					    G = nx.DiGraph()
 | 
				
			||||||
    with Session(engine) as session:
 | 
					    with Session(engine) as session:
 | 
				
			||||||
        for p in session.exec(select(P)).fetchall():
 | 
					        for p in session.exec(select(P)).fetchall():
 | 
				
			||||||
            nodes.append({"id": p.name})
 | 
					 | 
				
			||||||
            G.add_node(p.name)
 | 
					            G.add_node(p.name)
 | 
				
			||||||
        subquery = (
 | 
					        subquery = (
 | 
				
			||||||
            select(C.user, func.max(C.time).label("latest"))
 | 
					            select(C.user, func.max(C.time).label("latest"))
 | 
				
			||||||
@@ -70,8 +67,10 @@ def sociogram_data():
 | 
				
			|||||||
        )
 | 
					        )
 | 
				
			||||||
        for c in session.exec(statement2):
 | 
					        for c in session.exec(statement2):
 | 
				
			||||||
            for i, p in enumerate(c.love):
 | 
					            for i, p in enumerate(c.love):
 | 
				
			||||||
                G.add_edge(c.user, p, rank=i, popularity=1 - 0.08 * i)
 | 
					                G.add_edge(c.user, p, group="love", rank=i, popularity=1 - 0.08 * i)
 | 
				
			||||||
                links.append({"source": c.user, "target": p})
 | 
					            if dislike:
 | 
				
			||||||
 | 
					                for i, p in enumerate(c.hate):
 | 
				
			||||||
 | 
					                    G.add_edge(c.user, p, group="hate", rank=8, popularity=-0.16)
 | 
				
			||||||
    return G
 | 
					    return G
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -83,6 +82,12 @@ class Params(BaseModel):
 | 
				
			|||||||
    distance: float | None = 0.2
 | 
					    distance: float | None = 0.2
 | 
				
			||||||
    weighting: bool | None = True
 | 
					    weighting: bool | None = True
 | 
				
			||||||
    popularity: bool | None = True
 | 
					    popularity: bool | None = True
 | 
				
			||||||
 | 
					    dislike: bool | None = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ARROWSTYLE = {"love": "-|>", "hate": "-|>"}
 | 
				
			||||||
 | 
					EDGESTYLE = {"love": "-", "hate": ":"}
 | 
				
			||||||
 | 
					EDGECOLOR = {"love": "#404040", "hate": "#cc0000"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async def render_sociogram(params: Params):
 | 
					async def render_sociogram(params: Params):
 | 
				
			||||||
@@ -91,7 +96,7 @@ async def render_sociogram(params: Params):
 | 
				
			|||||||
    ax.set_facecolor("none")  # Set the axis face color to none (transparent)
 | 
					    ax.set_facecolor("none")  # Set the axis face color to none (transparent)
 | 
				
			||||||
    ax.axis("off")  # Turn off axis ticks and frames
 | 
					    ax.axis("off")  # Turn off axis ticks and frames
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    G = sociogram_data()
 | 
					    G = sociogram_data(params.dislike)
 | 
				
			||||||
    pos = nx.spring_layout(G, scale=2, k=params.distance, iterations=50, seed=None)
 | 
					    pos = nx.spring_layout(G, scale=2, k=params.distance, iterations=50, seed=None)
 | 
				
			||||||
    nodes = nx.draw_networkx_nodes(
 | 
					    nodes = nx.draw_networkx_nodes(
 | 
				
			||||||
        G,
 | 
					        G,
 | 
				
			||||||
@@ -109,18 +114,20 @@ async def render_sociogram(params: Params):
 | 
				
			|||||||
        alpha=0.86,
 | 
					        alpha=0.86,
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    if params.popularity:
 | 
					    if params.popularity:
 | 
				
			||||||
        plt.colorbar(nodes)
 | 
					        cbar = plt.colorbar(nodes)
 | 
				
			||||||
 | 
					        cbar.ax.set_xlabel("popularity")
 | 
				
			||||||
    nx.draw_networkx_labels(G, pos, font_size=params.font_size)
 | 
					    nx.draw_networkx_labels(G, pos, font_size=params.font_size)
 | 
				
			||||||
    nx.draw_networkx_edges(
 | 
					    nx.draw_networkx_edges(
 | 
				
			||||||
        G,
 | 
					        G,
 | 
				
			||||||
        pos,
 | 
					        pos,
 | 
				
			||||||
        arrows=True,
 | 
					        arrows=True,
 | 
				
			||||||
        edge_color="#404040",
 | 
					        edge_color=[EDGECOLOR[G.edges()[*edge]["group"]] for edge in G.edges()],
 | 
				
			||||||
        arrowsize=params.arrow_size,
 | 
					        arrowsize=params.arrow_size,
 | 
				
			||||||
        node_size=params.node_size,
 | 
					        node_size=params.node_size,
 | 
				
			||||||
        width=params.edge_width,
 | 
					        width=params.edge_width,
 | 
				
			||||||
        arrowstyle="-|>",
 | 
					        style=[EDGESTYLE[G.edges()[*edge]["group"]] for edge in G.edges()],
 | 
				
			||||||
        # connectionstyle="arc3,rad=0.2",
 | 
					        arrowstyle=[ARROWSTYLE[G.edges()[*edge]["group"]] for edge in G.edges()],
 | 
				
			||||||
 | 
					        connectionstyle="arc3,rad=0.12",
 | 
				
			||||||
        alpha=[1 - 0.08 * G.edges()[*edge]["rank"] for edge in G.edges()]
 | 
					        alpha=[1 - 0.08 * G.edges()[*edge]["rank"] for edge in G.edges()]
 | 
				
			||||||
        if params.weighting
 | 
					        if params.weighting
 | 
				
			||||||
        else 1,
 | 
					        else 1,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,6 +33,7 @@ interface Params {
 | 
				
			|||||||
  distance: number;
 | 
					  distance: number;
 | 
				
			||||||
  weighting: boolean;
 | 
					  weighting: boolean;
 | 
				
			||||||
  popularity: boolean;
 | 
					  popularity: boolean;
 | 
				
			||||||
 | 
					  dislike: boolean;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface DeferredProps {
 | 
					interface DeferredProps {
 | 
				
			||||||
@@ -47,11 +48,12 @@ export default function Analysis() {
 | 
				
			|||||||
  const [params, setParams] = useState<Params>({
 | 
					  const [params, setParams] = useState<Params>({
 | 
				
			||||||
    nodeSize: 2000,
 | 
					    nodeSize: 2000,
 | 
				
			||||||
    edgeWidth: 1,
 | 
					    edgeWidth: 1,
 | 
				
			||||||
    arrowSize: 20,
 | 
					    arrowSize: 16,
 | 
				
			||||||
    fontSize: 10,
 | 
					    fontSize: 10,
 | 
				
			||||||
    distance: 2,
 | 
					    distance: 2,
 | 
				
			||||||
    weighting: true,
 | 
					    weighting: true,
 | 
				
			||||||
    popularity: true,
 | 
					    popularity: true,
 | 
				
			||||||
 | 
					    dislike: false,
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
  const [showControlPanel, setShowControlPanel] = useState(false);
 | 
					  const [showControlPanel, setShowControlPanel] = useState(false);
 | 
				
			||||||
  const [loading, setLoading] = useState(false);
 | 
					  const [loading, setLoading] = useState(false);
 | 
				
			||||||
@@ -72,15 +74,14 @@ export default function Analysis() {
 | 
				
			|||||||
        setLoading(false);
 | 
					        setLoading(false);
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  useEffect(() => {
 | 
					  useEffect(() => {
 | 
				
			||||||
    if (timeoutID) {
 | 
					    if (timeoutID) {
 | 
				
			||||||
      console.log(timeoutID);
 | 
					 | 
				
			||||||
      clearTimeout(timeoutID);
 | 
					      clearTimeout(timeoutID);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    timeoutID = setTimeout(() => {
 | 
					    timeoutID = setTimeout(() => {
 | 
				
			||||||
      console.log("fire");
 | 
					 | 
				
			||||||
      loadImage();
 | 
					      loadImage();
 | 
				
			||||||
    }, 1500);
 | 
					    }, 1000);
 | 
				
			||||||
  }, [params]);
 | 
					  }, [params]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
@@ -91,6 +92,14 @@ export default function Analysis() {
 | 
				
			|||||||
      <div id="control-panel" className={showControlPanel ? "opened" : ""}>
 | 
					      <div id="control-panel" className={showControlPanel ? "opened" : ""}>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <div className="control">
 | 
					        <div className="control">
 | 
				
			||||||
 | 
					          <div className="checkBox">
 | 
				
			||||||
 | 
					            <input
 | 
				
			||||||
 | 
					              type="checkbox"
 | 
				
			||||||
 | 
					              checked={params.dislike}
 | 
				
			||||||
 | 
					              onChange={(evt) => setParams({ ...params, dislike: evt.target.checked })}
 | 
				
			||||||
 | 
					            />
 | 
				
			||||||
 | 
					            <label>show dislike</label>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
          <div className="checkBox">
 | 
					          <div className="checkBox">
 | 
				
			||||||
            <input
 | 
					            <input
 | 
				
			||||||
              type="checkbox"
 | 
					              type="checkbox"
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user