viserjs / viser

viser is a toolkit fit for data vis engineer. https://viserjs.gitee.io/
https://viserjs.github.io
MIT License
1.61k stars 123 forks source link

[BUG]在element ui tabs组件使用的问题 #55

Closed GodStream closed 6 years ago

GodStream commented 6 years ago

在element ui tabs组件中,如果放在非第一个标签页里,点击切换到其余标签页时,图表没有渲染出来,但当我打开浏览器开发者工具时才会进行渲染。 但我如果一直打开开发者工具,刷新进行切换也不会渲染,只有关闭开发者工具才会渲染。 不知是触发渲染的机制出现了问题?

是否有事件可以进行手动初始化?目前没有文档十分不方便

浏览器:Chrome 63.0.3239.108 vue: 2.5.9 viser-vue: 1.3.0

evilucifero commented 6 years ago

Would you like to shou me your Vue template here? I can not understand your problems through your descriptions. Thanks

GodStream commented 6 years ago

我想应该是一开始图表渲染时,所在的容器并没有产生或者说未知宽度,导致会渲染失败,是否有一个方法可供再次渲染图表?

GodStream commented 6 years ago
<template>
  <div class="app-container">
    <tabs :list="tabList" @handleClick="handleClick">
      <template slot="details">
        <search-topbar
          :search-data="searchData">
        </search-topbar>
        <sj-table
          class="financial-table"
          :column-list="columnList">
        </sj-table>
      </template>
      <template slot="statistics">
        <!-- <tabs :list="tabStatList" :tab-type="''"></tabs> -->
        <v-chart ref="asd" :force-fit="true" :height="height" :data="chartData" :data-pre="dataPre">
          <v-coord :type="'rect'" :direction="'LT'" />
          <v-tooltip />
          <v-legend />
          <v-axis :data-key="'value'" :position="'right'" />
          <v-axis :data-key="'label'" :label="label" />
          <v-bar :position="'label*value'" :color="'type'" :adjust="adjust" />
        </v-chart>
      </template>
    </tabs>
  </div>
</template>
<script>
import Tabs from '../../components/Tab'
import SjTable from '../../components/Table/SjTable'
import SearchTopbar from '../components/SearchTopbar'
export default {
  components: {
    Tabs, SjTable, SearchTopbar
  },
  data() {
    const chartData = [
      { label: '货款统计', 增加货款: 2800, 消耗货款: 2260 }
    ]
    const dataPre = {
      transform: {
        type: 'fold',
        fields: [ '增加货款', '消耗货款' ],
        key: 'type',
        value: 'value'
      }
    }
    const label = { offset: 12 }
    const adjust = [{ type: 'dodge', marginRatio: 1 / 32 }]
    return {
      chartData,
      dataPre,
      height: 400,
      label,
      adjust,
      tabList: [
        { value: 'details', label: '货款明细' },
        { value: 'statistics', label: '货款统计' }
      ],
      tabStatList: [
        { value: 'today', label: '今日数据' },
        { value: 'yesterday', label: '昨日数据' },
        { value: 'month', label: '当月数据' },
        { value: 'total', label: '累计数据' },
        { value: 'search', label: '按日期筛选' }
      ],
      searchData: {},
      columnList: [
        { value: 'id', label: '代理' },
        { value: 'id', label: '变更项' },
        { value: 'id', label: '变更金额' },
        { value: 'id', label: '当前货款' },
        { value: 'id', label: '说明' },
        { value: 'id', label: '时间' }
      ]
    }
  },
  methods: {
    handleClick(val) {

    }
  }
}
</script>
evilucifero commented 6 years ago

Thanks for showing your demo. I'll review it ASAP.

ascoders commented 6 years ago

Hello, @GodStream , can you give me a demo on jsfiddle?

ColinCLL commented 6 years ago

This is not a bug.It is feature between element-ui-tabs and charts.Tab pages is display:none except first tab page.So you couldn't see charts in Dom witch width or height is 0. when you resize window charts would resize too.Then U can see.

To solve: 1.Create a tabs component without display:noe; 2.Use resize function (if G2 has?) in vue $nextTick function when element-ui-tabs tab-click callback.

英文不好,中文再说一次。 这不是bug,是ele-tabs组件和G2配合使用的问题。ele-tabs除了第一页其他都是display:none,所以渲染上去的时候你看不到。display:none看不到的的最根本原因是那时候tab页是没有宽高的,所以渲染图表的后,你点了tab页面,非第一个tab页resize后有了宽高,但图表画布不resize。触发window的resize后,图表也触发reszie,最终你就看见了图表。 解决办法: 1.自己写一个不用display:none的tabs组件。 2.在 ele-tabs tab-click 的回调函数中使用vue的 $nextTick 函数。在vue的 $nextTick 函数里面调用G2的resize方法(不知道G2有没),或者在这里重新渲染也可以。

ShawshankLin commented 6 years ago

viser现在出了repaint方法,但是我在$nextTick调用好像没有效果呢

ColinCLL commented 6 years ago

@ShawshankLin 要看看repaint有没有改变dom的大小,可以在控制台看看,或者用原生方法打印一下dom宽高看看。 试试在$nextTick里面直接画图,而不是repaint。根据原理应该可以解决,但我还没实践过。最好还是自己实现一个tabs,这种方法最好。

ShawshankLin commented 6 years ago

他的chat实例打出来的width属性是undefined,,,悲伤,,直接画图这个就不能用G2的语法了吧,,,那感觉还是找一个tabs简单,,是不是要找那些没有display:none的,,点击选项卡的时候才开始渲染的???

ColinCLL commented 6 years ago

@ShawshankLin 不要用那些虚拟dom隐藏和display:none的。自己实现那种使用position,然后left:9999偏移出屏幕的应该可以,或者那种div堆叠,点击后显示在最上层的应该也可以。

ShawshankLin commented 6 years ago

但是我为什么我自己用按钮实现的一个按钮选项卡,我使用v-show控制的,但是可以正常显示呢,,,v-show的效果不是跟display:none一样吗??

ColinCLL commented 6 years ago

我去,搞错了,应该v-if的不行。抱歉哈

ShawshankLin commented 6 years ago

没有,,你是对的,,,是使用v-show不行,,v-show是用的display:none,,我用v-show可以是因为用的是柱形图,,但是换成折线图就不不会了,,,而用v-if才是都可以的

ColinCLL commented 6 years ago

能解决问题就行。估计可以close了。

ShawshankLin commented 6 years ago

还是有些遗憾,,因为很多的ui框架都是采用的display:none的,所以还是希望viser可以出一个妥善的解决办法,,相比自己写一个tab插件可以少耽误好多时间了

ShawshankLin commented 6 years ago

正如你说的应该暴露resize的方法,,这样问题不就一下解决了

ColinCLL commented 6 years ago

恩恩,暴露resize方法确实可以,不过这个不知道是G2还是viser的锅。其他的话真不是viser的锅,我猜是canvas的。

ascoders commented 6 years ago

G2 图表依赖容器宽高,而且不会相应容器宽高的变化。

宽高自适应的图表可以满足这个要求,可惜 G2 不是。

当然使用的 Element 框架多少也存在问题,举个例子,Antd 的 tabs 组件,虽然动画是连续的,但当前定位在第一个元素时,后续所有 tab 内元素都不会渲染,生命周期函数也不会执行。

当然次一点的方案是 display: none,但是容器的宽高应该预设。当然,如果在组件初始化时统计曝光的话,这样做也会导致误打点。

一个组件库是否靠谱,就看这些琐碎的 “细节” 处理的是否恰当。

GodStream commented 6 years ago

我就是想有个resize方法,切换选项卡的时直接resize就解决了,也不用折腾这么多事

ColinCLL commented 6 years ago

果然,用户只要结果。 让我突然想到。。。。 硬件领域的一句话,决定一个产品生死的很多时候不是完美环境有多好,而是在极端环境不出错。

SuGod commented 6 years ago

其实你仔细阅读element-ui的文档,tab-panel 有一个lazy 属性 应该就是v-if实现的。