每个组件包括ExampleModel.js和ExampleModel.js以及index.js三个文件,在index.js通过D3Charts.registerComponent方法进行注册。
组件创建步骤
- 在
src/chart或src/component目录下新建文件夹,如src/chart/example; - 每个图表/组件至少包含两个文件(
ExampleModel.js和index.js,如有视图需要渲染则还需要ExampleView.js),在src/chart/example目录下新建三个js文件,分别命名为ExampleModel.js、ExampleView.js以及index.js; - 首先编写
src/chart/example/ExampleModel.js;- 图表类型继承
src/model/Series,组件类型继承src/model/Component; - 同时为静态属性和实例属性添加
type属性,同图表/组件类型名称; - 如有需要为图表/组件Model添加
update方法,用于绘图数据准备计算; - 通过设置
ExampleModel的defaultOption属性为图表/组件添加默认参数,或直接用static声明为静态属性;
- 图表类型继承
- 然后编写
src/chart/exampleExampleView.js;- 图表类型继承
src/view/Chart,组件类型继承src/view/Component; - 同时为静态属性和实例属性添加
type属性,同图表/组件类型名称以及对应Model的type属性; - 如有需要为图表/组件View添加
render方法,用于数据更新后的视图渲染; - 建议使用继承自
src/util/ShapeStorage的setShape和setShapeGroup方法创建相关shape,详见方法注释; - 有View必须有对应的Model,Model不一定需要View;
- 图表类型继承
- 再在
src/chart/example/index.js中进行图表/组件Model和View的注册,通过registerComponent方法; - 最后在
src/index.js中引用该图表/组件模块, 对应的调用页面见demo/examplechart.html;
内部创建组件示例
index.js
import TitleView from './TitleView';
import TitleModel from './TitleModel';
import { registerComponent } from '../../d3charts';
registerComponent(TitleModel, TitleView);TitleModel.js
import ComponentModel from '../../model/Component';
import { parsePercent } from '../../util';
export const TYPE = 'title';
export default class TitleModel extends ComponentModel {
static type = TYPE;
type = TYPE;
static defaultOption = {
zlevel: 0,
z: 0,
show: true, // {Boolean} 是否显示
// 显示位置
left: '50%', // {String | Number} 左
top: '5%', // {String | Number} 上
link: false, // {String} 标题文本超链接。
target: 'blank', // {String} 指定窗口打开主标题超链接。
style: { // 文本样式
normal: {
textAlign: 'center',
textVerticalAlign: 'center',
fill: '#333',
fontStyle: 'normal',
fontWeight: 'normal',
fontFamily: 'sans-serif',
fontSize: 18
},
emphasis: {
}
}
};
update() {
let { _option: { left, top, show }, global } = this;
let globalWidth = global.getWidth();
let globalHeight = global.getHeight();
this.show = show;
if (show) {
this.left = parsePercent(left, globalWidth);
this.top = parsePercent(top, globalHeight);
}
}
}TitleView.js
import ComponentView from '../../view/Component';
import { TYPE } from './TitleModel';
import { Text, setHoverStyle } from "../../util/graphic";
import { merge } from "../../util";
export default class TitleView extends ComponentView {
static type = TYPE;
type = TYPE;
render(model, globalModel) {
let { left, top, show } = model;
if (show) {
let data = model.getData();
let text = model.get('text') || (data && data.text || data);
let link = model.get('link');
let target = model.get('target');
let style = model.get('style');
let rotation = model.get('rotation');
this.setShape('title', Text, globalModel.getFormattedText({
position: [left, top],
style: {
text,
...style.normal
},
rechHover: true,
rotation
}), undefined, function (shape) {
setHoverStyle(shape, globalModel.getFormattedText(merge(style.emphasis, style.normal)));
if (link) {
shape.on('click', function () {
window.open(link, '_' + model.get('target'));
})
}
});
}
}
}外部创建组件示例
var chart = D3Charts.init('zr');
var type = 'new';
function NewModel() {
NewModel.superClass.apply(this, arguments);
this.type = type;
};
D3Charts.util.inherits(NewModel, D3Charts.ComponentModel);
NewModel.type = type;
NewModel.defaultOption = {
number: 1,
left: 200,
top: 200
};
NewModel.prototype.update = function () {
console.log('update');
}
function NewView() {
NewView.superClass.apply(this, arguments);
this.type = type;
}
D3Charts.util.inherits(NewView, D3Charts.ComponentView);
NewView.type = type;
NewView.prototype.render = function (model) {
let number = model.get('number');
let left = model.get('left');
let top = model.get('top');
this.setShape('customText', D3Charts.graphic.Text, {
style: {
x: left,
y: top + 50,
text: number,
textFill: '#6ac',
textVerticalAlign: 'center',
textAlign: 'center',
fontSize: 20
}
}, undefined);
this.setShape('plus', D3Charts.graphic.Circle, {
shape: {
cx: left,
cy: top,
r: 20
},
style: {
text: '+',
stroke: '#55a',
fill: 'white',
textVerticalAlign: 'center',
textAlign: 'center',
fontSize: 20
}
}, undefined, function (shape) {
shape.on('click', function () {
model.set('number', model.get('number') + 1);
});
D3Charts.graphic.setHoverStyle(shape, {
lineWidth: 2
});
});
this.setShape('mins', D3Charts.graphic.Circle, {
shape: {
cx: left + 50,
cy: top,
r: 20
},
style: {
text: '-',
stroke: '#55a',
fill: 'white',
textVerticalAlign: 'center',
textAlign: 'center',
fontSize: 20
}
}, undefined, function (shape) {
shape.on('click', function () {
model.set('number', model.get('number') - 1);
});
D3Charts.graphic.setHoverStyle(shape, {
lineWidth: 2
});
});
}
D3Charts.registerComponent(NewModel, NewView);
chart.setOption({
new: [
{
}
]
})