| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- <template>
- <div
- class="sortChart"
- :style="{'width':width + 'px', 'height': height+ 'px'}"
- >
- <!-- <div class="container"> -->
- <transition-group
- class="container"
- name="flip-list"
- tag="div"
- >
- <div
- v-for="item in listWithKey"
- :key="item.key"
- class="bar"
- :style="{'height': getHeight(item.value)+ 'px'
- ,'background-color': getColor(item.color)
- ,'top': getTop(item.value) + 'px'
- ,'width': itemWidth + 'px'
- }"
- >
- <div
- class="value"
- :style="{'left': itemWidth / 2 - 7 + 'px'}"
- >{{Math.abs(item["value"])}}</div>
- </div>
- </transition-group>
- <!-- </div> -->
- </div>
- </template>
- <script>
- /**
- * @name sortChart (组件名称)
- * @desc 柱状图,用于排序
- * @author Li Xuesong
- * @param list 传入要显示的内容
- * @param height 柱状图高度
- * @param itemContainerWidth 柱状图相邻两个柱子的宽度
- * @param itemWidth 柱子的宽度
- * @date
- * @example 调用示例
- * <sortChart></sortChart>
- */
- export default {
- name: 'sortChart',
- components: {},
- props: {
- list: {
- default: () => [],
- },
- height: {
- default: 150
- },
- itemContainerWidth: {
- default: 60
- },
- itemWidth: {
- default: 40
- }
- },
- data () {
- return {
- max: 20,
- width: 200,
- listWithKey: []
- }
- },
- mounted () {
- this.listWithKey = list.map((item, idx) => {
- return {
- key: idx,
- value: item.value,
- color: item.color
- }
- });
- },
- // computed: {
- // thisList (val) {
- // return this.list;
- // }
- // },
- watch: {
- list: {
- handler: function (data, old) {
- if (data == null || data.length == 0) {
- this.listWithKey = [];
- return;
- }
- // console.log(data, old);
- this.max = Math.max(...data.map(v => v["value"]));
- this.width = data.length * this.itemContainerWidth;
- if (old == null || old.length == 0) {
- this.listWithKey = data.map((item, idx) => {
- // console.log(idx);
- return {
- key: idx,
- value: item.value,
- color: item.color
- }
- });
- // console.log(this.listWithKey);
- } else this.diff(data, this.listWithKey);
- },
- immediate: true
- }
- },
- mounted () { },
- methods: {
- diff (val, old) {
- let status = {
- v0c1: [], //value 不变, color改变 => 全部变色
- v1c0: [], //value 变负, color不变 => 下移
- v1c1: [], //value 变负, color改变 => 下移+变色
- v2: [] //value 变其他数据 => 改变数据==2,交换; !=2,直接重新赋值
- };
- // old = [{value:1,color:red,key:0}, {value:2,color:red,key:1}]
- // val = [{value:2,color:red}, {value:1,color:red}]
- for (let i = 0; i < val.length; i++) {
- val[i]["key"] = old[i]["key"];
- }
- // console.log(val);
- for (let i = 0; i < val.length; i++) {
- if (old[i].value == val[i].value) {
- if (old[i].color != val[i].color) {
- status.v0c1.push(i);
- }
- } else if (old[i].value == -val[i].value) {
- if (old[i].color == val[i].color) {
- status.v1c0.push(i);
- }
- else {
- status.v1c1.push(i);
- }
- } else {
- status.v2.push(i);
- }
- }
- if (status.v2.length > 0 && status.v2.length != 2) return;
- status.v0c1.forEach(idx => this.$set(this.listWithKey, idx, val[idx]));
- status.v1c0.forEach(idx => this.$set(this.listWithKey, idx, val[idx]));
- status.v1c1.forEach(idx => this.$set(this.listWithKey, idx, val[idx]));
- if (status.v2.length == 2) {
- // console.log(status.v2);
- let tmp = val[status.v2[1]].key;
- val[status.v2[1]].key = val[status.v2[0]].key;
- val[status.v2[0]].key = tmp;
- this.$set(this.listWithKey, status.v2[1], val[status.v2[1]]);
- this.$set(this.listWithKey, status.v2[0], val[status.v2[0]]);
- }
- // console.log(this.listWithKey);
- },
- getTop (value) {
- return value >= 0 ? 0 : this.height;
- },
- getHeight (value) {
- return (value < 0 ? -value : value) / this.max * this.height + 1;
- },
- getColor (color) {
- switch (color) {
- case 'green': return '#00cec9';
- case 'orange': return '#e17055';
- case 'red': return '#ff7675';
- case 'purple': return '#a29bfe';
- case 'yellow': return '#fdcb6e';
- case 'white': return '#dfe6e9';
- case 'blue': return '#0984e3'
- }
- return color;
- }
- }
- }
- </script>
- <style scoped>
- .sortChart {
- /* width: 800px; */
- height: 300px;
- }
- .container {
- display: flex;
- width: 100%;
- height: 100%;
- align-items: flex-end;
- justify-content: space-around;
- flex-wrap: nowrap;
- flex-direction: row;
- }
- .bar {
- display: flex;
- width: 40px;
- position: relative;
- }
- .value {
- position: absolute;
- bottom: 10px;
- font-size: 14px;
- font-weight: 600;
- -moz-user-select: none; /* 火狐 */
- -webkit-user-select: none; /* 谷歌 */
- -ms-user-select: none; /* IE */
- user-select: none;
- }
- .flip-list-move {
- transition: transform 0.5s;
- }
- </style>
|