es-big-screen

repository·main·Indexed 42 days ago

https://github.com/vangleer/es-big-screen

A template for developing large-screen data visualization dashboards built with Vue 3, Echarts, Amap, and Pinia. It features tools for screen scaling via useResize, drag-and-drop layouts using useSortable, seamless scrolling with animejs, and pre-built component wrappers for ECharts and AMap.

Tokens
5K
Snippets
16
Records
20
Agent score
53%

What's inside es-big-screen

  1. Overview of es-big-screen features

    main

    es-big-screen is a large-screen data visualization project template built using Vue 3, Echarts, Amap (高德地图), and Pinia. It provides a foundation for building dashboard-style interfaces with the following core capabilities:

    • Large-screen adaptation: Tools for scaling content to fit various screen sizes.
    • Echarts component encapsulation: Pre-built wrappers for Echarts charts.
    • Amap component encapsulation: Pre-built wrappers for Amap (高德地图) maps.
    • Drag-and-drop layout: Support for arranging dashboard elements.
    • Entrance animations: Visual effects for when components load.
    • Seamless scrolling: Support for continuous scrolling content.
  2. Quickstart: Install and run es-big-screen

    main

    To set up the project locally, clone the repository, install dependencies using yarn, and start the development server.

    1. Clone the repository: git clone https://github.com/vangleer/es-big-screen.git
    2. Navigate to the directory: cd es-big-screen
    3. Install dependencies: yarn
    4. Start the development server: yarn dev

    Once running, you can access the application at http://127.0.0.1:3006/.

    git clone https://github.com/vangleer/es-big-screen.git
    
    cd es-big-screen
    
    yarn
    
    yarn dev
    
    # Access http://127.0.0.1:3006/
  3. Integrate AMap (Gaode Maps) in Vue 3

    main

    To use AMap for geographic data visualization:

    1. Install dependencies: yarn add @amap/amap-jsapi-loader and yarn add @amap/amap-jsapi-types -D.
    2. Obtain an API Key from the AMap developer portal (Web端 JS API).
    3. Use the AMapLoader to load the API and initialize the map instance.

    The component exposes the map instance via defineExpose.

    <template>
    	<div id="mapContainer"></div>
    </template>
    
    <script setup lang='ts'>
    import { onMounted, shallowRef } from 'vue'
    import '@amap/amap-jsapi-types'
    import AMapLoader from '@amap/amap-jsapi-loader'
    
    const map = shallowRef<AMap.Map | null>(null)
    
    function initMap() {
      AMapLoader.load({
        key: 'YOUR_AMAP_API_KEY', // Replace with your actual key
        version: '2.0',
        plugins: [],
      }).then((MyAMap: typeof AMap) => {
        map.value = new MyAMap.Map('mapContainer', {
          mapStyle: 'amap://styles/darkblue'
        })
      }).catch(e => {
        console.log(e);
      })
    }
    
    onMounted(() => {
      initMap()
    })
    
    defineExpose({
      map
    })
    </script>
    
    <style lang='scss'>
    #mapContainer {
      width: 100%;
      height: 100%;
    }
    .amap-logo, .amap-copyright {
      opacity: 0;
    }
    </style>
  4. Implement drag-and-drop layout with useSortable

    main

    To enable draggable component layouts, use the useSortable hook which wraps SortableJS.

    1. Install SortableJS: yarn add sortablejs.
    2. Pass a reactive list (e.g., a shallowRef of components) to useSortable.
    3. Bind the returned containerRef to the parent element containing the draggable items.

    The hook automatically synchronizes the underlying data array when items are reordered.

    <template>
    	<div ref="containerRef">
    		<component
    			v-for="item in components"
    			:key="item.name"
    			:is="item.component"
    			class="es-screen-right-item"
    		>
    			{{ item.name }}
    		</component>
    	</div
    </template>
    
    <script setup lang='ts'>
    import { shallowRef } from 'vue'
    import { useSortable } from '@/utils/useSortable'
    import Right1 from './Right1.vue'
    import Right2 from './Right2.vue'
    import Right3 from './Right3.vue'
    
    const components = shallowRef([
    	{ name: 'right1', component: Right1 },
    	{ name: 'right2', component: Right2 },
    	{ name: 'right3', component: Right3 }
    ])
    
    const { containerRef } = useSortable(components)
    </script>
  5. Install and use the v-chart component

    main

    The project provides a wrapper for ECharts to simplify integration in Vue 3.

    1. Install ECharts: yarn add echarts.
    2. Register the component via the provided plugin (e.g., app.use(chart)).
    3. Use the <v-chart /> component by passing an option object.

    The component exposes the underlying ECharts instance and methods via defineExpose.

    <template>
    	<v-chart ref="chartRef" :option="option" />
    </template>
    
    <script setup lang='ts'>
    import { ref } from 'vue'
    const chartRef = ref()
    const option = ref({
      xAxis: {
        type: 'category',
        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
      },
      yAxis: {
        type: 'value'
      },
      series: [
        {
          data: [120, 200, 150, 80, 70, 110, 130],
          type: 'bar',
          showBackground: true,
          backgroundStyle: {
            color: 'rgba(180, 180, 180, 0.2)'
          }
        }
      ]
    })
    </script>
  6. Implement screen scaling with useResize

    main

    The project uses a scale approach for big-screen adaptation, which adjusts the scale of a root element based on the browser's aspect ratio relative to a design draft (defaulting to 1920x1080). This avoids the complexity of rem + vw/vh while maintaining layout integrity.

    To use it, call useResize and bind the returned screenRef to the container element that needs to be scaled.

    <template>
    	<div ref="screenRef"></div
    </template>
    
    <script setup lang='ts'>
    import { useResize } from '@/utils/useResize'
    const { screenRef } = useResize()
    </script>
  7. Implement entrance animations using CSS

    main

    The project uses CSS @keyframes to create entrance animations for different screen sections. You can implement these by applying specific animation names and durations to your component classes.

    Common patterns used in the template:

    • Fade-in (Header): Uses opacity from 0 to 1.
    • Slide-in with bounce (Left/Right): Uses translateX to move elements from off-screen to a slight overshoot (e.g., 20px) before settling at 0, creating a 'spring' effect.
    • Slide and Fade (Center): Combines translateY and opacity to move elements upward while fading them in.
    /* Example: Slide-in animation for Left side */
    @keyframes slide {
      0% { transform: translateX(-100%); }
      80% { transform: translateX(20px); }
      100% { transform: translateX(0); }
    }
    
    .es-screen-left-item {
      animation-name: slide;
      animation-duration: 0.8s;
    }
  8. Use the `SeamlessScroll` component

    main

    For a simpler implementation, use the SeamlessScroll component which wraps the useSeamlessScroll hook. This component handles the container setup and provides a slot for your list items.

    Props:

    • width: (String | Number) The width of the component.
    • height: (String | Number) The height of the component.
    • option: (Object) An OptionsType object to configure direction, gap, and duration.

    Usage Example (Vertical Scrolling):

    <template>
      <SeamlessScroll class="es-list" :option="{ direction: 'vertical' }">
        <div v-for="item in 15" class="es-item">{{ 'Item ' + item }}</div>
      </SeamlessScroll>
    </template>
    
    <script setup lang='ts'>
    import SeamlessScroll from '@/components/SeamlessScroll.vue'
    </script>
    
    <style>
    .es-list {
      position: relative;
      width: 100%;
      height: 100%;
      overflow: hidden;
    }
    .es-item {
      position: absolute;
      height: 20px;
    }
    </style>
    <template>
    	<SeamlessScroll class="es-list" :option="{ direction: 'vertical' }">
    		<div v-for="item in 15" class="es-item">{{ '热销商品的占比 ' + item }}</div>
    	</SeamlessScroll>
    </template>
    
    <script setup lang='ts'>
    import SeamlessScroll from '@/components/SeamlessScroll.vue'
    </script>
    
    <style lang='scss' scoped>
    .es-list {
    	position: relative;
    	width: 100%;
    	height: 100%;
    	overflow: hidden;
    	.es-item {
    		position: absolute;
    		height: 20px;
    	}
    }
    </style>
  9. Configure useResize options

    main

    The useResize hook accepts an optional ResizeType configuration object:

    • w: Design width (default: 1920)
    • h: Design height (default: 1080)
    • fullScreen: If true, uses both width and height ratios for scaling (may cause distortion). If false, uses a single scale factor to maintain aspect ratio.
    • delay: Debounce delay in milliseconds (default: 100)
  10. Exposed methods of the v-chart component

    main

    The v-chart component exposes the following methods and properties via its template ref:

    • chart: The raw ECharts instance.
    • setOption(option, notMerge?, lazyUpdate?): Updates the chart configuration.
    • resize(): Manually triggers a chart resize.
  11. Use the `useSeamlessScroll` hook

    main

    The useSeamlessScroll hook provides seamless horizontal or vertical scrolling using animejs.

    Prerequisites: Install animejs via yarn:

    yarn add animejs

    Parameters:

    • listRef: A Vue Ref<HTMLElement | null> pointing to the container element that holds the list items.
    • options: An OptionsType object:
      • direction: 'horizontal' (default) or 'vertical'.
      • gap: The spacing between items in pixels (default: 10).
      • duration: The animation duration in milliseconds (default: 10000).

    Returns: An object containing:

    • listRef: The ref used for the container.
    • pause: Function to pause the animation.
    • play: Function to resume the animation.
    • animation: The raw animejs animation instance.
    import { ref } from 'vue'
    import { useSeamlessScroll } from '@/utils/useSeamlessScroll'
    
    const listRef = ref()
    // Initializes horizontal scrolling with default options
    useSeamlessScroll(listRef)
    
    /* 
    Template requirement: 
    - An outer container with `overflow: hidden` to prevent scrollbar visibility.
    - The `listRef` element containing the items.
    - Items should ideally be positioned (e.g., `position: absolute`) if they need to overlap or follow specific layout logic.
    */
  12. Configure `useSeamlessScroll` options

    main

    The OptionsType configuration object for the seamless scroll hook allows customizing the movement behavior:

    KeyTypeDefaultDescription
    direction'horizontal' | 'vertical''horizontal'The axis of movement.
    gapnumber10The pixel distance between consecutive items.
    durationnumber10000The time (ms) it takes to complete one full loop cycle.
    export type OptionsType = {
    	direction?: 'horizontal' | 'vertical'
    	gap?: number
    	duration?: number
    }