commit
b6745cff19
15 changed files with 44035 additions and 0 deletions
@ -0,0 +1,21 @@ |
|||||||
|
MIT License |
||||||
|
|
||||||
|
Copyright (c) 2019 AstronautOO7 |
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
of this software and associated documentation files (the "Software"), to deal |
||||||
|
in the Software without restriction, including without limitation the rights |
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
copies of the Software, and to permit persons to whom the Software is |
||||||
|
furnished to do so, subject to the following conditions: |
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all |
||||||
|
copies or substantial portions of the Software. |
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||||
|
SOFTWARE. |
@ -0,0 +1,7 @@ |
|||||||
|
# bi-plugin-boxline |
||||||
|
|
||||||
|
- npm install |
||||||
|
- 在 providers 中添加 provider |
||||||
|
- 修改 config.js 中的配置 |
||||||
|
- npm run build |
||||||
|
- 将打包好的文件放到 bi 插件 |
@ -0,0 +1,284 @@ |
|||||||
|
(function (factory) { |
||||||
|
typeof define === 'function' && define.amd ? define(factory) : |
||||||
|
factory(); |
||||||
|
}(function () { 'use strict'; |
||||||
|
|
||||||
|
function expanderProvider() { |
||||||
|
this.render = function () { |
||||||
|
var self = this; |
||||||
|
return { |
||||||
|
type: "bi.vertical", |
||||||
|
items: [{ |
||||||
|
type: "bi.multi_select_item", |
||||||
|
selected: BI.bind(getAttr, this)(), |
||||||
|
value: "设置项1", |
||||||
|
height: 16, |
||||||
|
handler: function () { |
||||||
|
BI.bind(setAttr, self)(this.isSelected()); |
||||||
|
} |
||||||
|
}], |
||||||
|
vgap: 10, |
||||||
|
hgap: 15 |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
function getAttr() { |
||||||
|
var attr = this.getInjectAttr(); |
||||||
|
return attr["testAttr"]; |
||||||
|
} |
||||||
|
|
||||||
|
function setAttr(value) { |
||||||
|
this.setInjectAttr("testAttr", value); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function chartDisplayProvider() { |
||||||
|
function formatData(data) { |
||||||
|
var header = data.header; |
||||||
|
var items = data.items; |
||||||
|
var dataGroup = {}, |
||||||
|
dimId, |
||||||
|
seriesName, |
||||||
|
targetId; |
||||||
|
BI.each(header, function(i, header) { |
||||||
|
if (!dimId && BI.Utils.isDimDimensionById(header.dId)) { |
||||||
|
dimId = header.dId; |
||||||
|
seriesName = header.text; |
||||||
|
} |
||||||
|
if (!targetId && BI.Utils.isTargetById(header.dId)) { |
||||||
|
targetId = header.dId; |
||||||
|
} |
||||||
|
}); |
||||||
|
BI.each(items, function(i, row) { |
||||||
|
var key, value; |
||||||
|
BI.each(row, function(idx, cell) { |
||||||
|
if (cell.dId === dimId) { |
||||||
|
key = cell.value; |
||||||
|
} |
||||||
|
if (cell.dId === targetId) { |
||||||
|
value = cell.value; |
||||||
|
} |
||||||
|
}); |
||||||
|
key = key || "0"; |
||||||
|
dataGroup[key] = dataGroup[key] || []; |
||||||
|
dataGroup[key].push(BI.parseFloat(value)); |
||||||
|
}); |
||||||
|
return { |
||||||
|
dataGroup: dataGroup, |
||||||
|
seriesName: seriesName |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
this.render = function(el, d) { |
||||||
|
var self = this; |
||||||
|
console.log(d); |
||||||
|
var result = formatData(d), |
||||||
|
series = []; |
||||||
|
var data = BI.map(result.dataGroup, function(i, item) { |
||||||
|
return item; |
||||||
|
}); |
||||||
|
var axisData = BI.keys(result.dataGroup); |
||||||
|
var preData = echarts.dataTool.prepareBoxplotData(data); |
||||||
|
var boxData = []; |
||||||
|
var lineData = []; |
||||||
|
BI.each(preData.boxData, function(i, item) { |
||||||
|
boxData.push({ |
||||||
|
name: axisData[i], |
||||||
|
value: item |
||||||
|
}); |
||||||
|
lineData.push(item[2]); |
||||||
|
}); |
||||||
|
var boxPlotSeries = { |
||||||
|
name: result.seriesName, |
||||||
|
type: "boxplot", |
||||||
|
data: boxData, |
||||||
|
tooltip: { |
||||||
|
formatter: function(param) { |
||||||
|
return [ |
||||||
|
"Experiment " + param.name + ": ", |
||||||
|
"upper: " + param.data[5], |
||||||
|
"Q3: " + param.data[4], |
||||||
|
"median: " + param.data[3], |
||||||
|
"Q1: " + param.data[2], |
||||||
|
"lower: " + param.data[1] |
||||||
|
].join("<br/>"); |
||||||
|
} |
||||||
|
}, |
||||||
|
emphasis: { |
||||||
|
itemStyle: { |
||||||
|
color: "rgba(134, 180, 230)" |
||||||
|
} |
||||||
|
}, |
||||||
|
itemStyle: { |
||||||
|
color: "rgba(134, 180, 230)", |
||||||
|
borderWidth: 2 |
||||||
|
} |
||||||
|
}; |
||||||
|
var lineSeries = { |
||||||
|
type: "line", |
||||||
|
data: lineData, |
||||||
|
zlevel: 1, |
||||||
|
itemStyle: { |
||||||
|
color: "rgb(224, 178, 60)" |
||||||
|
}, |
||||||
|
lineStyle: { |
||||||
|
width: 3 |
||||||
|
} |
||||||
|
}; |
||||||
|
var series = [boxPlotSeries, lineSeries]; |
||||||
|
|
||||||
|
// 切换图表的时候 创建过的实例不会创建,先dispose
|
||||||
|
echarts.dispose(el); |
||||||
|
this.chart = echarts.init(el); |
||||||
|
|
||||||
|
var options = { |
||||||
|
color: ["#61a0a8"], |
||||||
|
title: [ |
||||||
|
{ |
||||||
|
text: "upper: Q3 + 1.5 * IQR \nlower: Q1 - 1.5 * IQR", |
||||||
|
borderColor: "#999", |
||||||
|
borderWidth: 1, |
||||||
|
textStyle: { |
||||||
|
fontSize: 14 |
||||||
|
}, |
||||||
|
left: "10%", |
||||||
|
top: "90%" |
||||||
|
} |
||||||
|
], |
||||||
|
tooltip: { |
||||||
|
trigger: "item", |
||||||
|
axisPointer: { |
||||||
|
type: "shadow" |
||||||
|
} |
||||||
|
}, |
||||||
|
grid: { |
||||||
|
left: "10%", |
||||||
|
right: "10%", |
||||||
|
bottom: "15%" |
||||||
|
}, |
||||||
|
xAxis: { |
||||||
|
type: "category", |
||||||
|
data: axisData, |
||||||
|
boundaryGap: true, |
||||||
|
nameGap: 30, |
||||||
|
axisTick: { |
||||||
|
show: false |
||||||
|
}, |
||||||
|
splitArea: { |
||||||
|
show: false |
||||||
|
}, |
||||||
|
axisLabel: { |
||||||
|
formatter: "{value}" |
||||||
|
}, |
||||||
|
splitLine: { |
||||||
|
show: false |
||||||
|
} |
||||||
|
}, |
||||||
|
yAxis: { |
||||||
|
type: "value", |
||||||
|
name: "", |
||||||
|
axisLine: { |
||||||
|
show: false |
||||||
|
}, |
||||||
|
axisTick: { |
||||||
|
show: false |
||||||
|
}, |
||||||
|
splitArea: { |
||||||
|
show: false |
||||||
|
}, |
||||||
|
splitLine: { |
||||||
|
show: true |
||||||
|
} |
||||||
|
}, |
||||||
|
series: series |
||||||
|
}; |
||||||
|
this.chart.setOption(options); |
||||||
|
|
||||||
|
// var pointPara = {
|
||||||
|
// row: {
|
||||||
|
// "点击的点的维度id": "维度值",
|
||||||
|
// "点击的点的维度1id": "维度值",
|
||||||
|
// "点击的点的指标id": "指标值",
|
||||||
|
// "点击的点的指标2id": "指标值"
|
||||||
|
// },
|
||||||
|
// metaData: [{id: "维度字段id"}, {id: "指标字段id"}],
|
||||||
|
// pos: {x: 12, y:24} // 相对位置
|
||||||
|
// };
|
||||||
|
|
||||||
|
// var dimensionPara = {
|
||||||
|
// dId: "String",
|
||||||
|
// value: [{dId: string, text: ""}]
|
||||||
|
// };
|
||||||
|
// 触发联动 钻取
|
||||||
|
// this.pointTrigger();
|
||||||
|
// 触发维度联动
|
||||||
|
// this.dimensionTrigger(dimensionPara);
|
||||||
|
this.chart.on("click", function(para) { |
||||||
|
var pointPara = { |
||||||
|
pos: { |
||||||
|
x: para.event.offsetX, |
||||||
|
y: para.event.offsetY |
||||||
|
}, |
||||||
|
metaData: [ |
||||||
|
{ |
||||||
|
id: para.data.name |
||||||
|
} |
||||||
|
], |
||||||
|
row: {} |
||||||
|
}; |
||||||
|
pointPara.row[para.data.name] = 1; |
||||||
|
self.pointTrigger(pointPara); |
||||||
|
}); |
||||||
|
|
||||||
|
// echarts找到 横轴上维度点击的事件,但箱线图横轴维度点击不了,如果可以应该按如下写法
|
||||||
|
// this.chart.on("dimensionClick", function () {
|
||||||
|
// var dimensionPara = {
|
||||||
|
// dId: "String",
|
||||||
|
// value: [{dId: string, text: ""}]
|
||||||
|
// };
|
||||||
|
// self.dimensionTrigger(dimensionPara);
|
||||||
|
// })
|
||||||
|
}; |
||||||
|
|
||||||
|
this.resize = function(width, height) { |
||||||
|
this.chart && |
||||||
|
this.chart.resize({ |
||||||
|
width: width, |
||||||
|
height: height |
||||||
|
}); |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
BI.provider("bi.provider.share.chart", chartDisplayProvider); |
||||||
|
BI.provider("bi.provider.share.expander", expanderProvider); |
||||||
|
|
||||||
|
BI.config("bi.provider.chart", function(provider) { |
||||||
|
provider.inject({ |
||||||
|
type: "boxplot", |
||||||
|
text: "箱线图", |
||||||
|
cls: "chart-type-boxplot-column-icon", |
||||||
|
disabledCls: "chart-type-boxplot-column-disabled-icon", |
||||||
|
resultType: BICst.DESIGN.WIDGET.DETAIL, |
||||||
|
providers: { |
||||||
|
chartProvider: { |
||||||
|
// 自己注册的provider
|
||||||
|
type: "bi.provider.share.chart" |
||||||
|
} |
||||||
|
}, |
||||||
|
expanders: [ |
||||||
|
{ |
||||||
|
type: "bi.provider.share.expander", |
||||||
|
text: "xxx设置", |
||||||
|
value: "attr1" |
||||||
|
} |
||||||
|
], |
||||||
|
required: [ |
||||||
|
{ |
||||||
|
dimension: ">=1", |
||||||
|
measure: ">=1" |
||||||
|
} |
||||||
|
] |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
})); |
@ -0,0 +1,21 @@ |
|||||||
|
.chart-type-boxplot-column-icon .x-icon { |
||||||
|
display: block; |
||||||
|
background: url("/app/decision/resources?path=/com/finebi/plugin/web/image/boxplot.png") |
||||||
|
no-repeat center center; |
||||||
|
background-size: contain; |
||||||
|
} |
||||||
|
.chart-type-boxplot-column-icon .x-icon.hack { |
||||||
|
background: url("/app/decision/resources?path=/com/finebi/plugin/web/image/boxplot.png") |
||||||
|
no-repeat center center; |
||||||
|
} |
||||||
|
|
||||||
|
.chart-type-boxplot-column-disabled-icon .x-icon { |
||||||
|
display: block; |
||||||
|
background: url("/app/decision/resources?path=/com/finebi/plugin/web/image/disable.png") |
||||||
|
no-repeat center center; |
||||||
|
background-size: contain; |
||||||
|
} |
||||||
|
.chart-type-boxplot-column-disabled-icon .x-icon.hack { |
||||||
|
background: url("/app/decision/resources?path=/com/finebi/plugin/web/image/disable.png") |
||||||
|
no-repeat center center; |
||||||
|
} |
File diff suppressed because one or more lines are too long
@ -0,0 +1,229 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one |
||||||
|
* or more contributor license agreements. See the NOTICE file |
||||||
|
* distributed with this work for additional information |
||||||
|
* regarding copyright ownership. The ASF licenses this file |
||||||
|
* to you under the Apache License, Version 2.0 (the |
||||||
|
* "License"); you may not use this file except in compliance |
||||||
|
* with the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, |
||||||
|
* software distributed under the License is distributed on an |
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
||||||
|
* KIND, either express or implied. See the License for the |
||||||
|
* specific language governing permissions and limitations |
||||||
|
* under the License. |
||||||
|
*/ |
||||||
|
|
||||||
|
!(function(e, t) { |
||||||
|
"object" == typeof exports && "undefined" != typeof module |
||||||
|
? t(exports, require("echarts")) |
||||||
|
: "function" == typeof define && define.amd |
||||||
|
? define(["exports", "echarts"], t) |
||||||
|
: t((e.dataTool = {}), e.echarts); |
||||||
|
})(this, function(e, t) { |
||||||
|
"use strict"; |
||||||
|
function r(e, t, r) { |
||||||
|
if (e && t) { |
||||||
|
if (e.map && e.map === c) return e.map(t, r); |
||||||
|
for (var a = [], n = 0, o = e.length; n < o; n++) |
||||||
|
a.push(t.call(r, e[n], n, e)); |
||||||
|
return a; |
||||||
|
} |
||||||
|
} |
||||||
|
function a(e) { |
||||||
|
return e |
||||||
|
? r(u(e, "attribute"), function(e) { |
||||||
|
return { |
||||||
|
id: i(e, "id"), |
||||||
|
title: i(e, "title"), |
||||||
|
type: i(e, "type") |
||||||
|
}; |
||||||
|
}) |
||||||
|
: []; |
||||||
|
} |
||||||
|
function n(e, t) { |
||||||
|
return e |
||||||
|
? r(u(e, "node"), function(e) { |
||||||
|
var r = { |
||||||
|
id: i(e, "id"), |
||||||
|
name: i(e, "label"), |
||||||
|
itemStyle: { normal: {} } |
||||||
|
}, |
||||||
|
a = l(e, "viz:size"), |
||||||
|
n = l(e, "viz:position"), |
||||||
|
o = l(e, "viz:color"), |
||||||
|
s = l(e, "attvalues"); |
||||||
|
if ( |
||||||
|
(a && (r.symbolSize = parseFloat(i(a, "value"))), |
||||||
|
n && |
||||||
|
((r.x = parseFloat(i(n, "x"))), |
||||||
|
(r.y = parseFloat(i(n, "y")))), |
||||||
|
o && |
||||||
|
(r.itemStyle.normal.color = |
||||||
|
"rgb(" + |
||||||
|
[ |
||||||
|
0 | i(o, "r"), |
||||||
|
0 | i(o, "g"), |
||||||
|
0 | i(o, "b") |
||||||
|
].join(",") + |
||||||
|
")"), |
||||||
|
s) |
||||||
|
) { |
||||||
|
var f = u(s, "attvalue"); |
||||||
|
r.attributes = {}; |
||||||
|
for (var c = 0; c < f.length; c++) { |
||||||
|
var p = f[c], |
||||||
|
d = i(p, "for"), |
||||||
|
v = i(p, "value"), |
||||||
|
g = t[d]; |
||||||
|
if (g) { |
||||||
|
switch (g.type) { |
||||||
|
case "integer": |
||||||
|
case "long": |
||||||
|
v = parseInt(v, 10); |
||||||
|
break; |
||||||
|
case "float": |
||||||
|
case "double": |
||||||
|
v = parseFloat(v); |
||||||
|
break; |
||||||
|
case "boolean": |
||||||
|
v = "true" == v.toLowerCase(); |
||||||
|
} |
||||||
|
r.attributes[d] = v; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return r; |
||||||
|
}) |
||||||
|
: []; |
||||||
|
} |
||||||
|
function o(e) { |
||||||
|
return e |
||||||
|
? r(u(e, "edge"), function(e) { |
||||||
|
var t = { |
||||||
|
id: i(e, "id"), |
||||||
|
name: i(e, "label"), |
||||||
|
source: i(e, "source"), |
||||||
|
target: i(e, "target"), |
||||||
|
lineStyle: { normal: {} } |
||||||
|
}, |
||||||
|
r = t.lineStyle.normal, |
||||||
|
a = l(e, "viz:thickness"), |
||||||
|
n = l(e, "viz:color"); |
||||||
|
return ( |
||||||
|
a && (r.width = parseFloat(a.getAttribute("value"))), |
||||||
|
n && |
||||||
|
(r.color = |
||||||
|
"rgb(" + |
||||||
|
[ |
||||||
|
0 | i(n, "r"), |
||||||
|
0 | i(n, "g"), |
||||||
|
0 | i(n, "b") |
||||||
|
].join(",") + |
||||||
|
")"), |
||||||
|
t |
||||||
|
); |
||||||
|
}) |
||||||
|
: []; |
||||||
|
} |
||||||
|
function i(e, t) { |
||||||
|
return e.getAttribute(t); |
||||||
|
} |
||||||
|
function l(e, t) { |
||||||
|
for (var r = e.firstChild; r; ) { |
||||||
|
if (1 == r.nodeType && r.nodeName.toLowerCase() == t.toLowerCase()) |
||||||
|
return r; |
||||||
|
r = r.nextSibling; |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
function u(e, t) { |
||||||
|
for (var r = e.firstChild, a = []; r; ) |
||||||
|
r.nodeName.toLowerCase() == t.toLowerCase() && a.push(r), |
||||||
|
(r = r.nextSibling); |
||||||
|
return a; |
||||||
|
} |
||||||
|
function s(e) { |
||||||
|
return ( |
||||||
|
e.sort(function(e, t) { |
||||||
|
return e - t; |
||||||
|
}), |
||||||
|
e |
||||||
|
); |
||||||
|
} |
||||||
|
function f(e, t) { |
||||||
|
var r = (e.length - 1) * t + 1, |
||||||
|
a = Math.floor(r), |
||||||
|
n = +e[a - 1], |
||||||
|
o = r - a; |
||||||
|
return o ? n + o * (e[a] - n) : n; |
||||||
|
} |
||||||
|
var c = Array.prototype.map, |
||||||
|
p = (Object.freeze || Object)({ |
||||||
|
parse: function(e) { |
||||||
|
var t; |
||||||
|
if ( |
||||||
|
!(t = |
||||||
|
"string" == typeof e |
||||||
|
? new DOMParser().parseFromString(e, "text/xml") |
||||||
|
: e) || |
||||||
|
t.getElementsByTagName("parsererror").length |
||||||
|
) |
||||||
|
return null; |
||||||
|
var r = l(t, "gexf"); |
||||||
|
if (!r) return null; |
||||||
|
for ( |
||||||
|
var i = l(r, "graph"), |
||||||
|
u = a(l(i, "attributes")), |
||||||
|
s = {}, |
||||||
|
f = 0; |
||||||
|
f < u.length; |
||||||
|
f++ |
||||||
|
) |
||||||
|
s[u[f].id] = u[f]; |
||||||
|
return { nodes: n(l(i, "nodes"), s), links: o(l(i, "edges")) }; |
||||||
|
} |
||||||
|
}), |
||||||
|
d = function(e, t) { |
||||||
|
for ( |
||||||
|
var r = [], |
||||||
|
a = [], |
||||||
|
n = [], |
||||||
|
o = (t = t || []).boundIQR, |
||||||
|
i = "none" === o || 0 === o, |
||||||
|
l = 0; |
||||||
|
l < e.length; |
||||||
|
l++ |
||||||
|
) { |
||||||
|
n.push(l + ""); |
||||||
|
var u = s(e[l].slice()), |
||||||
|
c = f(u, 0.25), |
||||||
|
p = f(u, 0.5), |
||||||
|
d = f(u, 0.75), |
||||||
|
v = u[0], |
||||||
|
g = u[u.length - 1], |
||||||
|
h = (null == o ? 1.5 : o) * (d - c), |
||||||
|
b = i ? v : Math.max(v, c - h), |
||||||
|
m = i ? g : Math.min(g, d + h); |
||||||
|
r.push([b, c, p, d, m]); |
||||||
|
for (var y = 0; y < u.length; y++) { |
||||||
|
var x = u[y]; |
||||||
|
if (x < b || x > m) { |
||||||
|
var w = [l, x]; |
||||||
|
"vertical" === t.layout && w.reverse(), a.push(w); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return { boxData: r, outliers: a, axisData: n }; |
||||||
|
}; |
||||||
|
t.dataTool && |
||||||
|
((t.dataTool.version = "1.0.0"), |
||||||
|
(t.dataTool.gexf = p), |
||||||
|
(t.dataTool.prepareBoxplotData = d)), |
||||||
|
(e.version = "1.0.0"), |
||||||
|
(e.gexf = p), |
||||||
|
(e.prepareBoxplotData = d); |
||||||
|
}); |
@ -0,0 +1,39 @@ |
|||||||
|
module.exports = function(grunt) { |
||||||
|
// Project configuration.
|
||||||
|
grunt.initConfig({ |
||||||
|
pkg: grunt.file.readJSON("package.json"), |
||||||
|
concat: { |
||||||
|
options: { |
||||||
|
separator: "" |
||||||
|
}, |
||||||
|
chartJs: { |
||||||
|
src: [ |
||||||
|
"dist/boxline.chart.js", |
||||||
|
"dist/echarts.js", |
||||||
|
"dist/data.tool.js" |
||||||
|
], |
||||||
|
dest: "dist/chart.js" |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
uglify: { |
||||||
|
options: { |
||||||
|
banner: |
||||||
|
'/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd HH:MM:ss") %> */\n' |
||||||
|
}, |
||||||
|
docs: { |
||||||
|
files: { |
||||||
|
"dist/chart.min.js": [ |
||||||
|
"dist/boxline.chart.js", |
||||||
|
"dist/echarts.js", |
||||||
|
"dist/data.tool.js" |
||||||
|
] |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
grunt.loadNpmTasks("grunt-contrib-uglify"); |
||||||
|
grunt.loadNpmTasks("grunt-contrib-concat"); |
||||||
|
grunt.registerTask("default", ["concat", "uglify"]); |
||||||
|
}; |
@ -0,0 +1,12 @@ |
|||||||
|
<!DOCTYPE html> |
||||||
|
<html lang="en"> |
||||||
|
<head> |
||||||
|
<meta charset="UTF-8" /> |
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
||||||
|
<meta http-equiv="X-UA-Compatible" content="ie=edge" /> |
||||||
|
<title>plugin</title> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<script type="text/javascript" src="./dist/boxline.chart.js"></script> |
||||||
|
</body> |
||||||
|
</html> |
@ -0,0 +1,23 @@ |
|||||||
|
{ |
||||||
|
"name": "bi-plugin-boxline", |
||||||
|
"version": "1.0.0", |
||||||
|
"description": "", |
||||||
|
"main": "rollup.config.js", |
||||||
|
"scripts": { |
||||||
|
"test": "echo \"Error: no test specified\" && exit 1", |
||||||
|
"start": "rollup -c -w", |
||||||
|
"build": "rollup src/main.js --file dist/boxline.chart.js --format umd --name chart && grunt" |
||||||
|
}, |
||||||
|
"keywords": [ |
||||||
|
"boxline" |
||||||
|
], |
||||||
|
"author": "imp", |
||||||
|
"license": "ISC", |
||||||
|
"devDependencies": { |
||||||
|
"grunt": "^1.0.4", |
||||||
|
"grunt-contrib-concat": "^1.0.1", |
||||||
|
"grunt-contrib-uglify": "^1.0.1", |
||||||
|
"rollup": "^1.20.3", |
||||||
|
"rollup-plugin-live-server": "^1.0.3" |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,21 @@ |
|||||||
|
const liveServer = require("rollup-plugin-live-server"); |
||||||
|
|
||||||
|
export default { |
||||||
|
input: "src/main.js", |
||||||
|
output: { |
||||||
|
file: "dist/boxline.chart.js", |
||||||
|
format: "umd", |
||||||
|
name: "chart" |
||||||
|
}, |
||||||
|
plugins: [ |
||||||
|
liveServer({ |
||||||
|
port: 8001, |
||||||
|
host: "0.0.0.0", |
||||||
|
root: "demo", |
||||||
|
file: "index.html", |
||||||
|
mount: [["/dist", "./dist"], ["/index.html", "./index.html"]], |
||||||
|
open: false, |
||||||
|
wait: 500 |
||||||
|
}) |
||||||
|
] |
||||||
|
}; |
@ -0,0 +1,34 @@ |
|||||||
|
import { expanderProvider } from "./providers/expander.provider.js"; |
||||||
|
import { chartDisplayProvider } from "./providers/chartDisplay.provider.js"; |
||||||
|
|
||||||
|
BI.provider("bi.provider.share.chart", chartDisplayProvider); |
||||||
|
BI.provider("bi.provider.share.expander", expanderProvider); |
||||||
|
|
||||||
|
BI.config("bi.provider.chart", function(provider) { |
||||||
|
provider.inject({ |
||||||
|
type: "boxplot", |
||||||
|
text: "箱线图", |
||||||
|
cls: "chart-type-boxplot-column-icon", |
||||||
|
disabledCls: "chart-type-boxplot-column-disabled-icon", |
||||||
|
resultType: BICst.DESIGN.WIDGET.DETAIL, |
||||||
|
providers: { |
||||||
|
chartProvider: { |
||||||
|
// 自己注册的provider
|
||||||
|
type: "bi.provider.share.chart" |
||||||
|
} |
||||||
|
}, |
||||||
|
expanders: [ |
||||||
|
{ |
||||||
|
type: "bi.provider.share.expander", |
||||||
|
text: "xxx设置", |
||||||
|
value: "attr1" |
||||||
|
} |
||||||
|
], |
||||||
|
required: [ |
||||||
|
{ |
||||||
|
dimension: ">=1", |
||||||
|
measure: ">=1" |
||||||
|
} |
||||||
|
] |
||||||
|
}); |
||||||
|
}); |
@ -0,0 +1,216 @@ |
|||||||
|
export function chartDisplayProvider() { |
||||||
|
function formatData(data) { |
||||||
|
var header = data.header; |
||||||
|
var items = data.items; |
||||||
|
var dataGroup = {}, |
||||||
|
dimId, |
||||||
|
seriesName, |
||||||
|
targetId; |
||||||
|
BI.each(header, function(i, header) { |
||||||
|
if (!dimId && BI.Utils.isDimDimensionById(header.dId)) { |
||||||
|
dimId = header.dId; |
||||||
|
seriesName = header.text; |
||||||
|
} |
||||||
|
if (!targetId && BI.Utils.isTargetById(header.dId)) { |
||||||
|
targetId = header.dId; |
||||||
|
} |
||||||
|
}); |
||||||
|
BI.each(items, function(i, row) { |
||||||
|
var key, value, dId; |
||||||
|
BI.each(row, function(idx, cell) { |
||||||
|
if (cell.dId === dimId) { |
||||||
|
key = cell.value; |
||||||
|
} |
||||||
|
if (cell.dId === targetId) { |
||||||
|
value = cell.value; |
||||||
|
} |
||||||
|
}); |
||||||
|
key = key || "0"; |
||||||
|
dataGroup[key] = dataGroup[key] || []; |
||||||
|
dataGroup[key].push(BI.parseFloat(value)); |
||||||
|
}); |
||||||
|
return { |
||||||
|
dataGroup: dataGroup, |
||||||
|
seriesName: seriesName |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
this.render = function(el, d) { |
||||||
|
var self = this; |
||||||
|
console.log(d); |
||||||
|
var result = formatData(d), |
||||||
|
series = []; |
||||||
|
var data = BI.map(result.dataGroup, function(i, item) { |
||||||
|
return item; |
||||||
|
}); |
||||||
|
var axisData = BI.keys(result.dataGroup); |
||||||
|
var preData = echarts.dataTool.prepareBoxplotData(data); |
||||||
|
var boxData = []; |
||||||
|
var lineData = []; |
||||||
|
BI.each(preData.boxData, function(i, item) { |
||||||
|
boxData.push({ |
||||||
|
name: axisData[i], |
||||||
|
value: item |
||||||
|
}); |
||||||
|
lineData.push(item[2]); |
||||||
|
}); |
||||||
|
var boxPlotSeries = { |
||||||
|
name: result.seriesName, |
||||||
|
type: "boxplot", |
||||||
|
data: boxData, |
||||||
|
tooltip: { |
||||||
|
formatter: function(param) { |
||||||
|
return [ |
||||||
|
"Experiment " + param.name + ": ", |
||||||
|
"upper: " + param.data[5], |
||||||
|
"Q3: " + param.data[4], |
||||||
|
"median: " + param.data[3], |
||||||
|
"Q1: " + param.data[2], |
||||||
|
"lower: " + param.data[1] |
||||||
|
].join("<br/>"); |
||||||
|
} |
||||||
|
}, |
||||||
|
emphasis: { |
||||||
|
itemStyle: { |
||||||
|
color: "rgba(134, 180, 230)" |
||||||
|
} |
||||||
|
}, |
||||||
|
itemStyle: { |
||||||
|
color: "rgba(134, 180, 230)", |
||||||
|
borderWidth: 2 |
||||||
|
} |
||||||
|
}; |
||||||
|
var lineSeries = { |
||||||
|
type: "line", |
||||||
|
data: lineData, |
||||||
|
zlevel: 1, |
||||||
|
itemStyle: { |
||||||
|
color: "rgb(224, 178, 60)" |
||||||
|
}, |
||||||
|
lineStyle: { |
||||||
|
width: 3 |
||||||
|
} |
||||||
|
}; |
||||||
|
var series = [boxPlotSeries, lineSeries]; |
||||||
|
|
||||||
|
// 切换图表的时候 创建过的实例不会创建,先dispose
|
||||||
|
echarts.dispose(el); |
||||||
|
this.chart = echarts.init(el); |
||||||
|
|
||||||
|
var options = { |
||||||
|
color: ["#61a0a8"], |
||||||
|
title: [ |
||||||
|
{ |
||||||
|
text: "upper: Q3 + 1.5 * IQR \nlower: Q1 - 1.5 * IQR", |
||||||
|
borderColor: "#999", |
||||||
|
borderWidth: 1, |
||||||
|
textStyle: { |
||||||
|
fontSize: 14 |
||||||
|
}, |
||||||
|
left: "10%", |
||||||
|
top: "90%" |
||||||
|
} |
||||||
|
], |
||||||
|
tooltip: { |
||||||
|
trigger: "item", |
||||||
|
axisPointer: { |
||||||
|
type: "shadow" |
||||||
|
} |
||||||
|
}, |
||||||
|
grid: { |
||||||
|
left: "10%", |
||||||
|
right: "10%", |
||||||
|
bottom: "15%" |
||||||
|
}, |
||||||
|
xAxis: { |
||||||
|
type: "category", |
||||||
|
data: axisData, |
||||||
|
boundaryGap: true, |
||||||
|
nameGap: 30, |
||||||
|
axisTick: { |
||||||
|
show: false |
||||||
|
}, |
||||||
|
splitArea: { |
||||||
|
show: false |
||||||
|
}, |
||||||
|
axisLabel: { |
||||||
|
formatter: "{value}" |
||||||
|
}, |
||||||
|
splitLine: { |
||||||
|
show: false |
||||||
|
} |
||||||
|
}, |
||||||
|
yAxis: { |
||||||
|
type: "value", |
||||||
|
name: "", |
||||||
|
axisLine: { |
||||||
|
show: false |
||||||
|
}, |
||||||
|
axisTick: { |
||||||
|
show: false |
||||||
|
}, |
||||||
|
splitArea: { |
||||||
|
show: false |
||||||
|
}, |
||||||
|
splitLine: { |
||||||
|
show: true |
||||||
|
} |
||||||
|
}, |
||||||
|
series: series |
||||||
|
}; |
||||||
|
this.chart.setOption(options); |
||||||
|
|
||||||
|
// var pointPara = {
|
||||||
|
// row: {
|
||||||
|
// "点击的点的维度id": "维度值",
|
||||||
|
// "点击的点的维度1id": "维度值",
|
||||||
|
// "点击的点的指标id": "指标值",
|
||||||
|
// "点击的点的指标2id": "指标值"
|
||||||
|
// },
|
||||||
|
// metaData: [{id: "维度字段id"}, {id: "指标字段id"}],
|
||||||
|
// pos: {x: 12, y:24} // 相对位置
|
||||||
|
// };
|
||||||
|
|
||||||
|
// var dimensionPara = {
|
||||||
|
// dId: "String",
|
||||||
|
// value: [{dId: string, text: ""}]
|
||||||
|
// };
|
||||||
|
// 触发联动 钻取
|
||||||
|
// this.pointTrigger();
|
||||||
|
// 触发维度联动
|
||||||
|
// this.dimensionTrigger(dimensionPara);
|
||||||
|
this.chart.on("click", function(para) { |
||||||
|
var pointPara = { |
||||||
|
pos: { |
||||||
|
x: para.event.offsetX, |
||||||
|
y: para.event.offsetY |
||||||
|
}, |
||||||
|
metaData: [ |
||||||
|
{ |
||||||
|
id: para.data.name |
||||||
|
} |
||||||
|
], |
||||||
|
row: {} |
||||||
|
}; |
||||||
|
pointPara.row[para.data.name] = 1; |
||||||
|
self.pointTrigger(pointPara); |
||||||
|
}); |
||||||
|
|
||||||
|
// echarts找到 横轴上维度点击的事件,但箱线图横轴维度点击不了,如果可以应该按如下写法
|
||||||
|
// this.chart.on("dimensionClick", function () {
|
||||||
|
// var dimensionPara = {
|
||||||
|
// dId: "String",
|
||||||
|
// value: [{dId: string, text: ""}]
|
||||||
|
// };
|
||||||
|
// self.dimensionTrigger(dimensionPara);
|
||||||
|
// })
|
||||||
|
}; |
||||||
|
|
||||||
|
this.resize = function(width, height) { |
||||||
|
this.chart && |
||||||
|
this.chart.resize({ |
||||||
|
width: width, |
||||||
|
height: height |
||||||
|
}); |
||||||
|
}; |
||||||
|
} |
@ -0,0 +1,28 @@ |
|||||||
|
export function expanderProvider() { |
||||||
|
this.render = function () { |
||||||
|
var self = this; |
||||||
|
return { |
||||||
|
type: "bi.vertical", |
||||||
|
items: [{ |
||||||
|
type: "bi.multi_select_item", |
||||||
|
selected: BI.bind(getAttr, this)(), |
||||||
|
value: "设置项1", |
||||||
|
height: 16, |
||||||
|
handler: function () { |
||||||
|
BI.bind(setAttr, self)(this.isSelected()); |
||||||
|
} |
||||||
|
}], |
||||||
|
vgap: 10, |
||||||
|
hgap: 15 |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
function getAttr() { |
||||||
|
var attr = this.getInjectAttr(); |
||||||
|
return attr["testAttr"]; |
||||||
|
} |
||||||
|
|
||||||
|
function setAttr(value) { |
||||||
|
this.setInjectAttr("testAttr", value); |
||||||
|
} |
||||||
|
}; |
Loading…
Reference in new issue