diff --git a/frame.js b/frame.js
index fe1586d0..974c0f98 100644
--- a/frame.js
+++ b/frame.js
@@ -53,7 +53,7 @@ Volcanos("onappend", {
var option = can.page.Select(can, field, "form.option")[0];
var action = can.page.Select(can, field, "div.action")[0];
var output = can.page.Select(can, field, "div.output")[0];
- var feature = JSON.parse(meta.feature||"{}")||{}
+ var feature = can.base.Obj(meta.feature)
// 添加插件
if (Volcanos.meta.follow[can._root]) { debugger }
@@ -64,7 +64,8 @@ Volcanos("onappend", {
}, field);
// 添加控件
- can.core.Next(typeof meta.inputs == "string"? JSON.parse(meta.inputs||"[]"): meta.inputs || [], function(item, next) {
+ var args = can.base.Obj(meta.args, [])
+ can.core.Next(can.base.Obj(meta.inputs, []), function(item, next, index) {
sub[item.name] = Volcanos(item.name, { _help: item.name,
_target: can.onappend.input(sub, option, item.type, item),
_option: option, _action: action, _output: output,
@@ -95,15 +96,16 @@ Volcanos("onappend", {
if (silent) { typeof cb == "function" && cb(msg); return }
// 添加组件
- var display = msg.Option("display")||feature.display||"plugin/table"
+ var display = "plugin/"+(msg.Option("_display")||feature.display||"table.js")
sub[display] = Volcanos(display, { _target: output,
_option: option, _action: action, _output: output,
- }, Config.libs.concat([display]), function(table) {
+ }, Config.libs.concat(["frame.js", display]), function(table) {
table.onimport._init(table, msg, msg.append||[], function() {
}, output)
// 组件回调
table.run = function(event, cmds, cb, silent) {
+ cmds[0] == "field"? sub.run(event, cmds.slice(1), cb, silent):
input.run(event, cmds, cb, silent)
}
})
@@ -116,6 +118,11 @@ Volcanos("onappend", {
value(event, input);
})
}), next();
+
+ // 自动执行
+ if (item.type == "button" && item.action == "auto") {
+ input._target.click()
+ }
})
})
}); cb(sub);
@@ -134,8 +141,8 @@ Volcanos("onappend", {
return ui.item.Meta = item, ui.item
},
field: function(can, target, type, item) { var dataset = {}; item && item.name && (dataset.names = item.name);
- item.help = typeof item.help == "string" && item.help.startsWith("[") && (item.help = JSON.parse(item.help)[0]) || item.help || ""
- var field = can.page.Append(can, target, [{view: [(item.name||"")+" "+(type||"")+" "+(item.pos||""), "fieldset"], list: [
+ item.help = typeof item.help == "string" && item.help.startsWith("[") && (item.help = can.base.Obj(item.help, [""])[0]) || item.help || ""
+ var field = can.page.Append(can, target, [{view: [(type||"")+" "+(item.name||"")+" "+(item.pos||""), "fieldset"], list: [
item.pos? undefined: {text: [(item.nick||item.name||"")+"("+(item.help||"")+")", "legend"]},
{view: ["option", "form"], dataset: dataset, list: []},
{view: ["action"]}, {view: ["output"]}, {view: ["status"]},
@@ -175,11 +182,12 @@ Volcanos("onappend", {
break
}
- item.value == "auto" && (item.value = "", input.dataset.action = "auto")
+ item.value == "auto" && (item.value = "")
var target = can.page.Append(can, option, [{view: ["item "+item.type], list: [item.position && {text: item.name+": "}, input]}]).last
item.figure && item.figure.indexOf("@") == 0 && (item.figure = item.figure.slice(1)) && can.require(["plugin/input/"+item.figure], function() {
target.type != "button" && (target.value = "")
})
+ item.action == "auto" && (input.dataset.action = "auto")
item.type == "textarea" && can.page.Append(can, option, [{type: "br"}]);
item.type == "text" && !target.placeholder && (target.placeholder = item.name || "");
@@ -188,6 +196,15 @@ Volcanos("onappend", {
item.type == "select" && (target.value = item.value || item.values[item.index||0]);
return target;
},
+ table: function(can, target, type, msg, cb) {
+ var table = can.page.AppendTable(can, can._output, msg, msg.append, function(event, value, key, index, tr, td) {
+ can.page.Select(can, can._option, "input.args", function(input) { if (input.name == key) { var data = input.dataset || {}
+ input.value = value; if (data.action == "auto") {
+ can.run(event, [], function(msg) {})
+ }
+ } })
+ })
+ }
}, [], function(can) {})
Volcanos("onlayout", {
_init: function(can, meta, list, cb, target) {
diff --git a/index.js b/index.js
index 10157c9f..f4ad81b5 100644
--- a/index.js
+++ b/index.js
@@ -9,10 +9,11 @@ var Config = {name: "demo", volcano: "frame.js", iceberg: "/chat/", intshell: "p
{type: "pane", name: "Footer", help: "状态条", pos: "foot", list: ["pane/Footer.js", "pane/Footer.css"]},
], main: {name: "Header", engine: "remote", list: []},
list: ["plugin/state.js", "plugin/input.js", "plugin/table.js",
- "plugin/input/key.js",
- "plugin/input/date.js",
- "plugin/input/upload.js",
- "plugin/input/province.js",
+ "plugin/input/key",
+ "plugin/input/date",
+ "plugin/input/upload",
+ "plugin/input/province",
+ "publish/order.js",
],
}
@@ -23,7 +24,7 @@ var Preload = Config.libs; Config.panes.forEach(function(pane) {
Volcanos(Config.name, { _target: document.body,
_head: document.head, _body: document.body,
_width: window.innerWidth, _height: window.innerHeight,
-}, Preload.concat(Config.volcano, "publish/order.js"), function(can) { // 程序入口
+}, Preload.concat(Config.volcano), function(can) { // 程序入口
can.onimport._init(can, can.Conf(Config), [], function(msg) {
console.log(can._root, can._name, "start", can, msg);
can.Footer.onaction._init(can.Footer, msg);
diff --git a/lib/core.js b/lib/core.js
index c5106bff..bd2c3d7a 100644
--- a/lib/core.js
+++ b/lib/core.js
@@ -46,12 +46,12 @@ Volcanos("core", {help: "核心模块",
return list
}),
Next: shy("迭代器", function(obj, cb, cbs) {obj = typeof obj == "string"? [obj]: (obj || [])
- function next(list, cb) {
+ function next(list, cb, index) {
list && list.length > 0? typeof cb == "function" && cb(list[0], function() {
- list.length > 0 && next(list.slice(1), cb)
- }): typeof cbs == "function" && cbs()
+ list.length > 0 && next(list.slice(1), cb, index+1)
+ }, index): typeof cbs == "function" && cbs()
}
- next(obj, cb)
+ next(obj, cb, 0)
}),
Trim: shy("迭代器", function(obj) {
for (var i = obj.length; i >= 0; i--) {
diff --git a/plugin/local/mall/input.js b/plugin/local/mall/input.js
new file mode 100644
index 00000000..0aae3a62
--- /dev/null
+++ b/plugin/local/mall/input.js
@@ -0,0 +1,39 @@
+Volcanos("onimport", {help: "导入数据", list: [],
+ _init: function(can, feature, output, action, option) {
+ function passcode(event) {
+ can.Run(event, [], function(msg) {
+ can.page.Appends(can, output, [{type: "img", src: "data:image/jpg;base64,"+msg.image[0], onclick: function(event) {
+ var p = can.page.Append(can, output, [{view: ["what", "div"], dataset: {meta: ""+(event.offsetX+1)+","+(event.offsetY-30+1)+""}, style: {
+ background: "red", position: "absolute", width: "20px", height: "20px",
+ left: event.offsetX+1+"px", top: event.offsetY+30+1+"px",
+ }, onclick: function(event) {
+ p.parentNode.removeChild(p)
+ }}]).what
+ }}])
+ }, true)
+ }
+
+ can.page.Append(can, option, [
+ {button: ["刷新", passcode]},
+ {username: ["账号", "args"]}, {password: ["密码", "args"]},
+ {button: ["登录", function(event) {
+ var point = can.page.Select(can, output, "div.what", function(item) {return item.dataset.meta}).join(",")
+ point == ""? can.page.toast("请点击图片"): can.Run(event, ["check", point], function(msg) {
+ if (msg.result_code == "4") {
+ var input = can.page.Select(can, option, "input.args", function(item) {return item.value})
+ can.Run(event, ["login"].concat(input).concat([msg.cmds[4]]), function(msg) {
+ can.page.toast(msg.result_message[0])
+ })
+ } else {
+ passcode(event)
+ }
+ }, true)
+ }]},
+ ])
+ },
+})
+Volcanos("onaction", {help: "控件交互", list: []})
+Volcanos("onchoice", {help: "控件菜单", list: []})
+Volcanos("ondetail", {help: "控件详情", list: []})
+Volcanos("onexport", {help: "导出数据", list: []})
+
diff --git a/plugin/local/team/plan.css b/plugin/local/team/plan.css
new file mode 100644
index 00000000..a4932772
--- /dev/null
+++ b/plugin/local/team/plan.css
@@ -0,0 +1,22 @@
+fieldset.item.plan div.output td {
+ vertical-align:top;
+}
+fieldset.item.plan div.output td.over {
+ border:solid 2px red;
+}
+
+fieldset.item.plan div.output div.task.finish {
+ color:red;
+}
+fieldset.item.plan div.output div.task.finish:hover {
+ color:white;
+}
+fieldset.item.plan div.output div.task.process {
+ color:green;
+}
+fieldset.item.plan div.output div.task.process:hover {
+ color:white;
+}
+fieldset.item.plan div.output div.task.cancel {
+ color:yellow;
+}
diff --git a/plugin/local/team/plan.js b/plugin/local/team/plan.js
new file mode 100644
index 00000000..a51cc40b
--- /dev/null
+++ b/plugin/local/team/plan.js
@@ -0,0 +1,129 @@
+Volcanos("onimport", {help: "导入数据", list: [],
+ init: function(can, msg, cb, output, action, option) {output.innerHTML = "";
+ var table = can.page.AppendTable(can, output, msg, msg.append);
+ table.onclick = function(event) {switch (event.target.tagName) {
+ case "SPAN":
+ case "TD":
+ var input = can.user.input(event, can, ["zone", "type", "name", "text"], function(event, value, data) {
+ switch (value) {
+ case "提交":
+ // 创建任务
+ can.run(event, ["action", "insert", data.zone, data.type, data.name, data.text, "begin_time", can.base.Time()], function(msg) {
+ can.page.Remove(can, input.first)
+ can.user.toast("添加成功")
+ can.Runs(event)
+ return true
+ }, true)
+ break
+ case "关闭": return true;
+ }
+ })
+ break
+ case "TH":
+ break
+ case "TR":
+ case "TABLE":
+ }}
+
+ table.oncontextmenu = function(event) {var target = event.target;
+ switch (event.target.tagName) {
+ case "DIV":
+ // 任务操作
+ var data = target.dataset;
+ can.user.carte(event, shy("", can.ondetail, can.feature.detail || can.ondetail.list, function(event, cmd, meta) {var cb = meta[cmd];
+ typeof cb == "function"? cb(event, can, msg, data.id, data.zone, cmd, target):
+ can.run(event, ["action", typeof cb == "string"? cb: cmd, data.id, data.zone], function(msg) {
+ can.user.toast("修改成功")
+ }, true)
+ }))
+ event.stopPropagation()
+ event.preventDefault()
+ break
+ case "TD":
+ break
+ case "TH":
+ case "TR":
+ case "TABLE":
+ }
+ }
+
+ can.page.Select(can, table, "div.task", function(item) {
+ // 拖动排期
+ item.setAttribute("draggable", true)
+ item.ondragstart = function(event) {can.drag = event.target}
+ item.ondragover = function(event) {event.preventDefault()}
+ item.ondrop = function(event) {event.preventDefault()
+ can.preview.insertBefore(can.drag, item)
+ }
+ })
+
+ can.page.Select(can, table, "tr", function(tr) {tr.list = [];
+ can.page.Select(can, tr, "td", function(item, index) {tr.list.push(item);
+ item.ondragover = function(event) {event.preventDefault(), can.page.Select(can, table, "td.over", function(item) {
+ can.page.ClassList.del(can, item, "over")
+ }), can.page.ClassList.add(can, item, "over")}
+
+ item.ondrop = function(event) {event.preventDefault()
+ item.append(can.drag)
+
+ // 任务排期
+ var data = can.drag.dataset;
+ var begin_time = new Date(data.begin_time);
+
+ switch (can.Option("scale")) {
+ case "long":
+ begin_time.setYear(parseInt(tr.list[0].innerText));
+ break
+ case "year":
+ begin_time.setMonth(parseInt(tr.list[0].innerText)-1);
+ break
+ case "month":
+ can.page.Select(can, item, "span", function(item) {var data = item.dataset
+ begin_time.setYear(parseInt(data.year))
+ begin_time.setMonth(parseInt(data.month)-1)
+ begin_time.setDate(parseInt(data.day))
+ })
+ break
+ case "week":
+ begin_time.setDate(begin_time.getDate() - (begin_time.getDay() - index + 1))
+ case "day":
+ begin_time.setHours(parseInt(tr.list[0].innerText));
+ begin_time.setMinutes(0);
+ begin_time.setSeconds(0);
+ }
+
+ can.run(event, ["action", "modify", "begin_time", can.base.Time(begin_time), data.begin_time, data.id, data.zone], function(msg) {
+ can.user.toast("修改成功")
+ }, true);
+ }
+ })
+ })
+
+ return typeof cb == "function" && cb(msg), table;
+ },
+ which: function(event, table, list, cb) {if (event.target == table) {return cb(-1, "")}
+ can.page.Select(can, table, "tr", function(tr, index) {if (event.target == tr) {return cb(index-1, "")}
+ can.page.Select(can, tr, "th,td", function(td, order) {
+ if (event.target == td) {return cb(index-1, list[order])}
+ })
+ })
+ },
+}, ["plugin/local/team/plan.css"])
+Volcanos("onaction", {help: "组件交互", list: []})
+Volcanos("onchoice", {help: "组件菜单", list: ["返回", "清空"],
+ "返回": function(event, can, msg, cmd, target) {
+ can.run(event, ["", "Last"])
+ },
+ "清空": function(event, can, msg, cmd, target) {
+ can.target.innerHTML = "";
+ },
+})
+Volcanos("ondetail", {help: "组件详情", list: ["开始", "完成", "取消"],
+ "开始": "process",
+ "完成": "finish",
+ "取消": "cancel",
+})
+Volcanos("onexport", {help: "导出数据", list: []})
+
+
+
diff --git a/plugin/local/wiki/data.js b/plugin/local/wiki/data.js
new file mode 100644
index 00000000..72731fa7
--- /dev/null
+++ b/plugin/local/wiki/data.js
@@ -0,0 +1,149 @@
+Volcanos("onimport", {help: "导入数据", list: [],
+ init: function(can, msg, cb, output, action, option) {output.innerHTML = "";
+ can.table = can.page.AppendTable(can, output, msg, msg.append, function(event, value, key, index, tr, td) {
+ can.Export(event, value, key)
+ }, function(event, value, key, index, tr, td) {
+ can.user.carte(event, shy("上下文菜单", can.ondetail, can.ondetail.list, function(event, cmd, meta) {var cb = meta[cmd];
+ var sub = can.Event(event);
+ msg.append.forEach(function(key) {sub.Option(key, msg[key][index].trim())})
+
+ typeof cb == "function"? cb(event, can, msg, index, key, cmd, td, tr):
+ (cb = can.onchoice[cmd], typeof cb == "function")? cb(event, can, msg, index, key, cmd, td, tr):
+ (cb = can.onaction[cmd], typeof cb == "function")? cb(event, can, msg, index, key, cmd, td, tr):
+ can.run(event, ["action", typeof cb == "string"? cb: cmd, key, value.trim(), msg.Ids(index)], function(msg) {
+ can.user.toast(msg.Result())
+ }, true)
+ }))
+ });
+ },
+})
+Volcanos("onfigure", {help: "组件菜单", list: ["保存", "求和"],
+ "求和": function(event, can, res, td, index) {
+ res[index] = parseInt(td.innerText) + (res[index]||0);
+ },
+ "最大": function(event, can, res, td, index) {
+ var n = parseInt(td.innerText);
+ n > (res[index]||-10000) && (res[index] = n);
+ },
+ "最小": function(event, can, res, td, index) {
+ var n = parseInt(td.innerText);
+ n < (res[index]||10000) && (res[index] = n);
+ },
+ "平均": function(event, can, res, td, ncol, cols, rows, nrow) {
+ res[ncol] = parseInt(td.innerText) + (res[ncol]||0);
+ if (nrow == rows.length - 1) {
+ res[ncol] = res[ncol] / nrow
+ }
+ },
+})
+Volcanos("onaction", {help: "组件菜单", list: ["保存", ["mode", "正常", "块选", "反选", "多选", "拖动", "编辑"], "求和", "最大", "最小", "平均"],
+ "保存": function(event, can, msg, cmd, target) {
+ can.run(event, ["action", cmd, can.Option("path"), can.Export(event, "", "file")], function(msg) {
+ can.user.toast("保存成功")
+ }, true)
+ },
+ "正常": function(event, can, msg, cmd, target) {
+ cmd && can.Action("mode", cmd)
+ can.page.Select(can, can.table, "tr", function(item) {
+ item.setAttribute("contenteditable", false)
+ item.setAttribute("draggable", false)
+ item.onmouseenter = null
+ item.onclick = null
+ })
+ },
+ "块选": function(event, can, msg, cmd, target) {
+ cmd && can.Action("mode", cmd)
+ can.page.Select(can, can.table, "tr", function(item) {
+ item.onmouseenter = function() {
+ can.page.ClassList.add(can, item, "select")
+ }
+ })
+ },
+ "反选": function(event, can, msg, cmd, target) {
+ cmd && can.Action("mode", cmd)
+ can.page.Select(can, can.table, "tr", function(item) {
+ item.onmouseenter = function() {
+ can.page.ClassList.del(can, item, "select")
+ }
+ })
+ },
+ "多选": function(event, can, msg, cmd, target) {
+ cmd && can.Action("mode", cmd)
+ can.page.Select(can, can.table, "tr", function(item) {
+ item.onclick = function() {
+ can.page.ClassList.neg(can, item, "select")
+ }
+ })
+ },
+ "拖动": function(event, can, msg, cmd, target) {
+ can.onaction["正常"](event, can, msg, cmd, target)
+ can.page.Select(can, can.table, "tr", function(item) {
+ item.setAttribute("draggable", true)
+ item.ondragstart = function(event) {can.drag = item}
+ item.ondragover = function(event) {
+ event.preventDefault(),
+ can.page.ClassList.add(can, item, "over")}
+ item.ondragleave = function(event) {
+ can.page.ClassList.del(can, item, "over")
+ }
+ item.ondrop = function(event) {event.preventDefault()
+ can.table.insertBefore(can.drag, item)
+ }
+ })
+ },
+ "编辑": function(event, can, msg, cmd, target) {
+ cmd && can.Action("mode", cmd)
+ can.page.Select(can, can.table, "tr", function(item) {
+ item.setAttribute("contenteditable", true)
+ })
+ },
+
+ show: function(event, can, msg, cmd, target) {
+ var res = {};
+ var method = can.onfigure[cmd];
+ var mul = "tr" + (can.Action("mode") == "正常"? "": ".select");
+
+
+ can.page.Select(can, can.table, mul, function(tr, nrow, rows) {
+ (mul != "tr" || nrow > 0) && can.page.Select(can, tr, "td", function(td, ncol, cols) {
+ method && method(event, can, res, td, ncol, cols, rows, nrow)
+ })
+ });
+ can.page.Append(can, can.target, [{type: "table", list: [{type: "tr", list: can.core.Item(res, function(key, value) {
+ return {text: [value, "td"]}
+ }).concat([{text: [cmd, "td"]}])}]}]);
+ },
+ "求和": function(event, can, msg, cmd, target) {
+ can.onaction.show(event, can, msg, cmd, target)
+ },
+ "最大": function(event, can, msg, cmd, target) {
+ can.onaction.show(event, can, msg, cmd, target)
+ },
+ "最小": function(event, can, msg, cmd, target) {
+ can.onaction.show(event, can, msg, cmd, target)
+ },
+ "平均": function(event, can, msg, cmd, target) {
+ can.onaction.show(event, can, msg, cmd, target)
+ },
+})
+Volcanos("onchoice", {help: "组件交互", list: ["保存", "块选", "反选", "求和"]})
+Volcanos("ondetail", {help: "组件详情", list: ["复制", "块选", "反选", "编辑", "删除"],
+ "复制": function(event, can, msg, index, key, cmd, td, tr) {
+ var end = can.page.Append(can, can.table, [{type: "tr", list: can.page.Select(can, tr, "td", function(item) {
+ return {text: [item.innerHTML, "td"]}
+ })}]).tr
+ can.table.insertBefore(end, tr)
+ },
+ "删除": function(event, can, msg, index, key, cmd, td, tr) {
+ can.page.Remove(can, tr)
+ },
+})
+Volcanos("onstatus", {help: "组件状态", list: []})
+Volcanos("onexport", {help: "导出数据", list: [],
+ file: function(event, can, csv, cmd, target) {
+ return can.page.Select(can, target, "tr", function(tr) {
+ return can.page.Select(can, tr, "th,td", function(td) {return td.innerHTML}).join(",")
+ }).join("\n")
+ },
+})
+
diff --git a/plugin/local/wiki/draw.css b/plugin/local/wiki/draw.css
new file mode 100644
index 00000000..31a75bdb
--- /dev/null
+++ b/plugin/local/wiki/draw.css
@@ -0,0 +1,34 @@
+
+fieldset.item>div.output>div.status>div {
+ float:left;
+ height:20px;
+ border:1px solid black;
+}
+fieldset.item>div.output>div.status>input.cmd {
+ float:left;
+ background-color:black;
+ color:lightgreen;;
+ font-size:16px;
+ width:250px;
+}
+fieldset.item>div.output>div.action>button.trap {
+ background-color:lightblue;
+ border:2px blue solid;
+}
+fieldset.item>div.output>div.action>div.space {
+ width:10px;
+ display:inline-block;
+}
+fieldset.item>div.output>canvas {
+ background-color:#8dd09e;
+}
+fieldset table tr.hidden {
+ display:none;
+}
+fieldset table th.order {
+ background-color:red;
+ cursor:pointer;
+}
+fieldset table td.clip {
+ background-color:red;
+}
diff --git a/plugin/local/wiki/draw.js b/plugin/local/wiki/draw.js
new file mode 100644
index 00000000..b858ebf9
--- /dev/null
+++ b/plugin/local/wiki/draw.js
@@ -0,0 +1,921 @@
+Volcanos("onimport", {help: "导入数据", list: [],
+ _start: function(can) {
+ var def = {
+ "font-size": "24",
+ "stroke-width": 2,
+ "stroke": "yellow",
+ "fill": "purple",
+ "grid": "10",
+ }
+ // 默认参数
+ can.core.Item(def, function(key, value) {
+ can.svg.Value(key, can.Action(key, can.svg.Value(key)||value))
+ })
+ can.Action("mode", "select")
+ can.Action("mode", "draw")
+ can.Action("shape", "path")
+ },
+ init: function(can, msg, cb, output, action, option) {output.innerHTML = "";
+ if (msg.Option("_display") == "table") {
+ // 文件目录
+ can.page.AppendTable(can, output, msg, msg.append, function(event, value, key, index, tr, td) {
+ can.Export(event, value, key)
+ })
+ return typeof cb == "function" && cb(msg);
+ }
+
+ // 交互数据
+ can.point = [], can.keys = []
+ can.current = null, can.temp = null
+ can.group = null, can.svg = null
+ can.last = null
+
+ // 加载绘图
+ var code = can.page.AppendBoard(can, output, msg.Result()||can.Export(event, null, "file"))
+ can.page.Select(can, output, "svg", function(svg) {
+ // 画布
+ can.onaction.init(event, can, msg, "init", svg);
+ can.group = can.svg = svg;
+
+ var list = can.core.List(can.onaction.list, function(item, index) {if (item[0] == "group") {
+ // 清空分组
+ return can.onaction.list[index] = ["group", "svg"]
+ }})[0]
+
+ can.page.Select(can, svg, "*", function(item, index) {
+ // 元素
+ can.onaction.init(event, can, msg, index, item);
+ item.tagName == "g" && item.Value("class") != "" && list.push(item.Value("class"));
+ })
+ })
+
+ return typeof cb == "function" && cb(msg);
+ },
+ draw: function(event, can, value) {
+ var figure = can.onfigure[value.shape]
+ var data = figure.draw(event, can, value.point, value.style)
+ can.core.Item(value.style, function(key, value) {data[key] = value})
+ return can.onaction.push(event, can, data, value.shape, can.group||can.svg)
+ },
+ escape: function(event, can, value) {
+ can.point = can.point.slice(0, -1)
+ },
+ keydown: function(event, can, value) {
+ if (["Control", "Shift", "Meta", "Alt"].indexOf(value) > -1 ) {return}
+ can.keys.push((event.ctrlKey? "C-": "") + (event.shiftKey? value.toUpperCase(): value))
+
+ var list = {
+ a: {prefix: ["mode", "mode"],
+ w: {list: ["draw"]},
+ m: {list: ["move"]},
+ r: {list: ["resize"]},
+ s: {list: ["select"]},
+ d: {list: ["delete"]},
+ },
+ s: {prefix: ["shape", "shape"],
+ r: {list: ["rect"]},
+ c: {list: ["circle"]},
+ e: {list: ["ecllipse"]},
+ t: {list: ["text"]},
+ l: {list: ["line"]},
+ },
+ c: {prefix: ["stroke", "stroke"],
+ r: {list: ["red"]},
+ b: {list: ["blue"]},
+ g: {list: ["green"]},
+ y: {list: ["yellow"]},
+ p: {list: ["purple"]},
+ c: {list: ["cyan"]},
+ h: {list: ["black"]},
+ w: {list: ["white"]},
+ },
+ f: {prefix: ["fill", "fill"],
+ r: {list: ["red"]},
+ b: {list: ["blue"]},
+ g: {list: ["green"]},
+ y: {list: ["yellow"]},
+ p: {list: ["purple"]},
+ c: {list: ["cyan"]},
+ h: {list: ["black"]},
+ w: {list: ["white"]},
+ },
+ }
+
+ var prefix = []
+ can.core.List(can.keys, function(key) {
+ if (!list) {
+ // 查找失败
+ return can.keys = [], can.Status(event, can.keys, "keys")
+ }
+
+ // 查找递进
+ prefix = prefix.concat(can.core.List(list.prefix))
+ list = list[key]
+ })
+
+ if (!list || !list.list) {
+ // 等待输入
+ return can.Status(event, can.keys+"("+can.core.Item(list).join(",")+")", "keys")
+ }
+
+ function call(cmds) {
+ cmds && can.onaction[cmds[0]] && can.onaction[cmds[0]].apply(can, [event, can].concat(cmds.slice(1)))
+ }
+
+ // 执行命令
+ call(prefix.concat(list.list))
+ return can.keys = [], can.Status(event, can.keys, "keys")
+ },
+}, ["plugin/local/wiki/draw.css"])
+Volcanos("onfigure", {help: "图形绘制", list: [],
+ _spawn: function(sup, can) {can.sup = sup},
+ _swell: function(can, sub) {
+ can.sup && can.sup.action && sub.draw && can.page.Select(can, can.sup.action, "select.shape", function(shape) {
+ can.page.Append(can, shape, [{text: [sub._name, "option"]}])
+ })
+ },
+ svg: {
+ data: {
+ size: {},
+ }, //
+ show: function(event, can, value, target) {
+ return can.svg.Val("width") +","+ can.svg.Val("width")
+ },
+ },
+ rect: {
+ data: {
+ rx: 4, ry: 4,
+ size: {x: "x", y: "y"},
+ copy: ["width", "height", "rx", "ry"],
+ }, //
+ draw: function(event, can, point) {if (point.length < 2) {return}
+ var p0 = point[0], p1 = point[1];
+ var data = {
+ "x": p0.x > p1.x? p1.x: p0.x,
+ "y": p0.y > p1.y? p1.y: p0.y,
+ "width": Math.abs(p0.x-p1.x),
+ "height": Math.abs(p0.y-p1.y),
+ "rx": this.data.rx,
+ "ry": this.data.ry,
+ }
+ return event.type == "click" && point.length == 2 && (can.point = []), data;
+ },
+ text: function(event, can, data, target) {
+ data.x = target.Val("x")+target.Val("width")/2
+ data.y = target.Val("y")+target.Val("height")/2
+ return data
+ },
+ show: function(event, can, value, target) {
+ return ": (" + value.Val("x") + "," + value.Val("y") + ")"
+ + " + (" + value.Val("width") + "," + value.Val("height") + ")"
+ },
+ },
+ circle: {
+ data: {
+ size: {x: "cx", y: "cy", width: "r", height: "r"},
+ copy: ["r"],
+ }, //
+ draw: function(event, can, point) {if (point.length < 2) {return}
+ var p0 = point[0], p1 = point[1];
+ var data = {
+ "cx": p0.x, "cy": p0.y,
+ "r": Math.sqrt(Math.pow(p0.x-p1.x, 2)+Math.pow(p0.y-p1.y, 2)),
+ }
+ return event.type == "click" && point.length == 2 && (can.point = []), data;
+ },
+ text: function(event, can, data, target) {
+ data.x = target.Val("cx")
+ data.y = target.Val("cy")
+ return data
+ },
+ show: function(event, can, value, target) {
+ return ": (" + value.Val("cx") + "," + value.Val("cy") + ")"
+ + " > (" + parseInt(value.Val("r")) + ")"
+ },
+ },
+ ellipse: {
+ data: {
+ size: {x: "cx", y: "cy", width: "rx", height: "ry"},
+ copy: ["rx", "ry"],
+ }, //
+ draw: function(event, can, point) {if (point.length < 2) {return}
+ var p0 = point[0], p1 = point[1];
+ var data = {
+ "cx": p0.x, "cy": p0.y,
+ "rx": Math.abs(p0.x - p1.x), "ry": Math.abs(p0.y - p1.y),
+ }
+ return event.type == "click" && point.length == 2 && (can.point = []), data;
+ },
+ text: function(event, can, data, target) {
+ data.x = target.Val("cx")
+ data.y = target.Val("cy")
+ return data
+ },
+ show: function(event, can, value, target) {
+ return ": (" + value.Val("cx") + "," + value.Val("cy") + ")"
+ + " > (" + value.Val("rx") + value.Val("ry") + ")"
+ },
+ },
+ text: {
+ data: {
+ size: {x: "x", y: "y"},
+ copy: ["inner"],
+ }, // hi
+ draw: function(event, can, point, style) {if (point.length < 1 || event.type == "mousemove") {return}
+ var p0 = point[0];
+ var data = {
+ "x": p0.x, "y": p0.y,
+ "inner": style&&style.inner||can.user.prompt("text"),
+ }
+ return can.point = [], data;
+ },
+ show: function(event, can, value, target) {
+ return ": (" + target.Val("x") + "," + target.Val("y")+ ")"
+ }
+ },
+ line: {
+ data: {
+ size: {},
+ copy: ["x1", "y1", "x2", "y2"],
+ x: function(event, can, value, cmd, target) {
+ if (value != undefined) {
+ var offset = value - target.Val("xx")
+ target.Val("x1", target.Val("x1") + offset)
+ // target.Val("x2", target.Val("x2") + offset)
+ target.Val("xx", value)
+ }
+ return target.Val("xx")
+ },
+ y: function(event, can, value, cmd, target) {
+ if (value != undefined) {
+ var offset = value - target.Val("yy")
+ target.Val("y1", target.Val("y1") + offset)
+ // target.Val("y2", target.Val("y2") + offset)
+ target.Val("yy", value)
+ }
+ return target.Val("yy")
+ },
+ width: function(event, can, value, cmd, target) {
+ return value != undefined && target.Val("x2", target.Val("x1") + parseInt(value)), target.Val("x2") - target.Val("x1")
+ },
+ height: function(event, can, value, cmd, target) {
+ return value != undefined && target.Val("y2", target.Val("y1") + parseInt(value)), target.Val("y2") - target.Val("y1")
+ },
+ }, //
+ grid: function(event, can, point) {var target = event.target
+ if (event.target == can.svg) {return}
+ var pos = can.page.Prepos(event, target)
+ var p = point[point.length-1]
+ p.target = target
+ p.anchor = pos
+ target.Val && can.page.Anchor(event, target, pos, p)
+ return point
+ },
+ draw: function(event, can, point) {if (point.length < 2) {return}
+ var p0 = point[0], p1 = point[1];
+ var data = {
+ "x1": p0.x, "y1": p0.y,
+ "x2": p1.x, "y2": p1.y,
+ }
+ return event.type == "click" && point.length == 2 && (can.point = []), data;
+ },
+ text: function(event, can, data, target) {
+ data.x = (target.Val("x1") + target.Val("x2")) / 2
+ data.y = (target.Val("y1") + target.Val("y2")) / 2
+ return data
+ },
+ show: function(event, can, value, target) {
+ return ": (" + value.Val("x1") + "," + value.Val("y1") + ")"
+ + " - (" + value.Val("x2") + "," + value.Val("y2") + ")"
+ },
+ },
+ path: {
+ data: {
+ size: {},
+ x: function(event, can, value, cmd, target) {
+ var tt = JSON.parse(target.Value("tt")||'{"tx":0, "ty":0}')
+ if (value != undefined) {
+ tt.tx = value-target.Val("xx")
+ target.Value("tt", JSON.stringify(tt))
+ target.Value("transform", "translate("+tt.tx+","+tt.ty+")")
+ }
+ return target.Val("xx")+tt.tx
+ },
+ y: function(event, can, value, cmd, target) {
+ var tt = JSON.parse(target.Value("tt")||'{"tx":0, "ty":0}')
+ if (value != undefined) {
+ tt.ty = value-target.Val("yy")
+ target.Value("tt", JSON.stringify(tt))
+ target.Value("transform", "translate("+tt.tx+","+tt.ty+")")
+ }
+ return target.Val("yy")+tt.ty
+ },
+ copy: ["d", "cmd", "name", "meta", "tt", "xx", "yy", "fill"],
+ }, //
+ draw: function(event, can, point) {
+ if (point.length == 1) {
+ can._temp = {}
+ }
+ if (point.length < 2) {return}
+ if (can.keys && can.keys.length > 0) {
+ switch (can._temp[point.length-1] = can.keys[0]) {
+ case "C": can._temp[point.length+1] = ","
+ case "Q": can._temp[point.length] = ","; break
+ default:
+ }
+ can.keys = can.keys.slice(1)
+ }
+
+ var skip = 0;
+ var end = false;
+ var data = {
+ d: can.core.List(point, function(p, i) {var k = p.k
+ if (i < skip) {return}
+ switch (i) {
+ case 0: k = "M"; break
+ default: k = can._temp[i] || p.k || "L"; break
+ }
+ if (end) {return}
+
+ switch (k) {
+ case "Z": return can.point = [], can._temp = {}, k
+ case "L": return k+" " + p.x + " " + p.y
+ case "M": return k+" " + p.x + " " + p.y
+ case "H": return k+" " + p.x
+ case "V": return k+" " + p.y
+ case "A":
+ switch (point.length - i) {
+ case 1: end = true;
+ return k+" " + (point[i-1].x+p.x)/2 + " " + (point[i-1].y+p.y)/2 + " 0 0 0 " + p.x + " " + p.y
+ case 2: end = true;
+ var r = Math.sqrt(Math.pow(point[i+1].x - p.x, 2) + Math.pow(point[i+1].y - p.y, 2))
+ return k+" " + r + " " + r + " 0 0 0 " + p.x + " " + p.y
+ case 3:
+ if (!p.done) {
+ var r = Math.sqrt(Math.pow(point[i+1].x - p.x, 2) + Math.pow(point[i+1].y - p.y, 2))
+ var temp = point[i]
+ p = point[i] = point[i+1]
+ point[i+1] = temp
+ var temp = can.point[i]
+ p = can.point[i] = can.point[i+1]
+ can.point[i+1] = temp
+ p.x = r
+ p.y = r
+ p.done = true
+ p.arg = " 0 0 0 "
+ }
+ default:
+ skip = i + 2
+ return k+" " + p.x + " " + p.y + " 0 0 0 " + point[i+1].x + " " + point[i+1].y
+ }
+ break
+ case "C":
+ switch (point.length - i) {
+ case 1: end = true;
+ return k+" " + (point[i-1].x+p.x)/2 + " " + (point[i-1].y+p.y)/2 + "," + (point[i-1].x+p.x)/2 + " " + (point[i-1].y+p.y)/2 + "," + p.x + " " + p.y
+ case 2: end = true;
+ return k+" " + point[i+1].x + " " + point[i+1].y + "," + (point[i-1].x+p.x)/2 + " " + (point[i-1].y+p.y)/2 + "," + p.x + " " + p.y
+ case 3:
+ return k+" " + point[i+1].x + " " + point[i+1].y + "," + point[i+2].x + " " + point[i+2].y + "," + p.x + " " + p.y
+ case 4:
+ if (!p.done) {
+ var temp = point[i]
+ p = point[i] = point[i+1]
+ point[i+1] = temp
+
+ var temp = point[i+1]
+ point[i+1] = point[i+2]
+ point[i+2] = temp
+ p.done = true
+ }
+ default:
+ return k+" " + p.x + " " + p.y
+ }
+ case "Q":
+ switch (point.length - i) {
+ case 1: end = true;
+ return k+" " + (point[i-1].x+p.x)/2 + " " + (point[i-1].y+p.y)/2 + "," + p.x + " " + p.y
+ case 2: end = true;
+ return k+" " + point[i+1].x + " " + point[i+1].y + "," + p.x + " " + p.y
+ case 3:
+ if (!p.done) {
+ var temp = point[i]
+ p = point[i] = point[i+1]
+ point[i+1] = temp
+ p.done = true
+ }
+ default:
+ return k+" " + p.x + " " + p.y
+ }
+ default: return k+" " + p.x + " " + p.y
+ }
+ }).join(" ")
+ }
+ return data;
+ },
+ text: function(event, can, data, target) {
+ data.x = (target.x1.baseVal.value + target.x2.baseVal.value) / 2
+ data.y = (target.y1.baseVal.value + target.y2.baseVal.value) / 2
+ return data
+ },
+ show: function(event, can, value, target) {
+ return value.tagName
+ },
+ },
+
+ think: {
+ data: {
+ rx: 4, ry: 4,
+ size: {x: "x", y: "y"},
+ copy: ["width", "height", "rx", "ry"],
+ }, //
+ draw: function(event, can, point) {if (point.length < 2) {return}
+ can._temp && can.page.Remove(can, can._temp) && delete(can._temp);
+ can._temp = can.onaction.push(event, can, {}, "g", can.group||can.svg)
+ var rect = can.onaction.push(event, can, can.onfigure.rect.draw(event, can, point), "rect", can._temp)
+ if (event.type == "click" && point.length == 2) {
+ can.ondetail["标签"](event, can, {}, "", rect);
+ delete(can._temp)
+ }
+ return
+ },
+ text: function(event, can, data, target) {
+ data.x = target.Val("x")+target.Val("width")/2
+ data.y = target.Val("y")+target.Val("height")/2
+ return data
+ },
+ show: function(event, can, value, target) {
+ return ": (" + value.Val("x") + "," + value.Val("y") + ")"
+ + " + (" + value.Val("width") + "," + value.Val("height") + ")"
+ },
+ },
+ polyline: {
+ data: {}, //
+ draw: function(event, can, point) {if (point.length < 2) {return}
+ var data = {
+ points: can.core.List(point, function(item) {return item.x + " " + item.y}).join(", ")
+ }
+ return data;
+ },
+ text: function(event, can, data, target) {
+ data.x = (target.x1.baseVal.value + target.x2.baseVal.value) / 2
+ data.y = (target.y1.baseVal.value + target.y2.baseVal.value) / 2
+ return data
+ },
+ show: function(event, can, value, target) {
+ return value.tagName + ": (" + value.points.baseVal.value + ")"
+ },
+ },
+ polygon: {
+ data: {}, //
+ draw: function(event, can, point) {if (point.length < 2) {return}
+ var data = {
+ points: can.core.List(point, function(item) {return item.x + " " + item.y}).join(", ")
+ }
+ return data;
+ },
+ text: function(event, can, data, target) {
+ data.x = (target.x1.baseVal.value + target.x2.baseVal.value) / 2
+ data.y = (target.y1.baseVal.value + target.y2.baseVal.value) / 2
+ return data
+ },
+ show: function(event, can, value, target) {
+ return value.tagName + ": (" + value.points.baseVal.value + ")"
+ },
+ },
+}, Config.libs.concat(["plugin/local/wiki/draw/heart"]))
+Volcanos("onaction", {help: "组件菜单", list: ["保存", "清空", "删除", "添加",
+ ["group", "svg"],
+ ["font-size", 12, 16, 18, 24, 32],
+ ["stroke-width", 1, 2, 3, 4, 5],
+ {text: "c"}, ["stroke", "red", "yellow", "green", "purple", "blue", "cyan", "white", "black"],
+ {text: "f"}, ["fill", "red", "yellow", "green", "purple", "blue", "cyan", "white", "black", "#0000"],
+ {text: "a"}, ["go", "auto", "manual"],
+ {text: "a"}, ["mode", "draw", "move", "resize", "select", "delete"],
+ {text: "s"}, ["shape", "think", "rect", "circle", "ellipse", "text", "line", "path", "polyline", "polygon"],
+ ["grid", 1, 2, 3, 4, 5, 10, 20],
+ ],
+ "保存": function(event, can, msg, cmd, target) {
+ can.run(event, ["action", cmd, can.Option("path"), can.Export(event, can.svg, "file")], function() {
+ can.user.toast("保存成功")
+ }, true)
+ },
+ "清空": function(event, can, msg, cmd, target) {
+ can.svg.innerHTML = ""
+ can.point = []
+ can.keys = []
+ },
+ "删除": function(event, can, msg, cmd, target) {if (can.group == can.svg) {return}
+ can.page.Remove(can, can.group), can.page.Select(can, can.action, "option[value="+can.group.Value("class")+"]", function(item) {
+ can.page.Remove(can, item)
+ })
+ can.Action("group", "svg")
+ },
+ "添加": function(event, can, msg, cmd, target) {
+ can.user.prompt("add group", function(name) {
+ var group = document.createElementNS('http://www.w3.org/2000/svg', 'g');
+ can.group.append(can.onaction.init(event, can, msg, cmd, group))
+
+ can.group = group, can.group.Value("class", name)
+ can.core.List(["font-size", "stroke-width", "stroke", "fill"], function(name) {
+ can.group.Value(name, can.Action(name))
+ })
+ can.page.Select(can, can.action, "select.group", function(item) {
+ can.page.Append(can, item, [{type: "option", value: name, inner: name}]);
+ item.value = name
+ })
+ })
+ },
+
+ group: function(event, can, value, cmd, target) {
+ if (cmd == "svg") {
+ can.group = can.svg
+ } else {
+ can.page.Select(can, can.svg, "g."+cmd, function(item) {
+ can.group = item
+ })
+ }
+ can.core.List(["font-size", "storke-width", "stroke", "fill"], function(key) {
+ can.Action(key, can.group.Value(key)||can.Action(key))
+ })
+ return can.group
+ },
+ "font-size": function(event, can, value, cmd, target) {can.Action(value, can.group.Value(value, cmd))},
+ "stroke-width": function(event, can, value, cmd, target) {can.Action(value, can.group.Value(value, cmd))},
+ stroke: function(event, can, value, cmd, target) {can.Action(value, can.group.Value(value, cmd))},
+ fill: function(event, can, value, cmd, target) {can.Action(value, can.group.Value(value, cmd))},
+ shape: function(event, can, value, cmd, target) {cmd && can.Action(value, cmd)},
+ mode: function(event, can, value, cmd, target) {cmd && can.Action(value, cmd)},
+ grid: function(event, can, value, cmd, target) {cmd && can.Action(value, cmd)},
+
+ init: function(event, can, msg, cmd, item) {
+ item.Value = function(key, value) {
+ if (typeof key == "object") {
+ can.core.Item(key, function(key, value) {
+ item.Value(key, value)
+ })
+ return
+ }
+ var figure = can.onaction._get(can, item);
+ key && (key = figure && figure.data && figure.data.size && figure.data.size[key] || key)
+ if (figure && figure.data && typeof figure.data[key] == "function") {
+ return figure.data[key](event, can, value, key, item)
+ }
+ if (key == "inner") {
+ return value != undefined && (item.innerHTML = value), item.innerHTML
+ }
+ return value && item.setAttribute(key, value), item.getAttribute(key||"class")||item[key]&&item[key].baseVal&&item[key].baseVal.value||item[key]&&item[key].baseVal||"";
+ }
+ item.Val = function(key, value) {
+ return parseInt(item.Value(key, value == undefined? value: parseInt(value)||0))||0;
+ }
+ item.Group = function() {var target = item
+ while (target) {
+ if (["svg", "g"].indexOf(target.tagName) > -1) {
+ return target;
+ }
+ target = target.parentNode;
+ }
+ return can.svg
+ }
+ return item;
+ },
+ push: function(event, can, msg, cmd, target) {
+ var rect = document.createElementNS("http://www.w3.org/2000/svg", cmd);
+ target.appendChild(can.onaction.init(event, can, msg, cmd, rect));
+
+ can.core.Item(msg, function(key, value) {
+ if (key == "inner") {return rect.innerHTML = value}
+ rect.Value(key, value)
+ });
+
+ if (can.point.length == 0) {
+ var pid = "p"+ can.svg.Val("count", can.svg.Val("count")+1)
+ rect.Value("class", (rect.Value("class") + " " + rect.Value("pid", pid)).trim());
+ }
+ return can.last = rect;
+ },
+ _get: function(can, item, name) {
+ return can.onfigure[name||item.getAttribute("name")||item.tagName];
+ },
+ _ship: function(can, value, target) {
+ var ship = JSON.parse(target.Value("ship")||"[]").concat([value])
+ target.Value("ship", JSON.stringify(ship))
+ },
+ _run: function(event, can, target) {
+ var figure = can.onaction._get(can, event.target);
+ var msg = can.Event(event);
+ figure && can.core.List(["x", "y", "cmd"].concat(figure.copy||[]), function(item) {
+ msg.Option(item, target.Value(item))
+ })
+ figure && figure.run? figure.run(event, can, figure, "run", event.target): (event.type == "click" && can.run(event, ["action", "执行", target.Value("cmd")], function(msg) {
+ msg.Table(function(value, index) {
+ index > 0 && can.core.Item(value, function(key, val) {
+ target.Value(key, val)
+ })
+ })
+ }, true))
+ return
+ },
+ _draw: function(event, can, point) {
+ var shape = can.Action("shape");
+ var figure = can.onfigure[shape];
+ figure && figure.grid && figure.grid(event, can, point);
+ var data = figure && figure.draw(event, can, point);
+ var obj = data && can.onaction.push(event, can, data, figure.data.name||shape, can.group||can.svg);
+
+ event.type == "click" && obj && can.core.List(point, function(item, index) {if (!item.target) {return}
+ can.onaction._ship(can, {pid: obj.Value("pid"), which: index, anchor: item.anchor}, item.target)
+ })
+ return obj
+ },
+ _move: function(event, can, point) {
+ if (point.length == 1) {if (event.type != "click") {return}
+ can.onaction._select(event, can, point)
+ // can.point = point, can.current = {target: can.group}
+ can.point = point, can.current = {target: event.target}
+ } else if (point.length == 2) {
+ if (event.type == "click") {
+ return can.point = [], delete(can.current)
+ }
+ }
+
+ var target = can.current.target
+ var figure = can.onaction._get(can, target);
+ if (point.length == 1) {
+ target.style.cursor = "move"
+ can.current.pos = 5, can.current.begin = can.core.List([target], function(item) {
+ if (item.tagName == "g") {return}
+ return target.style.cursor = "move", {
+ target: item,
+ x: item.Val("x"),
+ y: item.Val("y"),
+ width: item.Val("width"),
+ height: item.Val("height"),
+ ship: can.core.List(JSON.parse(item.Value("ship")||"[]"), function(ship) {
+ return ship.pid && (ship.target = can.page.Select(can, can.svg, "."+ship.pid)[0]) && ship
+ })
+ }
+ })
+ /*
+ can.current.pos = 5, can.current.begin = can.page.Select(can, target, "*", function(item) {
+ if (item.tagName == "g") {return}
+ return target.style.cursor = "move", {
+ target: item,
+ x: item.Val("x"),
+ y: item.Val("y"),
+ width: item.Val("width"),
+ height: item.Val("height"),
+ ship: can.core.List(JSON.parse(item.Value("ship")||"[]"), function(ship) {
+ ship.target = can.page.Select(can, can.svg, "."+ship.pid)[0];
+ return ship
+ })
+ }
+ })
+ */
+ return
+ }
+
+ can.core.List(can.current.begin, function(item) {
+ var figure = can.onaction._get(can, item.target)
+
+ can.page.Resizes(event, item.target, item, point[0], point[1], can.current.pos)
+ can.page.Select(can, can.svg, "."+item.target.Value("text"), function(text) {
+ text.Value(figure.text(event, can, {}, item.target))
+ })
+ can.core.List(item.ship, function(ship) {
+ var p = can.page.Anchor(event, item.target, ship.anchor, {})
+ if (ship.which == 0) {
+ ship.target.Val("x1", p.x)
+ ship.target.Val("y1", p.y)
+ }
+ if (ship.which == 1) {
+ ship.target.Val("x2", p.x)
+ ship.target.Val("y2", p.y)
+ }
+ })
+ })
+ },
+ _resize: function(event, can, point) {
+ if (point.length == 1) {if (event.type != "click") {return}
+ can.current = {target: event.target}
+ } else if (point.length == 2) {
+ if (event.type == "click") {
+ return can.point = [], delete(can.current)
+ }
+ }
+
+ var target = can.current.target
+ var figure = can.onaction._get(can, target);
+ if (point.length == 1) {
+ can.current.pos = can.page.Prepos(event, target)
+ can.current.begin = {
+ x: target.Val("x"),
+ y: target.Val("y"),
+ width: target.Val("width"),
+ height: target.Val("height"),
+ }
+ return
+ }
+
+ can.page.Resizes(event, target, can.current.begin, point[0], point[1], can.current.pos)
+ },
+ _scale: function(event, can, point) {if (point.length < 2) {return}
+ if (point.length == 2) {
+ can.last && can.page.Remove(can, can.last)
+ var figure = can.onfigure["line"];
+ var data = figure && figure.draw(event, can, point);
+ can.last = can.onaction.push(event, can, data, "line", can.group||can.svg)
+ if (event.type == "click" && point.length == 2) {
+ can.point = point
+ }
+ return
+ }
+
+ can.now && can.page.Remove(can, can.now)
+ var figure = can.onfigure["line"];
+ var data = figure && figure.draw(event, can, [point[0], point[2]]);
+ can.now = can.onaction.push(event, can, data, "line", can.group||can.svg)
+ if (event.type == "click" && point.length == 3) {
+ can.now && can.page.Remove(can, can.now)
+ can.last && can.page.Remove(can, can.last)
+ can.point = []
+ }
+
+ can.group.Value("transform", "scale("+(point[2].x-point[0].x)/(point[1].x-point[0].x)+","+(point[2].y-point[0].y)/(point[1].y-point[0].y)+")")
+ },
+ _delete: function(event, can, point) {
+ can.point = [], event.target != can.svg && can.page.Remove(can, event.target)
+ },
+ _select: function(event, can, point) {var target = event.target
+ while (target) {
+ if (target.tagName == "g") {
+ can.Action("group", target.Value("class"))
+ can.group = target
+ break
+ }
+ if (target.tagName == "svg") {
+ can.Action("group", "svg")
+ can.group = can.svg
+ break
+ }
+ target = target.parentNode
+ }
+ can.point = []
+ },
+
+ oncontextmenu: function(event, can) {var target = event.target
+ var figure = can.onaction._get(can, target);
+ can.user.carte(event, shy("", can.ondetail, figure.data.detail || can.ondetail.list, function(event, key, meta) {var cb = meta[key];
+ typeof cb == "function" && cb(event, can, figure, key, target);
+ }), can), event.stopPropagation(), event.preventDefault()
+ },
+ onclick: function(event, can) {
+ var p = can.svg.getBoundingClientRect();
+ var point = {x: event.clientX-p.x, y: event.clientY-p.y};
+ point.x = point.x - point.x % parseInt(can.Action("grid"));
+ point.y = point.y - point.y % parseInt(can.Action("grid"));
+ can.point = (can.point || []).concat([point]);
+
+ can.temp && can.page.Remove(can, can.temp) && delete(can.temp);
+ can.temp = can.onaction["_"+can.Action("mode")](event, can, can.point);
+ can.point.length == 0 && delete(can.temp);
+ },
+ onmouseover: function(event, can) {
+ can.Status(event, event.target, "which")
+ },
+ onmousemove: function(event, can) {
+ var p = can.svg.getBoundingClientRect()
+ var point = {x: event.clientX-p.x, y: event.clientY-p.y}
+ point.x = point.x - point.x % parseInt(can.Action("grid"));
+ point.y = point.y - point.y % parseInt(can.Action("grid"));
+ can.Status(event, point, "point")
+
+ var pos = can.page.Prepos(event, event.target)
+
+ if (can.Action("go") == "auto" && can.point.length == 0) {
+ if (event.target.tagName == "text") {
+
+ } else if (event.target == can.svg) {
+ if (pos == 5) {
+ can.Action("mode", "draw")
+ can.Action("shape", "think")
+ } else {
+ can.Action("mode", "resize")
+ }
+ } else {
+ if (pos == 5) {
+ can.Action("mode", "move")
+ } else {
+ can.Action("mode", "draw")
+ can.Action("shape", "line")
+ }
+ }
+ }
+
+ // if (["move", "resize"].indexOf(can.Action("mode"))) {
+ // can.current ||
+ // }
+
+ can.temp && can.page.Remove(can, can.temp) && delete(can.temp);
+ can.temp = can.onaction["_"+can.Action("mode")](event, can, can.point.concat(point));
+ can.point.length == 0 && delete(can.temp);
+ },
+})
+Volcanos("onchoice", {help: "组件交互", list: ["move", "draw", "保存", "添加", "删除"],
+ "move": function(event, can, msg, cmd, target) {
+ can.Action("mode", cmd)
+ },
+ "draw": function(event, can, msg, cmd, target) {
+ can.Action("mode", cmd)
+ },
+})
+Volcanos("ondetail", {help: "组件详情", list: ["标签", "编辑", "复制", "变色", "运行", "删除"],
+ "标签": function(event, can, value, cmd, target) {
+ var def = value.def; can.page.Select(can, can.svg, "."+target.Value("text"), function(item) {
+ def = item.Value("inner")
+ })
+ can.user.prompt("文字", function(text) {
+ if (target.tagName == "text") {return target.innerHTML = text}
+
+ if (can.page.Select(can, can.svg, "."+target.Value("text"), function(item) {
+ item.Value("inner", text)
+ }).length > 0) {
+ return
+ }
+
+ var figure = can.onaction._get(can, target);
+ var data = figure.text(event, can, {inner: text}, target)
+ var obj = can.onaction.push(event, can, data, "text", target.Group())
+ target.Value("text", obj.Value("pid"))
+ }, def, value.silent)
+ },
+ "编辑": function(event, can, value, cmd, target) {
+ var figure = can.onaction._get(can, target);
+ can.user.input(event, can, can.core.List(["x", "y"].concat(figure.data.copy||[]), function(item) {
+ return {_input: "text", name: item, value: target.Value(item)}
+ }), function(event, cmd, meta, list) {
+ can.core.Item(meta, function(key, value) {
+ target.Value(key, value)
+ })
+ })
+ },
+ "复制": function(event, can, value, cmd, target) {
+ var figure = can.onaction._get(can, target).data;
+ var data = {}
+ can.core.List(figure.copy, function(item) {data[item] = target.Value(item)});
+ data[figure.size.x||"x"] = parseInt(target.Value(figure.size.x||"x"))+20;
+ data[figure.size.y||"y"] = parseInt(target.Value(figure.size.y||"y"))+20;
+
+ var p = data && can.onaction.push(event, can, data, target.tagName, can.group||can.svg)
+ can.page.Select(can, can.svg, "."+target.Value("text"), function(item) {
+ can.ondetail["标签"](event, can, {silent: true, def: item.Value("inner")}, "", p);
+ })
+
+ return p
+ },
+ "变色": function(event, can, value, cmd, target) {
+ if (target._timer) {
+ target._timer.stop = true
+ delete(target._timer)
+ return
+ }
+
+ var list = ["red", "green", "yellow", "blue"]
+ target._timer = can.Timer({value: 500, length: -1}, function() {
+ target.Value("fill", list[parseInt(Math.random()*list.length%list.length)])
+ })
+ },
+ "运行": function(event, can, value, cmd, target) {
+ if (target._timer) {
+ target._timer.stop = true
+ delete(target._timer)
+ return
+ }
+
+ target._timer = can.Timer({value: 500, length: -1}, function(event) {
+ can.onaction._run({type: "click", target: target}, can, target)
+ })
+ },
+ "删除": function(event, can, value, cmd, target) {can.page.Remove(can, target)},
+})
+Volcanos("onstatus", {help: "组件状态", list: ["point", "which", "begin", "width", "keys"],
+ "point": function(event, can, value, cmd, target) {target.innerHTML = value.x+","+value.y},
+ "which": function(event, can, value, cmd, target) {
+ var figure = can.onaction._get(can, value);
+ target.innerHTML = (value.Group && value.Group().Value("class") || "") + " " + value.tagName + " " + (
+ figure? figure.show(event, can, value, value): "")
+ },
+ "begin": function(event, can, value, cmd, target) {target.innerHTML = value? value.x+","+value.y: ""},
+ "width": function(event, can, value, cmd, target) {target.innerHTML = value? value.Val("width")+","+value.Val("height"): ""},
+ "keys": function(event, can, value, cmd, target) {target.innerHTML = value},
+})
+Volcanos("onexport", {help: "导出数据", list: [],
+ file: function(event, can, svg, cmd, target) {
+ return ['"]).join("")
+ },
+})
+
diff --git a/plugin/local/wiki/draw/heart.js b/plugin/local/wiki/draw/heart.js
new file mode 100644
index 00000000..c12d90c3
--- /dev/null
+++ b/plugin/local/wiki/draw/heart.js
@@ -0,0 +1,71 @@
+Volcanos("heart", {help: "心形", list: [],
+ data: {name: "path",
+ size: {},
+ x: function(event, can, value, cmd, target) {
+ var tt = JSON.parse(target.Value("tt")||'{"tx":0, "ty":0}')
+ if (value != undefined) {
+ tt.tx = value-target.Val("xx")
+ target.Value("tt", JSON.stringify(tt))
+ target.Value("transform", "translate("+tt.tx+","+tt.ty+")")
+ }
+ return target.Val("xx")+tt.tx
+ },
+ y: function(event, can, value, cmd, target) {
+ var tt = JSON.parse(target.Value("tt")||'{"tx":0, "ty":0}')
+ if (value != undefined) {
+ tt.ty = value-target.Val("yy")
+ target.Value("tt", JSON.stringify(tt))
+ target.Value("transform", "translate("+tt.tx+","+tt.ty+")")
+ }
+ return target.Val("yy")+tt.ty
+ },
+ copy: ["d", "cmd", "name", "meta", "tt", "xx", "yy", "fill"],
+ }, //
+ draw: function(event, can, point) {if (point.length < 2) {return}
+
+ var p0 = point[0], p1 = point[1], p2 = point[2];
+ pl = {x: 2*p0.x - p1.x, y:2*p0.y-p1.y}
+ var r0 = Math.sqrt(Math.pow(p0.x - p1.x, 2), Math.pow(p0.y - p1.y, 2)) / 2
+ var d = [
+ "M", pl.x, pl.y,
+ "A", r0, r0, 0, 0, 0, p0.x, p0.y,
+ "A", r0, r0, 0, 0, 0, p1.x, p1.y,
+ ]
+
+ if (point.length == 3) {
+ var r1 = Math.sqrt(Math.pow(p2.x - p1.x, 2), Math.pow(p2.y - p1.y, 2))
+ d = d.concat([
+ "A", r1, r1, 180, 0, 0, p2.x, p2.y,
+ "A", r1, r1, 180, 0, 0, pl.x, pl.y,
+ ])
+ }
+
+ var data = {
+ cmd: "pwd",
+ name: "heart", d: d.join(" "),
+ meta: JSON.stringify(point),
+ tt: JSON.stringify({tx: 0, ty: 0}),
+ xx: p0.x, yy:p1.y,
+ }
+
+ // can._tmp && can.page.Remove(can, can._tmp) && delete(can._tmp)
+ // can._tmp = can.onaction.push(event, can, data, "path", can.group||can.svg)
+ // event.type == "click" && point.length == 3 && (can.point = [], can._tmp = null);
+ return event.type == "click" && point.length == 3 && (can.point = []), data;
+ },
+ text: function(event, can, data, target) {
+ data.x = target.Val("cx")
+ data.y = target.Val("cy")
+ return data
+ },
+ show: function(event, can, value, target) {
+ return ": (" + value.Val("cx") + "," + value.Val("cy") + ")"
+ + " > (" + parseInt(value.Val("r")) + ")"
+ },
+ // run: function(event, can, value, cmd, target) {
+ // event.type == "click" && can.Run(event, ["action", "执行", target.Value("cmd")], function(msg) {
+ // can.user.toast(msg.Result())
+ // }, true)
+ // },
+})
+
diff --git a/plugin/local/wiki/feel.js b/plugin/local/wiki/feel.js
new file mode 100644
index 00000000..863533a7
--- /dev/null
+++ b/plugin/local/wiki/feel.js
@@ -0,0 +1,172 @@
+Volcanos("onimport", {help: "导入数据", list: [],
+ init: function(can, msg, cb, output, action, option) {output.innerHTML = "";
+ if (!msg.append || msg.append.length == 0) {return}
+
+ var list = msg.Table()
+ function view(index, width, auto, cb) {var item = list[can.page.Select(can, table, "tr")[index+1].dataset.index];
+ function menu(event) {var target = event.target;
+ can.user.carte(event, shy("", can.ondetail, can.feature.detail || can.ondetail.list, function(event, cmd, meta) {var cb = meta[cmd];
+ typeof cb == "function" && cb(event, can, item, index, "path", cmd, target);
+ }))
+ }
+
+ var items = item.path.split(".");
+ switch (items[items.length-1]) {
+ case "png":
+ case "jpg":
+ case "JPG":
+ return {className: "preview", img: "/share/local/web.wiki.feel/"+item.path, width: width, oncontextmenu: menu}
+ case "MOV":
+ case "m4v":
+ return {className: "preview", type: "video", width: width, oncontextmenu: menu,
+ onplay: cb, onpause: cb,
+ onloadedmetadata: cb,
+ onloadeddata: cb,
+ ontimeupdate: cb,
+ onended: cb,
+ data: {src: "/share/local/web.wiki.feel/"+item.path, controls: "controls", autoplay: auto, loop: false}}
+ default:
+ return
+ }
+ }
+
+ var table = can.page.AppendTable(can, output, msg, msg.append);
+
+ var begin = 0, limit = 3;
+ var rate = 1, width = 600;
+ var control = can.page.Append(can, output, [{view: ["control"], list: [
+ {select: [["width", 100, 200, 400, 600, 800], function(event, value) {width = parseInt(value), page(begin, limit)}]},
+ {select: [["rate", 0.1, 0.2, 0.5, 1, 2, 3, 5, 10], function(event, value) {rate = value}]},
+ {button: ["prev", function() {
+ begin > 0 && (begin -= limit, page(begin, limit));
+ }]},
+ {text: [begin+"-"+(begin+limit)], name: "offset"},
+ {button: ["next", function() {
+ begin < msg[msg.append[0]].length && (begin += limit, page(begin, limit));
+ }]},
+ {text: [list.length]},
+ {select: [["limit", 3, 6, 9, 12, 15], function(event, value) {limit = parseInt(value), page(begin, limit)}]},
+ ]}])
+ control.rate.value = rate
+ control.width.value = width
+
+ var preview = can.page.Append(can, output, [{view: ["preview"]}]).last
+ function page(begin, limit) {
+ control.offset.innerHTML = begin+"-"+(begin+limit);
+ can.page.Appends(can, preview, msg.Table(function(item, index) {
+ if (begin <= index && index < begin+limit) {return view(index, width, false, function(event) {var video = event.target;
+ switch (event.type) {
+ case "loadeddata": video.playbackRate = rate; break
+ case "timeupdate": video.playbackRate = rate; break
+ }
+ })}
+ }));
+ }
+ page(begin, limit);
+
+ function show(index) {var item = list[can.page.Select(can, table, "tr")[index+1].dataset.index];
+ var video = {};
+ var timer = can.user.toast({text: "", list: [{view: "control", list: [
+ {button: ["close", function(event) {video.pause(), timer.toast.Hide()}]},
+ {select: [["width", 100, 200, 400, 600, 800], function(event, value) {timer.toast.Show(event, parseInt(value)+20),
+ width = value
+ timer.toast.preview.setAttribute("width", value)
+ // video.width = value
+ }]},
+ {select: [["rate", 0.1, 0.2, 0.5, 1, 2, 3, 5, 10], function(event, value) {rate = video.playbackRate = value}]},
+ {button: ["prev", function(event) {show(index-1)}]},
+ {text: index+"/"+list.length},
+ {button: ["next", function(event) {show(index+1)}]},
+ {type: "br"}, {text: item.path},
+ {type: "br"}, {text: item.label},
+ ]}].concat([view(index, 600, true, function(event) {video = event.target;
+ switch (event.type) {
+ case "loadeddata": video.playbackRate = rate; break
+ case "ended": show(index+1); break
+ }
+ })]), width: 600+20, height: 620, duration: -1})
+ timer.toast.width.value = 600;
+ timer.toast.rate.value = rate;
+ }
+
+ table.onclick = function(event) {switch (event.target.tagName) {
+ case "TD":
+ can.onimport.which(event, table, msg.append, function(index, key) {
+ var name = event.target.innerHTML.trim()
+ if (name.endsWith("/")) {
+ can.Option("name", name), can.run(event, [name])
+ } else {
+ show(index);
+ }
+ })
+ break
+ case "TH":
+ break
+ case "TR":
+ case "TABLE":
+ }}
+ table.oncontextmenu = function(event) {var target = event.target;
+ switch (event.target.tagName) {
+ case "TD":
+ can.onimport.which(event, table, msg.append, function(index, key) {
+ can.user.carte(event, shy("", can.ondetail, can.feature.detail || can.ondetail.list, function(event, cmd, meta) {var cb = meta[cmd];
+ var id = msg.Ids(index);
+ var sub = can.Event(event);
+ msg.append.forEach(function(key) {sub.Option(key, msg[key][index].trim())})
+ typeof cb == "function"? cb(event, can, msg, index, key, cmd, target):
+ // can.run(event, [id, typeof cb == "string"? cb: cmd, key, target.innerHTML], function(msg) {
+ can.run(event, ["action", typeof cb == "string"? cb: cmd, key, target.innerHTML], function(msg) {
+ can.onimport.init(can, msg, cb, output, option)
+ }, true)
+ }))
+ })
+ event.stopPropagation()
+ event.preventDefault()
+ break
+ case "TH":
+ case "TR":
+ case "TABLE":
+ }
+ }
+ return typeof cb == "function" && cb(msg), table;
+ },
+ which: function(event, table, list, cb) {if (event.target == table) {return cb(-1, "")}
+ can.page.Select(can, table, "tr", function(tr, index) {if (event.target == tr) {return cb(index-1, "")}
+ can.page.Select(can, tr, "th,td", function(td, order) {
+ if (event.target == td) {return cb(index-1, list[order])}
+ })
+ })
+ },
+})
+Volcanos("onaction", {help: "组件菜单", list: ["预览", "上传"],
+ "预览": function(event, can, msg, cmd, target) {
+ },
+ "上传": function(event, can, msg, cmd, target) {
+ can.run(event, ["action", cmd, can.Option("name"), can.page.Select(can, target, "tr", function(tr) {return can.page.Select(can, tr, "th,td", function(td) {return td.innerHTML}).join(",")}).join("\n")], function() {
+ can.user.toast("保存成功")
+ }, true)
+ },
+})
+Volcanos("onchoice", {help: "组件交互", list: ["保存", "清空", ["rect", "rect", "line", "circle"]],
+ "清空": function(event, can, msg, cmd, target) {
+ console.log("choice", cmd)
+ },
+})
+Volcanos("ondetail", {help: "组件详情", list: ["标签"],
+ "标签": function(event, can, msg, index, key, cmd, target) {
+ can.user.prompt("目标", function(kind) {
+ can.run(event, ["action", "标签", msg.path, kind], function() {
+ }, true)
+ })
+ },
+})
+Volcanos("onstatus", {help: "组件状态", list: ["begin", "width", "point", "which"],
+ "begin": function(event, can, value, cmd, target) {target.innerHTML = value? value.x+","+value.y: ""},
+ "width": function(event, can, value, cmd, target) {target.innerHTML = value? value.width+","+value.height: ""},
+ "point": function(event, can, value, cmd, target) {target.innerHTML = value.x+","+value.y},
+ "which": function(event, can, value, cmd, target) {var figure = can.onfigure[value.tagName];
+ target.innerHTML = figure? figure.show(event, can, value, target): value.tagName;
+ },
+})
+Volcanos("onexport", {help: "导出数据", list: []})
+
diff --git a/plugin/local/wiki/walk.js b/plugin/local/wiki/walk.js
new file mode 100644
index 00000000..1c4d1d0c
--- /dev/null
+++ b/plugin/local/wiki/walk.js
@@ -0,0 +1,155 @@
+Volcanos("onimport", {help: "导入数据", list: [],
+ init: function(can, msg, cb, output, action, option) {output.innerHTML = "";
+ if (!msg.result || msg.result.length == 0) {
+ var table = can.page.AppendTable(can, output, msg, msg.append);
+ table.onclick = function(event) {switch (event.target.tagName) {
+ case "TD":
+ can.onimport.which(event, table, msg.append, function(index, key) {
+ can.Option("file", event.target.innerHTML.trim())
+ can.run(event, [event.target.innerHTML.trim()], function(msg) {})
+ })
+ break
+ case "TH":
+ break
+ case "TR":
+ case "TABLE":
+ }}
+ return typeof cb == "function" && cb(msg), table;
+ }
+
+ // can.page.Append(can, action, [{type: "script", src: "https://cdn.bootcss.com/echarts/4.2.0-rc.2/echarts.js"}]);
+ can.page.Append(can, output, [{include: ["plugin/github.com/shylinux/echarts/echarts.js", function(event) {
+ can.page.Append(can, output, [{include: ["plugin/github.com/shylinux/echarts/china.js", function(event) {
+ var china_chart = echarts.init(can.page.Append(can, output, [{type: "div", style: {width: "600px", height: "400px"}}]).last);
+ var data = msg.Table()
+
+ var yData = [];
+ var barData = [];
+ for (var i = 0; i < (data.length>10? 10: data.length); i++) {
+ yData.push(i + data[i].name);
+ barData.push(data[i]);
+ }
+
+ var option = {
+ title: [{
+ text: msg.Option("title"),
+ show: true, right: 250, top: 10,
+ textStyle: {color: '#2D3E53', fontSize: 18},
+ }],
+ tooltip: {
+ show: true, formatter: function(params) {
+ return params.name +": "+params.value
+ },
+ },
+ visualMap: {
+ type: 'continuous',
+ orient: 'horizontal',
+ itemWidth: 10,
+ itemHeight: 80,
+ text: ['高', '低'],
+ showLabel: true,
+ seriesIndex: [0],
+ min: 0,
+ max: data[1].value,
+ inRange: {
+ color: ['#6FCF6A', '#FFFD64', '#FF5000']
+ },
+ textStyle: {
+ color: '#7B93A7'
+ },
+ bottom: 30,
+ left: 'left',
+ },
+ grid: {right: 10, top: 135, bottom: 100, width: '20%'},
+ xAxis: {show: false},
+ yAxis: {
+ type: 'category',
+ inverse: true,
+ nameGap: 16,
+ axisLine: {show: false, lineStyle: {color: '#ddd'}},
+ axisTick: {show: false, lineStyle: {color: '#ddd'}},
+ axisLabel: {
+ margin: 0,
+ interval: 0,
+ textStyle: {color: '#455A74', align: 'left', fontSize: 14},
+ rich: {
+ a: {
+ color: '#fff',
+ backgroundColor: '#FAAA39',
+ width: 20,
+ height: 20,
+ align: 'center',
+ borderRadius: 2
+ },
+ b: {
+ color: '#fff',
+ backgroundColor: '#4197FD',
+ width: 20,
+ height: 20,
+ align: 'center',
+ borderRadius: 2
+ }
+ },
+ formatter: function(params) {
+ if (parseInt(params.slice(0, 1)) < 3) {
+ return [
+ '{a|' + (parseInt(params.slice(0, 1)) + 1) + '}' + ' ' + params.slice(1)
+ ].join('\n')
+ } else {
+ return [
+ '{b|' + (parseInt(params.slice(0, 1)) + 1) + '}' + ' ' + params.slice(1)
+ ].join('\n')
+ }
+ }
+ },
+ data: yData
+ },
+ geo: {
+ map: 'china', left: 'left', right: '100',
+ label: {emphasis: {show: false}},
+ itemStyle: {emphasis: {areaColor: '#fff464'}},
+ },
+ series: [{
+ roam: false, type: 'map', name: 'mapSer',
+ geoIndex: 0, label: {show: false},
+ data: data
+ }, {
+ roam: false, type: 'bar', name: 'barSer',
+ visualMap: false, barGap: 0, barMaxWidth: 8,
+ zlevel: 100, itemStyle: {
+ normal: {
+ color: function(params) {
+ // build a color map as your need.
+ var colorList = [{colorStops: [
+ {offset: 0, color: '#FFD119'}, // 0% 处的颜色
+ {offset: 1, color: '#FFAC4C'}, // 100% 处的颜色
+ ]}, {colorStops: [
+ {offset: 0, color: '#00C0FA'}, // 0% 处的颜色
+ {offset: 1, color: '#2F95FA'}, // 100% 处的颜色
+ ]}];
+ return params.dataIndex < 3? colorList[0]: colorList[1]
+ },
+ barBorderRadius: 15
+ }
+ },
+ data: barData
+ }]
+ };
+ china_chart.setOption(option);
+ }]}]);
+ }]}]);
+ },
+ which: function(event, table, list, cb) {if (event.target == table) {return cb(-1, "")}
+ can.page.Select(can, table, "tr", function(tr, index) {if (event.target == tr) {return cb(index-1, "")}
+ can.page.Select(can, tr, "th,td", function(td, order) {
+ if (event.target == td) {return cb(index-1, list[order])}
+ })
+ })
+ },
+})
+Volcanos("onaction", {help: "组件交互", list: []})
+Volcanos("onchoice", {help: "组件菜单", list: []})
+Volcanos("ondetail", {help: "组件详情", list: []})
+Volcanos("onexport", {help: "导出数据", list: []})
+
+
diff --git a/plugin/local/wiki/word.css b/plugin/local/wiki/word.css
new file mode 100644
index 00000000..c13b4646
--- /dev/null
+++ b/plugin/local/wiki/word.css
@@ -0,0 +1,50 @@
+fieldset.story {
+ clear:both;
+}
+fieldset.float {
+ float:left;
+ clear:none;
+}
+fieldset.clear {
+ clear:both;
+}
+
+fieldset p.story {
+ white-space:pre;
+}
+fieldset ul.story li:hover {
+ border:solid 2px red;
+ cursor:pointer;
+}
+fieldset code.story {
+ display:block;
+ color:white;
+ font-size:14px;
+ font-family:monospace;
+ background-color:#272822;
+ white-space:pre;
+ padding:10px;
+ overflow:auto;
+ border:solid 3px green;
+ max-height:640px;
+}
+
+fieldset div.stack:hover {
+ background-color:red;
+}
+fieldset div.stack {
+ cursor:pointer;
+ width:fit-content;
+}
+fieldset div.stack.fold {
+ font-weight:bold;
+}
+fieldset ul.stack {
+ border:solid 2px #0000;
+ margin:0px;
+}
+fieldset ul.stack:hover {
+ border:solid 2px red;
+}
+
+
diff --git a/plugin/local/wiki/word.js b/plugin/local/wiki/word.js
new file mode 100644
index 00000000..dd7db39e
--- /dev/null
+++ b/plugin/local/wiki/word.js
@@ -0,0 +1,29 @@
+Volcanos("onimport", {help: "导入数据", list: [],
+ _init: function(can, msg, list, cb, target) { can._output.innerHTML = "";
+ can.onappend.table(can, target, "table", msg)
+
+ // if (msg.Option("_display") == "table") {
+ // var table = can.page.AppendTable(can, can._output, msg, msg.append, function(event, value, key, index, tr, td) {
+ // can.page.Select(can, can._option, "input.args", function(input) { if (input.name == key) { var data = input.dataset || {}
+ // input.value = value
+ // if (data.action == "auto") {
+ // can.run(event, [], function(msg) {})
+ // }
+ // } })
+ // })
+ // return typeof cb == "function" && cb(msg);
+ // }
+ //
+ can._output.innerHTML = msg.Result()
+
+ can.page.Select(can, can._output, "fieldset.story", function(item) {var data = item.dataset
+ can.onappend._init(can, JSON.parse(data.meta||"{}"), Config.libs.concat(["plugin/state.js"]), function(sub) {
+ sub.run = function(event, cmds, cb, silent) {
+ can.run(event, ["field", "action", "story", data.type, data.name, data.text].concat(cmds), cb, silent)
+ }
+ }, item)
+ })
+ return typeof cb == "function" && cb(msg)
+ },
+}, ["plugin/local/wiki/word.css"])
+
diff --git a/plugin/story/trend.js b/plugin/story/trend.js
new file mode 100644
index 00000000..4b76594a
--- /dev/null
+++ b/plugin/story/trend.js
@@ -0,0 +1,204 @@
+Volcanos("onimport", {help: "导入数据", list: [],
+ _init: function(can, msg, list, cb, target) { can._output.innerHTML = "";
+ if (msg.Option("_display") == "table") {
+ var table = can.page.AppendTable(can, can._output, msg, msg.append, function(event, value, key, index, tr, td) {
+ can.page.Select(can, can._option, "input.args", function(input) { if (input.name == key) { var data = input.dataset || {}
+ input.value = value
+ if (data.action == "auto") {
+ can.run(event, [], function(msg) {})
+ }
+ } })
+ })
+ return typeof cb == "function" && cb(msg);
+ }
+
+
+ can.ui = can.page.Append(can, target, [{view: "action"}, {view: "output"}, {view: "status"}, {view: "total"}, {
+ view: "display", style: {position: "absolute", "white-space": "pre", color: "yellow"}, onclick: function(event) {
+ can.page.ClassList.add(can, can.ui.display, "hidden")
+ },
+ }])
+ can.data = can.msg.Table()
+ can.page.ClassList.add(can, can.ui.total, "status")
+
+ can.sub = can.Output(can, {}, "/plugin/local/wiki/draw", can.Event({}), function() {
+ can.Action("width", 600)
+ can.onaction["编辑"]({}, can)
+ can.onaction["股价图"]({}, can)
+ }, can.ui.output, can.ui.action, option, can.ui.status)
+ },
+})
+Volcanos("onaction", {help: "组件菜单", list: ["编辑", "清空", "股价图", "趋势", "比例", ["width", "200", "400", "600", "800", "1000"], ["height", "200", "400", "600"], "表格"],
+ "编辑": function(event, can, value, cmd, target) {
+ can.page.ClassList.neg(can, can.ui.action, "hidden")
+ can.page.ClassList.neg(can, can.ui.status, "hidden")
+ },
+ "清空": function(event, can, value, cmd, target) {
+ can.sub.svg.innerHTML = ""
+ },
+ "股价图": function(event, can, value, cmd, target) {var sub = can.sub, data = can.data;
+ if (!can.list) {
+ var count = 0, add = 0, del = 0, max = 0
+ can.max = 0, can.rest = 0, can.list = can.core.List(data, function(value, index) {
+ var line = {};
+ line.note = value[can.msg.append[4]]
+ line.date = value[can.msg.append[0]]
+ line.add = parseInt(value[can.msg.append[1]])
+ line.del = parseInt(value[can.msg.append[2]])
+
+ line.begin = can.rest
+ line.max = can.rest + line.add
+ line.min = can.rest - line.del
+ line.close = can.rest = can.rest + line.add - line.del
+
+ count++
+ add += line.add
+ del += line.del
+ if (line.max - line.min > max) {
+ max = line.max - line.min
+ }
+ if (line.max > can.max) {
+ can.max = line.max
+ }
+ return line
+ })
+
+ var begin = new Date(data[0].date)
+ var end = new Date(data[data.length-1].date)
+ var avg = parseInt((add + del) / (end - begin) * 1000 * 3600 * 24)
+ can.page.AppendStatus(can, can.ui.total, ["from", "days", "count", "avg", "max", "add", "del", "rest"], {
+ from: can.base.Time(begin).split(" ")[0], days: can.base.Duration(end-begin),
+ count: count, avg: avg, max: max, add: add, del: del, rest: can.rest,
+ })
+ }
+
+ var space = 10
+ var view = parseInt(can.Action("height"))
+ var max = parseInt(can.Action("width"))
+ var step = parseInt(max / can.list.length)||2
+
+ var width = can.list.length * step + space * 2
+ sub.svg.Val("width", width)
+
+ var height = view + space * 2
+ sub.svg.Val("height", height)
+
+ can.core.List(can.list, function(line, index) {
+ sub.onimport.draw({}, sub, {
+ shape: "line", point: [
+ {x: space/2+step*index+step/4, y: space/2+view-line.min/can.max*view},
+ {x: space/2+step*index+step/4, y: space/2+view-line.max/can.max*view},
+ ], style: line.begin < line.close? {
+ "stroke-width": 1, "stroke": "white",
+ }: {
+ "stroke-width": 1, "stroke": "black",
+ },
+ })
+
+ var one = line.begin < line.close? sub.onimport.draw({}, sub, {
+ shape: "rect", point: [
+ {x: space/2+step*index, y: space/2+view-line.begin/can.max*view},
+ {x: space/2+step*index+step/2, y: space/2+view-line.close/can.max*view},
+ ], style: {
+ "rx": 0, "ry": 0,
+ "stroke-width": 1, "stroke": "white", "fill": "white",
+ },
+ }): sub.onimport.draw({}, sub, {
+ shape: "rect", point: [
+ {x: space/2+step*index, y: space/2+view-line.close/can.max*view},
+ {x: space/2+step*index+step/2, y: space/2+view-line.begin/can.max*view},
+ ], style: {
+ "rx": 0, "ry": 0,
+ "stroke-width": 1, "stroke": "black", "fill": "black",
+ },
+ })
+
+ one.onmouseover = function(event) {
+ can.page.ClassList.del(can, can.ui.display, "hidden")
+ can.ui.display.style.left = event.clientX+space/2+"px"
+ can.ui.display.style.top = event.clientY+space/2+"px"
+
+ var msg = can.Event(event);
+ msg.Push(line, ["date", "note", "begin", "add", "del", "close"], "detail")
+ can.ui.display.innerHTML = ""
+ can.page.AppendTable(can, can.ui.display, msg, msg.append)
+ }
+ })
+ },
+ "趋势": function(event, can, value, cmd, target) {var sub = can.sub, data = can.data;
+ var space = 10
+ var view = parseInt(can.Action("height"))
+ var max = parseInt(can.Action("width"))
+ var step = parseInt(max / can.list.length)||2
+
+ var width = can.list.length * step + space * 2
+ sub.svg.Val("width", width)
+
+ var height = 0
+ var max = {};
+ can.core.List(can.msg.append, function(key, which) {
+ height += view + space * 2
+ max[key] = 0;
+ can.core.List(data, function(value, index) {
+ if ((parseInt(value[key])||0) > max[key]) {
+ max[key] = parseInt(value[key])||0
+ }
+ })
+ })
+
+ sub.svg.Val("height", height+space*2)
+
+ can.core.List(can.msg.append, function(key, which) {
+ var y = (space*2+view)*(which+1)
+ sub.onimport.draw({}, sub, {
+ shape: "text", point: [
+ {x: width/2, y: y+space},
+ ],
+ style: {
+ "font-size": 20,
+ "stroke-width": 0,
+ "fill": "red",
+ inner: key,
+ },
+ })
+
+ can.core.List(data, function(value, index) {
+ var one = sub.onimport.draw({}, sub, {
+ shape: "rect",
+ point: [
+ {x: space+step*index, y: y},
+ {x: space+step*index+step/4, y: y-parseInt(value[key])/(max[key]||1)*view}
+ ],
+ style: {
+ "rx": 0, "ry": 0,
+ "stroke-width": 1, "stroke": "white", "fill": "white",
+ },
+ })
+
+ one.onmouseover = function(event) {
+ can.page.ClassList.del(can, can.ui.display, "hidden")
+ can.ui.display.style.left = event.clientX+space/2+"px"
+ can.ui.display.style.top = event.clientY+space/2+"px"
+
+ var msg = can.Event(event);
+ msg.Push(value, can.core.Item(value, function(key) {
+ return msg[key] = [], key
+ }), "detail")
+ can.ui.display.innerHTML = ""
+ can.page.AppendTable(can, can.ui.display, msg, msg.append)
+ }
+ })
+ })
+ },
+ "表格": function(event, can, value, cmd, target) {var sub = can.sub, data = can.data;
+ if (!can.ui.table) {
+ can.ui.table = can.page.AppendTable(can, can.target, can.msg, can.msg.append)
+ can.ui.table.style.clear = "both"
+ return
+ }
+ can.page.ClassList.neg(can, can.ui.table, "hidden")
+ },
+})
+Volcanos("onchoice", {help: "组件交互", list: []})
+Volcanos("ondetail", {help: "组件详情", list: []})
+Volcanos("onexport", {help: "导出数据", list: []})
diff --git a/plugin/table.js b/plugin/table.js
index dc6403ad..d3279b80 100644
--- a/plugin/table.js
+++ b/plugin/table.js
@@ -1,15 +1,8 @@
Volcanos("onimport", {help: "导入数据", list: [],
_init: function(can, msg, list, cb, target) { can._output.innerHTML = "";
- var table = can.page.AppendTable(can, can._output, msg, msg.append, function(event, value, key, index, tr, td) {
- can.page.Select(can, can._option, "input.args", function(input) { if (input.name == key) { var data = input.dataset || {}
- input.value = value
- if (data.action == "auto") {
- can.run(event, [], function(msg) {})
- }
- } })
- }, function(event, value, key, index, tr, td) {
- });
+ can.onappend.table(can, target, "table", msg)
msg.result && can.page.AppendBoard(can, can._output, msg.result.join(""))
+ return typeof cb == "function" && cb(msg)
},
})
Volcanos("onaction", {help: "控件交互", list: [],
diff --git a/proto.js b/proto.js
index 10269573..4a867ce4 100644
--- a/proto.js
+++ b/proto.js
@@ -100,6 +100,9 @@ var Volcanos = shy("火山架", {cache: {}, index: 1, order: 1, debug: {
return typeof cb == "function" && (res = cb(one, index, array)) && res != undefined && res || one
})
}),
+ Result: shy("遍历数据", function(cb) {
+ return msg.result && msg.result.join("") || ""
+ }),
Clear: function(key) {
switch (key) {
case "append":