diff --git a/src/components/partials/Visualization.vue b/src/components/partials/Visualization.vue index 4e1dac0533833d5120638f29410b63fe1055d472..a4ffc3cca2568db114f3d5e988249c97ea09d5bc 100644 --- a/src/components/partials/Visualization.vue +++ b/src/components/partials/Visualization.vue @@ -25,7 +25,8 @@ <b-form-group class="mb-0 mr-5"> <b-form-radio-group v-model="selected" name="position-options"> <b-form-radio value="normal">Normal</b-form-radio> - <b-form-radio value="sorted">Terurut</b-form-radio> + <b-form-radio value="sorted">Merata</b-form-radio> + <b-form-radio value="sorted-proportional">Proporsional</b-form-radio> <b-form-radio value="separated">Pisah</b-form-radio> <b-form-input v-if="selected == 'separated'" v-model="separator" type="range" :min="minRadius" :max="maxRadius"></b-form-input> </b-form-radio-group> @@ -124,19 +125,25 @@ export default { this.width = this.$refs.container.clientWidth }, setSimulation() { - let self = this this.simulation = d3.forceSimulation(this.src) - .force('charge', d3.forceManyBody().strength(-20)) - .force('collision', d3.forceCollide().radius(function(d) { - return self.radiusCircles(d[self.columnForWidth]) + .force('charge', d3.forceManyBody().strength((d) => { + if (this.selected == 'sorted' || this.selected == 'sorted-proportional') + return -10 + else + return -20 })) - .force('x', d3.forceX(function(d) { - if (self.selected == 'sorted') - return self.width*(self.radiusCircles(d[self.columnForWidth])/self.maxRadius - 0.5)*0.75 - else if (self.selected == 'normal') + .force('collision', d3.forceCollide().radius((d) => { + return this.radiusCircles(d[this.columnForWidth]) + 1 + })) + .force('x', d3.forceX((d) => { + if (this.selected == 'sorted') + return this.width*((this.src.length-d.index-1)/this.src.length - 0.5)*0.75 + else if (this.selected == 'sorted-proportional') + return this.width*(this.radiusCircles(d[this.columnForWidth])/this.maxRadius - 0.5)*0.75 + else if (this.selected == 'normal') return 0 - else if (self.selected == 'separated') - return self.radiusCircles(d[self.columnForWidth]) < self.separator ? -self.width/3 : self.width/3 + else if (this.selected == 'separated') + return this.radiusCircles(d[this.columnForWidth]) < this.separator ? -this.width/3 : this.width/3 })) .force('y', d3.forceY()) .on('tick', this.ticked) @@ -176,17 +183,28 @@ export default { .style("max-width", "400px") .style("box-shadow", "0 5px 10px rgba(0, 0, 0, 0.25)") .text("") - + + function validate(x, a, b) { + if (x < a) { + x = a + } + if (x > b) x = b + return x + } + // ticked handler function self.ticked = function(e) { + node.attr("cx", function(d) { - return d.x + let radius = self.radiusCircles(d[self.columnForWidth]) + return validate(d.x, -self.width/2+radius, self.width/2-radius) }) .attr("cy", function(d) { - return d.y + let radius = self.radiusCircles(d[self.columnForWidth]) + return validate(d.y, -self.height/2+radius, self.height/2-radius) }); } - + //create circles width by data self.radiusCircles = d3.scaleSqrt().domain([d3.min(data, function(d) { return +d[self.columnForWidth]