html生成一张饼图,HTML5 Canvas饼图生成器

JavaScript

语言:

JaveScriptBabelCoffeeScript

确定

const opts = {

width: 720,

height: 600,

};

const COLORS = ["f1c40f", "2ecc71", "3498db", "9b59b6", "34495e", "c0392b", "7f8c8d", "1abc9c"];

const App = (() => {

const model = {

inputs: {

name: m.stream(""),

value: m.stream("")

},

valueList: [{

name: "Isn't this cool",

value: 10,

id: 0

}, {

name: "Now there's titles",

value: 3,

id: 1

}, {

name: "I know right?",

value: 6.7,

id: 2

}],

controls: {

radius: m.stream(100),

thickness: m.stream(10),

gap: m.stream(1),

listOffset: m.stream(10),

}

}

const ctrl = {

handle: {

input: {

name: (e) => {

e.preventDefault();

model.inputs.name(e.target.value);

},

value: (e) => {

e.preventDefault();

let val = e.target.value.replace(/[^0-9.]/g, "").replace(/(\.)\1/g, ".");

model.inputs.value(val);

},

submit: (e) => {

e.preventDefault();

let id = model.valueList.length,

name = model.inputs.name(),

value = model.inputs.value();

name != "" && value != "" ? model.valueList.push({

name: name,

value: value,

id: id

}) : void 0;

model.inputs.name("");

model.inputs.value("");

}

},

control: {

thickness: (e) => {

model.controls.thickness(e.target.value);

},

radius: (e) => {

console.log(e.target.value)

model.controls.radius(e.target.value);

}

}

},

removeValue: (val) => {

model.valueList = model.valueList.filter((el) => {

return el.id !== val.id;

})

}

}

function view(vnode) {

let list = model.valueList.map((el, ind) => {

el.remove = () => {

ctrl.removeValue({

id: el.id

});

}

el.view = (vnode) => {

return m("div.values--value-item", [

m("p.values--value-item-value", vnode.attrs.value),

m("p.values--value-item-name", vnode.attrs.name),

m("button", {

onclick: el.remove

}, String.fromCharCode(215))

])

}

return m(el, {

name: el.name,

value: el.value,

});

});

return m("div.app--container", {

style: "width: " + opts.width + "px; height: " + opts.height + "px"

}, [

m("div.app--values--wrapper", [

m("p.app--title", "Values"),

m("div.app--values--input-wrapper", [

m("div.values--description", [

m("div.values--description-name", "Name"),

m("div.values--description-value", "Value"),

]),

m("div.values--list", list),

m("form.values--input", {

onsubmit: ctrl.handle.input.submit

}, [

m("input.values--input-submit", {

type: "submit",

value: String.fromCharCode(215),

}),

m("input.values--input-name", {

oninput: ctrl.handle.input.name,

value: model.inputs.name(),

placeholder: "Name..."

}),

m("input.values--input-value", {

oninput: ctrl.handle.input.value,

value: model.inputs.value(),

placeholder: "Value.."

})

])

])

]),

m("div.app--canvas--wrapper", [

m("p.app--title", "Result"),

m(Canvas, {

width: 432,

height: 320,

list: model.valueList,

controls: model.controls

}),

]),

m("div.app--controls--wrapper", [

m("p.app--title", "Controls"),

m("div.app--controls--holder", [

m("div.app--controls--input", [

m("label.app--controls--label", {

for: "thickness-control"

}, "Thickness"),

m("input.app--controls--thickness", {

id: "thickness-control",

className: "app--controls--thickness slider",

type: "range",

min: "1",

max: "30",

oninput: ctrl.handle.control.thickness,

value: model.controls.thickness()

}),

]),

m("div.app--controls--input", [

m("label.app--controls--label", {

for: "radius-control"

}, "Radius"),

m("input.app--controls--radius", {

id: "radius-control",

className: "slider",

type: "range",

min: "10",

max: "100",

oninput: ctrl.handle.control.radius,

value: model.controls.radius()

})

])

]),

]),

]);

}

return {

view: view

}

});

const Canvas = (() => {

const model = {

dom: null

}

const ctrl = {

render: (vnode) => {

let $ = model.dom.getContext("2d"),

w = model.dom.width,

h = model.dom.height,

list = vnode.attrs.list,

pi = Math.PI,

pi2 = pi * 2,

piDeg = Math.PI / 180,

ctrls = vnode.attrs.controls;

let total = list.reduce((s, val) => {

val.value = +val.value;

return s + val.value;

}, 0),

totalListHeight = list.length * 3 * 10,

middleTopOffset = h / 2 - totalListHeight / 2;

$.fillStyle = "white";

$.fillRect(0, 0, w, h);

for (let i = 0, val = 0; i < list.length; i++) {

$.beginPath();

$.arc(+ctrls.radius() + ctrls.thickness() * 2, h / 2, +ctrls.radius(), (val / total) * pi2 + piDeg * ctrls.gap(), (val += list[i].value) / total * pi2 - piDeg * ctrls.gap());

$.strokeStyle = "#" + COLORS[i];

$.lineWidth = ctrls.thickness();

$.stroke();

$.fillStyle = "#" + COLORS[i];

$.save();

$.translate(ctrls.radius() * 2 + ctrls.thickness() * 3 + ctrls.listOffset(), middleTopOffset + 10 * i * 3);

$.fillRect(0, 0, 10, 10);

$.font = 15 + "px Open Sans";

$.fillStyle = "black";

$.fillText(list[i].name, 2 * 10, 10)

$.restore();

};

}

}

function oncreatedom(vnode) {

model.dom = vnode.dom;

ctrl.render(vnode)

}

function view(vnode) {

model.dom ? ctrl.render(vnode) : void 0;

return m("canvas", {

width: vnode.attrs.width,

height: vnode.attrs.height

})

}

return {

view: view,

oncreate: oncreatedom

};

})

m.route(document.body, "/app", {

"/app": App

});

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值