DataV 是阿里云出品的拖拽式可视化工具,专精于业务数据与地理信息融合的大数据可视化。快速开始
准备环境
Node版本在 8.0.0 及以上,10.12.0以下,推荐使用nvm管理node版本。nvm使用说明
安装开发工具套件
// 开发工具
npm install --registry=https://registry.npm.taobao.org datav-cli -g
// 开发工具版本
datav --version
帮助命令
$ datav -h
Usage: datav [options] <folder|file...>
Commands:
set-key|login set-key with you username and token in the datav.aliyun.com
init init com for datav-coms
start|run [options] start service for preview component
publish|pbl [options] publish component
package|pack package component
locale Set your locale
locale-clear|lc Clear your locale
help help
latest check datav-cli latest version
whoami display datav username, datav region
Options:
-h, --help output usage information
-V, --version output the version number
-v --verbose increase verbosity
-E --exclude <items> exclude file or folder
-V, --version output the version number
生成基础代码包
预览组件
cd 您的组件名
datav run
http://localhost:1111/
预览页主要分为中心画布区,底部工具栏和右侧工具栏三部分,详细介绍如下:
- 中心画布区
- 中心画布区是用来展现组件,实时观测组件变化的区域。
- 所有右侧工具栏的配置、数据修改都会实时展示在中心画布的组件上。
- 组件的白框代表了组件的容器范围大小,每个方向上的白框都可以缩放来测试组件在任意方向缩放的表现。
- 底部工具栏可以切换组件的语言环境。
- 右侧工具栏右侧工具栏分为配置、数据、交互和发布4个面板。
主要文件
index.js //入口文件
package.json //组件配置项 默认的配置和数据都在这里
package.json
{
"name": "@iwhalecloud-poc/ScrollZone",
"version": "0.0.5",
"dependencies": {
"bcore": "0.0.18",
"echarts": "^4.6.0",
"jquery": "2.1.4",
"lodash": "4.6.1",
"zrender": "3.4.4"
},
"datav": {
"cn_name": "滚动区",
"icon": "",
"protocol": 2,
"type": [
"regular_bar"
],
"view": {
"width": "600",
"height": "400",
"minWidth": "40",
"minHeight": "20"
},
"apis": {
"source": {
"handler": "render",
"description": "滚动事件列表接口",
"fields": {
"url": {
"description": "事件图标",
"type": "string",
"optional": true
},
"title": {
"description": "事件标题",
"type": "string"
},
"status": {
"description": "事件状态",
"type": "int"
},
"desc": {
"description": "事件简述",
"type": "string"
},
"time": {
"description": "时间",
"type": "string",
"optional": true
},
"act": {
"description": "时间",
"type": "string",
"optional": true
},
"actIconUrl": {
"description": "处理动作图标",
"type": "string",
"optional": true
}
}
}
},
"config": {
"options": {
"name": "菜单",
"type": "menu",
"children": {
"zone": {
"name": "全局",
"mode": "single",
"children": {
"size": {
"type": "suite",
"name": "大小",
"children": {
"width": {
"name": "宽度",
"type": "stepper",
"default": 200,
"step": 1,
"min": 0,
"suffix": "px",
"description": "",
"col": 12
},
"height": {
"name": "高度",
"type": "stepper",
"default": 400,
"step": 1,
"min": 0,
"suffix": "px",
"description": "",
"col": 12
}
}
},
"position": {
"name": "位置",
"type": "suite",
"children": {
"left": {
"name": "x",
"type": "stepper",
"default": 0,
"step": 0.1,
"suffix": "px",
"description": "",
"col": 12
},
"top": {
"name": "y",
"type": "stepper",
"default": 0,
"step": 0.1,
"suffix": "px",
"description": "",
"col": 12
}
}
},
"direction": {
"name": "排列方式",
"type": "select",
"range": [
{
"name": "水平",
"value": "row"
},
{
"name": "竖直",
"value": "column"
}
],
"default": "column"
}
}
},
"card": {
"name": "卡片",
"mode": "single",
"children": {
"margin": {
"type": "margin",
"name": "边距",
"default": {
"top": 10,
"bottom": 10,
"left": 10,
"right": 10
}
},
"border": {
"type": "suite",
"name": "边框",
"children": {
"borderWidth": {
"name": "边框粗细",
"type": "stepper",
"step": 1,
"default": 2,
"col": 12,
"suffix": "px"
},
"borderColor": {
"name": "边框颜色",
"type": "fill",
"default": "rgba(0,0,0,0.7)",
"col": 12
},
"borderRadius": {
"name": "边框圆角",
"type": "stepper",
"step": 1,
"default": 0,
"col": 12,
"suffix": "px"
},
"lineStyle": {
"name": "边框线型",
"type": "select",
"range": [
{
"name": "实线",
"value": "solid"
},
{
"name": "虚线",
"value": "dashed"
},
{
"name": "点状",
"value": "dotted"
}
],
"default": "solid",
"col": 12
}
}
},
"color": {
"name": "颜色",
"type": "fill",
"default": {
"type": "flat",
"value": "rgba(0,0,0,0.6)"
},
"components": [
"flat",
"linearGradient"
]
},
"icon": {
"name": "图标",
"type": "group",
"children": {
"show": {
"name": "显示",
"type": "boolean",
"default": true
},
"size": {
"type": "suite",
"name": "大小",
"children": {
"width": {
"name": "宽度",
"type": "stepper",
"default": 16,
"step": 1,
"min": 0,
"suffix": "px",
"description": "",
"col": 12
},
"height": {
"name": "高度",
"type": "stepper",
"default": 16,
"step": 1,
"min": 0,
"suffix": "px",
"description": "",
"col": 12
}
}
},
"position": {
"name": "位置",
"type": "suite",
"children": {
"left": {
"name": "x",
"type": "stepper",
"default": 0,
"step": 0.1,
"suffix": "px",
"description": "",
"col": 12
},
"top": {
"name": "y",
"type": "stepper",
"default": 0,
"step": 0.1,
"suffix": "px",
"description": "",
"col": 12
}
}
},
"url": {
"name": "图标",
"type": "image",
"default": "./assets/warning.png"
}
}
},
"title": {
"name": "标题",
"type": "group",
"children": {
"show": {
"name": "显示",
"type": "boolean",
"default": true
},
"size": {
"type": "suite",
"name": "大小",
"children": {
"width": {
"name": "宽度",
"type": "stepper",
"default": 0,
"step": 1,
"min": 0,
"suffix": "px",
"description": "",
"col": 12
},
"height": {
"name": "高度",
"type": "stepper",
"default": 30,
"step": 1,
"min": 0,
"suffix": "px",
"description": "",
"col": 12
}
}
},
"position": {
"name": "位置",
"type": "suite",
"children": {
"left": {
"name": "x",
"type": "stepper",
"default": 0,
"step": 0.1,
"suffix": "px",
"description": "",
"col": 12
},
"top": {
"name": "y",
"type": "stepper",
"default": 0,
"step": 0.1,
"suffix": "px",
"description": "",
"col": 12
}
}
},
"text": {
"name": "标题文字",
"type": "text",
"default": "标题文字"
},
"textStyle": {
"type": "font",
"name": "文本",
"default": {
"fontFamily": "Microsoft Yahei",
"fontWeight": "normal",
"fontSize": 12,
"color": "rgb(255, 255, 255)"
}
},
"align": {
"name": "对齐方式",
"type": "select",
"range": [
{
"name": "左对齐",
"value": "flex-start"
},
{
"name": "居中对齐",
"value": "center"
},
{
"name": "右对齐",
"value": "flex-end"
}
],
"default": "center"
},
"direction": {
"name": "排列方式",
"type": "select",
"range": [
{
"name": "水平",
"value": "horizontal"
},
{
"name": "竖直",
"value": "vertical"
}
],
"default": "horizontal"
}
},
"fold": true
}
}
}
}
}
},
"api_data": {
"source": [
{
"url": "",
"title": "我是事件标题1",
"status": 0,
"desc": "我是事件简述我是事件简述我是事件简述我是事件简述我是事件简述我是事件简述",
"time": "2020年03月10日",
"act": "前往处理"
}
]
},
"events": {
"title-click": {
"description": "点击触发标题事件",
"fields": {
"value": {
"description": "点击值"
}
}
}
}
}
}
index.js
var Event = require("bcore/event");
var $ = require("jquery");
var _ = require("lodash");
// var EChart = require("echarts");
// var Utils = require("datav:/com/maliang-echarts-utils/0.0.18");
/**
* 马良基础类
*/
module.exports = Event.extend(
function Base(container, config) {
this.config = {
theme: {}
};
this.container = $(container); //容器
this.apis = config.apis; //hook一定要有
this._data = null; //数据
this.chart = null; //图表
this.init(config);
},
{
/**
* 公有初始化
*/
init: function(config) {
//1.初始化,合并配置
this.mergeConfig(config);
//2.刷新布局,针对有子组件的组件 可有可无
this.updateLayout();
//3.子组件实例化
//this.chart = new Chart(this.container[0], this.config);
//4.如果有需要, 更新样式
this.updateStyle();
},
/**
* 绘制
* @param data
* @param options 不一定有
* !!注意: 第二个参数支持config, 就不需要updateOptions这个方法了
*/
render: function(data, config) {
// console.log(data, config);
data = this.data(data);
// console.log("data:", data);
var cfg = this.mergeConfig(config);
// console.log("config:", cfg);
var card = cfg.options.card;
var items = ["<div class='zone'>"];
data.forEach(element => {
items.push(
"<div class='card'><div class='title-row'><img class='icon' src=" +
(element.url || card.icon.url) +
"></img><span class='title'>" +
element.title +
"</span><span class='status'>" +
element.status +
"</span></div>" +
"<div class='desc'>" +
element.desc +
"</div>" +
"<div class='time'>" +
element.time +
"</div>" +
"<div class='act'>" +
(element.act || card.act.text.text) +
"<span class='act-icon'><img src=" +
(element.actIconUrl || card.act.suffix.url) +
"></img></span>" +
"</div></div>"
);
});
items.push("</div>");
//更新图表
//this.chart.render(data, cfg);
// console.log(this.container);
this.container.html(items.join(""));
//如果有需要的话,更新样式
this.updateStyle();
this.scrollY();
},
scrollY: function() {
$(function() {
var $this = $(".datav-wraper");
if (!$this.length) {
$this = $(".-datav-wraper");
}
var scrollTimer;
$this
.hover(
function() {
clearInterval(scrollTimer);
},
function() {
scrollTimer = setInterval(function() {
scrollNews($this);
}, 2000);
}
)
.trigger("mouseleave");
function scrollNews(obj) {
var $self = obj.find(".zone");
var lineHeight = $self.find(".card:nth-child(1)").height();
$self.animate(
{
transform: "translateY(" + lineHeight + "px)",
transition: "2s linear"
},
2000,
function() {
$self
.css({
transform: "translateY(0)",
transition: "2s linear"
})
.find(".card:nth-child(1)")
.appendTo($self);
}
);
}
});
},
/**
*
* @param width
* @param height
*/
resize: function(width, height) {
this.updateLayout(width, height);
//更新图表
//this.chart.render({
// width: width,
// height: height
//})
},
/**
* 每个组件根据自身需要,从主题中获取颜色 覆盖到自身配置的颜色中.
* 暂时可以不填内容
*/
setColors: function() {
//比如
//var cfg = this.config;
//cfg.color = cfg.theme.series[0] || cfg.color;
},
/**
* 数据,设置和获取数据
* @param data
* @returns {*|number}
*/
data: function(data) {
if (data) {
this._data = data;
}
return this._data;
},
/**
* 更新配置
* 优先级: config.colors > config.theme > this.config.theme > this.config.colors
* [注] 有数组的配置一定要替换
* @param config
* @private
*/
mergeConfig: function(config) {
if (!config) {
return this.config;
}
this.config.theme = _.defaultsDeep(config.theme || {}, this.config.theme);
this.setColors();
this.config = _.defaultsDeep(config || {}, this.config);
return this.config;
},
/**
* 更新布局
* 可有可无
*/
updateLayout: function() {},
/**
* 更新样式
* 有些子组件控制不到的,但是需要控制改变的,在这里实现
*/
updateStyle: function() {
var cfg = this.config;
var card = cfg.options.card;
var keys = Object.keys(card);
keys = keys.filter(item => item !== "margin");
keys.forEach(function(name) {
// console.log(name);
var element = name === "act" ? card[name].text : card[name];
// console.log(element);
var tdom = $("." + name);
if (element.show) {
if (name === "icon") {
tdom.css({
width: element.size.width,
height: element.size.height,
position: "relative",
top: element.position.top,
left: element.position.left
});
return;
} else if (["title", "status"].indexOf(name) > -1) {
tdom.css({
display: "inline-flex"
});
} else {
tdom.css({
display: "flex"
});
}
if (name === "act") {
var item = card[name].suffix;
$(".act-icon").css({
display: "flex",
"align-items": "center"
});
$(".act-icon img").css({
width: item.size.width ? item.size.width : undefined,
height: item.size.height,
position: "relative",
top: item.position.top,
left: item.position.left
});
}
tdom.css({
"font-size": element.textStyle.fontSize,
"font-family": element.textStyle.fontFamily,
"font-weight": element.textStyle.fontWeight,
color: element.textStyle.color,
"justify-content": element.align,
"align-items": "center",
width: element.size.width ? element.size.width : undefined,
height: element.size.height,
position: "relative",
top: element.position.top,
left: element.position.left,
overflow: "hidden",
"text-overflow": "ellipsis",
"white-space": "nowrap"
});
} else {
tdom.css({
display: "none"
});
}
});
$(".title-row").css({
display: "flex",
"justify-content": "space-between",
"align-items": "center"
});
// console.log(card);
$(".card").css(
card.color.type === "flat"
? {
background: card.color.value
}
: {
background:
"linear-gradient(" +
card.color.value.angle +
"deg, " +
card.color.value.stops[0].color +
", " +
card.color.value.stops[1].color +
")"
}
);
$(".card").css({
width: "auto",
height: "auto",
// border: "2px solid #000",
"border-color": card.border.borderColor,
"border-width": card.border.borderWidth,
"border-style": card.border.lineStyle,
"border-radius": card.border.borderRadius,
// background: "rgba(0, 0, 0, 0.5)",
"margin-top": card.margin.top,
"margin-right": card.margin.right,
"margin-bottom": card.margin.bottom,
"margin-left": card.margin.left
});
// console.log(cfg);
var zone = cfg.options.zone;
$(".zone").css({
display: "flex",
"flex-direction": zone.direction,
position: "absolute",
top: zone.position.top,
left: zone.position.left,
// width: "100%",
width: zone.size.width,
height: zone.size.height,
overflow: "hidden"
});
// $(".datav-com,.datav-wraper").css({
// width: zone.size.width,
// height: zone.size.height,
// overflow: "hidden"
// });
// $(".-datav-transform-tool").css({
// width: zone.size.width + 24,
// height: zone.size.height + 24
// });
// this.container.css({
// "font-size": cfg.size,
// color: cfg.color || "#fff"
// });
},
/**
* 更新配置
* !!注意:如果render支持第二个参数options, 那updateOptions不是必须的
*/
//updateOptions: function (options) {},
/**
* 更新某些配置
* 给可以增量更新配置的组件用
*/
//updateXXX: function () {},
/**
* 销毁组件
*/
destroy: function() {
console.log("请实现 destroy 方法");
}
}
);
发布组件
您可通过以下三种方式发布组件:
- 方式一(推荐)进入组件的目录地址下,执行datav publish命令,组件将自动打包压缩发布至账号所在域的服务器。
- 方式二进入组件的目录地址下,执行datav package命令,在组件目录外会有一个以
组件-版本号
命名的tar.gz压缩包,将此压缩包上传到datav.aliyun.com的组件页,即可发布。- 创建组件包
- 方法三进入预览组件页面下的发布页面,单击发布,即可发布组件。
踩坑
问题:datav init 一直报错,
网上搜,说是gulp和node版本不一致
问题:组件上传不上去
字面意思是上传超限,实际是命名空间不对应导致;
组件包英文名:iwhalecloud-poc
package.json里也要对应上
so datav publish
问题:使用datav login命令,让输入UID和token
问题:哪里设置视频自动播放呢?
文档中关于设置视频自动播放的方法不再有用了
https://gov-mod-asset-zb.oss-cn-zhangjiakou.aliyuncs.com/video/dapindi.mp4
问题:跨域问题,页面打不开
code: EBADCSRFTOKEN,
message: invalid csrf token,
rid: undefined
Chrome 中打开 chrome://flags/#same-site-by-default-cookies 和 chrome://flags/#cookies-without-same-site-must-be-secure ,设置为 Disabled,重启浏览器