首页/ mobileweb/ 图表工具大全 · 移动端数据可视化图表库(原生 JS 无依赖)/ 代码预览

💻 代码预览 · 图表工具大全 · 移动端数据可视化图表库(原生 JS 无依赖)

mw_tool · 上传者 驰旭教育
← 返回详情
r111/app.js · 约 4025 字符
1/* r111 图表工具大全 · 公共运行时(纯原生 JS,零依赖) */2var $ = function (s, r) { return (r || document).querySelector(s); };3var $$ = function (s, r) { return Array.prototype.slice.call((r || document).querySelectorAll(s)); };45/* ---------------- 数据集加载器:优先 fetch 读取 data/*.json ---------------- */6var DS = (function () {7  var cache = {};8  var INDEX = null;910  function fromFallback(name) {11    var f = window.__DATA__ || {};12    if (f[name]) return f[name];13    throw new Error('数据集不存在:' + name);14  }15  function get(name) {16    if (cache[name]) return Promise.resolve(cache[name]);17    var url = 'data/' + name + '.json';18    var p;19    try {20      p = fetch(url).then(function (r) {21        if (!r.ok) throw new Error('HTTP ' + r.status);22        return r.json();23      });24    } catch (e) {25      p = Promise.reject(e);26    }27    return p.then(function (j) {28      j.__from = 'json';29      cache[name] = j;30      return j;31    })['catch'](function () {32      /* file:// 协议或离线打开时 fetch 会失败,回落到内置副本,保证 zip 解压后双击即可运行 */33      var j = fromFallback(name);34      j.__from = 'inline';35      cache[name] = j;36      return j;37    });38  }39  function index() {40    if (INDEX) return Promise.resolve(INDEX);41    return get('index').then(function (j) { INDEX = j.datasets || []; return INDEX; });42  }43  function all(names) { return Promise.all(names.map(get)); }44  return { get: get, all: all, index: index, cache: cache };45})();4647/* ---------------- 通用工具 ---------------- */48function toast(msg, ms) {49  var t = $('#toast');50  if (!t) return;51  t.textContent = msg;52  t.classList.add('on');53  clearTimeout(t._t);54  t._t = setTimeout(function () { t.classList.remove('on'); }, ms || 1600);55}56function openSheet(id) {57  var s = $(id), m = $('#mask');58  if (s) s.classList.add('on');59  if (m) m.classList.add('on');60}61function closeSheet() {62  $$('.sheet').forEach(function (s) { s.classList.remove('on'); });63  var m = $('#mask');64  if (m) m.classList.remove('on');65}66function segGroup(root, cb) {67  var box = typeof root === 'string' ? $(root) : root;68  if (!box) return;69  box.addEventListener('click', function (e) {70    var b = e.target.closest('button');71    if (!b || b.classList.contains('on')) return;72    Array.prototype.forEach.call(box.children, function (c) { c.classList.remove('on'); });73    b.classList.add('on');74    cb(b.dataset.v, b);75  });76}77function segValue(root) {78  var box = typeof root === 'string' ? $(root) : root;79  var on = box && box.querySelector('.on');80  return on ? on.dataset.v : null;81}82function loading(host, text) {83  if (!host) return;84  host.innerHTML = '<div class="loading"><div class="spin"></div>' + (text || '数据加载中') + '</div>';85}86function failBox(host, err) {87  if (!host) return;88  host.innerHTML = '<div class="loading">数据加载失败:' + (err && err.message ? err.message : err) + '</div>';89}90function esc(s) {91  return String(s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');92}93/* 简易 JSON 语法高亮 */94function hlJSON(obj) {95  var txt = esc(JSON.stringify(obj, null, 2));96  txt = txt.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"\s*:)/g, '<span class="k">$1</span>');97  txt = txt.replace(/:\s*("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*")/g, ': <span class="s">$1</span>');98  txt = txt.replace(/:\s*(-?\d+\.?\d*([eE][+-]?\d+)?)/g, ': <span class="n">$1</span>');99  txt = txt.replace(/:\s*(true|false|null)/g, ': <span class="n">$1</span>');100  return txt;101}102/* 数据来源徽标:告诉用户当前数据是从 JSON 文件读取还是内置回落 */103function srcBadge(ds) {104  return ds && ds.__from === 'json'105    ? '<span class="tag g">data/' + ds.id + '.json</span>'106    : '<span class="tag o">内置副本(file:// 离线)</span>';107}108109document.addEventListener('click', function (e) {110  if (e.target.id === 'mask') closeSheet();111  if (e.target.classList && e.target.classList.contains('x')) closeSheet();112});113