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 ['', svg? svg.innerHTML: "", ""]).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":