五、d3中sort的使用

131 阅读1分钟

作用

对选择集进行排序

效果

show-06.gif

代码

<!--
TODO: 编写组件说明
@author pan
@date 2022-04-29
-->
<script lang="ts" setup>
import { onMounted, ref } from 'vue'
import { select, selectAll } from 'd3-selection'

const myContainerRef = ref<HTMLDivElement>()
const dataArr = [
  { expense: 10, category: 'Retail' },
  { expense: 15, category: 'Gas' },
  { expense: 30, category: 'Retail' },
  { expense: 50, category: 'Dining' },
  { expense: 80, category: 'Gas' },
  { expense: 65, category: 'Retail' },
  { expense: 55, category: 'Gas' },
  { expense: 30, category: 'Dining' },
  { expense: 20, category: 'Retail' },
  { expense: 10, category: 'Dining' },
  { expense: 8, category: 'Gas' },
]

function render(data: any[], comparatorFun?: (a: any, b: any) => number) {
  const containerDom = myContainerRef.value as HTMLDivElement
  let bars = select(containerDom).selectAll('div.h-bar').data(data)

  bars.enter().append('div').classed('h-bar', true).append('span')

  selectAll('div.h-bar')
    .style('width', function (d: any) {
      return d.expense * 5 + 'px'
    })
    .select('span')
    .text(function (d: any) {
      return d.category
    })

  if (comparatorFun) {
    bars.sort(comparatorFun)
  }
}

onMounted(() => {
  render(dataArr)
})

const compareByExpense = function (a: any, b: any) {
  return a.expense < b.expense ? -1 : 1
}

const compareByCategory = function (a: any, b: any) {
  return a.category < b.category ? -1 : 1
}

function doSort(sortType?: string) {
  let compareFun = undefined
  switch (sortType) {
    case 'compareByExpense': {
      compareFun = compareByExpense
      break
    }
    case 'compareByCategory': {
      compareFun = compareByCategory
      break
    }
  }
  render(dataArr, compareFun)
}
</script>

<template>
  <div class="myDiv">
    <h3>表格</h3>
    <button @click="doSort('compareByExpense')">compareByExpense</button>
    <button @click="doSort('compareByCategory')">compareByCategory</button>
    <button @click="doSort()">Reset</button>

    <div ref="myContainerRef"></div>
  </div>
</template>

<style lang="scss" scoped>
.myDiv {
  margin-left: 30px;
  ::v-deep(.h-bar) {
    background-color: #42b8dd;
    margin-bottom: 10px;
  }
  ::v-deep(.selected) {
    background-color: pink;
  }
}
</style>