多少年以前,我在一家BI企业负责数据可视化产品的开发,作为产品创新的需要,一篇论文吸引了我的目光,《Sketchy Rendering for Information Visualization》(该论文发表于2013年)
于是我带这两个实习生,利用论文中的知识做出了该工具的原型。收到了领导的赞许,就像很多有用和没用的创新一样,这东西最终无疾而终了。
论文的核心是对基本的图形元素的利用随机变形实现手绘风格。例如线和圆:
最近我发现一些手绘风格图表库出现在我的视野,例如chart.xkcd和chartjs-plugin-rough。
chart.xkcd风格很好看,但是支持的图表类型有限。
chartjs-plugin-rough仅仅是chartjs的扩展,使用的范围也很有限。
我希望能有一个通用的工具能够把任意类型的数据可视化转化为手绘风格,于是开发了这个Sketchify。
Sketchify同样是基于Roughjs,Roughjs是是个非常强大的手绘风格基础工具,可以实现基本的绘画元素在Canvas和SVG上的手绘风格的实现。
Skethcify的原理非常简单,从一个给定的根DOM元素开始,找到所有的SVG对象,然后递归寻找所有的子元素,读出子元素的基本属性,利用roughjs创建一个手绘风格的元素拷贝,隐藏原始元素。这样手绘风格的SVG元素就取代了原始的图形。当需要回到初始状态的时候,只要重现所有隐藏的原始元素,移除后加入的手绘元素即可。
代码如下:
const option = {
fillStyle: 'hachure',
roughness: 1,
bowing: 1,
chartType: 'highcharts',
};
// container is the root dom element that contains related graph svg
const handler = Sketchifier(container, option);
handler.handify();
// call restore will turn the graph back to original one
handler.restore();
我实验了几种常见类型的SVG图表:
以下是一些演示截图(包含原始数据图和手绘风格的对照):
ECharts
Echart的泡泡图手绘有些问题,这位灵魂画手不太擅长画泡泡。
AntV G2
G2的手绘效果非常好。
highcharts
amcharts with solid fill
xCharts with cross-hatch fill
你也可以到Codepen上去尝试这些例子:
最后要提一下,手绘风格的字体来自于Google Fonts,选择handwriting类别,能够给出很多好看的手绘风格字体,居然还有中文。Sketchify使用了Indie Flower
提示:
- 该工具仅仅支持以SVG为基础的数据可视化,不支持基于Canvas的库,例如ECharts和Ant G2。
- 手绘风格的处理会引入大量的svg图形元素,可能会消耗大量资源,请量力而为!
如果你喜欢数据可视化的话题,欢迎和我交流。如果你喜欢Sketchify,请到我的github点赞。
相关作品和引用
- Rough.js 本作品的基础 https://github.com/pshihn/rough/wiki
- chartjs的rough插件 https://nagix.github.io/chartjs-plugin-rough/
- 利用python和matplotlib实现手绘xkcd风格的chart https://jakevdp.github.io/blog/2012/10/07/xkcd-style-plots-in-matplotlib/
- xkcd风格的chart的js实现 https://github.com/timqian/chart.xkcd
- d3的手绘风格库 https://github.com/sebastian-meier/d3.sketchy
- d3手绘地图的演示 https://bl.ocks.org/emeeks/c42968993536f921a5c8
- 基于process的手绘风格库 https://www.gicentre.net/handy/
- Sketchy Data Visualization in Semiotic
- Introducing Semiotic for Data Visualization