Skip to content

Commit

Permalink
trama2: sidebar and working on zoom
Browse files Browse the repository at this point in the history
  • Loading branch information
bianchimro committed Jun 4, 2020
1 parent 861b0b1 commit baff826
Show file tree
Hide file tree
Showing 4 changed files with 375 additions and 180 deletions.
154 changes: 101 additions & 53 deletions src/visualizations/Trama2/LineeTrama.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import React, {
} from "react";
import { line, curveMonotoneX } from "d3-shape";
import { scaleLinear } from "d3-scale";
import { zoom } from "d3";

const MAX_ZOOM_LEVEL = 10;
const TOP_SVG_PADDING = 20;

function LineaTrama({
racconto,
Expand All @@ -20,38 +22,56 @@ function LineaTrama({
index,
gradient,
itemSelected,
toggleItem
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'

const stroke = itemSelected ? `url('#trama-gradient-${zoomLevel}')` : "#ddd";
return (
<g>
{/* <rect
width={width}
height={height}
style={{fill:`teal`, fillOpacity: 0.2}}
></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>
<path
d={d}
className={`trama2-pointer ${itemSelected ? "selected" : ""}`}
onClick={toggleItem}
></path>
<path
d={d}
className="trama2-line"
style={{ stroke, strokeWidth: zoomLevel }}
></path>

{/* <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>}
{itemSelected && (
<g>
<g>
{/* <rect ></rect> */}
<text x={width} y={0} style={{ textAnchor: "end" }}>
{data.racconto.titolo}
</text>
</g>

{data.map((d, i) => (
<circle
key={i}
className="trama2-circle"
cx={d.x}
cy={d.y * zoomLevel}
r={2}
>
<title>{d.motivo_type}</title>
</circle>
))}
</g>
)}
</g>
);
}
Expand All @@ -64,15 +84,13 @@ export default function LineeTrama({
scalaMotivoY,
colors,
selected,
toggleSelect
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);

useEffect(() => {
const m = containerRef.current.getBoundingClientRect();
setMeasures(m);
Expand All @@ -89,6 +107,7 @@ export default function LineeTrama({
}
if (newLevel <= 1) {
setZoomY(0);
setZoomLevel(1)
return;
}
setZoomLevel(Math.max(1, Math.min(newLevel, MAX_ZOOM_LEVEL)));
Expand All @@ -101,18 +120,18 @@ export default function LineeTrama({
[zoomLevel, zoomY]
);

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

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

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

const delta = useMemo(() => {
if (!measures) {
Expand All @@ -133,54 +152,66 @@ export default function LineeTrama({
return [];
}
return racconti.map((racconto) => {
return data[racconto.titolo]
.filter((d) => !!d.y)
const out = data[racconto.titolo]
.filter((d) => d.y !== undefined)
.map((d) => {
return {
...d,
x: xScale(d.x),
y: d.y,
};
});
out.racconto = racconto;
return out;
});
}, [data, racconti, xScale]);

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

const displacements = useMemo(() => {
if(!measures){
return []
}
return dataRacconti.map((d, i) => {
let dy = baseDisplacements[i];
//return dy * zoomLevel

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

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

//const translation = zoomLevel === 1 ? 0 : (measures.height / (2 * delta * zoomLevel) - 1) * (delta * zoomLevel)
//const translation =
const factor = (zoomLevel-1) / (MAX_ZOOM_LEVEL-1);
const diff = zoomLevel === 1 ? 0 : delta * j * zoomLevel - (measures.height / 2)// / zoomLevel

return dy * zoomLevel - diff * factor;
});
}, [baseDisplacements, dataRacconti, delta, zoomLevel, zoomY]);
// const diff1 = delta * j * 1
// const diffMax = delta * j * MAX_ZOOM_LEVEL - (measures.height / 2)
// const diff = diff1 + (diffMax - diff1) / (MAX_ZOOM_LEVEL - 1) * (zoomLevel - 1)

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



//

return dy * zoomLevel - diff
// return diff - (j - i) * delta * zoomLevel
});
}, [baseDisplacements, dataRacconti, delta, measures, zoomLevel, zoomY]);

const deltaColors = useMemo(() => {
return 100 / (colors.length - 1);
}, [colors.length]);


return (
<div
ref={containerRef}
className="w-100 h-100"
style={{ overflow: "auto" }}
>
{/* <div>
{colors.map(color => <div key={color} style={{background:color, height: 10}}></div>)}
</div> */}
{measures && (
<svg
style={{
Expand All @@ -191,11 +222,28 @@ export default function LineeTrama({
}}
ref={containerRef}
>
<linearGradient id={`trama-gradient-${zoomLevel}`} gradientUnits="userSpaceOnUse" y1={0} y2={height* zoomLevel} x1={0} x2={0}>
<linearGradient
id={`trama-gradient-${zoomLevel}`}
gradientUnits="userSpaceOnUse"
y2={0}
y1={height * zoomLevel}
x1={0}
x2={0}
>
{colors.map((color, i) => (
<stop key={i} offset={`${deltaColors*i}%`} stopColor={color}></stop>
<stop
key={i}
offset={`${deltaColors * i}%`}
stopColor={color}
></stop>
))}
</linearGradient>
{/* <linearGradient id={`trama-gradient-${zoomLevel}`} gradientUnits="userSpaceOnUse" y1={0} y2={height* zoomLevel} x1={0} x2={0}>
<stop offset={`0%`} stopColor={'#000'}></stop>
<stop offset={`100%`} stopColor={'#fff'}></stop>
</linearGradient> */}

{dataRacconti.map((datum, i) => {
const dy = displacements[i];
Expand All @@ -222,8 +270,8 @@ export default function LineeTrama({
width={measures.width}
height={height * zoomLevel}
zoomLevel={zoomLevel}
itemSelected={selected[i]}
toggleItem={toggleSelect(i)}
itemSelected={selected[racconti[i].titolo]}
toggleItem={toggleSelect(racconti[i].titolo)}
xScale={xScale}
racconto={racconti[i]}
data={datum}
Expand Down
29 changes: 29 additions & 0 deletions src/visualizations/Trama2/SideBar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from "react";
import keyBy from "lodash/keyBy";

export default function SideBar({ tipologie, bounds, addBound, setBounds }) {
const boundsByKey = keyBy(bounds);

return (
<div className="trama2-sidebar">
<div className="trama2-sidebar-header"></div>
{tipologie.map((tipologia) => (
<div
key={tipologia.tipologia}
onClick={addBound(tipologia.tipologia)}
className={`trama2-sidebar-item ${boundsByKey[tipologia.tipologia] ? 'selected' : ''}`}
style={{
background: boundsByKey[tipologia.tipologia]
? tipologia.colore.colori
: undefined,
}}
>
{tipologia.tipologia}
</div>
))}
<div>
{bounds.length > 0 && <span onClick={()=> {setBounds([])}}>Clear</span>}
</div>
</div>
);
}
Loading

0 comments on commit baff826

Please sign in to comment.