Skip to content

Commit

Permalink
Merge branch 'mauro.bianchi.dev' into iosonosempreio.dev
Browse files Browse the repository at this point in the history
  • Loading branch information
iosonosempreio committed Jun 5, 2020
2 parents 3696185 + baff826 commit 7f16ad2
Show file tree
Hide file tree
Showing 13 changed files with 9,097 additions and 2 deletions.
5 changes: 5 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"react-scroll-transitions": "^1.2.1",
"react-spring": "^8.0.27",
"react-use-dimensions": "^1.2.1",
"react-zoom-pan-pinch": "^1.6.1",
"svg-points": "^6.0.1"
},
"scripts": {
Expand Down
5 changes: 3 additions & 2 deletions src/views/AtlasRouter/AtlasRouter.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ import Articles from '../Articles/Articles';
import DoubtInformationSheet from '../../informationSheets/DoubtInformationSheet/DoubtInformationSheet';
import ShapeInformationSheet from '../../informationSheets/ShapeInformationSheet/ShapeInformationSheet';
import SpaceInformationSheet from '../../informationSheets/SpaceInformationSheet/SpaceInformationSheet';
import Trama from '../../visualizations/Trama/Trama';
import Trama from '../../visualizations/Trama';
import Trama2 from '../../visualizations/Trama2';
import ProcessDoubting from '../ProcessDoubting/ProcessDoubting';
import Df3 from '../Df3';

Expand Down Expand Up @@ -91,7 +92,7 @@ export default function AtlasRouter()
<Route exact path="/Problem/intro"><ProblemIntro /></Route>
<Route exact path="/Problem/cancellation"><Df3 /></Route>
<Route exact path="/Problem/realism">problema / realismo</Route>
<Route exact path="/Problem/plot">problema / trama</Route>
<Route exact path="/Problem/plot"><Trama2 title="COMBINARE"></Trama2></Route>

<Route exact path="/About"><AboutAndContacts /></Route>
<Route exact path="/Project"><Project/></Route>
Expand Down
286 changes: 286 additions & 0 deletions src/visualizations/Trama2/LineeTrama.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,286 @@
import React, {
useRef,
useState,
useMemo,
useEffect,
useCallback,
} 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,
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>
{/* <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, strokeWidth: zoomLevel }}
></path>

{/* <line x1={0} x2={width} y1={height} y2={height} style={{stroke: '#000'}}></line> */}
{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>
);
}

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);

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

return false;
},
[zoomLevel, zoomY]
);

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

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

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

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 [];
}
return racconti.map((racconto) => {
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 //+ 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.floor(zoomY / delta);


//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

// 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)


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={{
height: measures.height,
width: measures.width,
// transform: `perspective(${zoomLevel})`,
// transformOrigin: `50% 50%`,
}}
ref={containerRef}
>
<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>
))}
</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];

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[racconti[i].titolo]}
toggleItem={toggleSelect(racconti[i].titolo)}
xScale={xScale}
racconto={racconti[i]}
data={datum}
></LineaTrama>
</g>
);
})}
</svg>
)}
</div>
);
}
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 7f16ad2

Please sign in to comment.