diff --git a/package.json b/package.json
index 1e588da311..3b172940b0 100644
--- a/package.json
+++ b/package.json
@@ -20,6 +20,7 @@
 		"format": "gulp format"
 	},
 	"dependencies": {
+		"@antv/g2": "3.3.1",
 		"@fortawesome/fontawesome-svg-core": "1.2.6",
 		"@fortawesome/free-brands-svg-icons": "5.4.1",
 		"@fortawesome/free-regular-svg-icons": "5.4.1",
diff --git a/src/client/app/desktop/views/pages/deck/deck.user-column.vue b/src/client/app/desktop/views/pages/deck/deck.user-column.vue
index db21f04512..b707bfb090 100644
--- a/src/client/app/desktop/views/pages/deck/deck.user-column.vue
+++ b/src/client/app/desktop/views/pages/deck/deck.user-column.vue
@@ -39,6 +39,9 @@
 				:title="`${image.name}\n${(new Date(image.createdAt)).toLocaleString()}`"
 			></router-link>
 		</div>
+		<div class="activity">
+			<div ref="chart"></div>
+		</div>
 		<div class="tl">
 			<x-notes ref="timeline" :more="existMore ? fetchMoreNotes : null"/>
 		</div>
@@ -56,6 +59,7 @@ import Menu from '../../../../common/views/components/menu.vue';
 import MkUserListsWindow from '../../components/user-lists-window.vue';
 import Ok from '../../../../common/views/components/ok.vue';
 import { concat } from '../../../../../../prelude/array';
+import * as G2 from '@antv/g2';
 
 const fetchLimit = 10;
 
@@ -127,6 +131,56 @@ export default Vue.extend({
 				const files = concat(notes.map((n: any): any[] => n.files));
 				this.images = files.filter(f => image.includes(f.type)).slice(0, 9);
 			});
+
+			(this as any).api('charts/user/notes', {
+				userId: this.user.id,
+				span: 'day',
+				limit: 30
+			}).then(stats => {
+				const data = [];
+
+				const now = new Date();
+				const y = now.getFullYear();
+				const m = now.getMonth();
+				const d = now.getDate();
+
+				for (let i = 0; i < 30; i++) {
+					const x = new Date(y, m, d - i + 1);
+					data.push({
+						x: x,
+						type: 'normal',
+						count: stats.diffs.normal[i]
+					});
+					data.push({
+						x: x,
+						type: 'reply',
+						count: stats.diffs.reply[i]
+					});
+					data.push({
+						x: x,
+						type: 'renote',
+						count: stats.diffs.renote[i]
+					});
+				}
+
+				const chart = new G2.Chart({
+					container: this.$refs.chart as HTMLDivElement,
+					forceFit: true,
+					height: 100,
+					padding: 16,
+					renderer: 'svg'
+				});
+
+				chart.intervalStack().position('x*count').color('type');
+				chart.legend(false);
+				chart.axis('x', false);
+				chart.axis('count', false);
+				chart.tooltip(true, {
+					showTitle: false,
+				});
+				chart.source(data);
+				chart.render();
+			});
 		});
 	},
 
@@ -205,7 +259,7 @@ export default Vue.extend({
 
 <style lang="stylus" scoped>
 .zubukjlciycdsyynicqrnlsmdwmymzqu
-	background var(--deckUserColumnBg)
+	background var(--deckColumnBg)
 
 	> .is-remote
 		padding 8px 16px
@@ -283,7 +337,7 @@ export default Vue.extend({
 
 	> .pinned
 		padding-bottom 16px
-		background var(--deckUserColumnBg)
+		background var(--deckColumnBg)
 
 		> p
 			margin 0
@@ -309,6 +363,11 @@ export default Vue.extend({
 			background-clip content-box
 			border-radius 4px
 
+	> .activity
+		margin-bottom 16px
+		background var(--face)
+		line-height 0
+
 	> .tl
 		background var(--face)
 
diff --git a/src/client/theme/dark.json5 b/src/client/theme/dark.json5
index deb4c4ceee..68c001d354 100644
--- a/src/client/theme/dark.json5
+++ b/src/client/theme/dark.json5
@@ -174,7 +174,7 @@
 		desktopSettingsNavItemHover: ':lighten<10<$text',
 
 		deckAcrylicColumnBg: 'rgba(0, 0, 0, 0.25)',
-		deckUserColumnBg: ':darken<3<@face',
+		deckColumnBg: ':darken<3<@face',
 
 		mobileHeaderBg: ':lighten<5<$secondary',
 		mobileHeaderFg: '$text',
diff --git a/src/client/theme/light.json5 b/src/client/theme/light.json5
index c5b3148834..3570dd40b5 100644
--- a/src/client/theme/light.json5
+++ b/src/client/theme/light.json5
@@ -174,7 +174,7 @@
 		desktopSettingsNavItemHover: ':darken<10<$text',
 
 		deckAcrylicColumnBg: 'rgba(0, 0, 0, 0.1)',
-		deckUserColumnBg: ':darken<4<@face',
+		deckColumnBg: ':darken<4<@face',
 
 		mobileHeaderBg: ':lighten<5<$secondary',
 		mobileHeaderFg: '$text',