Skip to content

Commit

Permalink
fixed dataset. coloring lines, no zoom for now
Browse files Browse the repository at this point in the history
  • Loading branch information
bianchimro committed Jun 3, 2020
1 parent b240a3d commit 861b0b1
Show file tree
Hide file tree
Showing 4 changed files with 272 additions and 164 deletions.
336 changes: 204 additions & 132 deletions src/visualizations/Trama2/LineeTrama.js
Original file line number Diff line number Diff line change
@@ -1,166 +1,238 @@
import React, { useRef, useState, useMemo, useEffect, useCallback } from 'react'
import { line, curveMonotoneX } from 'd3-shape'
import { scaleLinear } from 'd3-scale'


const MAX_ZOOM_LEVEL = 10




function LineaTrama({racconto, data, xScale, width, height, zoomLevel, index}){
const lineGenerator = line().x(d => d.x).y(d => d.y * zoomLevel).curve(curveMonotoneX)
const d = lineGenerator(data)
return <g>
{/* <rect width={width} height={height} style={{fill: "teal", fillOpacity:0.3}}></rect> */}
<path d={d} className="trama2-line"></path>
<text x={0} y={height-10}>{index}</text>
{/* <line x1={0} x2={width} y1={height} y2={height} style={{stroke: '#000'}}></line> */}
import React, {
useRef,
useState,
useMemo,
useEffect,
useCallback,
} from "react";
import { line, curveMonotoneX } from "d3-shape";
import { scaleLinear } from "d3-scale";

const MAX_ZOOM_LEVEL = 10;

function LineaTrama({
racconto,
data,
xScale,
width,
height,
zoomLevel,
index,
gradient,
itemSelected,
toggleItem
}) {
const lineGenerator = line()
.x((d) => d.x)
.y((d) => d.y * zoomLevel)
.curve(curveMonotoneX);
const d = lineGenerator(data);
const stroke = itemSelected ? `url('#trama-gradient-${zoomLevel}')` : '#ddd'
return (
<g>
{data.map((d,i) => (<circle key={i} className="trama2-circle" cx={d.x} cy={d.y*zoomLevel } r={2}></circle>))}
{/* <rect
width={width}
height={height}
></rect> */}
<path d={d} className={`trama2-pointer ${itemSelected ? 'selected' : ''}`} onClick={toggleItem}></path>
<path d={d} className="trama2-line" style={{stroke}}></path>
<text x={0} y={height - 10}>
{index}
</text>
{/* <line x1={0} x2={width} y1={height} y2={height} style={{stroke: '#000'}}></line> */}
{itemSelected && <g>
{data.map((d, i) => (
<circle
key={i}
className="trama2-circle"
cx={d.x}
cy={d.y * zoomLevel}
r={2}
></circle>
))}
</g>}
</g>
</g>
);
}

export default function LineeTrama({
racconti = [],
data = {},
height,
scalaColore,
scalaMotivoY,
colors,
selected,
toggleSelect
}) {
const containerRef = useRef(null);
const [measures, setMeasures] = useState(null);
const [zoomLevel, setZoomLevel] = useState(1.0);
const [zoomY, setZoomY] = useState(0);

console.log("colors", colors);

export default function LineeTrama({racconti=[], data={}, height, scalaColore, scalaMotivoY}){

useEffect(() => {
const m = containerRef.current.getBoundingClientRect();
setMeasures(m);
}, []);

const containerRef = useRef(null)
const [measures, setMeasures] = useState(null)
const [zoomLevel, setZoomLevel] = useState(1.0)
const [zoomY, setZoomY] = useState(0)
const scrollHandler = useCallback(
(e, n) => {
const sign = e.deltaY > 0 ? 1.0 : -1.0;



useEffect(() => {
const m = containerRef.current.getBoundingClientRect()
setMeasures(m)
}, [])

const scrollHandler = useCallback((e, n) => {


const sign = e.deltaY > 0 ? 1.0 : -1.0

const newLevel = zoomLevel + (0.1 * sign)

if(newLevel > MAX_ZOOM_LEVEL){
return
const newLevel = zoomLevel + 0.1 * sign;

if (newLevel > MAX_ZOOM_LEVEL) {
return;
}
if(newLevel <= 1){
setZoomY(0)
return
if (newLevel <= 1) {
setZoomY(0);
return;
}
setZoomLevel(Math.max(1, Math.min(newLevel, MAX_ZOOM_LEVEL)))
if(!zoomY){
setZoomY(e.layerY)
setZoomLevel(Math.max(1, Math.min(newLevel, MAX_ZOOM_LEVEL)));
if (!zoomY) {
setZoomY(e.layerY);
}


return false


}, [zoomLevel, zoomY])

useEffect(() => {
const n = containerRef.current
return false;
},
[zoomLevel, zoomY]
);

const sh = (e) => {scrollHandler(e, n)}

n.addEventListener('wheel', sh, {passive: true});
return () => {
n.removeEventListener('wheel', sh, {passive: true});
}

}, [scrollHandler])

// useEffect(() => {
// const n = containerRef.current;

const delta = useMemo(() => {
if(!measures){ return 0}
return (measures.height - height) / racconti.length
// const sh = (e) => {
// scrollHandler(e, n);
// };

}, [height, measures, racconti.length])
// n.addEventListener("wheel", sh, { passive: true });
// return () => {
// n.removeEventListener("wheel", sh, { passive: true });
// };
// }, [scrollHandler]);

const xScale = useMemo(() => {
if(!measures){ return null}
return scaleLinear().domain([0, 1]).range([0, measures.width])
}, [measures])
const delta = useMemo(() => {
if (!measures) {
return 0;
}
return (measures.height - height) / racconti.length;
}, [height, measures, racconti.length]);

const xScale = useMemo(() => {
if (!measures) {
return null;
}
return scaleLinear().domain([0, 1]).range([0, measures.width]);
}, [measures]);

const dataRacconti = useMemo(() => {
if(!xScale){
return []
if (!xScale) {
return [];
}
return racconti.map(racconto => {
return data[racconto.titolo].filter(d => !!d.y).map(d => {
return {
x: xScale(d.x),
y: d.y
}
})
})
}, [data, racconti, xScale])
return racconti.map((racconto) => {
return data[racconto.titolo]
.filter((d) => !!d.y)
.map((d) => {
return {
x: xScale(d.x),
y: d.y,
};
});
});
}, [data, racconti, xScale]);


const baseDisplacements = useMemo(() => {
return dataRacconti.map((d, i) => {
let dy = delta * i;
return dy
})
}, [dataRacconti, delta])
return dy;
});
}, [dataRacconti, delta]);


const displacements = useMemo(() => {
return dataRacconti.map((d, i) => {
let dy = baseDisplacements[i]
let dy = baseDisplacements[i];

const j = Math.round(zoomY/delta)
const j = Math.round(zoomY / delta);

const diff = delta * j * zoomLevel
const factor = (zoomLevel - 1) / (MAX_ZOOM_LEVEL - 1) * zoomLevel
const diff = delta * j * zoomLevel;
const factor = ((zoomLevel - 1) / (MAX_ZOOM_LEVEL - 1)) * zoomLevel;

return dy * zoomLevel - diff * factor
})
}, [baseDisplacements, dataRacconti, delta, zoomLevel, zoomY])
return dy * zoomLevel - diff * factor;
});
}, [baseDisplacements, dataRacconti, delta, zoomLevel, zoomY]);

const deltaColors = useMemo(() => {
return ( height * zoomLevel) / colors.length
}, [colors.length, height, zoomLevel])


return <div ref={containerRef} className="w-100 h-100" style={{overflow:'auto'}}>
{measures && <svg
style={{height:measures.height, width: measures.width,
transform : `perspective(${zoomLevel})`, transformOrigin:`50% 50%`
}} ref={containerRef}>
{dataRacconti.map((datum, i) => {



const dy = displacements[i]

//

if(dy < - height * zoomLevel){
return null
}
if(dy > measures.height){
return null
}


// const datum = data[racconto]
return <g key={i} style={{
transform: `translateY(${dy}px)`,
}}>
<LineaTrama scalaColore={scalaColore} scalaMotivoY={scalaMotivoY}
index={i}
width={measures.width}
height={height*zoomLevel}
zoomLevel={zoomLevel}
xScale={xScale} racconto={racconti[i]} data={datum}></LineaTrama>
</g>
})}

</svg>}
</div>


}



return (
<div
ref={containerRef}
className="w-100 h-100"
style={{ overflow: "auto" }}
>
{measures && (
<svg
style={{
height: measures.height,
width: measures.width,
// transform: `perspective(${zoomLevel})`,
// transformOrigin: `50% 50%`,
}}
ref={containerRef}
>
<linearGradient id={`trama-gradient-${zoomLevel}`} gradientUnits="userSpaceOnUse" y1={0} y2={height* zoomLevel} x1={0} x2={0}>
{colors.map((color, i) => (
<stop key={i} offset={`${deltaColors*i}%`} stopColor={color}></stop>
))}
</linearGradient>

{dataRacconti.map((datum, i) => {
const dy = displacements[i];

if (dy < -height * zoomLevel) {
return null;
}
if (dy > measures.height) {
return null;
}

// const datum = data[racconto]
return (
<g
key={i}
style={{
transform: `translateY(${dy}px)`,
}}
>
<LineaTrama
scalaColore={scalaColore}
scalaMotivoY={scalaMotivoY}
index={i}
width={measures.width}
height={height * zoomLevel}
zoomLevel={zoomLevel}
itemSelected={selected[i]}
toggleItem={toggleSelect(i)}
xScale={xScale}
racconto={racconti[i]}
data={datum}
></LineaTrama>
</g>
);
})}
</svg>
)}
</div>
);
}
Loading

0 comments on commit 861b0b1

Please sign in to comment.