Davinci数据可视化-新增图表类型-旭日图
Davinci 介绍
Davinci 是宜信出品的DVaaS(数据可视化及服务)的一款BI产品。
官网链接
概叙
由于网上并没有太多Davinci 教程文档,自己想新增一些其它的图表类型,对于我这个小白来说,花费了一些时间,避免一些朋友像我一样浪费时间。这里把代码贴出来,仅供参考。
最终效果图
新增图表类型-旭日图过程
旭日图有点特殊,所要求的数据需具备父子结构。
为了能够确保无限层级结构,这三个列是必不可少的。
- id: 当前节点ID
- pid: 当前节点父ID。0=顶级
- isParent: 该节点下是否还有节点。该属性既是基线条件,也是递归条件。
所以要保证在已有的数据源中,用于旭日图展示的数据包含这样的结构。一般的层级、分类数据都包含类似的几个列。 不确定的是这个列名不一样。
以下一些代码,由于文件代码过多,只提供修改的片段,要自行对比位置修改加入。注意别搞错了哈。
新增可视化类型
修改 webapp/app/containers/View/constants.ts
export enum ViewModelVisualTypes {Number = 'number',String = 'string',Date = 'date',GeoCountry = 'geoCountry',GeoProvince = 'geoProvince',GeoCity = 'geoCity',//新加入TreeNodeId = 'treeNodeId', //节点IDTreeParentId = 'treeParentId', //父节点IDTreeIsParent = "treeIsParent" //是否拥有子节点
}export const ViewModelVisualTypesLocale = {[ViewModelVisualTypes.Number]: '数字',[ViewModelVisualTypes.String]: '字符',[ViewModelVisualTypes.Date]: '日期',[ViewModelVisualTypes.GeoCountry]: '地理国家',[ViewModelVisualTypes.GeoProvince]: '地理省份',[ViewModelVisualTypes.GeoCity]: '地理城市',//新加入[ViewModelVisualTypes.TreeNodeId]: '树-节点ID',[ViewModelVisualTypes.TreeParentId]: '树-父节点ID',[ViewModelVisualTypes.TreeIsParent]: '树-是否拥有子节点',
}
修改 webapp/app/containers/Widget/render/chart/util.ts (后面会用到)
//新加入
//确定列名、确定属性角色
export function treeKeyUnknownToknown(cols,model) {let idKey,pidKey,ispidKey,nameKey;cols.forEach((col) => {const { visualType } = model[col.name]if ( ViewModelVisualTypes.TreeParentId == visualType ){pidKey = col.name}else if ( ViewModelVisualTypes.TreeIsParent == visualType ){ispidKey = col.name}else if ( ViewModelVisualTypes.TreeNodeId == visualType ){idKey = col.name}else {nameKey = col.name}})return{idKey,pidKey,ispidKey,nameKey}
}
效果图
在新增view的时候,通过选择可视化类型来告诉程序这每个属性对应着的角,方便后面解析数据。
新增图表类型
修改 webapp/app/containers/Widget/config/chart/ChartTypes.ts
//新加入/*** 旭日图*/Sunburst = 20 ,
修改 webapp/app/containers/Widget/config/chart/index.tsx 这里参照该文件导入导出就行。
新增 webapp/app/containers/Widget/config/chart/sunburst.ts
图表类型的配置,包含一些默认样式、图表规范…
import ChartTypes from './ChartTypes'
import {IChartInfo} from "containers/Widget/components/Widget";
import {CHART_LABEL_POSITIONS,PIVOT_CHART_FONT_FAMILIES,PIVOT_DEFAULT_AXIS_LINE_COLOR,PIVOT_DEFAULT_FONT_COLOR,PIVOT_DEFAULT_HEADER_BACKGROUND_COLOR
} from "app/globalConstants";
import {monitoredSyncDataAction} from "containers/Dashboard/actions";const sunburst:IChartInfo = {id: ChartTypes.Sunburst,name: 'sunburst',title: '旭日图',icon: 'icon-xuri',coordinate: 'cartesian',rules: [{ dimension: [3,4] , metric: [1,1] }],dimetionAxis: 'col',data: {cols: {title: '列',type: 'category'},rows: {title: '行',type: 'category'},metrics: {title: '指标',type: 'category'},filters: {title: '筛选',type: 'all'},},style: {sunburst: {themeColor: null,border: {color: '#000',width: 2,type: 'solid',},internalRadius: 0,dxternalRadius: 100,},spec: {},label: {showLabel: false,labelPosition: CHART_LABEL_POSITIONS[0].value,labelFontFamily: PIVOT_CHART_FONT_FAMILIES[0].value,labelFontSize: '12',labelColor: PIVOT_DEFAULT_FONT_COLOR},}
}
export default sunburst
新增 webapp/app/containers/Widget/components/Workbench/ConfigSections/SunburstSection.tsx
操作面板的样式栏
import React from 'react'
import debounce from 'lodash/debounce'
import { CheckboxChangeEvent } from 'antd/lib/checkbox'
import { Row, Col, Modal, Icon, InputNumber, Select, Checkbox,Slider } from 'antd'
import {IDataParamProperty, IDataParams} from "containers/Widget/components/Workbench/OperatingPanel";
import {treeKeyUnknownToknown} from "containers/Widget/render/chart/util";
import {IViewModel} from "containers/View/types";
import ColorPicker from 'components/ColorPicker'
import {PIVOT_CHART_LINE_STYLES} from "app/globalConstants";
const defaultTheme = require('assets/json/echartsThemes/default.project.json')const styles = require('../Workbench.less')
const defaultThemeColors = defaultTheme.theme.colorexport interface color {key: Stringvalue: String
}export interface SunburstConfig {themeColor: color[],border: {color: stringwidth: numbertype: 'solid' | 'dashed' | 'dotted'},internalRadius: Number,dxternalRadius: Number,
}interface SunburstStates {tThemeColor: color[] //主题色colorItems: any[] //主题色彩色器
}interface SunburstSectionProps {config: SunburstConfigonChange: (prop: string,value: number | string | boolean | color[] ,propPath: string[] | null) => voiddataSource: object[]dataParams: IDataParamsmodel: IViewModel,}export class SunburstSection extends React.PureComponent<SunburstSectionProps ,SunburstStates,{}> {private debounceInputChange = nullconstructor (props: SunburstSectionProps) {super(props)this.state = {tThemeColor: new Array<color>(),colorItems: []}const { dataSource , dataParams , model ,config} = this.propslet { themeColor } = configconst { cols } = dataParamslet {idKey,pidKey,ispidKey,nameKey} = treeKeyUnknownToknown( cols.items , model );let pid;let nameIndex = 0 ;dataSource.map( ( g , index )=>{pid = g[pidKey];if ( pid == 0 ){if ( themeColor == null ){themeColor = [];}themeColor[nameIndex] = {key: g[nameKey] ,value: themeColor[nameIndex] ? themeColor[nameIndex].value : defaultThemeColors[nameIndex]};nameIndex += 1}})this.state = {tThemeColor: themeColor,colorItems: this.buildColours( themeColor )}this.props.onChange("themeColor",themeColor,null);this.debounceInputChange = debounce(props.onChange, 1500)}/*** 构建采色器* @param tThemeColor*/private buildColours( tThemeColor ){let ci = [];tThemeColor.map( ( g , index )=>{ci.push(<Row key={index} gutter={8} type="flex" align="middle" className={styles.blockRow}><Col span={8}>{g.key}</Col><Col span={4}><ColorPickervalue={g.value}onChange={this.colorChange( index )}/></Col></Row>)})return ci;}private sliderChange = (prop) => (value) => {this.props.onChange( prop , value , null );}private propChange = (propName: string, propPath?: string) => (e: number | string | CheckboxChangeEvent) => {const value = (e as CheckboxChangeEvent).target? (e as CheckboxChangeEvent).target.checked: (e as string | number)this.props.onChange(propName, value, propPath ? [propPath] : [])}private colorChange = (index) => (color) => {const tThemeColor = this.state.tThemeColor;tThemeColor[index].value = colorthis.setState({tThemeColor: tThemeColor.map((item, _index) => _index == index ? {...item, value: color} : item),colorItems: this.buildColours( tThemeColor )})this.props.onChange("themeColor",tThemeColor,null);}private lineStyles = PIVOT_CHART_LINE_STYLES.map((l) => (<Option key={l.value} value={l.value}>{l.name}</Option>))public render () {const { model ,config} = this.propsconst { color, width, type } = config.borderconst { internalRadius , dxternalRadius } = configconst { colorItems } = this.statefunction formatter(value) {return `${value}%`;}return (<div><div className={styles.paneBlock}><h4>主题颜色</h4><div className={styles.blockBody}>{(colorItems)}</div></div><div className={styles.paneBlock}><h4>边框</h4><Rowgutter={8}type="flex"align="middle"className={styles.blockRow}><Col span={10}><Selectplaceholder="样式"className={styles.blockElm}value={type}onChange={this.propChange('type', 'border')}>{this.lineStyles}</Select></Col><Col span={10}><InputNumberplaceholder="粗细"className={styles.blockElm}value={width}min={0}onChange={this.propChange('width', 'border')}/></Col><Col span={4}><ColorPickervalue={color}onChange={this.propChange('color', 'border')}/></Col></Row></div><div className={styles.paneBlock}><h4>半径</h4><Rowgutter={8}type="flex"align="middle"className={styles.blockRow}><Col key="cLabel" span={8}>内部半径</Col><Col span={14}><Slider value={internalRadius} onChange={this.sliderChange("internalRadius")} /></Col></Row><Rowgutter={8}type="flex"align="middle"className={ styles.blockRow}><Col key="dLabel" span={8}>外部半径</Col><Col span={14}><Slider value={dxternalRadius} onChange={this.sliderChange("dxternalRadius")} /></Col></Row></div></div>)}
}export default SunburstSection
修改 webapp/app/containers/Widget/components/Widget
//加入
import {SunburstConfig} from "containers/Widget/components/Workbench/ConfigSections/SunburstSection";export interface IChartStyles {//....省略//加入sunburst?: SunburstConfig
}
修改 webapp/app/containers/Widget/components/Workbench/OperatingPanel.tsx
//分别导入
import SunburstSection from './ConfigSections/SunburstSection'
import sunburst from "containers/Widget/config/chart/sunburst";const {spec, xAxis, yAxis, axis, splitLine, pivot: pivotConfig, label, legend,visualMap, toolbox, areaSelect, scorecard, gauge, iframe, table, bar, radar, doubleYAxis,ds,river,pictorialBar ,sunburst //加入} = styleParams//新加入{sunburst && <SunburstSectiondataSource={dataSource}dataParams={dataParams}model={selectedView.model}config={sunburst}onChange={this.styleChange('sunburst')}/>}
新增 webapp/app/containers/Widget/render/chart/sunburst.ts
用于构建旭日图
import { IChartProps } from '../../components/Chart'
import { decodeMetricName } from '../../components/util'
import {getLegendOption, getLabelOption, treeKeyUnknownToknown} from './util'
import { EChartOption } from 'echarts'
import defaultTheme from 'assets/json/echartsThemes/default.project.json'
const defaultThemeColors = defaultTheme.theme.color/*** 最基础的旭日图组装需要父子结构的数据,支持无限递归,直到没有子节点。* 所以数据得包含三个属性,才可保证。* id 当前节点ID* pid 当前节点父ID。0=顶级* isP 该节点下是否还有节点。该属性既是基线条件,也是递归条件。* @param chartProps* @param drillOptions*/
export default function (chartProps: IChartProps, drillOptions?: any) {const {cols,data,metrics,chartStyles,model,} = chartPropsconst {label , sunburst } = chartStylesconst { themeColor,border, internalRadius, dxternalRadius } = sunburstconst {color: borderColor,width: borderWidth,type: borderType,} = borderlet id,pid,ispid,name;const labelOption = {label: getLabelOption('sunburst', label, metrics)}/*** 确认每个属性的key*/let {idKey,pidKey,ispidKey,nameKey} = treeKeyUnknownToknown( cols,model );let dataObj = new Array();//遍历指标metrics.forEach((m, i) => {const decodedMetricName = decodeMetricName(m.name)data.map((g, index) => {let value = g[`${m.agg}(${decodedMetricName})`];pid = g[pidKey];name = g[nameKey];id = g[idKey];if ( pid == 0 ){let children = new Array();findNode( data , id , children)let node = {name: name,value: value,children: children}dataObj.push( node );}})})var colors = [];if ( themeColor == null ){colors = defaultThemeColors;}else{themeColor.map( (item , index) => {colors[index] = item.value} );}let seriesObj = {color: colors,series: {type: "sunburst",data: dataObj,...labelOption,itemStyle: {borderColor,borderType,borderWidth},radius: [`${internalRadius}%`, `${dxternalRadius}%`]},}function findNode( data , id , children ) {metrics.forEach((m, i) => {const decodedMetricName = decodeMetricName(m.name)data.map((g, index) => {pid = g[pidKey];if (pid === id) {ispid = g[ispidKey];let childrenNode = new Array();if (ispid === 0) {findNode(data, g[idKey], childrenNode)}let node = {name: g[nameKey],value: g[`${m.agg}(${decodedMetricName})`],children: childrenNode}children.push(node);}})})}return {...seriesObj}
}
修改 webapp/app/containers/Widget/render/chart/index.ts
//加入
import sunburst from './sunburst'//加入
case 'sunburst': return sunburst(chartProps, drillOptions)
到这就结束辣,需要修改的地方大致就是这几个。有问题的地方欢迎大家提出、指正。
图表、图表样式的构建,还有要优化、新增的功能,大家可以自己修改。以上仅供参考。‘
漏了几处
Widget\components\Workbench\index.tsx 文件中<OperatingPanel//...//新加入dataSource={data} >Widget\components\Workbench\OperatingPanel.tsx 文件中interface IOperatingPanelProps {//...//新加入dataSource: object[]
}public render () {const {//...//新加入dataSource} = this.props//...
/>
Davinci数据可视化-新增图表类型-旭日图相关推荐
- Python数据可视化 Pyecharts 制作 Sunburst 旭日图
Python3 的 Pyecharts 制作 Sunburst(旭日图) 时需要使用的设置参数和常用模板案例,可根据实际情况对案例中的内容进行调整即可. 文章目录 Demo 标准旭日图 饮料风味旭日图 ...
- 几种常见的数据可视化分析图表
可视化技术的高速发展带动着数据的进步.数据可视化的数据分析图表,借助于可视化的大屏,将数据以图表的形式进行汇总分析,加快着用户对于数据的接受时间,同时对于整体的布局美观,也是一种合理化的设计.如何设计 ...
- 数据图表与分析图_史上最全最实用的数据可视化分析图表制作工具汇总
俗话说的好:工欲善其事,必先利其器!一款好的工具可以让你事半功倍,尤其是在大数据时代,更需要强有力的工具通过使数据有意义的方式实现数据可视化,还有数据的可交互性;我们还需要跨学科的团队,而不是单个数据 ...
- Echarts数据可视化event图表事件的相关操作,开发全解+完美注释
全栈工程师开发手册 (作者:栾鹏) Echarts数据可视化开发代码注释全解 Echarts数据可视化开发参数配置全解 6大公共组件详解(点击进入): title详解. tooltip详解.toolb ...
- Echarts数据可视化action图表行为的相关操作,开发全解+完美注释
全栈工程师开发手册 (作者:栾鹏) Echarts数据可视化开发代码注释全解 Echarts数据可视化开发参数配置全解 6大公共组件详解(点击进入): title详解. tooltip详解.toolb ...
- 数据可视化,图表使用技巧全解析!
数据总是能最完整.正确地反映客观情况,也最能帮助我们发现规律和趋势,并对未来事件进行预测. 但是你知道不同类型的数据适合用什么样的图表吗? 优秀的数据可视化从来都不是罗列数据,更要根据自己的数据特征, ...
- r语言siggenes包_初探R语言可视化交互式包plotly——旭日图(Sunburst Chart)
ploylt原来是一款用来做数据分析和可视化的在线平台,后来有人开发了一些语言(Python.R.Matlab等)的API,在R里就是plotly包了.plotly已经发布在CRAN上了,要想安装,仅 ...
- 数据可视化必修课 - 图表篇
本文由作者 友设青年 发布于社区 随着互联网数字化越来越完善,数据可视化这个词的使用频率也越来越高,而图表是数据可视化中最常用的一种表现形式.无论是工作汇报还是后台设计,都离不开图表的使用.然而关于图 ...
- echarts 折线图 设置y轴最小刻度_数据可视化—Echarts图表应用
<错误>郑愁予 我打江南走过, 那等在季节里的容颜如莲花的开落,东风不来,三月的柳絮不飞.你的心如小小寂寞的城,恰若青石的街道向晚.蛩音不响,三月的春帷不揭,你的心是小小的窗扉紧掩.我达达 ...
最新文章
- javascript客户端检测技术
- JAVA学习笔记--初始化与清理
- DCMTK:读取多个图像的示例应用程序
- 02-CSS基础与进阶-day7_2018-09-07-21-27-32
- Reactive Extensions 相见恨晚的Rx.Net
- C语言,利用数组编写程序输入30个数,分别统计正整数,0,负数个数,并求和
- Linux下shell反弹
- JS 父子(弹出)窗口操作总结
- 分布式文件系统(FastDFS+Tengine+fastdfs-nginx-module)
- Android 实现微信扫码登陆功能-详细教程
- Java Web ——基于Jsp+Servlet的学生上课签到打卡系统/上课考勤管理系统
- PDFDOC365工具箱
- 离散数学证明公式整理
- 基于java的小额支付管理平台
- 大数据分析平台和工具,主要有哪些?
- 清华大学两名博士生被开除:你不吃学习的苦,就要吃生活的苦
- 最好用的六款虚拟机软件,赶紧收藏
- JS判断是否含有某个字段
- jenkins插件管理提示_jenkins插件管理及安装
- 小程序列表页tab切换swiper并滚动到上次位置