Frontend Development 17 min read

Custom Theme Colors, Gradient Effects, and Advanced Decorations for Data Dashboard Visualizations with VChart

This article demonstrates how to build impressive data dashboards using VChart by configuring scene‑specific theme colors, implementing gradient fills, adding high‑customizable decorative marks and component decorations, and creating rich animation effects, all with detailed code examples and links to live demos.

ByteFE
ByteFE
ByteFE
Custom Theme Colors, Gradient Effects, and Advanced Decorations for Data Dashboard Visualizations with VChart

In large‑screen products, visualization plays a crucial role in information display, user experience, data analysis, brand differentiation, and storytelling. Using the DataWind data‑screen as an example, this article explains how to create stunning dashboards with VChart.

Scene‑Specific Theme Color Configuration

Different industries benefit from tailored color themes to improve visual impact, data meaning, brand recognition, and user needs. VChart supports scene‑based theme registration and switching, allowing users to select appropriate palettes for finance, advertising, and other sectors.

Core Code for Theme Registration and Switching

const response = await fetch('https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/theme.json');
const colorTheme = await response.json();

// 注册主题
const theme = {};
for (const colorKey in colorTheme) {
  const colorName = colorTheme[colorKey].name;
  theme[colorName] = {
    colorScheme: {
      default: colorTheme[colorKey].colors
    }
  };
  VChart.ThemeManager.registerTheme(colorKey, theme[colorName]);
}

// 主题切换
VChart.ThemeManager.setCurrentTheme('volcanoBlue');

Online example: https://www.visactor.io/vchart/guide/tutorial_docs/Theme/Customize_Theme

Gradient Effect Implementation

The transition from solid to gradient colors is achieved by applying gradient fills and strokes to chart marks.

Core Code for Gradient Effect

const gradientCallback = (datum, ctx, type) => {
  return {
    gradient: "linear",
    x0: 0,
    y0: 0,
    x1: 0,
    y1: 1,
    stops: [
      {
        offset: 0,
        fillOpacity: 0,
        color: hexToRgba(ctx.seriesColor(datum.type), 1),
      },
      {
        offset: 1,
        fillOpacity: 1,
        color: hexToRgba(ctx.seriesColor(datum.type), 0),
      }
    ]
  };
};
// 以同样的方式在主题中注册和切换
const theme = {
  series: {
    bar: {
      bar: {
        style: {
          fill: (datum, ctx) => gradientCallback(datum, ctx, "fill"),
          stroke: (datum, ctx) => gradientCallback(datum, ctx, "stroke"),
          lineWidth: 2
        }
      }
    }
  }
}
VChart.ThemeManager.registerTheme(theme, 'gradient');
VChart.ThemeManager.setCurrentTheme('gradient');

Gradient details: https://www.visactor.io/vchart/guide/tutorial_docs/Chart_Concepts/Series/Mark

Highly Customizable Decorative Marks

Fine‑grained decorations on chart marks enhance visual appeal, brand identity, and data readability. VChart’s extensible Mark feature enables rendering of decorative symbols attached to existing marks.

Core Code for Mark Decoration

extensionMark: [
  {
    name: "markSymbol",
    type: "symbol",
    dataId: "data", // 绑定的数据id
    visible: true,
    style: {
      x: (datum, ctx, elements, dataView) => {
        return ctx.valueToX([datum["beinirRbfVnf"]]); // 自定义x映射
      },
      y: (datum, ctx, elements, dataView) => {
        return ctx.valueToY([datum["10002"]]); // 自定义y映射
      },
      size: 13,
      fillOpacity: 0.1,
      fill: "#FFF",
      strokeOpacity: 0.5,
      lineWidth: 1,
      stroke: {
        gradient: "conical",
        startAngle: 0,
        endAngle: 6.283185307179586,
        stops: [
          { offset: 0, color: "rgba(255, 255, 255, 0)" },
          { offset: 1, color: "rgba(255, 255, 255, 1)" }
        ]
      }
    }
  }
];

Live demo: https://codesandbox.io/s/line-with-halo-j54hv8

Component Decoration (Axis Tick Customization)

To highlight axis coverage, VChart’s axis tick callback can hide intermediate ticks and show only the first and last.

Core Code for Axis Tick

axes: [{
  // ...
  tick: {
    size: 6,
    visible: true,
    style: (...args: any[]) => {
      // args[1]为tick index, args[3]为tick全量数据
      tickCount = args[3].length - 1;
      return {
        lineWidth: args[1] === 0 || args[1] === tickCount ? 2 : 0,
        stroke: "rgb(0,110,255)"
      };
    }
  }
}];

Demo: https://codesandbox.io/s/axes-with-tick-sign-9n9jtf

Rich and Flexible Animation Effects

Data‑screen animations include data‑update, highlight, and ambience effects to draw attention and convey changes. VChart leverages VRender for shape deformation and VGrammar for animation flow.

Core Code for Simple Update Animation

animationUpdate: {
  type: 'moveIn',
  duration: 500
}

Core Code for Bar Chart Normal Animation

animationNormal: {
  bar: [
    {
      loop: true,
      startTime: 100,
      oneByOne: 100,
      timeSlices: [
        {
          delay: 1000,
          effects: {
            channel: { fillOpacity: { to: 0.5 } },
            easing: "linear"
          },
          duration: 500
        },
        {
          effects: {
            channel: { fillOpacity: { to: 1 } },
            easing: "linear"
          },
          duration: 500
        }
      ]
    }
  ]
};

Bar update demo: https://codesandbox.io/s/animation-bar-yypwgs?file=/src/index.ts

Bar highlight demo: https://codesandbox.io/s/animation-highlight-j6d4f2?file=/src/index.ts

Bar ambience animation uses VRender.StreamLight for a glowing effect.

Chart Extensibility and Custom Mapping

Beyond built‑in charts, VChart allows users to define custom mappings, layouts, animations, and interactions via VGrammar. An example shows building a ranking list with rectangles, symbols, and text marks.

Core Code for Custom Mapping (excerpt)

marks: [
  // Rectangle
  {
    type: 'rect',
    from: { data: chartSpec.data[0].id },
    dependency: ['viewBox', 'xScale', 'yScale'],
    encode: {
      update: (datum, element, params) => {
        return {
          x: params.xScale.scale(dataMin),
          y: params.yScale.scale(datum['category']),
          width: params.xScale.scale(datum['value']),
          height: barWidth
        };
      }
    }
  },
  // Symbol (decorative point)
  {
    type: 'symbol',
    from: { data: chartSpec.data[0].id },
    dependency: ['viewBox', 'yScale', 'xScale'],
    encode: {
      update: (datum, element, params) => {
        return {
          x: params.xScale.scale(replaceNilDatum(datum, 'value', dataMin)),
          y: params.yScale.scale(datum['category'])
        };
      }
    }
  },
  // Text (title)
  {
    type: 'text',
    from: { data: chartSpec.data[0].id },
    dependency: ['viewBox', 'yScale', 'xScale'],
    encode: {
      update: (datum, element, params) => {
        return {
          text: leftTextFormatMethod(datum['category']),
          x: params.xScale.scale(dataMin),
          y: params.yScale.scale(datum['category'])
        };
      }
    }
  }
];

Ranking list demo: https://codesandbox.io/s/vgrammar-ranking-list-animation-dr87sy

Custom Animation for Ranking List

Animations include entrance (y moves from outside to position), update (width grows from 0), and exit (y moves out).

Core Code for Entrance, Update, and Exit

enter: [
  {
    delay: 0,
    duration: durationTime,
    channel: {
      dy: {
        from: (datum, element, params) => params.viewBox.y2,
        to: 0
      }
    }
  }
];

// Update (width)
enter: [
  {
    delay: 0,
    duration: durationTime,
    channel: {
      width: {
        from: 0,
        to: (datum, element, params) => params.xScale.scale(datum['value'])
      }
    }
  }
];

// Exit (y moves out)
exit: [
  {
    delay: 0,
    duration: durationTime,
    channel: {
      dy: {
        from: 0,
        to: (datum, element, params) => params.viewBox.y2
      }
    }
  }
];

Interaction example uses addEventListener('pointerdown', this.clickEventHandler) to handle mark clicks.

Conclusion

The article showcases how to build an impressive data‑screen using VChart, covering theme customization, gradient fills, decorative marks, component decorations, animation techniques, and extensibility, providing practical code and live demos for developers.

Contact & Resources

DataWind product: https://www.volcengine.com/product/datawind

VisActor project: https://www.visactor.io/

GitHub repository: https://github.com/VisActor/VChart

frontendanimationData Visualizationtheme customizationVChart
ByteFE
Written by

ByteFE

Cutting‑edge tech, article sharing, and practical insights from the ByteDance frontend team.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.