Browse Source

Added total timeline chart.

master
Denis Thiessen 8 months ago
parent
commit
f995f72d0f
  1. 4
      src/components/SingleFileUpload.jsx
  2. 24
      src/components/TimelineAreaChart.jsx
  3. 14
      src/components/TotalPieChart.jsx
  4. 133
      src/components/TotalTimelineAreaChart.jsx
  5. 3336
      src/data/clockify_data1.js
  6. 3336
      src/data/clockify_data2.js
  7. 6
      src/index.js

4
src/components/SingleFileUpload.jsx

@ -90,7 +90,9 @@ function SingleFileUpload({ onFileUploaded }) {
<Spacer h={2} />
<ButtonGroup>
<Button onClick={loadFirstDataSet}>Data Set 1 (26/09/23 - 28/03/24)</Button>
<Button onClick={loadSecondDataSet}>Data Set 2 (Combined) (26/09/23 - 28/03/24)</Button>
<Button onClick={loadSecondDataSet}>
Data Set 2 (Combined) (26/09/23 - 28/03/24)
</Button>
</ButtonGroup>
</div>
)

24
src/components/TimelineAreaChart.jsx

@ -1,11 +1,11 @@
import { React, useRef } from "react";
import Highcharts from "highcharts";
import HighchartsReact from "highcharts-react-official";
import { fileContent } from "./SingleFileUpload";
import { React, useRef } from "react"
import Highcharts from "highcharts"
import HighchartsReact from "highcharts-react-official"
import { fileContent } from "./SingleFileUpload"
require("highcharts/modules/accessibility")(Highcharts);
require("highcharts/modules/exporting")(Highcharts);
require("highcharts/modules/export-data")(Highcharts);
require("highcharts/modules/accessibility")(Highcharts)
require("highcharts/modules/exporting")(Highcharts)
require("highcharts/modules/export-data")(Highcharts)
// Date, Map
var projectDataMap = new Map()
@ -34,7 +34,9 @@ export default function AreaChart() {
})
}
const btn = (
<button id="visibilityButton" onClick={btnClickFunction}>Toggle Visiblity of all elements</button>
<button id="visibilityButton" onClick={btnClickFunction}>
Toggle Visiblity of all elements
</button>
)
return (
<div>
@ -127,11 +129,11 @@ function getOptions() {
},
yAxis: {
title: {
text: "Time spent (h)"
}
text: "Time spent (h)",
},
},
accessibility: {
enabled: true
enabled: true,
},
series: highChartsSeries,
}

14
src/components/TotalPieChart.jsx

@ -1,11 +1,11 @@
import React from "react";
import Highcharts from "highcharts";
import HighchartsReact from "highcharts-react-official";
import { fileContent } from "./SingleFileUpload";
import React from "react"
import Highcharts from "highcharts"
import HighchartsReact from "highcharts-react-official"
import { fileContent } from "./SingleFileUpload"
require("highcharts/modules/accessibility")(Highcharts);
require("highcharts/modules/exporting")(Highcharts);
require("highcharts/modules/export-data")(Highcharts);
require("highcharts/modules/accessibility")(Highcharts)
require("highcharts/modules/exporting")(Highcharts)
require("highcharts/modules/export-data")(Highcharts)
export default function TestChart() {
return <HighchartsReact highcharts={Highcharts} options={getOptions()} />

133
src/components/TotalTimelineAreaChart.jsx

@ -0,0 +1,133 @@
import { React, useRef } from "react"
import Highcharts from "highcharts"
import HighchartsReact from "highcharts-react-official"
import { fileContent } from "./SingleFileUpload"
require("highcharts/modules/accessibility")(Highcharts)
require("highcharts/modules/exporting")(Highcharts)
require("highcharts/modules/export-data")(Highcharts)
export default function TotalAreaChart() {
const chartComponent = useRef(null)
var chartOptions = getOptions()
return (
<HighchartsReact
ref={chartComponent}
highcharts={Highcharts}
options={chartOptions}
/>
)
}
function getOptions() {
var projectDataMap = []
var entryExtremes = getLowestAndHighestDates(fileContent)
var lowestStartDate = entryExtremes.lDate
var highestStartDate = entryExtremes.hDate
var itDate = lowestStartDate
while (itDate < highestStartDate) {
const projectEntries = fileContent.filter(function (e) {
return entryDateEqualsItDate(e, itDate)
})
var accumulatedHourValue = 0.0
for (const pe of projectEntries) {
if (pe.Start_Date === pe.End_Date) {
const durationDecimal = parseFloat(pe.Duration_Decimal)
accumulatedHourValue += durationDecimal
}
// TODO THINK ABOUT ROLLOVER...
/*
if (pe.Start_Date === pe.End_Date) {
var accumulatedHours = projectDataMap.get(projectName) || [];
const durationDecimal = pe.Duration_Decimal;
projectDataMap.set(projectName, accumulatedHours + durationDecimal);
} else {
// Calculate duration decimal on each date between start and end
const accumulatedHours = projectDataMap.get(projectName) || [];
const startDateDecimal = (24 - new Date(pe.Start_Date).getHours()) / 24;
projectDataMap.set(projectName, accumulatedHours + startDateDecimal);
//const endDateDecimal = new Date(pe.End_Date).getHours() / 24;
//projectDataMap.set(projectName, accumulatedHours.concat(endDateDecimal));
}*/
}
projectDataMap.push(accumulatedHourValue)
itDate = new Date(itDate.valueOf() + 3600 * 1000 * 24)
}
// Convert accumulated data into HighCharts Series Object
const highChartsSeries = {
name: "Total hours spent",
data: projectDataMap,
tooltip: {
valueSuffix: "h",
pointFormat: "Time spent: <b>{point.y:,.2f}h</b>",
},
pointStart: Date.UTC(
lowestStartDate.getFullYear(),
lowestStartDate.getMonth(),
lowestStartDate.getDate(),
),
pointInterval: 3600 * 1000 * 24, // 24 Hours
}
const highchartsOptions = {
chart: {
type: "area",
},
title: {
text: "Timeline per project",
},
xAxis: {
title: {
text: "Date",
},
type: "datetime",
},
yAxis: {
title: {
text: "Time spent (h)",
},
},
accessibility: {
enabled: true,
},
series: [highChartsSeries],
}
return highchartsOptions
}
function getLowestAndHighestDates(entries) {
var lowestDate = new Date()
var highestDate = new Date(1970, 1, 1)
var datePattern = /(\d{2})\/(\d{2})\/(\d{4})/
for (var e of entries) {
var entryDate = new Date(e.Start_Date.replace(datePattern, "$3-$2-$1"))
if (entryDate < lowestDate) {
lowestDate = entryDate
} else if (entryDate > highestDate) {
highestDate = entryDate
}
}
return {
lDate: lowestDate,
hDate: new Date(highestDate.valueOf() + 3600 * 1000 * 24),
}
}
function entryDateEqualsItDate(e, itDate) {
var datePattern = /(\d{2})\/(\d{2})\/(\d{4})/
var entryDate = new Date(e.Start_Date.replace(datePattern, "$3-$2-$1"))
var itD = new Date(itDate)
return (
entryDate.getUTCDate() === itD.getUTCDate() &&
entryDate.getUTCMonth() === itD.getUTCMonth() &&
entryDate.getUTCFullYear() === itD.getUTCFullYear()
)
}

3336
src/data/clockify_data1.js
File diff suppressed because it is too large
View File

3336
src/data/clockify_data2.js
File diff suppressed because it is too large
View File

6
src/index.js

@ -3,6 +3,7 @@ import ReactDOM from "react-dom/client"
import "./index.css"
import TimelineAreaChart from "./components/TimelineAreaChart"
import TotalPieChart from "./components/TotalPieChart"
import TotalAreaChart from "./components/TotalTimelineAreaChart"
import SingleFileUploader, { fileContent } from "./components/SingleFileUpload"
import { GeistProvider, Page, CssBaseline, Tabs } from "@geist-ui/core"
@ -38,7 +39,10 @@ export default function App() {
<Tabs.Item label="Project timeline" value="2" disabled={!fileUploaded}>
<TimelineAreaChart />
</Tabs.Item>
<Tabs.Item label="Total time spent" value="3" disabled={!fileUploaded}>
<Tabs.Item label="Total timeline" value="3" disabled={!fileUploaded}>
<TotalAreaChart />
</Tabs.Item>
<Tabs.Item label="Total time spent" value="4" disabled={!fileUploaded}>
<TotalPieChart />
</Tabs.Item>
</Tabs>

Loading…
Cancel
Save