Skip to content

Commit

Permalink
testing zoom on trama
Browse files Browse the repository at this point in the history
  • Loading branch information
bianchimro committed Jun 3, 2020
1 parent 4452b60 commit b240a3d
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 25 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
144 changes: 123 additions & 21 deletions src/visualizations/Trama2/LineeTrama.js
Original file line number Diff line number Diff line change
@@ -1,64 +1,166 @@
import React, { useRef, useState, useMemo, useEffect } from 'react'
import React, { useRef, useState, useMemo, useEffect, useCallback } from 'react'
import { line, curveMonotoneX } from 'd3-shape'
import { scaleLinear } from 'd3-scale'

const lineGenerator = line().x(d => d.x).y(d => d.y).curve(curveMonotoneX)

function LineaTrama({racconto, data}){
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> */}
<g>
{data.map((d,i) => (<circle key={i} className="trama2-circle" cx={d.x} cy={d.y} r={2}></circle>))}
{data.map((d,i) => (<circle key={i} className="trama2-circle" cx={d.x} cy={d.y*zoomLevel } r={2}></circle>))}
</g>
</g>
}


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


const svgRef = useRef(null)
const containerRef = useRef(null)
const [measures, setMeasures] = useState(null)
const [zoomLevel, setZoomLevel] = useState(1.0)
const [zoomY, setZoomY] = useState(0)



useEffect(() => {
const m = svgRef.current.getBoundingClientRect()
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)
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 - MOTIVO_LINE_HEIGHT) / racconti.length
return (measures.height - height) / racconti.length

}, [MOTIVO_LINE_HEIGHT, measures, racconti.length])
}, [height, measures, racconti.length])

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

return <svg className="w-100 h-100" ref={svgRef}>
{measures && racconti.map((racconto, i) => {
const datum = data[racconto.titolo].map(d => {

const dataRacconti = useMemo(() => {
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 || 0
y: d.y
}
})
})
}, [data, racconti, xScale])


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


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

const j = Math.round(zoomY/delta)

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 <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={racconto.titolo} style={{
transform: `translateY(${delta*i}px)`,
return <g key={i} style={{
transform: `translateY(${dy}px)`,
}}>
<LineaTrama scalaColore={scalaColore} scalaMotivoY={scalaMotivoY}
xScale={xScale} racconto={racconto} data={datum}></LineaTrama>



index={i}
width={measures.width}
height={height*zoomLevel}
zoomLevel={zoomLevel}
xScale={xScale} racconto={racconti[i]} data={datum}></LineaTrama>
</g>
})}

</svg>

</svg>}
</div>


}
5 changes: 4 additions & 1 deletion src/visualizations/Trama2/Trama2.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
.trama2-container {
position: relative;
height: calc(100vh - var(--navigation-height));
background-color: #ccc;
}


Expand Down Expand Up @@ -45,14 +46,16 @@
z-index:1;
min-height: 600px;
min-width: 960px;
height: 100%;
height: calc(100% - 15px);
width: 100%;


}

.trama2-content {
padding: 70px 30px;
height: 100%;

}

.trama2-line {
Expand Down
10 changes: 7 additions & 3 deletions src/visualizations/Trama2/Trama2Main.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import sortBy from "lodash/sortBy";
import uniqBy from "lodash/uniqBy";
import mapValues from "lodash/mapValues";
import get from "lodash/get";
import take from "lodash/take"
import { extent } from 'd3-array'

//visual helpers
Expand Down Expand Up @@ -34,12 +35,12 @@ const ordineMotivoByMotivo = mapValues(keyBy(ordineColore, 'tipologia'), item =>

//scales
const motivoExtent = extent(ordineColore, item => +item['ordine tipologia'])
const scalaMotivoY = scaleLinear().domain(motivoExtent).range([0, MOTIVO_LINE_HEIGHT])
const scalaMotivoY = scaleLinear().domain(motivoExtent).range([MOTIVO_LINE_HEIGHT, 0])
const colorsOrdered = sortBy(coloriPosizioni, item => +item.ordine)
// const colorsExtent = extent(coloriPosizioni, item => +item.ordine)
const scalaColore = scaleLinear().domain(colorsOrdered.map(item => item.ordine)).range(colorsOrdered.map(item => item.colori))

const racconti = sortBy(uniqBy(datasetLines, item => item["titolo racconto"]).map(item => ({
let racconti = sortBy(uniqBy(datasetLines, item => item["titolo racconto"]).map(item => ({
titolo: item["titolo racconto"],
anno: item["anno"],
mese: item["mese"]
Expand All @@ -50,6 +51,9 @@ const racconti = sortBy(uniqBy(datasetLines, item => item["titolo racconto"]).ma
return `${anno.toFixed(4)}${mese.toFixed(2)}`
})

//#TODO: remove this (limiting for debug)
racconti = take(racconti,20)


const datasetLinesNormalized = datasetLines.map((item) => {
const tot = +item["tot caratteri"]
Expand Down Expand Up @@ -100,7 +104,7 @@ export default function Trama2Main() {
<div className="trama2-content">

<LineeTrama
racconti={racconti} data={byRacconto} MOTIVO_LINE_HEIGHT={MOTIVO_LINE_HEIGHT}
racconti={racconti} data={byRacconto} height={MOTIVO_LINE_HEIGHT}
scalaColore={scalaColore}
scalaMotivoY={scalaMotivoY}

Expand Down

0 comments on commit b240a3d

Please sign in to comment.