Skip to content

Commit

Permalink
add doughnut chart
Browse files Browse the repository at this point in the history
  • Loading branch information
vitalikda committed Dec 1, 2020
1 parent f3a91d4 commit 380d48c
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 27 deletions.
17 changes: 17 additions & 0 deletions components/DoughnutChart.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<script>
import { Doughnut } from "vue-chartjs";
export default {
extends: Doughnut,
props: ["labels", "datasets"],
mounted() {
this.renderChart(
{
labels: this.labels,
datasets: this.datasets
},
{ responsive: true, maintainAspectRatio: false }
);
}
};
</script>
72 changes: 58 additions & 14 deletions pages/demo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,37 +11,59 @@

<v-container id="workout-stats" v-show="status === 2" fluid>
<v-row>
<v-col cols="12" sm="4">
<v-col cols="12" sm="3">
<v-card shaped>
<v-card-title class="display-2">
{{ workoutStats.totalWorkouts }}
{{ workoutStats.totalWorkouts | fInteger }}
</v-card-title>
<v-card-text>Total workouts</v-card-text>
</v-card>
</v-col>
<v-col cols="12" sm="4">
<v-col cols="12" sm="3">
<v-card shaped>
<v-card-title class="display-2">
{{ workoutStats.hoursTrained }}
{{ workoutStats.hoursTrained | fInteger }}
</v-card-title>
<v-card-text>Hours trained</v-card-text>
</v-card>
</v-col>
<v-col cols="12" sm="4">
<v-col cols="12" sm="3">
<v-card shaped>
<v-card-title class="display-2">
{{ workoutStats.yearsTrained }}
{{ workoutStats.yearsTrained | fInteger }}
</v-card-title>
<v-card-text>Years trained</v-card-text>
</v-card>
</v-col>
<v-col cols="12" sm="3">
<v-card shaped>
<v-card-title class="display-2">
{{ workoutStats.workoutsPerWeek | fInteger }}
</v-card-title>
<v-card-text>Workouts per week</v-card-text>
</v-card>
</v-col>
</v-row>
</v-container>

<v-container id="line-chart" v-if="status === 2" fluid>
<v-container id="charts" v-if="status === 2" fluid>
<v-row>
<v-col>
<line-chart :datasets="chartData" />
<v-col cols="12" sm="8">
<v-card>
<v-card-text>
<line-chart :datasets="lineChartData" />
</v-card-text>
</v-card>
</v-col>
<v-col cols="12" sm="4">
<v-card>
<v-card-text>
<doughnut-chart
:labels="doughnutChartData.labels"
:datasets="doughnutChartData.datasets"
/>
</v-card-text>
</v-card>
</v-col>
</v-row>
</v-container>
Expand Down Expand Up @@ -91,8 +113,13 @@

<script>
import dayjs from "dayjs";
import { calculateTrainedHours, getWorkoutsDataForLineChart } from "../utils";
import {
calculateTrainedHours,
getWorkoutsDataForLineChart,
getWorkoutsDataForDoughnutChart
} from "../utils";
import LineChart from "../components/LineChart";
import DoughnutChart from "../components/DoughnutChart";
const STATUS_INITIAL = 0,
STATUS_LOADING = 1,
Expand All @@ -101,7 +128,8 @@ const STATUS_INITIAL = 0,
export default {
components: {
LineChart
LineChart,
DoughnutChart
},
data() {
return {
Expand All @@ -111,9 +139,12 @@ export default {
workoutStats: {
totalWorkouts: 0,
hoursTrained: 0,
yearsTrained: 0
yearsTrained: 0,
workoutsPerWeek: 0
},
chartData: null
lineChartData: null,
doughnutChartData: null,
doughnutChartOutputLength: 5
};
},
async fetch() {
Expand All @@ -125,6 +156,9 @@ export default {
fDate(date) {
date = new Date(date);
return dayjs(date).format("DD MMM YYYY HH:mm:ss");
},
fInteger(number) {
return Math.floor(number);
}
},
methods: {
Expand All @@ -143,7 +177,17 @@ export default {
this.workouts[this.workouts.length - 1].performed_at,
"year"
);
this.chartData = await getWorkoutsDataForLineChart(this.workouts);
this.workoutStats.workoutsPerWeek =
this.workouts.length /
(await dayjs(this.workouts[0].performed_at).diff(
this.workouts[this.workouts.length - 1].performed_at,
"week"
));
this.lineChartData = await getWorkoutsDataForLineChart(this.workouts);
this.doughnutChartData = await getWorkoutsDataForDoughnutChart(
this.workouts,
this.doughnutChartOutputLength
);
this.status = STATUS_SUCCESS;
} catch (e) {
this.showError(e);
Expand Down
65 changes: 54 additions & 11 deletions pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -57,34 +57,56 @@
<v-col cols="12" sm="3">
<v-card shaped>
<v-card-title class="display-2">
{{ workoutStats.totalWorkouts }}
{{ workoutStats.totalWorkouts | fInteger }}
</v-card-title>
<v-card-text>Total workouts</v-card-text>
</v-card>
</v-col>
<v-col cols="12" sm="3">
<v-card shaped>
<v-card-title class="display-2">
{{ workoutStats.hoursTrained }}
{{ workoutStats.hoursTrained | fInteger }}
</v-card-title>
<v-card-text>Hours trained</v-card-text>
</v-card>
</v-col>
<v-col cols="12" sm="3">
<v-card shaped>
<v-card-title class="display-2">
{{ workoutStats.yearsTrained }}
{{ workoutStats.yearsTrained | fInteger }}
</v-card-title>
<v-card-text>Years trained</v-card-text>
</v-card>
</v-col>
<v-col cols="12" sm="3">
<v-card shaped>
<v-card-title class="display-2">
{{ workoutStats.workoutsPerWeek | fInteger }}
</v-card-title>
<v-card-text>Workouts per week</v-card-text>
</v-card>
</v-col>
</v-row>
</v-container>

<v-container id="line-chart" v-if="status === 2" fluid>
<v-container id="charts" v-if="status === 2" fluid>
<v-row>
<v-col>
<line-chart :datasets="chartData" />
<v-col cols="12" sm="8">
<v-card>
<v-card-text>
<line-chart :datasets="lineChartData" />
</v-card-text>
</v-card>
</v-col>
<v-col cols="12" sm="4">
<v-card>
<v-card-text>
<doughnut-chart
:labels="doughnutChartData.labels"
:datasets="doughnutChartData.datasets"
/>
</v-card-text>
</v-card>
</v-col>
</v-row>
</v-container>
Expand Down Expand Up @@ -158,7 +180,11 @@
<script>
import yaml from "js-yaml";
import dayjs from "dayjs";
import { calculateTrainedHours, getWorkoutsDataForLineChart } from "../utils";
import {
calculateTrainedHours,
getWorkoutsDataForLineChart,
getWorkoutsDataForDoughnutChart
} from "../utils";
import LineChart from "../components/LineChart";
const STATUS_INITIAL = 0,
Expand All @@ -179,9 +205,12 @@ export default {
workoutStats: {
totalWorkouts: 0,
hoursTrained: 0,
yearsTrained: 0
yearsTrained: 0,
workoutsPerWeek: 0
},
chartData: null
lineChartData: null,
doughnutChartData: null,
doughnutChartOutputLength: 5
};
},
filters: {
Expand All @@ -191,6 +220,9 @@ export default {
fDate(date) {
date = new Date(date);
return dayjs(date).format("DD MMM YYYY HH:mm:ss");
},
fInteger(number) {
return Math.floor(number);
}
},
methods: {
Expand All @@ -202,7 +234,8 @@ export default {
hoursTrained: 0,
yearsTrained: 0
};
this.chartData = null;
this.lineChartData = null;
this.doughnutChartData = null;
},
showError(e) {
this.status = STATUS_FAILED;
Expand Down Expand Up @@ -246,7 +279,17 @@ export default {
this.workouts[this.workouts.length - 1].performed_at,
"year"
);
this.chartData = await getWorkoutsDataForLineChart(this.workouts);
this.workoutStats.workoutsPerWeek =
this.workouts.length /
(await dayjs(this.workouts[0].performed_at).diff(
this.workouts[this.workouts.length - 1].performed_at,
"week"
));
this.lineChartData = await getWorkoutsDataForLineChart(this.workouts);
this.doughnutChartData = await getWorkoutsDataForDoughnutChart(
this.workouts,
this.doughnutChartOutputLength
);
this.status = STATUS_SUCCESS;
} catch (e) {
this.showError(e);
Expand Down
46 changes: 44 additions & 2 deletions utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,53 @@ function getWorkoutsDataForLineChart(workouts) {
datasets.push({
label: key,
data: d[key],
backgroundColor: "#" + Math.floor(Math.random() * 16777215).toString(16)
backgroundColor: random_rgba()
});
});

return datasets;
}

export { calculateTrainedHours, getWorkoutsDataForLineChart };
// generate random rgba
function random_rgba() {
let o = Math.round,
r = Math.random,
s = 255;
return `rgba(${o(r() * s)},${o(r() * s)},${o(r() * s)},${r().toFixed(2)})`;
}

// util to calculate data for Doughnut chart
function getWorkoutsDataForDoughnutChart(workouts, outputLength) {
const d = {};
workouts.forEach(w => {
const name = w.workout;
if (!d[name]) {
d[name] = 0;
}
d[name]++;
});

const chartData = {
labels: [],
datasets: [{ data: [], backgroundColor: [], borderWidth: 0 }]
};
Object.keys(d)
.sort((a, b) => {
return d[b] - d[a];
})
.forEach((key, index) => {
if (index < outputLength) {
chartData["labels"].push(key);
chartData["datasets"][0]["data"].push(d[key]);
chartData["datasets"][0]["backgroundColor"].push(random_rgba());
}
});

return chartData;
}

export {
calculateTrainedHours,
getWorkoutsDataForLineChart,
getWorkoutsDataForDoughnutChart
};

0 comments on commit 380d48c

Please sign in to comment.