import * as d3 from "d3";
import PropTypes from "prop-types"
addTooltip.propTypes = {
svg : PropTypes.object.isRequired
}
/**
* create tooltip to display curve informations
* @param {object} svg - svg dom object
* @returns {object} tooltip svg group
*/
function addTooltip(svg) {
// Création d'un groupe qui contiendra tout le tooltip plus le cercle de suivi
var tooltip = svg.append("g")
.attr("id", "tooltip")
.style("display", "none");
// Le cercle intérieur bleu foncé
tooltip.append("circle")
.attr("fill", "white")
.attr("stroke", "#fff")
.attr("r", 4);
// Le tooltip en lui-même
// Il faut le dimensionner en fonction du contenu
tooltip.append("rect")
.attr("width","40")
.attr("height","25")
.style("fill", "white")
.attr("transform", "translate(-20, -55)");
// Cet élément contiendra tout notre texte
var text = tooltip.append("text")
.style("font-size", "10px")
.style("font-family", "Segoe UI")
.style("color", "#333333")
.style("fill", "#333333")
.attr("transform", "translate(-15, -40)");
// Element pour la date avec positionnement spécifique
text.append("tspan")
.attr("dx", "-5")
.attr("id", "tooltip-date");
// Le texte "Cours : "
text.append("tspan")
.attr("dx", "5");
// Le texte pour la valeur de l'or à la date sélectionnée
text.append("tspan")
.attr("id", "tooltip-close")
.style("font-weight", "bold");
return tooltip;
}
/**
* generate user's average sessions chart
* @param {array} data - array of objects with day and sessionLength attributes
* @param {number} height - chart height
* @param {object} svg - svg contains chart
* @param {number} width - chart width
* @param {object} [margin] - contains attributes : marginTop, marginRight, marginBottom, marginLeft
*/
function averageSessions( data, height, svg, width, margin ){
const chartTitle = ["Durée moyenne des", "sessions"]
svg.attr("transform", `translate(${-width/9}, 0)`);
// data preparation
let days = ["s", "L", "M", "M ", "J", "V", "S", "D", "e"]
let xCoords = days.map((d, i) => i * width/7);
let dataModified = []
data.forEach((d, i) => {
if(d.day === 1){
dataModified.push({
day: "start",
sessionLength: d.sessionLength/2
})
}
dataModified.push({day: d.day, sessionLength: d.sessionLength})
if(d.day === 7){
dataModified.push({day: "end", sessionLength: d.sessionLength/2})
}
})
const x = d3.scaleOrdinal().domain(days).range(xCoords);
const y = d3.scaleLinear()
.domain(d3.extent(dataModified, d => d.sessionLength))
.range([parseInt(height*0.9), parseInt(height*0.3)]);
// Draw the lines
const line = d3.line()
.x((d) => x(d.day))
.y((d) => y(d.sessionLength))
.curve(d3.curveCatmullRom);
// Add axis
svg.append("g")
.attr("transform", `translate(0, ${height*0.9})`)
.call(d3.axisBottom(x))
.attr("stroke-width", 0)
.style("color", "rgba(255, 255, 255, 0.6)")
.style("font-size", "small")
.style("font-weight", "bold")
.style("text-align", "center");
// Add path to calculate line function
svg.append("path")
.datum(dataModified)
.attr("class", "line")
.attr("d", line)
.attr("stroke", "white")
.attr("stroke-width", 2)
.attr("fill", "none");
svg.append("rect")
.attr("class", "overlayBackground")
.attr("width", width*0.94)
.attr("height", height)
.attr("opacity", 0.15)
.attr("y", 0)
.attr("transform", `translate(${width/9}, 0)`);
const tooltip = addTooltip(svg)
svg.append("rect")
.attr("class", "overlay")
.attr("width", (width/7)*9)
.attr("height", height)
.attr("fill", "transparent")
.style("overflow", "hidden")
.on("mouseover", function(event) {
tooltip.style("display", null);
})
.on("mouseout", function(event) {
tooltip.style("display", "none");
})
.on("mousemove", mousemove);
function mousemove(event){
let position = d3.pointer(event)[0]
let xSlice = width/7
let i = parseInt(position/xSlice)
let d = dataModified[i]
d3.select('.overlayBackground').attr("transform", `translate(${position}, 0)`)
if(i >= dataModified.length){
i = 8
d = dataModified[i]
}
if(i >= 0) {
let xTenthSlice = xSlice /10
let startPosition = (i * xSlice)
let yPosition = y(d.sessionLength)
if(i <= 8){
let countQuarterSlice = (positionInSlice) => {
for(let i = 1; i <= 10; i++){ if((i*xTenthSlice)>positionInSlice){ return (i-1)*0.1 } } }
yPosition += (y(dataModified[i+1].sessionLength) - yPosition) * countQuarterSlice(position - startPosition)
}
tooltip.attr("transform", "translate(" +position + "," + yPosition + ")");
d3.select('#tooltip-close')
.text(d.sessionLength + " min");
}
}
let titlePath = svg.append("text").attr("fill", "white").style("color", "white").attr("opacity", 0.5)
titlePath.append("tspan").text(chartTitle[0]).attr("y", 20).attr("x", 50)
titlePath.append("tspan").text(chartTitle[1]).attr("x", 50).attr("dy", "1.95em")
}
export default averageSessions;