Can I get a listing of my gists?
Such a listing would list all gists, not only four and not show the contents of a gist until I click it.
There is a simple way:
https://gist.github.com/anders
just put user name in the end of the url: gist.github.com/[user name]
Use GitHub Gist API: https://developer.github.com/v3/gists/#list-a-users-gists
For example, list all public Gist of user anders: https://api.github.com/users/anders/gists
a part of return result:
"html_url": "https://gist.github.com/5b2bd534992dafe3f05202d43d8e48a2",
Then access: https://gist.github.com/5b2bd534992dafe3f05202d43d8e48a2 you will see detail content of this specific gist.
You can use the github API
for example:
MY Gists
https://api.github.com/users/{your git username}/gists
produces a json file like seen below:
This answer correctly suggests retreiving gist information with the free, unauthenticated, cors-enabled API: https://api.github.com/users/${username}/gists.
However, the answer doesn't mention that the initial request only returns the first page. To get all public gists for a user, iterate the pages until you see an empty array response (I guess you could save a request if any returns less than the maximum page size, which appears to be 30). Here's an example in JS for convenience:
const fetchJson = (...args) =>
fetch(...args).then(response => {
if (!response.ok) {
throw Error(response.status);
}
return response.json();
});
const fetchGists = async (username, maxPages=10) => {
const gists = [];
for (let page = 1; page <= maxPages; page++) {
const url = `https://api.github.com/users/${username}/gists?page=${page}`;
const chunk = await fetchJson(url);
if (chunk.length === 0) {
break;
}
gists.push(...chunk);
}
return gists;
};
fetchGists("gaearon").then(gists => {
// for all fields:
//document.body.textContent = JSON.stringify(gists, null, 2);
// ...or select interesting fields:
gists = gists.map(({
description, files, html_url, created_at, updated_at
}) => ({
description, files, html_url, created_at, updated_at
})).sort((a, b) => b.updated_at.localeCompare(a.updated_at));
document.body.textContent =
`total number of public gists: ${gists.length}
${JSON.stringify(gists, null, 2)}`;
});
body {
white-space: pre;
font-family: monospace;
}
Caution: the rate limit at the time of writing is 60 requests per hour, which is easy to exceed. You can monitor your current rate limits in the response headers:
x-ratelimit-limit: 60
x-ratelimit-remaining: 0
x-ratelimit-reset: 1664391218
x-ratelimit-resource: core
x-ratelimit-used: 60
Here's a more comprehensive example which shows the rate limits and gists and a prettier interface. I host a version on GitHub pages so I can easily find my gists (the built-in GitHub website gist page is awkward to click through 10 items at a time and has poor search functionality):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Gist List</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/5.1.0/github-markdown-dark.min.css" crossorigin="anonymous" referrerpolicy="no-referrer" />
<style>
body {
margin: 0;
padding: 2.5em;
box-sizing: border-box;
}
.markdown-body {
min-width: 200px;
max-width: 980px;
margin: 0 auto;
}
.github-limits {
margin-top: 1em;
margin-bottom: 2em;
}
.gists ul {
list-style-type: none;
padding: 0 !important;
margin: 0 !important;
}
.gists th {
cursor: pointer;
position: relative;
}
.gists .sorted-desc:after {
position: absolute;
right: 0.5em;
content: "\25BC";
font-size: 0.8em;
}
.gists .sorted-asc:after {
position: absolute;
right: 0.5em;
content: "\25B2";
font-size: 0.8em;
}
.github-logo {
position: absolute;
right: 1.5em;
top: 1.5em;
}
td, th {
min-width: 75px;
font-size: 0.9em;
word-break: break-word;
}
#media (max-width: 767px) {
.markdown-body {
padding: 15px;
}
}
#media (max-width: 467px) {
.markdown-body {
padding: 10px;
}
td, th {
min-width: 70px;
font-size: 0.8em;
}
}
</style>
</head>
<body class="markdown-body">
<div class="github-logo">
<a href="https://github.com/ggorlen/gist-list">
<img src="https://github.githubassets.com/images/modules/site/icons/footer/github-mark.svg" alt="GitHub mark" width="20" height="20">
</a>
</div>
<h1>Gist List</h1>
<div>
<form class="gist-search">
<input
class="github-username"
placeholder="Enter a GitHub username"
autofocus
>
<input type="submit" value="search">
</form>
</div>
<div class="github-limits"></div>
<div class="gists"></div>
<script>
"use strict";
class GHRequestError extends Error {
constructor(limits = {}, ...params) {
super(...params);
if (Error.captureStackTrace) {
Error.captureStackTrace(this, GHRequestError);
}
this.name = "GHRequestError";
this.limits = limits;
}
}
const fetchJson = (...args) => fetch(...args).then(async response => {
const {headers} = response;
const limits = {
remaining: headers.get("x-ratelimit-remaining"),
limit: headers.get("x-ratelimit-limit"),
reset: new Date(headers.get("x-ratelimit-reset") * 1000),
};
if (!response.ok) {
const message = response.statusText || response.status;
throw new GHRequestError(limits, message);
}
return {limits, payload: await response.json()};
});
const fetchGists = async (username, maxPages=10) => {
const gists = [];
let limits;
for (let page = 1; page <= maxPages; page++) {
const url = `https://api.github.com/users/${username}/gists?page=${page}`;
const {limits: lastLimits, payload: chunk} = await fetchJson(url);
limits = lastLimits;
if (chunk.length === 0) {
break;
}
gists.push(...chunk);
}
return {limits, gists};
};
const firstFile = gist =>
Object.keys(gist.files).length
? Object.values(gist.files)[0].filename : "";
const gistDescription = gist => `
<a href="${gist.html_url}">
${gist.description || (
Object.keys(gist.files).length
? firstFile(gist)
: "<em>no description</em>"
)
}
</a>
`;
const gistFiles = gist => `
<ul>
${Object.values(gist.files)
.map(e => `
<li>${e.filename}</li>
`)
.join("")}
</ul>
`;
const gistTableRow = gist => `
<tr>
<td>
${gistDescription(gist)}
</td>
<td>
${gistFiles(gist)}
</td>
<td>
${gist.created_at.slice(0, 10)}
</td>
<td>
${gist.updated_at.slice(0, 10)}
</td>
</tr>
`;
const gistsTable = gists =>
gists.length === 0 ? "<div>No gists found</div>" : `
<table>
<tbody>
<tr>
${headers.map(({name}) => `<th>${name}</th>`).join("")}
</tr>
${gists.map(gistTableRow).join("")}
</tbody>
</table>
`;
const listenToHeaderClick = header => {
header.addEventListener("click", ({target: {textContent}}) => {
let {key, ascending} = headers.find(e => e.name === textContent);
if (sortedBy === textContent) {
gists.reverse();
ascending = header.classList.contains("sorted-desc");
}
else {
sortedBy = textContent;
gists.sort((a, b) => key(a).localeCompare(key(b)));
if (!ascending) {
gists.reverse();
}
}
gistsToDOM(gists);
showSortedIcon(ascending);
});
};
const gistsToDOM = gists => {
document.querySelector(".gists").innerHTML = gistsTable(gists);
document.querySelectorAll(".gists th").forEach(listenToHeaderClick);
};
const limitsToDOM = limits => {
document.querySelector(".github-limits").innerHTML = `
<small>
<em>
${limits.remaining}/${limits.limit} API requests remaining.
Usage resets at ${limits.reset}.
</em>
</small>
`;
};
const showSortedIcon = ascending => {
document.querySelectorAll(".gists th").forEach(e => {
if (e.textContent === sortedBy) {
e.classList.add(ascending ? "sorted-asc" : "sorted-desc");
}
});
};
const handleGistsResponse = response => {
({limits, gists} = response);
limitsToDOM(limits);
gistsToDOM(gists);
showSortedIcon(headers.find(e => e.name === sortedBy).ascending);
};
const handleError = err => {
const gistsEl = document.querySelector(".gists");
gistsEl.innerHTML = err.message;
limitsToDOM(err.limits);
};
const searchGists = username => {
const submit = document.querySelector(".gist-search [type='submit']");
submit.disabled = true;
fetchGists(username)
.then(handleGistsResponse)
.catch(handleError)
.finally(() => submit.disabled = false);
};
const trySearchFromURLParam = () => {
const username = new URLSearchParams(window.location.search).get("username");
if (username) {
const unEl = document.querySelector(".github-username");
unEl.value = username;
searchGists(username);
}
};
const listenForSubmit = () => {
document.querySelector(".gist-search")
.addEventListener("submit", event => {
event.preventDefault();
const {value} = event.target.querySelector(".github-username");
searchGists(value);
});
};
let limits;
let gists;
let sortedBy = "Created";
const headers = Object.freeze([
{
name: "Description",
key: e => e.description || firstFile(e),
ascending: true,
},
{
name: "Files",
key: firstFile,
ascending: true,
},
{
name: "Created",
key: e => e.created_at,
ascending: false,
},
{
name: "Updated",
key: e => e.updated_at,
ascending: false,
},
]);
trySearchFromURLParam();
listenForSubmit();
</script>
</body>
</html>
Related
I want to make a separate tooltip for every stacked bar, Ex. My demo "2022-01-17" has TWO stacked bars with FOUR values but I need a total of Stack 1 group and Stack 2 group
I've reviewed most of the options in chartjs https://www.chartjs.org/docs/3.5.1/samples/bar/stacked-groups.html
var barChartData = {
labels: ["2022-01-17","2022-01-18","2022-01-19","2022-01-20","2022-01-21","2022-01-22","2022-01-23","2022-01-24","2022-01-25","2022-01-26","2022-01-27","2022-01-28","2022-01-29","2022-01-30"],
datasets: [{"label":"Product 2","data":["292.53","328.5","273.83","305.44","260.33","251.87","118.15","253.95","86.64","87.78","116.68","295.49","61.32","83.78"],"backgroundColor":"#66bb6a","borderColor":"#66bb6a","pointBackgroundColor":"#66bb6a","stack":"Stack 0"},{"label":"Product ","data":["1522.27","1844.83","1581.01","2767.68","2821.36","2940.31","2876.1","2037.79","1593.01","1900.86","1607.21","2188.92","2428.74","2508.81"],"backgroundColor":"#1b5e20","borderColor":"#1b5e20","pointBackgroundColor":"#1b5e20","stack":"Stack 0"},{"label":"Product 2","data":["200","4.14","28.51","13.68","0","0","19.93","0","0","0","10.47","23.05","9.42","10.58"],"backgroundColor":"#ffcdd2","borderColor":"#ffcdd2","pointBackgroundColor":"#ffcdd2","stack":"Stack 1"},{"label":"Product ","data":["680.2","536.51","524.41","479.69","453.19","521.87","530.57","485.13","440.25","591.29","722.73","711.58","686.63","510.72"],"backgroundColor":"#ef9a9a","borderColor":"#ef9a9a","pointBackgroundColor":"#ef9a9a","stack":"Stack 1"}]
};
const footer = (tooltipItems) => {
let sum = 0;
tooltipItems.forEach(function(tooltipItem) {
sum += tooltipItem.parsed.y;
});
return 'Sum: ' + sum;
};
var ctx = document.getElementById("canvas").getContext("2d");
var myBar = new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
interaction: {
intersect: false,
mode: 'index',
},
plugins: {
tooltip: {
callbacks: {
footer: (tooltipItem) => {
let sum = 0;
tooltipItem.forEach(function(tooltipItem) {
sum += tooltipItem.parsed.y;
});
return 'Sum: ' + sum;
}
}
}
}
}
});
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.7.0/dist/chart.min.js"></script>
<canvas id="canvas" height="100"></canvas>
to get the total of each stack, you can use the dataPoints found in the tooltip context
and use the dataset labels to group by each stack
// group stacks
const groups = {};
tooltip.dataPoints.forEach(function (point) {
if (groups.hasOwnProperty(barChartData.datasets[point.datasetIndex].label)) {
groups[barChartData.datasets[point.datasetIndex].label] += parseFloat(barChartData.datasets[point.datasetIndex].data[point.dataIndex]);
} else {
groups[barChartData.datasets[point.datasetIndex].label] = parseFloat(barChartData.datasets[point.datasetIndex].data[point.dataIndex]);
}
});
e.g. --> {"Product 2":492.53,"Product ":2202.4700000000003}
then use the external option to create a custom tooltip
see following working snippet...
$(document).ready(function() {
var barChartData = {
labels: ["2022-01-17","2022-01-18","2022-01-19","2022-01-20","2022-01-21","2022-01-22","2022-01-23","2022-01-24","2022-01-25","2022-01-26","2022-01-27","2022-01-28","2022-01-29","2022-01-30"],
datasets: [{"label":"Product 2","data":["292.53","328.5","273.83","305.44","260.33","251.87","118.15","253.95","86.64","87.78","116.68","295.49","61.32","83.78"],"backgroundColor":"#66bb6a","borderColor":"#66bb6a","pointBackgroundColor":"#66bb6a","stack":"Stack 0"},{"label":"Product ","data":["1522.27","1844.83","1581.01","2767.68","2821.36","2940.31","2876.1","2037.79","1593.01","1900.86","1607.21","2188.92","2428.74","2508.81"],"backgroundColor":"#1b5e20","borderColor":"#1b5e20","pointBackgroundColor":"#1b5e20","stack":"Stack 0"},{"label":"Product 2","data":["200","4.14","28.51","13.68","0","0","19.93","0","0","0","10.47","23.05","9.42","10.58"],"backgroundColor":"#ffcdd2","borderColor":"#ffcdd2","pointBackgroundColor":"#ffcdd2","stack":"Stack 1"},{"label":"Product ","data":["680.2","536.51","524.41","479.69","453.19","521.87","530.57","485.13","440.25","591.29","722.73","711.58","686.63","510.72"],"backgroundColor":"#ef9a9a","borderColor":"#ef9a9a","pointBackgroundColor":"#ef9a9a","stack":"Stack 1"}]
};
var ctx = document.getElementById("canvas").getContext("2d");
var myBar = new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
interaction: {
intersect: false,
mode: 'index',
},
plugins: {
tooltip: {
enabled: false,
position: 'nearest',
external: function (context) {
// init
const {chart, tooltip} = context;
// remove old tooltip
var container = chart.canvas.parentNode.querySelector('.tooltip');
if (container) {
chart.canvas.parentNode.removeChild(container);
}
// determine if tooltip exists
if (tooltip.opacity === 0) {
return;
}
// group stacks
const groups = {};
tooltip.dataPoints.forEach(function (point) {
if (groups.hasOwnProperty(barChartData.datasets[point.datasetIndex].label)) {
groups[barChartData.datasets[point.datasetIndex].label] += parseFloat(barChartData.datasets[point.datasetIndex].data[point.dataIndex]);
} else {
groups[barChartData.datasets[point.datasetIndex].label] = parseFloat(barChartData.datasets[point.datasetIndex].data[point.dataIndex]);
}
});
// build tooltip rows
var rows = '';
Object.keys(groups).forEach(function (groupName) {
rows += renderTemplate('template-tooltip-row', {
group: groupName,
value: groups[groupName].toLocaleString(undefined, {minimumFractionDigits: 2})
});
});
// build tooltip
chart.canvas.parentNode.insertAdjacentHTML('beforeEnd', renderTemplate('template-tooltip', {
rows: rows,
title: tooltip.title[0]
}));
// position tooltip
const {offsetLeft: positionX, offsetTop: positionY} = chart.canvas;
container = chart.canvas.parentNode.querySelector('.tooltip');
container.style.left = positionX + tooltip.caretX + 'px';
container.style.top = positionY + tooltip.caretY + 'px';
container.style.font = tooltip.options.bodyFont.string;
container.style.padding = tooltip.options.padding + 'px ' + tooltip.options.padding + 'px';
}
}
}
}
});
/**
* render html template
* #param {string} templateId - id of html template
* #param {object} templateValues - values for each template placeholder
* #return {string} template content
*/
function renderTemplate(templateId, templateValues) {
var propHandle; // property key
var templateText; // html template content
var templateValue; // value for template placeholder
// get template content, replace each placeholder with value
templateText = document.querySelector('#' + templateId).innerHTML;
if (templateValues) {
for (propHandle in templateValues) {
if (templateValues.hasOwnProperty(propHandle)) {
templateValue = '';
// convert template value to string
if (templateValues[propHandle] !== null) {
if (templateValues[propHandle].hasOwnProperty('results')) {
templateValue = encodeURIComponent(JSON.stringify(templateValues[propHandle].results));
} else {
templateValue = templateValues[propHandle].toString();
}
}
// handle dollar sign in template value
if (templateValue.indexOf('$') > -1) {
templateValue = templateValue.replace(new RegExp('\\$', 'g'), '$$$');
}
// replace template placeholder(s) with template value
if (templateText.indexOf('{{' + propHandle + '}}') > -1) {
templateText = templateText.replace(
new RegExp('{{' + propHandle + '}}', 'g'),
templateValue
);
}
}
}
}
return templateText.trim();
}
});
.align-right {
text-align: right;
}
.table {
border-collapse: separate;
border-spacing: 0vw 0vw;
display: table;
}
.table-body {
display: table-row-group;
}
.table-cell {
display: table-cell;
padding: 4px;
}
.table-foot {
display: table-footer-group;
}
.table-head {
display: table-header-group;
}
.table-row {
display: table-row;
}
.title {
font-weight: bold;
}
.tooltip {
background-color: rgba(0, 0, 0, 0.85);
border-radius: 3px;
color: #ffffff;
pointer-events: none;
position: absolute;
transform: translate(-50%, 0);
transition: all 0.1s ease;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.7.0/dist/chart.min.js"></script>
<canvas id="canvas" height="100"></canvas>
<script id="template-tooltip" type="text/html">
<div class="tooltip">
<div class="title">{{title}}</div>
<div class="table">
<div class="table-body">{{rows}}</div>
</div>
</div>
</script>
<script id="template-tooltip-row" type="text/html">
<div class="table-row">
<div class="table-cell title">{{group}}:</div>
<div class="table-cell align-right">{{value}}</div>
</div>
</script>
Is it possible to detect state and county based on coordinates from a click on OSM map (US only)?
I can get the coordinated using click event in Leaflet JS:
map.on('click', function(ev) {
console.log(ev.latlng);
});
I can also get location data by doing something l;like this:
map.on("click", function(ev) {
var ln = ev.latlng["lng"],
lt = ev.latlng["lat"];
pt = "https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat="+lt+"&lon="+ln;
});
Which will return json data that looks like this:
https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=28.964162684075685&lon=-98.29776763916017
But I can't seem to be able to figure out what to do next... How do I get the county and state values from it?
You can just fetch, Ajax from jquery or use axios.
let config = {
minZoom: 2,
maxZoom: 18,
};
const zoom = 5;
const lat = 28.964162684075685;
const lng = -98.29776763916017;
const map = L.map("map", config).setView([lat, lng], zoom);
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
attribution: '© OpenStreetMap contributors',
}).addTo(map);
map.on("click", function(e) {
const { lat, lng } = e.latlng;
const api = `https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lng}&zoom=18&addressdetails=1`;
fetchData(api).then((data) => {
const { county, state } = data.address;
console.log(county, state);
});
});
async function fetchData(url) {
try {
const response = await fetch(url);
const data = await response.json();
return data;
} catch (err) {
console.error(err);
}
}
*,
:after,
:before {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html {
height: 100%;
}
body,
html,
#map {
width: 100%;
height: 100%;
}
body {
position: relative;
min-height: 100%;
margin: 0;
padding: 0;
background-color: #f1f1f1;
}
<script src="https://unpkg.com/leaflet#1.7.1/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet#1.7.1/dist/leaflet.css" rel="stylesheet" />
<div id="map"></div>
I want to use "el-upload" to upload images and documents, but I want to display the images. If "list-type='picture-card'" is used, the document will also be shown with an incorrect cover. So is there any way I can upload files that show images thumbnails, documents that show names?
enter image description here
<el-upload
action=""
ref="upload"
:auto-upload="false"
:on-change="onchange">
<el-button slot="trigger" size="small" type="primary">Click to Upload</el-button>
</el-upload>
<el-image
style="width: 100px; height: 100px"
:src="fileList[0]"
:preview-src-list="fileList">
</el-image>
data() {
return {
fileList: []
}
}, methods: {
onchange(file, fileList){
this.fileList.push(URL.createObjectURL(file.raw))
}
}
<template>
<div class="upload-file">
<el-upload
multiple
:action="uploadFileUrl"
:before-upload="handleBeforeUpload"
:file-list="fileList"
:limit="limit"
:on-error="handleUploadError"
:on-exceed="handleExceed"
:on-success="handleUploadSuccess"
:show-file-list="false"
:headers="headers"
class="upload-file-uploader"
ref="upload"
>
<!-- 上传按钮 -->
<el-button type="primary">选取文件</el-button>
</el-upload>
<!-- 上传提示 -->
<!-- <div class="el-upload__tip" v-if="showTip">
请上传
<template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template>
<template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>
的文件
</div> -->
<!-- 文件列表 -->
<transition-group
class="upload-file-list el-upload-list el-upload-list--text"
name="el-fade-in-linear"
tag="ul"
>
<li
:key="file.uid"
class="el-upload-list__item ele-upload-list__item-content"
v-for="(file, index) in fileList">
<el-link
:href="`${baseUrl}${file.url}`"
:underline="false"
target="_blank"
>
<span class="el-icon-document"> {{ getFileName(file.name) }} </span>
</el-link>
<div class="ele-upload-list__item-content-action">
<el-link :underline="false" #click="handleDelete(index)" type="danger"
>删除</el-link
>
</div>
</li>
</transition-group>
</div>
</template>
<script setup>
import { getToken } from "#/utils/auth";
const props = defineProps({
modelValue: [String, Object, Array],
// 数量限制
limit: {
type: Number,
default: 1,
},
// 大小限制(MB)
fileSize: {
type: Number,
default: 2,
},
// 文件类型, 例如['png', 'jpg', 'jpeg']
fileType: {
type: Array,
default: () => ["png", "jpg", "gif"],
},
// 是否显示提示
isShowTip: {
type: Boolean,
default: true,
},
});
const { proxy } = getCurrentInstance();
const emit = defineEmits();
const number = ref(0);
const uploadList = ref([]);
const baseUrl = "URL HERE";
const uploadFileUrl = baseUrl + "Folder_URL"; //
const headers = ref({ Authorization: "Bearer " + getToken() });
const fileList = ref([]);
const showTip = computed(
() => props.isShowTip && (props.fileType || props.fileSize)
);
watch(
() => props.modelValue,
(val) => {
if (val) {
let temp = 1;
const list = Array.isArray(val) ? val : props.modelValue.split(",");
fileList.value = list.map((item) => {
if (typeof item === "string") {
item = { name: item, url: item };
}
item.uid = item.uid || new Date().getTime() + temp++;
return item;
});
} else {
fileList.value = [];
return [];
}
},
{ deep: true, immediate: true }
);
function handleBeforeUpload(file) {
if (props.fileType.length) {
let fileExtension = "";
if (file.name.lastIndexOf(".") > -1) {
fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
}
const isTypeOk = props.fileType.some((type) => {
if (file.type.indexOf(type) > -1) return true;
if (fileExtension && fileExtension.indexOf(type) > -1) return true;
return false;
});
if (!isTypeOk) {
proxy.$modal.msgError(
${props.fileType.join("/")}
);
return false;
}
}
if (props.fileSize) {
const isLt = file.size / 1024 / 1024 < props.fileSize;
if (!isLt) {
proxy.$modal.msgError(`上传文件大小不能超过 ${props.fileSize} MB!`);
return false;
}
}
proxy.$modal.loading("正在上传文件,请稍候...");
number.value++;
return true;
}
function handleExceed() {
proxy.$modal.msgError(`上传文件数量不能超过 ${props.limit} 个!`);
}
function handleUploadError(err) {
proxy.$modal.msgError("上传文件失败");
}
// 上传成功回调
function handleUploadSuccess(res, file) {
uploadList.value.push({ name: res.fileName, url: res.fileName });
if (uploadList.value.length === number.value) {
fileList.value = fileList.value
.filter((f) => f.url !== undefined)
.concat(uploadList.value);
uploadList.value = [];
number.value = 0;
emit("update:modelValue", listToString(fileList.value));
proxy.$modal.closeLoading();
console.log("url", file);
}
}
// 删除文件
function handleDelete(index) {
fileList.value.splice(index, 1);
emit("update:modelValue", listToString(fileList.value));
}
// 获取文件名称
function getFileName(name) {
if (name.lastIndexOf("/") > -1) {
return name.slice(name.lastIndexOf("/") + 1);
} else {
return "";
}
}
// 对象转成指定字符串分隔
function listToString(list, separator) {
let strs = "";
separator = separator || ",";
for (let i in list) {
if (undefined !== list[i].url) {
strs += list[i].url + separator;
}
}
return strs != "" ? strs.substr(0, strs.length - 1) : "";
}
</script>
//tu
<style scoped lang="scss">
.upload-file-uploader {
margin-bottom: 5px;
}
.upload-file-list .el-upload-list__item {
border: 1px solid #e4e7ed;
line-height: 2;
margin-bottom: 10px;
position: relative;
}
.upload-file-list .ele-upload-list__item-content {
display: flex;
justify-content: space-between;
align-items: center;
color: inherit;
}
.ele-upload-list__item-content-action .el-link {
margin-right: 10px;
}
</style>
I thought this.name is the way to access a custom tag. But that's undefined, this.tags only includes 2 of the 6-8 custom tags on the page.
<eservices-mma-receive-inventory-scan>
<style scoped>
:scope {
position: relative;
display: block;
}
.relative {
position: relative;
}
.table-info {
margin-top: 18px;
}
.table-info .clearfix span {
color: var(colorPrimary1);
display: inline-block;
font-weight: 200;
font-size: 20px;
margin-top: 2px;
}
.receive-inventory-scan-button-area {
padding: 14px;
background-color: var(colorPrimaryNeutral0);
margin-top:15px;
}
.receive-inventory-scan-button-area mdt-button {
margin-bottom: 0;
}
.receive-inventory-general-toast-area {
margin-top:15px;
margin-bottom:15px;
}
mdt-searchbar {
margin-top: 15px;
}
.right {
float: right;
}
.h3 {
color: var(colorSecondaryNeutral1);
font-size: 16px;
font-weight: 200;
line-height: 19px;
margin: 0 0 5px 0;
}
.total-count-no-tabs {
font-size: 20px;
font-weight: 200;
padding-left: 6px;
color: var(colorSecondaryNeutral1);
text-align: left;
}
.total-count-no-tabs strong {
color: var(colorPrimary2);
font-weight: 200;
}
mdt-tabs .total-count {
/* Base text style */
font-size: 20px;
font-weight: 200;
padding-right: 6px;
color: var(colorSecondaryNeutral1);
}
mdt-tabs .total-count strong {
color: var(colorPrimary2);
font-weight: 200;
}
#media screen and (min-width: var(breakpointDtoDHD)) {
:scope .container {
width: 1135px;
}
}
#media screen and (min-width: var(breakpointMtoT)) {
:scope .container {
width: auto;
}
:scope > span {
width: auto;
}
:scope .table-info > span {
font-size: 20px;
margin-top: 0;
}
}
/* mdt-tabs style temp override */
[role=topbuffer]{
height:10px;
background:var(colorPrimary6);
}
[role=bottombuffer]{
height:0px;
background:var(colorPrimary5);
}
[role=wrapper]{
overflow:hidden;
background:var(colorPrimary6);
}
[role=tab]{
width:33.33%;
color:var(colorPrimaryNeutral0);
height:35px;
line-height:35px;
float:left;
background:var(colorPrimary4);
cursor:pointer;
font-size: 16px;
text-align: center;
text-transform: uppercase;
border-right:1px solid var(colorPrimary4);
border-top:1px solid var(colorPrimary4);
}
[role=tab]:not(.active):hover{
background:var(colorPrimaryAlternate2);
}
[role=tab].active {
cursor:auto;
background: var(colorPrimary2);
}
[role="custom-content"] {
float: right;
text-align: right;
}
eservices-warning-toast {
margin-top: 10px;
}
</style>
<!-- general PO info -->
<mma-receive-inventory-review-head-info po-number="{ order.po }"
po-date="{ order.submissiondate}"
supplier-name="{ order.supplier.name }"
po-is-noar="{ order.isnoar }"
noar-reason="{ order.reason.name }"
po-itemsinshipment=" { order.itemsinshipment }"
/>
<div class="receive-inventory-general-toast-area">
<!-- cancel submit scanned results buttons -->
<div class="container-fluid receive-inventory-scan-button-area" each="{ displaySubmitActionButtons ? [true] : [] }">
<div class="row" >
<div class="col-md-6">
<mdt-button name="mdt-receiveinventory-scan-cancel" label="{__('nis.receiveInventoryScan.buttons.cancel')}" context="cancel"
onclick="{cancelCheckin}" disabled="{ !cancelButtonEnabled }" />
</div>
<div class="col-md-6">
<mdt-button name="mdt-receiveinventory-scan-reviewandsubmit" label="{__('nis.receiveInventoryScan.buttons.submit')}" context="primary"
type="submit" onclick="{submitCheckin}" disabled="{ !submitButtonEnabled}"
/>
</div>
</div>
</div>
<eservices-warning-toast each="{warning ? [true] : []}" title="{warning.title}" message="{warning.message}" cancel-label="{warning.cancelLabel}"
confirm-icon="{warning.cancelIcon}" confirm-label="{warning.confirmLabel}" oncancel="{warning.cancelCallback}" onconfirm="{warning.confirmCallback}">
</eservices-warning-toast>
<!-- cancel checking toast -->
<eservices-warning-toast each="{ (displayCheckinCancelToast) ? [true] : [] }"
title="{__('nis.receiveInventoryScan.cancelCheckinToast.title')}"
message="{ __('nis.receiveInventoryScan.cancelCheckinToast.content')}"
onconfirm="{onCancelCheckinConfirm}"
oncancel="{onCancelCheckinCancel}"
confirm-label="{__('nis.receiveInventoryScan.cancelCheckinToast.buttonConfirm')}"
cancel-label="{__('nis.receiveInventoryScan.cancelCheckinToast.buttonCancel')}"/>
<!-- mark all as damaged toast -->
<mma-receive-inventory-scan-table-warninginput-toast
title="{__('nis.receiveInventoryScan.scanitemstatustoasts.alldamaged.title')}"
content="{ __('nis.receiveInventoryScan.scanitemstatustoasts.alldamaged.content') }"
button-label-cancel="{ __('nis.receiveInventoryScan.scanitemstatustoasts.alldamaged.buttonCancel') }"
button-label-confirm="{ __('nis.receiveInventoryScan.scanitemstatustoasts.alldamaged.buttonConfirm') }"
input-label="{ __('nis.receiveInventoryScan.scanitemstatustoasts.alldamaged.commentinputlabel') }"
input-placeholder="{ __('nis.receiveInventoryScan.scanitemstatustoasts.alldamaged.commentinputplaceholder') }"
onconfirm="{ onSubmitMarkAllAsDamaged }"
oncancel="{ onCancelMarkAllAsDamaged }"
each="{ displayMarkAllAsDamagedToast ? [true] : [] }"
inline="{ false }"
/>
<!-- not in catalog toast -->
<mma-receive-inventory-scan-warning-toast
title="{ __('nis.receiveInventoryScan.scanitemstatustoasts.notincatalog.title') }"
content="{ __('nis.receiveInventoryScan.scanitemstatustoasts.notincatalog.content') }"
button-label-confirm="{ __('nis.receiveInventoryScan.scanitemstatustoasts.notincatalog.buttonConfirm') }"
onconfirm="{ onSubmitNotInCatalog }"
each="{ displayNotInCatalogToast ? [true] : [] }"
inline="{ false }"
/>
<!-- item already received on already received list -->
<mma-receive-inventory-scan-warning-toast
title="{ __('nis.receiveInventoryScan.scanitemstatustoasts.alreadyreceived.title') }"
content="{ __('nis.receiveInventoryScan.scanitemstatustoasts.alreadyreceived.content') }"
button-label-confirm="{ __('nis.receiveInventoryScan.scanitemstatustoasts.alreadyreceived.buttonConfirm') }"
onconfirm="{ onSubmitAlreadyReceived }"
each="{ displayIsAlreadyReceivedToast ? [true] : [] }"
inline="{ false }"
/>
<!-- serialised item already in stockroom -->
<mma-receive-inventory-scan-warning-toast
title="{ __('nis.receiveInventoryScan.scanitemstatustoasts.alreadyinstockroom.title') }"
content="{ __('nis.receiveInventoryScan.scanitemstatustoasts.alreadyinstockroom.content') }"
button-label-confirm="{ __('nis.receiveInventoryScan.scanitemstatustoasts.alreadyinstockroom.buttonConfirm') }"
onconfirm="{ onSubmitAlreadyInStockroom }"
each="{ displayAlreadyInStockroomToast ? [true] : [] }"
inline="{ false }"
/>
</div>
<!-- scan section -->
<mdt-searchbar name="scanInput" disabled="{ isScanDisabled }" icon-face="barcode" action-context="tertiary" mode="scan" placeholder="{ __('nis.receiveInventoryScan.scanPlaceholder') }"
each="{ displaySc anSearchBar ? [true] : [] }" storage="{storage}">
</mdt-searchbar>
<audio name="audioPlayer" >
<source src="mp3/UBDError.mp3" type="audio/mpeg" />
{ __('generic.audio.audioCompatibilityError.notSupported') }
</audio>
<mma-receive-inventory-scan-toast-error each="{ displayScanErrorToast ? [true] : [] }"></mma-receive-inventory-scan-toast-error>
<mma-receive-inventory-scan-toast-missing-information each="{ displayMissingInfosToast ? [true] : [] }"></mma-receive-inventory-scan-toast-missing-information>
<mma-receive-inventory-scan-toast-manual-entry each="{ displayManualEntryToast ? [true] : [] }"></mma-receive-inventory-scan-toast-manual-entry>
<!-- list of scanned products -->
<div>
<div each="{ tabsVisible ? [] : [true] }" class="total-count-no-tabs">{ __('nis.receiveInventoryScan.labels.totalScannedCount') } <strong>{totalScannedCount}</strong></div>
</div>
<mdt-tabs each="{ tabs && tabsVisible ? [true] : []}" name="tabSelector" tabs="{ parent.tabs }" onselect="{parent.onTabSelected}">
<span if="{parent.displayProductsToBeReceived}" class="total-count">{ __('nis.receiveInventoryScan.labels.totalScannedCount') } <strong>{parent.totalScannedCount}</strong></span>
<span if="{parent.displayProductsReceived}" class="total-count">{ __('nis.receiveInventoryScan.labels.totalReceivedCount') } <strong>{parent.totalReceivedCount}</strong></span>
</mdt-tabs>
<mma-receive-inventory-scan-table table-interaction-disabled="{ isTableInteractionDisabled }" />
<script>
var self = this;
//if no param is passed in the url, assume its a noar
this.orderId = riot.router.current.params.orderid;
RiotBus.requestStore('receiveinventoryscan', this, this.orderId ? this.orderId : null);
this.storage = {scanInput: ''};
this.store = this.stores.receiveinventoryscan;
this.states = this.stores.receiveinventoryscan.states;
this.on('update', function() {
self.displayScanErrorToast = self.stores.receiveinventoryscan.is(this.stores.receiveinventoryscan.states.SCAN_ERROR);
self.displayMissingInfosToast = this.stores.receiveinventoryscan.is(this.stores.receiveinventoryscan.states.MISSING_INFORMATION) && !this.stores.receiveinventoryscan.is(this.stores.receiveinventoryscan.states.MANUAL_ENTRY);
self.displayManualEntryToast = this.stores.receiveinventoryscan.is(this.stores.receiveinventoryscan.states.MANUAL_ENTRY);
self.isScanDisabled = !this.stores.receiveinventoryscan.is(this.stores.receiveinventoryscan.states.SCAN_ENABLED);
self.displaySubmitActionButtons = true;
self.displayCheckinCancelToast = false;
self.displayCheckinSubmitToast = false;
self.displayMarkAllAsDamagedToast = false;
self.displayNotInCatalogToast = false;
self.displayIsAlreadyReceivedToast = false;
self.displayAlreadyInStockroomToast = false;
if( self.stores.receiveinventoryscan.is(self.stores.receiveinventoryscan.states.CHECKIN_CANCEL) ) {
self.displayCheckinCancelToast = true;
};
if( self.stores.receiveinventoryscan.is(self.stores.receiveinventoryscan.states.CHECKIN_SUBMIT) ) {
self.displayCheckinSubmitToast = true;
};
if( self.stores.receiveinventoryscan.is(self.stores.receiveinventoryscan.states.MARK_ALL_AS_DAMAGED) ) {
self.displayMarkAllAsDamagedToast = true;
};
if( self.stores.receiveinventoryscan.is(self.stores.receiveinventoryscan.states.SCAN_ERROR_NOTINCATALOG) ) {
self.displayNotInCatalogToast = true;
};
if( self.stores.receiveinventoryscan.is(self.stores.receiveinventoryscan.states.ALREADY_RECEIVED) ) {
self.displayIsAlreadyReceivedToast = true;
};
if( self.stores.receiveinventoryscan.is(self.stores.receiveinventoryscan.states.ALREADY_INSTOCKROOM) ) {
self.displayAlreadyInStockroomToast = true;
};
//todo: use state for this?
var isAnyItemInErrorState = _.any(self.stores.receiveinventoryscan.getItems(), function(item) { return self.isItemInErrorState(item);});
self.displaySubmitActionButtons = !self.displayMarkAllAsDamagedToast && !self.displayAlreadyInStockroomToast && !self.displayIsAlreadyReceivedToast && !self.displayNotInCatalogToast && !self.displayCheckinCancelToast && !self.displayCheckinSubmitToast &&
!(self.stores.receiveinventoryscan.is(self.stores.receiveinventoryscan.states.MISSING_INFORMATION) || self.stores.receiveinventoryscan.is(self.stores.receiveinventoryscan.states.MANUAL_ENTRY));
self.displayScanSearchBar = !self.displayCheckinSubmitToast && !self.displayCheckinCancelToast && !self.displayMarkAllAsDamagedToast;
self.submitButtonEnabled = self.displaySubmitActionButtons && (!self.displayCheckinCancelToast && !self.displayCheckinSubmitToast && !self.displayAlreadyInStockroomToast && !self.displayIsAlreadyReceivedToast) && !isAnyItemInErrorState;//&& self.totalScannedCount >0
self.cancelButtonEnabled = self.displaySubmitActionButtons && (!self.displayCheckinCancelToast && !self.displayCheckinSubmitToast);
self.tabs = self.stores.receiveinventoryscan.getTabs();
self.tabsVisible = _.any(self.tabs, function(tab) { return tab.isVisible() === true; });
self.displayProductsToBeReceived = self.stores.receiveinventoryscan.isTabSelected(self.stores.receiveinventoryscan.tabids.TAB_PRODUCTSTOBERECEIVED);
self.displayProductsReceived = self.stores.receiveinventoryscan.isTabSelected(self.stores.receiveinventoryscan.tabids.TAB_PRODUCTSRECEIVED);
if(!self.displayProductsToBeReceived && !self.displayProductsReceived){
self.displayProductsToBeReceived = true;
}
self.isScanDisabled = !self.stores.receiveinventoryscan.is(self.stores.receiveinventoryscan.states.SCAN_ENABLED) || isAnyItemInErrorState
|| self.displayMarkAllAsDamagedToast || self.displayAlreadyInStockroomToast || self.displayIsAlreadyReceivedToast || self.displayNotInCatalogToast || self.displayMissingInfosToast || self.displayManualEntryToast
|| self.displayProductsReceived;
//TODO: instead of doing these checks, on every set of MISSING_INFORMATION, MANUAL_ENTRY, SCAN_ERROR_NOTINCATALOG, we should also remove scanenabled
self.isTableInteractionDisabled = function() { return self.isScanDisabled;};
if(!self.isScanDisabled){
/*
setTimeout(function(){
$("[name='scanInput']").find('input').focus();
$("[name='scanInput']").find('input').focusout(function(){
$("[name='scanInput']").find('input').focus();
});
}, 1);
*/
//$("[name='scanInput']").setFocus();
debugger;
this.tags.scanInput.setFocus();
}
self.buildWarning();
});
/**
* Building warning toast references
*/
this.buildWarning = function () {
self.flushWarning();
if(self.store.is(self.states.SCAN_ERROR_INVALID_FOR_SUPPLIER)) {
self.warning = {
title: __('nis.receiveInventoryScan.warning.invalidForSupplier.title'),
message: __('nis.receiveInventoryScan.warning.invalidForSupplier.message'),
confirmLabel: __('nis.receiveInventoryScan.warning.invalidForSupplier.ok'),
confirmCallback: self.onScanInvalidForSupplierConfirm
};
}
if (self.warning) {
window.scrollTo(0, 0);
}
};
/**
* Killingwarning toast references
*/
this.flushWarning = function () {
if (self.warning) {
self.warning.title = null;
self.warning.message = null;
self.warning.cancelLabel = null;
self.warning.cancelIcon = null;
self.warning.confirmLabel = null;
self.warning.cancelCallback = null;
self.warning.confirmCallback = null;
self.warning = null;
}
};
this.isItemInErrorState = function(instance) {
return instance.isalreadyreceived
|| (instance.isunexpected && !instance.isunexpectedconfirmed)
|| (instance.isshortdated && !instance.isshortdatedconfirmed)
|| (instance.isexpired && !instance.isexpiredconfirmed)
|| (instance.isovershipment && !instance.isovershipmentconfirmed)
|| (instance.markasdamaged && !instance.isdamagedconfirmed);
},
this.on('mount', function(){
this.orderId = riot.router.current.params.orderid;
RiotBus.on('receiveinventoryscan.changed', this.refreshFromStore);
RiotBus.on('beforeunload', this.beforeUnload);
this.root.addEventListener('mdtsearchchange', this.scan);
this.refreshFromStore();
});
this.on('unmount', function(){
RiotBus.releaseStore('receiveinventoryscan', this);
RiotBus.off('receiveinventoryscan.changed', this.refreshFromStore);
RiotBus.off('beforeunload', this.beforeUnload);
this.root.removeEventListener('mdtsearchchange', this.scan);
});
this.scan = function(e) {
RiotBus.trigger('scan.item.scancodebar', e.target.value);
// Reset value
self.storage.scanInput = "";
self.update();
};
this.submitCheckin = function(e){
RiotBus.trigger('receiveinventoryscan.submitCheckin');
};
this.cancelCheckin= function(e){
RiotBus.trigger('receiveinventoryscan.cancelCheckin');
};
this.refreshFromStore = function() {
self.order = self.stores.receiveinventoryscan.getOrder();
self.totalScannedCount = self.stores.receiveinventoryscan.getScannedItemsCount();
self.totalReceivedCount = self.stores.receiveinventoryscan.getItemsReceivedCount();
// Sound effect on error
if (self.stores.receiveinventoryscan.is(self.stores.receiveinventoryscan.states.SCAN_ERROR)) {
self.audioPlayer.play();
}
self.update();
};
this.beforeUnload = function(e){
RiotBus.trigger('receiveinventoryscan.beforeunload', e);
},
this.onTabSelected = function(e) {
RiotBus.trigger('receiveinventoryscan.tabselected', e.currentTarget.value)
};
this.onCancelCheckinCancel = function() {
RiotBus.trigger('receiveinventoryscan.cancelCheckin.cancel');
};
this.onCancelCheckinConfirm = function() {
RiotBus.trigger('receiveinventoryscan.cancelCheckin.confirm');
};
this.onCancelMarkAllAsDamaged = function() {
RiotBus.trigger('receiveinventoryscan.markallasdamaged.cancel');
};
this.onSubmitMarkAllAsDamaged = function(comments) {
RiotBus.trigger('receiveinventoryscan.markallasdamaged.submit', comments);
};
this.onSubmitNotInCatalog = function() {
RiotBus.trigger('receiveinventoryscan.notincatalog.submit');
};
this.onSubmitAlreadyReceived = function() {
RiotBus.trigger('receiveinventoryscan.alreadyreceived.submit');
};
this.onSubmitAlreadyInStockroom = function() {
RiotBus.trigger('receiveinventoryscan.alreadyinstockroom.submit');
};
this.onScanInvalidForSupplierConfirm = function() {
RiotBus.trigger('receiveinventoryscan.productinvalidforsupplier.confirm');
};
</script>
I know it's a lot of code, but I'm very new to riotjs so want to be sure that the typo is visible to you guys.
So in if(!self.isScanDisabled){} I want to access mdt-searchbar. The tags array only includes mma-receive-inventory-review-head-info and mma-receive-inventory-scan-table.
Any idea?
if(isScanEnabled){
if (self.scanInput) {
self.scanInput._tag.setFocus();
}
}
DOM wasn't ready when function was executed in the first run, so check if tag exists and wait a few cycles
at my work I try to print some graph with nvd3.
But I can only display 1 graph on my page, and I don't understand why the previous graph don't appear.
Could you give me some hint ?
<!DOCTYPE html>
<meta charset="utf-8">
<head>
<link href="lib/css/nv.d3.css" rel="stylesheet">
</head>
<style>
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
margin: auto;
position: relative;
width: 960px;
}
/**********
* Legend
*/
.nvd3 .nv-legend .nv-series {
cursor: pointer;
}
.nvd3 .nv-legend .nv-disabled circle {
fill-opacity: 0;
}
text {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
form {
position: absolute;
right: 10px;
top: 10px;
}
#chart, #pid svg {
height: 600px;
width: 600px;
}
</style>
<div id="pid">
<svg></svg>
</div>
<div id="chart">
<svg></svg>
</div>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="lib/js/nv.d3.js"></script>
<script>
var divs = ["pid", "chart"];
divs["pid"]= {id:"#pid svg", datam:[
{
values:[
{x:"M",y:1},
{x:"T",y:2},
{x:"W",y:3},
{x:"R",y:3},
{x:"F",y:4},
{x:"S",y:5},
{x:"U",y:6}
],
key:"Apples"
},
{
values:[
{x:"M",y:5},
{x:"T",y:2},
{x:"W",y:6},
{x:"R",y:8},
{x:"F",y:2},
{x:"S",y:4},
{x:"U",y:1}
],
key:"Zebras"
},
{
values:[
{x:"M",y:4},
{x:"T",y:6},
{x:"W",y:5},
{x:"R",y:7},
{x:"F",y:7},
{x:"S",y:2},
{x:"U",y:5}
],
key:"Bananas"
}
], color:['purple', 'black', 'yellow']};
divs["chart"]= {id:"#chart svg", datam:[
{
values:[
{x:"M",y:1},
{x:"T",y:2},
{x:"W",y:3},
{x:"R",y:3},
{x:"F",y:4},
{x:"S",y:5},
{x:"U",y:6}
],
key:"Apples"
},
{
values:[
{x:"M",y:5},
{x:"T",y:2},
{x:"W",y:6},
{x:"R",y:8},
{x:"F",y:2},
{x:"S",y:4},
{x:"U",y:1}
],
key:"Zebras"
}
], color:['red', 'blue', 'green']};
console.log(divs)
var i=0;
var chart = new Array(2);
nv.render = function render(step) {
// number of graphs to generate in each timeout loop
step = step || 1;
nv.render.active = true;
nv.dispatch.render_start();
setTimeout(function() {
var chart, graph;
for (var i = 0; i < step && (graph = nv.render.queue[i]); i++) {
chart = graph.generate();
if (typeof graph.callback == typeof(Function)) graph.callback(chart);
nv.graphs.push(chart);
}
nv.render.queue.splice(0, i);
if (nv.render.queue.length) setTimeout(arguments.callee, 0);
else {
nv.dispatch.render_end();
nv.render.active = false;
}
}, 0);
};
nv.render.active = false;
nv.render.queue = [];
for (var key in divs) {
console.log(i);
nv.addGraph(function(obj) {
if (typeof arguments[0] === typeof(Function)) {
obj = {generate: arguments[0], callback: arguments[1]};
}
nv.render.queue.push(obj);
console.log(nv.render.queue.length);
if (!nv.render.active) {
nv.render();
}
chart[i] = nv.models.multiBarChart().showControls(true).groupSpacing(0.5).color(divs[key]['color']);
chart[i].yAxis
.tickFormat(d3.format(',.1f'));
d3.select(divs[key]['id'])
.datum(divs[key]['datam'])
.transition().duration(500).call(chart[i]);
nv.utils.windowResize(chart[i].update);
return chart[i];
});
i++;
};
// render function is used to queue up chart rendering
// in non-blocking timeout functions
</script>
I hope you colud help me, thanks.