7 Commits
pivot ... v2021

Author SHA1 Message Date
Aarni Koskela
7f4ec17f8f Disable cron 2021-05-25 15:51:24 +03:00
Aarni Koskela
65e3480a78 Clean up oy/oyj 2021-02-26 12:19:47 +02:00
Aarni Koskela
acf8e4bf21 Ingest new data 2021-02-26 12:16:45 +02:00
Aarni Koskela
f1e90addde Link analysaattori 2021-02-22 20:35:08 +02:00
Aarni Koskela
bc7e6ad4b3 Fix pandas-profiling fork URL 2021-02-22 15:14:43 +02:00
Aarni Koskela
b49a1f3528 Build analysaattori in GHA 2021-02-22 14:52:06 +02:00
Aarni Koskela
511b2da2f3 Add React analysaattori 2021-02-22 14:52:06 +02:00
18 changed files with 11609 additions and 10 deletions

View File

@@ -5,11 +5,11 @@ on:
branches: [ master ]
pull_request:
branches: [ master ]
schedule:
#schedule:
# Update automatically on weekdays during work hours
- cron: '0 10,13,16 * * 1-5'
#- cron: '0 10,13,16 * * 1-5'
# ... and every night
- cron: '0 0 * * *'
#- cron: '0 0 * * *'
jobs:
build:
runs-on: ubuntu-latest
@@ -33,6 +33,26 @@ jobs:
python -m pip install -r requirements.txt
- name: Build
run: make -j3
- uses: actions/setup-node@v2
with:
node-version: '12'
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v2
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- run: yarn
working-directory: analysaattori
- run: yarn build
working-directory: analysaattori
env:
GENERATE_SOURCEMAP: 'false'
- run: cp -a analysaattori/build ./out/analysaattori
- run: ls -laR out
- name: Deploy
uses: JamesIves/github-pages-deploy-action@4.0.0
with:

23
analysaattori/.gitignore vendored Normal file
View File

@@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

View File

@@ -0,0 +1,44 @@
{
"name": "analysaattori",
"version": "0.1.0",
"private": true,
"homepage": "https://koodiklinikka.github.io/palkkakysely/analysaattori/",
"dependencies": {
"@types/node": "^14.14.31",
"@types/react": "^17.0.2",
"@types/react-dom": "^17.0.1",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-pivottable": "^0.11.0",
"react-plotly.js": "^2.5.1",
"react-scripts": "4.0.2",
"swr": "^0.4.2",
"typescript": "^4.1.5"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all",
"not ie 11"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@types/plotly.js": "^1.54.8",
"@types/react-plotly.js": "^2.2.4"
}
}

1
analysaattori/public/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
data.json

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="Web site created using create-react-app" />
<script src="https://cdn.plot.ly/plotly-latest.min.js" charset="utf-8"></script>
<title>Palkka-analysaattori</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>

36
analysaattori/src/App.tsx Normal file
View File

@@ -0,0 +1,36 @@
import React from 'react';
import PivotTableUI from 'react-pivottable/PivotTableUI';
import 'react-pivottable/pivottable.css';
import TableRenderers from 'react-pivottable/TableRenderers';
import createPlotlyComponent from 'react-plotly.js/factory';
import createPlotlyRenderers from 'react-pivottable/PlotlyRenderers';
import useSWR from "swr/esm";
const Plot = createPlotlyComponent(window.Plotly);
const PlotlyRenderers = createPlotlyRenderers(Plot);
const renderers = Object.assign({}, TableRenderers, PlotlyRenderers);
function App() {
const qs = new URLSearchParams(window.location.search);
const [pivotState, setPivotState] = React.useState({});
const dataSwr = useSWR(qs.get("url") || "/palkkakysely/data.json");
if (!dataSwr.data) {
if (dataSwr.error) {
return <>Virhe ladatessa dataa: {`${dataSwr.error}`}</>;
}
return <>Ladataan...</>;
}
return (
<div>
<PivotTableUI
data={dataSwr.data}
renderers={renderers}
onChange={setPivotState}
{...pivotState}
/>
</div>
);
}
export default App;

View File

@@ -0,0 +1,10 @@
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);

1
analysaattori/src/react-app-env.d.ts vendored Normal file
View File

@@ -0,0 +1 @@
/// <reference types="react-scripts" />

View File

@@ -0,0 +1,3 @@
declare module "react-pivottable/PivotTableUI";
declare module "react-pivottable/TableRenderers";
declare module "react-pivottable/PlotlyRenderers";

View File

@@ -0,0 +1,26 @@
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
},
"include": [
"src"
]
}

11388
analysaattori/yarn.lock Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -94,7 +94,7 @@ Timestamp Missä kaupungissa työpaikkasi pääasiallinen toimisto sijaitsee? Ik
2/15/2021 13:30:27 Tampere 41-45 v Mies 21 Työntekijä / palkollinen 100% Arkkitehti Noin 50/50 hybridimalli 6500 90000 Kyllä
2/15/2021 13:30:30 Tampere 36-40 v Mies 9 Työntekijä / palkollinen 100% Ohjelmistokehittäjä Pääosin tai kokonaan toimistolla 4150 Ei
2/15/2021 13:30:39 PK-Seutu (Helsinki, Espoo, Vantaa) 46-50 v mies 20 Työntekijä / palkollinen 100% full-stack-kehittäjä, arkkitehti Pääosin tai kokonaan toimistolla 6600 85000 Kyllä
2/15/2021 13:34:11 PK-Seutu (Helsinki, Espoo, Vantaa) 31-35 v mies 11 Työntekijä / palkollinen 100% ohjelmistokehittäjä / -arkkitehti Noin 50/50 hybridimalli 6000 75000 Kyllä UpCloud
2/15/2021 13:34:11 PK-Seutu (Helsinki, Espoo, Vantaa) 31-35 v mies 11 Työntekijä / palkollinen 100% ohjelmistokehittäjä / -arkkitehti Noin 50/50 hybridimalli 6000 75000 Kyllä
2/15/2021 13:34:46 PK-Seutu (Helsinki, Espoo, Vantaa) 41-45 v mies 25 Työntekijä / palkollinen 100% seniori automaatio säätäjä Noin 50/50 hybridimalli 5800 70000 Kyllä
2/15/2021 13:45:44 PK-Seutu (Helsinki, Espoo, Vantaa) 31-35 v Mies 7 Työntekijä / palkollinen 100% ohjelmistkoehittäjä, full-stack Pääosin tai kokonaan toimistolla 4700 58750 Ei
2/15/2021 13:49:32 Jyväskylä 31-35 v mies 10 Työntekijä / palkollinen 100% Lead developer Pääosin tai kokonaan etätyö 6200 77500 Kyllä
@@ -467,4 +467,29 @@ Timestamp Missä kaupungissa työpaikkasi pääasiallinen toimisto sijaitsee? Ik
2/22/2021 12:54:09 PK-Seutu (Helsinki, Espoo, Vantaa) 26-30 v Mies 9 Työntekijä / palkollinen 100% Tuotepäällikkö Pääosin tai kokonaan toimistolla 5500 82500 Kyllä
2/22/2021 13:03:17 Tampere 31-35 v Mies 5 Työntekijä / palkollinen 100% Lead front end dev Pääosin tai kokonaan toimistolla 4200 50000 Kyllä
2/22/2021 13:33:48 PK-Seutu (Helsinki, Espoo, Vantaa) 26-30 v mies 0 Työntekijä / palkollinen 100% harjoittelija Pääosin tai kokonaan toimistolla 2200 Ei
2/22/2021 14:11:08 EU 31-35 v Mies 8 Työntekijä / palkollinen 100% Senior Backend Developer Pääosin tai kokonaan toimistolla 4800 59000 Ei
2/22/2021 14:11:08 EU 31-35 v Mies 8 Työntekijä / palkollinen 100% Senior Backend Developer Pääosin tai kokonaan toimistolla 4800 59000 Ei
2/22/2021 18:58:46 PK-Seutu (Helsinki, Espoo, Vantaa) 41-45 v Mies 15 Työntekijä / palkollinen 100% Teknologiajohtaja Pääosin tai kokonaan toimistolla 12000 220000 Kyllä
2/22/2021 23:53:12 PK-Seutu (Helsinki, Espoo, Vantaa) 31-35 v Mies 8 Työntekijä / palkollinen 100% senior game developer Noin 50/50 hybridimalli 4000 50000 Ei
2/23/2021 8:54:21 PK-Seutu (Helsinki, Espoo, Vantaa) 31-35 v Nainen 3 Työntekijä / palkollinen 100% full-stack Pääosin tai kokonaan etätyö 3500 Ei
2/23/2021 9:56:27 PK-Seutu (Helsinki, Espoo, Vantaa) 31-35 v mies 8 Työntekijä / palkollinen 100% full-stack conslut Pääosin tai kokonaan toimistolla 5300 70000 Kyllä keskikokoinen konsulttifirma
2/23/2021 10:12:27 Lahti 36-40 v Mies 14 Työntekijä / palkollinen 100% Front-end Developer Pääosin tai kokonaan toimistolla 4695,70 58696,25 Kyllä
2/23/2021 10:43:09 PK-Seutu (Helsinki, Espoo, Vantaa) 41-45 v mies 9 Työntekijä / palkollinen 100% ohjelmistokehittäjä/konsultti (senior, full-stack) Noin 50/50 hybridimalli 3926 50000 Ei Vincit Olen firmaan, sen etuihin ja työilmapiiriin tyytyväinen.
2/23/2021 12:41:18 Turku 26-30 v Mies 5 Työntekijä / palkollinen 100% Ohjelmistokehittäjä Pääosin tai kokonaan toimistolla 4500 56250 Kyllä
2/23/2021 12:51:35 Hanksalmi 26-30 v mies 2 Freelancer 50% ohjelmistokehittäjä Pääosin tai kokonaan etätyö 1100 13750 Ei
2/23/2021 13:07:41 PK-Seutu (Helsinki, Espoo, Vantaa) 36-40 v Mies 4 Työntekijä / palkollinen 100% Fullstaxk Pääosin tai kokonaan etätyö 4300 58000 Kyllä
2/23/2021 14:00:37 Tampere 26-30 v mies 5 Työntekijä / palkollinen 100% Senior/Lead developer Pääosin tai kokonaan toimistolla 4000 52000 Ei
2/23/2021 16:18:52 Tampere 10 Työntekijä / palkollinen 100% Ohjelmistokehittäjä Pääosin tai kokonaan toimistolla 4250 54000 Kyllä
2/23/2021 21:38:09 Nokia 36-40 v Mies 6 Yrittäjä 100% Full Stack Web Developer / CEO Pääosin tai kokonaan etätyö 27 000 Ei Tuspe Design Oy
2/24/2021 15:19:47 Mikkeli 31-35 v Mies 7 Työntekijä / palkollinen 100% Full-stack Pääosin tai kokonaan etätyö 3000 Ei
2/24/2021 16:09:33 PK-Seutu (Helsinki, Espoo, Vantaa) 31-35 v Mies 2 Työntekijä / palkollinen 100% Ohjelmistokehittäjä Pääosin tai kokonaan etätyö 3500 43750 Kyllä
2/24/2021 17:28:57 Kuopio 21-25 v mies 2 Työntekijä / palkollinen 100% frontend Noin 50/50 hybridimalli 2900 36000 Ei
2/24/2021 23:49:22 Tampere 26-30 v Mies 2 Työntekijä / palkollinen 100% Ohjelmistokehittäjä (frontend) Pääosin tai kokonaan etätyö 2860 35850 Ei
2/25/2021 9:34:48 Kuopio 31-35 v Mies 6 Työntekijä / palkollinen 100% Ohjelmistokehittäjä, Tech Lead Pääosin tai kokonaan toimistolla 4500 Kyllä
2/25/2021 10:53:42 PK-Seutu (Helsinki, Espoo, Vantaa) 26-30 v Mies 6 Työntekijä / palkollinen 100% full-stack Noin 50/50 hybridimalli 5100 64000 Ei
2/25/2021 11:09:17 PK-Seutu (Helsinki, Espoo, Vantaa) 26-30 v Mies-oletettu 3 Työntekijä / palkollinen 100% Fullstack ja pientä devops tunkkia Pääosin tai kokonaan toimistolla 3500 44000 Ei
2/25/2021 11:10:42 31-35 v 15 Työntekijä / palkollinen 100% Pääosin tai kokonaan toimistolla 5200 68000 Ei
2/25/2021 12:33:58 PK-Seutu (Helsinki, Espoo, Vantaa) 26-30 v Mies 5 Työntekijä / palkollinen 100% Full-stack developer Pääosin tai kokonaan toimistolla 5500 68000 Kyllä
2/25/2021 14:10:33 Tampere 21-25 v naisoletettu 1 Työntekijä / palkollinen 50% Systems Administrator ja firmän sisäinen 1st line -tukihessu Pääosin tai kokonaan toimistolla 1081 14000 Kyllä Kk-palkkani on varsinkin vaihteleva, koska riippuu vuorolisistä (mahdollisista pyhä- ja yövuoroista ja tuurauksista). Jonkinlaisen oletuksen nyt yritin lyödä vuositulolle, mutta taitaa jäädä todellisuudessa hivenen sen alle.
2/25/2021 21:17:36 PK-Seutu (Helsinki, Espoo, Vantaa) 31-35 v Mies 10 Työntekijä / palkollinen 100% Full-stack ohjemistokehittäjä Pääosin tai kokonaan toimistolla 4600 58000 Kyllä
2/26/2021 9:33:00 Oulu 46-50 v Mies 21 Työntekijä / palkollinen 100% Backend-koodari Pääosin tai kokonaan etätyö 5000 70000 Kyllä Nokia
2/26/2021 12:16:20 Tampere 36-40 v Mies 15 Työntekijä / palkollinen 100% Ohjelmistosuunnittelija Pääosin tai kokonaan toimistolla 4300 53750 Ei Gofore
Can't render this file because it contains an unexpected character in line 232 and column 265.

Binary file not shown.

View File

@@ -82,6 +82,9 @@ def read_data() -> pd.DataFrame:
df["Kuukausipalkka"] = df["Kuukausipalkka"].apply(map_numberlike)
df["Vuositulot"] = df["Vuositulot"].apply(map_numberlike)
# Remove Oy, Oyj, etc. from work places
df["Työpaikka"] = df["Työpaikka"].replace(re.compile(r"\s+oy|oyj$", flags=re.I), "")
# Fill in Vuositulot as 12.5 * Kk-tulot if empty
df["Vuositulot"] = df.apply(map_vuositulot, axis=1)

View File

@@ -2,4 +2,4 @@ bokeh
jinja2
openpyxl
pandas
https://github.com/akx/pandas-profiling/archive/no-hard-ipywidgets.zip#egg=pandas-profiling
https://github.com/akx/pandas-profiling/archive/no-phik.zip#egg=pandas-profiling

View File

@@ -66,7 +66,7 @@ openpyxl==3.0.6
# via -r requirements.in
packaging==20.9
# via bokeh
https://github.com/akx/pandas-profiling/archive/no-hard-ipywidgets.zip#egg=pandas-profiling
https://github.com/akx/pandas-profiling/archive/no-phik.zip#egg=pandas-profiling
# via -r requirements.in
pandas==1.2.2
# via

View File

@@ -22,18 +22,22 @@
<li>Mediaanivuositulot = {{ num_v.median()|round(0) }} €</li>
{% endwith %}
</ul>
<h2>Lisää</h2>
<h2>Työkalut</h2>
<ul>
<li><a href="charts.html">Kaaviot</a></li>
<li><a href="profiling_report.html">Lähdedatan analyysi</a></li>
<li><a href="analysaattori">Pivot-työkalu</a></li>
</ul>
<h2>Data</h2>
<ul>
<li><a href="data.csv">Lähdedata (CSV)</a></li>
<li><a href="data.html">Lähdedata (HTML)</a></li>
<li><a href="data.json">Lähdedata (JSON)</a></li>
<li><a href="data.xlsx">Lähdedata (XLSX)</a></li>
<li><a href="profiling_report.html">Lähdedatan analyysi</a></li>
<li><a href="raw.tsv">Raakadata (TSV)</a></li>
<li><a href="raw.xlsx">Raakadata (XLSX)</a></li>
</ul>
<h2>Vielä lisää</h2>
<h2>Kysely</h2>
<ul>
<li><a href="http://bit.ly/koodiklinikka-palkkakysely">Vastaa kyselyyn (Google Forms)</a>
<li><a href="http://bit.ly/koodiklinikka-palkkakysely-vastaukset">Vastaukset raakamuodossa (Google Sheets)</a>