整理した
This commit is contained in:
		
							
								
								
									
										103
									
								
								src/client/app/desktop/views/components/activity.chart.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								src/client/app/desktop/views/components/activity.chart.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,103 @@
 | 
			
		||||
<template>
 | 
			
		||||
<svg :viewBox="`0 0 ${ viewBoxX } ${ viewBoxY }`" preserveAspectRatio="none" @mousedown.prevent="onMousedown">
 | 
			
		||||
	<title>Black ... Total<br/>Blue ... Posts<br/>Red ... Replies<br/>Green ... Reposts</title>
 | 
			
		||||
	<polyline
 | 
			
		||||
		:points="pointsPost"
 | 
			
		||||
		fill="none"
 | 
			
		||||
		stroke-width="1"
 | 
			
		||||
		stroke="#41ddde"/>
 | 
			
		||||
	<polyline
 | 
			
		||||
		:points="pointsReply"
 | 
			
		||||
		fill="none"
 | 
			
		||||
		stroke-width="1"
 | 
			
		||||
		stroke="#f7796c"/>
 | 
			
		||||
	<polyline
 | 
			
		||||
		:points="pointsRepost"
 | 
			
		||||
		fill="none"
 | 
			
		||||
		stroke-width="1"
 | 
			
		||||
		stroke="#a1de41"/>
 | 
			
		||||
	<polyline
 | 
			
		||||
		:points="pointsTotal"
 | 
			
		||||
		fill="none"
 | 
			
		||||
		stroke-width="1"
 | 
			
		||||
		stroke="#555"
 | 
			
		||||
		stroke-dasharray="2 2"/>
 | 
			
		||||
</svg>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
 | 
			
		||||
function dragListen(fn) {
 | 
			
		||||
	window.addEventListener('mousemove',  fn);
 | 
			
		||||
	window.addEventListener('mouseleave', dragClear.bind(null, fn));
 | 
			
		||||
	window.addEventListener('mouseup',    dragClear.bind(null, fn));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function dragClear(fn) {
 | 
			
		||||
	window.removeEventListener('mousemove',  fn);
 | 
			
		||||
	window.removeEventListener('mouseleave', dragClear);
 | 
			
		||||
	window.removeEventListener('mouseup',    dragClear);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	props: ['data'],
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			viewBoxX: 140,
 | 
			
		||||
			viewBoxY: 60,
 | 
			
		||||
			zoom: 1,
 | 
			
		||||
			pos: 0,
 | 
			
		||||
			pointsPost: null,
 | 
			
		||||
			pointsReply: null,
 | 
			
		||||
			pointsRepost: null,
 | 
			
		||||
			pointsTotal: null
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	created() {
 | 
			
		||||
		this.data.reverse();
 | 
			
		||||
		this.data.forEach(d => d.total = d.posts + d.replies + d.reposts);
 | 
			
		||||
		this.render();
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		render() {
 | 
			
		||||
			const peak = Math.max.apply(null, this.data.map(d => d.total));
 | 
			
		||||
			if (peak != 0) {
 | 
			
		||||
				this.pointsPost = this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.posts / peak)) * this.viewBoxY}`).join(' ');
 | 
			
		||||
				this.pointsReply = this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.replies / peak)) * this.viewBoxY}`).join(' ');
 | 
			
		||||
				this.pointsRepost = this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.reposts / peak)) * this.viewBoxY}`).join(' ');
 | 
			
		||||
				this.pointsTotal = this.data.map((d, i) => `${(i * this.zoom) + this.pos},${(1 - (d.total / peak)) * this.viewBoxY}`).join(' ');
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
		onMousedown(e) {
 | 
			
		||||
			const clickX = e.clientX;
 | 
			
		||||
			const clickY = e.clientY;
 | 
			
		||||
			const baseZoom = this.zoom;
 | 
			
		||||
			const basePos = this.pos;
 | 
			
		||||
 | 
			
		||||
			// 動かした時
 | 
			
		||||
			dragListen(me => {
 | 
			
		||||
				let moveLeft = me.clientX - clickX;
 | 
			
		||||
				let moveTop = me.clientY - clickY;
 | 
			
		||||
 | 
			
		||||
				this.zoom = baseZoom + (-moveTop / 20);
 | 
			
		||||
				this.pos = basePos + moveLeft;
 | 
			
		||||
				if (this.zoom < 1) this.zoom = 1;
 | 
			
		||||
				if (this.pos > 0) this.pos = 0;
 | 
			
		||||
				if (this.pos < -(((this.data.length - 1) * this.zoom) - this.viewBoxX)) this.pos = -(((this.data.length - 1) * this.zoom) - this.viewBoxX);
 | 
			
		||||
 | 
			
		||||
				this.render();
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
svg
 | 
			
		||||
	display block
 | 
			
		||||
	padding 10px
 | 
			
		||||
	width 100%
 | 
			
		||||
	cursor all-scroll
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
		Reference in New Issue
	
	Block a user