Przeglądaj źródła

Implement page views chart

sbkwgh 8 lat temu
rodzic
commit
c459628c23
1 zmienionych plików z 125 dodań i 17 usunięć
  1. 125 17
      src/components/widgets/CategoriesChart.vue

+ 125 - 17
src/components/widgets/CategoriesChart.vue

@@ -9,7 +9,23 @@
 			:style='{ "left": tooltipX, "top": tooltipY }'
 		>
 		</div>
-		<svg></svg>
+		<div class='widgets__categories_chart__main'>
+			<svg>
+				<g ref='g'></g>
+			</svg>
+			<div class='widgets__categories_chart__main__legend'>
+				<div
+					v-for='(category, $index) in data'
+					class='widgets__categories_chart__label'
+					@mouseover='toggleLabelHover($index)'
+					@mouseout='toggleLabelHover($index)'
+				>
+					<div class='widgets__categories_chart__label__square' :style="{ 'background-color': category.color }"></div>
+					{{category.label}}
+				</div>
+			</div>
+		</div>
+
 	</div>
 </template>
 
@@ -23,33 +39,88 @@
 		name: 'CategoriesChart',
 		components: { LoadingIcon },
 		data () {
-			let data = []
+			let data_ = [
+				{ label: 'category 1', value: 0 },
+				{ label: 'category 2', value: 2 },
+				{ label: 'category 3', value: 3 },
+				{ label: 'category 4', value: 4 },
+				{ label: 'category 5', value: 5 }
+			]
+
+			let colors = d3
+				.scaleLinear()
+				.domain([0, data_.length])
+				.interpolate(d3.interpolateHcl)
+				.range(['#415f9c', '#4bd9ff'])
 
 			return {
 				loading: false,
-				padding: 10,
+				padding: 20,
 				
 				tooltipX: 0,
 				tooltipY: 0,
 				tooltipShow: false,
 				tooltipItem: 0,
 
-				data
+				colors,
+				data_
+			}
+		},
+		computed: {
+			data () {
+				return this.data_.map((d, i) => {
+					d.color = this.colors(i)
+
+					return d
+				})
 			}
 		},
 		methods: {
 			updateFuncs () {
-				let width = this.$refs.container.getBoundingClientRect().width - this.padding*2
-				let height = this.$refs.container.getBoundingClientRect().height - this.padding*2
-			},
-			showTooltip (e, i) {
-				this.tooltipShow = true
-				this.tooltipX = e.clientX + 'px'
-				this.tooltipY = e.clientY - 30 + 'px'
-				this.tooltipItem = i
+				let height = this.$refs.container.getBoundingClientRect().height
+
+				let paddedHeight = (height - this.padding) / 2
+				let translate = paddedHeight + this.padding / 2
+
+				let pieSegments = d3.pie()(this.data.map(d => d.value))
+				let arcGenerator = d3.arc()
+					.innerRadius(paddedHeight - 40)
+					.outerRadius(paddedHeight)
+					.padAngle(Math.PI*2 * 2/360)
+
+				let g = d3.select(this.$refs.g).attr('transform', `translate(${translate}, ${translate})`)
+
+				let arcs = g.selectAll('path')
+					.data(pieSegments)
+					.enter()
+					.append('path')
+					.attr('d', arcGenerator)
+					.attr('data-index', (d, i) => i)
+					.attr('fill', (d, i) => this.colors(i))
+
+				let labels = g.selectAll('text')
+					.data(pieSegments)
+					.enter()
+					.append('text')
+					.text(d => d.value ? d.value : '')
+					.attr('fill', '#fff')
+					.attr('transform', d => {
+						d.innerRadius = paddedHeight - 40
+						d.outerRadius = paddedHeight
+		
+						
+						let coords = arcGenerator.centroid(d)
+							.map((val, i) => i ? val+5 : val-5)
+							.join(',')
+
+						return `translate(${coords})`
+					})
 			},
-			hideTooltip () {
-				this.tooltipShow = false
+			toggleLabelHover (index) {
+				let g = this.$refs.g
+				let path = g.querySelector('path[data-index="' + index + '"]')
+
+				path.classList.toggle('widgets__categories_chart__main--large')
 			}
 		},
 		mounted () {
@@ -67,7 +138,7 @@
 	@import '../../assets/scss/variables.scss';
 
 	.widgets__categories_chart {
-		background-color: #2ecc71;
+		background-color: rgba(225, 245, 254, 0.5);
 		width: 100%;
 		height: 100%;
 		overflow: hidden;
@@ -78,9 +149,46 @@
 			@include loading-overlay(#2ecc71, 0.25rem 0.25rem 0 0);
 		}
 
-		svg {
+		@at-root #{&}__main {
+			display: flex;
+			flex-direction: row;
 			height: 100%;
-			width: 100%;
+			
+			svg {
+				height: 100%;
+				width: 11rem;
+	
+				path {
+					transition: all 0.2s;
+				}
+			}
+			@at-root #{&}--large {
+				transform: scale(1.075);
+			}
+			@at-root #{&}__legend {
+				padding: 10px 0;
+			}
+		}
+
+		@at-root #{&}__label {
+			position: relative;
+			cursor: default;
+			margin-left: 1rem;
+
+		
+		 	&:hover {
+				text-decoration: underline;
+			}
+
+			@at-root #{&}__square {
+				position: absolute;
+				top: 0.375rem;
+				left: -1.25rem;
+				height: 0.75rem;
+				width: 0.75rem;
+				border-radius: 0.125rem;
+			}
 		}
+
 	}
 </style>