How to save HTML5 canvas image as json file - html5-canvas

Hi I am new to HTML5 canvas i have draw rectangle boxes in canvas with name i want to save the canvas image as JSON file(Json file also given below how i want json file) (i am going to do drag and drop functionalities later with in the Canvas layout after need to save the modified Layout as a JSON file(Here first i asked to convert Canvas Layout as JSON file))
<html>
<body>
<canvas id="NodeList" name="NodeList" style="border:2px solid black;" width="1078" height="450"></canvas>
</body>
</html>
<script>
var c = document.getElementById("NodeList");
var ctx = c.getContext("2d");
ctx.rect(3,3,40,40);
ctx.fillText(1, 15, 25);
ctx.rect(46,3,40,40);
ctx.fillText(2, 65, 25);
ctx.rect(89,3,40,40);
ctx.fillText(3, 105, 25);
ctx.rect(3,46,40,40);
ctx.fillText(4, 13, 70);
ctx.rect(46,46,40,40);
ctx.fillText(5, 56, 70);
ctx.rect(89,46,40,40);
ctx.fillText(6, 99, 70);
ctx.rect(606,3,40,40);
ctx.fillText(7, 616, 25);
ctx.rect(649,3,40,40);
ctx.fillText(8, 659, 25);
ctx.rect(821,3,40,40);
ctx.fillText(9, 831, 25);
ctx.rect(864,3,40,40);
ctx.fillText(10, 874, 25);
ctx.font="15px Verdana";
ctx.fillText('Shop', 415,205);
ctx.fillText('sweets', 55, 110);
ctx.fillText('Zone 1', 55, 130);
ctx.fillText('fried grams', 780, 110);
ctx.fillText('Zone 2', 780, 130);
ctx.stroke();
</script>
Need to save Canvas layout Output as JSON File like below
[
{
"x":3,
"y":3,
"height":40,
"width":40,
"binnum":1,
"binx":13,
"biny":25
},
{
"x":46,
"y":3,
"height":40,
"width":40,
"binnum":2,
"binx":56,
"biny":25
},
{
"x":89,
"y":3,
"height":40,
"width":40,
"binnum":3,
"binx":99,
"biny":25
},
{
"x":3,
"y":46,
"height":40,
"width":40,
"binnum":6,
"binx":13,
"biny":70
},
{
"x":46,
"y":46,
"height":40,
"width":40,
"binnum":7,
"binx":56,
"biny":70
},
{
"x":89,
"y":46,
"height":40,
"width":40,
"binnum":8,
"binx":99,
"biny":70
},
{
"x":606,
"y":3,
"height":40,
"width":40,
"binnum":10,
"binx":616,
"biny":25
},
{
"x":649,
"y":3,
"height":40,
"width":40,
"binnum":11,
"binx":659,
"biny":25
},
{
"x":821,
"y":3,
"height":40,
"width":40,
"binnum":15,
"binx":831,
"biny":25
},
{
"x":864,
"y":3,
"height":40,
"width":40,
"binnum":16,
"binx":874,
"biny":25
}
]

You could attain this in the following way ...
<html>
<body>
<canvas id="NodeList" name="NodeList" style="border:2px solid black;" width="1078" height="450"></canvas>
<script>
let c = document.getElementById("NodeList");
let ctx = c.getContext("2d");
let data = [{
rect: [3, 3, 40, 40],
text: [1, 15, 25]
}, {
rect: [46, 3, 40, 40],
text: [2, 65, 25]
}, {
rect: [89, 3, 40, 40],
text: [3, 105, 25]
}, {
rect: [3, 46, 40, 40],
text: [4, 13, 70]
}, {
rect: [46, 46, 40, 40],
text: [5, 56, 70]
}, {
rect: [89, 46, 40, 40],
text: [6, 99, 70]
}, {
rect: [606, 3, 40, 40],
text: [7, 616, 25]
}, {
rect: [649, 3, 40, 40],
text: [8, 659, 25]
}, {
rect: [821, 3, 40, 40],
text: [9, 831, 25]
}, {
rect: [864, 3, 40, 40],
text: [10, 874, 25]
}];
ctx.font = "15px Verdana";
ctx.fillText('Shop', 415, 205);
ctx.fillText('sweets', 55, 110);
ctx.fillText('Zone 1', 55, 130);
ctx.fillText('fried grams', 780, 110);
ctx.fillText('Zone 2', 780, 130);
function getJSON(ctx, data) {
let ja = [];
data.forEach(function(e) {
let ra = e.rect,
ta = e.text;
ja.push({
"x": ra[0],
"y": ra[1],
"height": ra[2],
"width": ra[3],
"binnum": ta[0],
"binx": ta[1],
"biny": ta[2]
});
ctx.strokeRect(ra[0], ra[1], ra[2], ra[3]);
ctx.fillText(ta[0], ta[1], ta[2]);
});
return ja;
}
let json = getJSON(ctx, data);
console.log(json);
</script>
</body>
</html>

Related

Add an image as background in ChartJS chart area [Not to canvas]

Is there any way to add an image into chart area [I'm using chart JS bubble chart].
Presently I added image to canvas through css.
Best approach, drawing it on the canvas
The best way to achieve this is by drawing it directly on the canvas since you have direct access and control over the pixels so you are sure it is aligned pixel perfect.
Extending on uminders answer, but making it so it only draws within the chart area:
const myChart = new Chart('myChart', {
type: 'bubble',
plugins: [{
beforeDraw: chart => {
var ctx = chart.ctx;
ctx.save();
const image = new Image();
image.src = 'https://upload.wikimedia.org/wikipedia/commons/thumb/0/02/Stack_Overflow_logo.svg/2560px-Stack_Overflow_logo.svg.png';
ctx.drawImage(image, chart.chartArea.left, chart.chartArea.top, chart.chartArea.width, chart.chartArea.height);
ctx.restore();
}
}],
data: {
datasets: [{
label: 'My Dataset',
data: [{
x: 0,
y: 12,
r: 10
},
{
x: 1,
y: 19,
r: 12
},
{
x: 2,
y: 3,
r: 8
},
{
x: 3,
y: 5,
r: 7
},
{
x: 4,
y: 2,
r: 4
},
{
x: 5,
y: 3,
r: 8
}
],
backgroundColor: [
'rgba(255, 99, 132, 0.4)',
'rgba(54, 162, 235, 0.4)',
'rgba(255, 206, 86, 0.4)',
'rgba(75, 192, 192, 0.4)',
'rgba(153, 102, 255, 0.4)',
'rgba(255, 159, 64, 0.4)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
]
}]
},
options: {
responsive: true,
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.8.0/chart.js"></script>
<canvas id="myChart" height="80"></canvas>
Alternative approach without drawing on the canvas
If you really don't want to draw it on the canvas but use a normal img element, you can use an absolute position and use a custom plugin to position it correctly, downside is that it seems that canvas pixels are different from CSS so they cant be used 1:1 and have to be approximated which may lead to slight alignment issues:
const myChart = new Chart('myChart', {
type: 'bubble',
plugins: [{
beforeDraw: chart => {
const image = document.getElementById('img')
image.width = chart.chartArea.width;
image.height = chart.chartArea.height;
image.style.left = `${chart.chartArea.left*1.3}px`;
image.style.top = `${chart.chartArea.top*1.3}px`;
}
}],
data: {
datasets: [{
label: 'My Dataset',
data: [{
x: 0,
y: 12,
r: 10
},
{
x: 1,
y: 19,
r: 12
},
{
x: 2,
y: 3,
r: 8
},
{
x: 3,
y: 5,
r: 7
},
{
x: 4,
y: 2,
r: 4
},
{
x: 5,
y: 3,
r: 8
}
],
backgroundColor: [
'rgba(255, 99, 132, 0.4)',
'rgba(54, 162, 235, 0.4)',
'rgba(255, 206, 86, 0.4)',
'rgba(75, 192, 192, 0.4)',
'rgba(153, 102, 255, 0.4)',
'rgba(255, 159, 64, 0.4)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
]
}]
},
options: {
responsive: true,
}
});
#img {
position: absolute;
z-index: -1/* Draw image behind the canvas */
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.8.0/chart.js"></script>
<img id="img" src="https://upload.wikimedia.org/wikipedia/commons/thumb/0/02/Stack_Overflow_logo.svg/2560px-Stack_Overflow_logo.svg.png" />
<canvas id="myChart" height="80"></canvas>
The Plugin Core API offers a range of hooks that can be used for performing custom code. You can use the beforeDraw for example to draw the images through CanvasRenderingContext2D.drawImage(). But this effectively draws the image directly on the canvas.
plugins: [{
beforeDraw: chart => {
var ctx = chart.chart.ctx;
ctx.save();
var image = new Image();
image.src = 'https://i.stack.imgur.com/S7tJH.png';
imageSize = 250;
ctx.drawImage(image, chart.chart.width / 2 - imageSize / 2, chart.chart.height / 2 - imageSize / 2, imageSize, imageSize);
ctx.restore();
}
}],
Please have a look at the runnable code snippet below.
var myChart = new Chart('myChart', {
type: 'bubble',
plugins: [{
beforeDraw: chart => {
var ctx = chart.chart.ctx;
ctx.save();
var image = new Image();
image.src = 'https://i.stack.imgur.com/S7tJH.png';
imageSize = 250;
ctx.drawImage(image, chart.chart.width / 2 - imageSize / 2, chart.chart.height / 2 - imageSize / 2, imageSize, imageSize);
ctx.restore();
}
}],
data: {
datasets: [{
label: 'My Dataset',
data: [
{ x: "05:22", y: 12, r: 10 },
{ x: "12:13", y: 19, r: 12 },
{ x: "13:45", y: 3, r: 8 },
{ x: "18:31", y: 5, r: 7 },
{ x: "19:05", y: 2, r: 4 },
{ x: "22:55", y: 3, r: 8 }
],
backgroundColor: [
'rgba(255, 99, 132, 0.4)',
'rgba(54, 162, 235, 0.4)',
'rgba(255, 206, 86, 0.4)',
'rgba(75, 192, 192, 0.4)',
'rgba(153, 102, 255, 0.4)',
'rgba(255, 159, 64, 0.4)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
]
}]
},
options: {
responsive: true,
legend: {
display: false
},
scales: {
xAxes: [{
type: 'time',
time: {
parser: 'HH:mm',
unit: 'hour',
stepSize: 1,
displayFormats: {
hour: 'HH:mm'
},
tooltipFormat: 'HH:mm'
},
ticks: {
min: '00:00',
max: '24:00',
callback: (value, index) => index == 24 ? '24:00' : value
}
}],
yAxes: [{
ticks: {
beginAtZero: true,
stepSize: 5
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js"></script>
<canvas id="myChart" height="80"></canvas>

C3 Extent not working as expected

I'm creating a pretty simple line graph and want the initial load to be a section of all available data, so am setting extent on the x axis:
This is how I am setting the extent:
axis: {
"x": {
"type": "timeseries",
"tick": {
"format": "%d/%m/%Y"
},
"label": {
"text": "X Label",
"position": "outer-center"
},
"padding": {
"left": 0
},
"extent": ["2017-10-01", "2017-10-05"]
},
"y": {
"label": {
"text": "Y Label",
"position": "outer-middle"
}
}
},
But it is ignored. The chart just shows the full extent of the data.
Is this the correct way to show a subset of the data when the chart is generated?
This is the full code and here's a fiddle (I tried a code snippet but didn't work)
const columnData = [
["x", "2017-10-01", "2017-10-02", "2017-10-03", "2017-10-04", "2017-10-05", "2017-10-06", "2017-10-07", "2017-10-08", "2017-10-09", "2017-10-10", "2017-10-11", "2017-10-12", "2017-10-13", "2017-10-14", "2017-10-15", "2017-10-16"],
["data0", -55, -50, 11, -18, 39, 65, -84, -15, 14, 81, -79, 67, -48, 38, 99, -60],
["data1", 28, 14, -99, -33, 55, 71, 58, 66, 7, -88, 99, -37, -7, 59, -13, -57],
["data2", 14, 6, -9, 25, 42, -93, -6, 67, -35, 88, 36, 45, 42, 78, 51, -88],
["data3", 31, -73, -69, 45, 55, 15, -48, 41, -64, -12, -6, 14, -69, 16, -65, -73],
["data4", 98, 60, 82, 80, -62, -47, 55, 87, -65, 37, 22, 30, 93, -69, -88, 33],
["data5", -98, 57, 71, -25, -40, 13, 72, -90, 71, -71, -21, -9, -90, 73, -94, 100]
];
const generateChart = function() {
const chart = c3.generate({
data: {
"x": "x",
"columns": columnData,
"type": "line"
},
axis: {
"x": {
"type": "timeseries",
"tick": {
"format": "%d/%m/%Y"
},
"label": {
"text": "X Label",
"position": "outer-center"
},
"padding": {
"left": 0
},
"extent": ["2017-10-01", "2017-10-05"]
},
"y": {
"label": {
"text": "Y Label",
"position": "outer-middle"
}
}
},
zoom: {
enabled: true
},
transition: {
duration: 100
},
legend: {
show: false
},
subchart: {
show: true
},
size: {
height: 500
},
grid: {
x: {
show: true
},
y: {
show: true
}
}
});
};
generateChart();
As of 11th May 2018 it seems this is a bug: https://github.com/c3js/c3/issues/2357
I switched to earlier versions (see below) of C3 and D3 and it works as it should.
I am now using C3 version 0.4.10 and D3 version 3.5.0

How to allow Duplicate Tick Labels in Plotly?

I observed that while providing duplicate ticklabels (with an aim to mention the class of categorical variable), plotly creates a unique set and displays only the non-repeated tick labels. Is there a way to by-pass this feature and allow duplicate tick-labels?
var data = [
{
z: [[1, 20, 30, 50, 1], [20, 1, 60, 80, 30], [30, 60, 1, -10, 20]],
x: ['Healthy', 'Healthy', 'Moderate', 'Diseased', 'Diseased'],
y: ['Morning', 'Afternoon', 'Evening'],
type: 'heatmap'
}
];
Plotly.newPlot('myDiv', data);
Following is the jsfiddle depicting the issue:
https://jsfiddle.net/mam8sgwx/
Set the layout with ticktext:
var layout = {
xaxis: {
tickmode: "array",
ticktext: ['Healthy', 'Healthy', 'Moderate', 'Diseased', 'Diseased'],
tickvals: [0, 1, 2, 3, 4]
}
}
Here is the demo:
var data = [{
z: [
[1, 20, 30, 50, 1],
[20, 1, 60, 80, 30],
[30, 60, 1, -10, 20]
],
y: ['Morning', 'Afternoon', 'Evening'],
type: 'heatmap'
}];
var layout = {
xaxis: {
tickmode: "array",
ticktext: ['Healthy', 'Healthy', 'Moderate', 'Diseased', 'Diseased'],
tickvals: [0, 1, 2, 3, 4]
}
}
Plotly.newPlot('myDiv', data, layout);
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<body>
<div id="myDiv"></div>

Processing hierarchical JSON data with d3.js

I'm trying to understand how to use more complicated data sets with d3. Below I will show the JSON data I would like to display;
{
"questions": ["Large choice of food", "Food quality", "Food freshness", "Taste of food", "Waiting time to recieve food", "Value for money"],
"places": ["US", "UK", "TK"],
"dates": ["Jan", "Feb", "Mar"],
"values": [
[
[24, 42, 72],
[29, 45, 79],
[34, 39, 84]
],
[
[33, 73, 41],
[21, 16, 45],
[43, 22, 17]
],
[
[75, 53, 78],
[55, 33, 22],
[94, 83, 99]
],
[
[63, 37, 11],
[47, 67, 62],
[33, 34, 35]
],
[
[43, 89, 78],
[99, 92, 87],
[41, 23, 71]
],
[
[92, 11, 45],
[100, 0, 50],
[40, 72, 62]
]
]
}
From here I would like to be able to select one question, then pair it with a place + date and then retrieve the value based on this.
I have tried to find resources online which could help educate me with how to access this kind of data in this way, but i've had no such luck. I have created a plnk to provide a set up for this.
http://plnkr.co/edit/Cdwm5RXoIdBNg0uxeeP6?p=preview
So the question is how can I retrieve this data in d3, and display it in the console in the order of question+[place + date][values based on this].
Any advice and links to good educational resources would be a big help for me at this stage,
Cheers
EDIT:
The above JSON format may be a little confusing, here is perhaps a more simplified version?
{
"dates": ["Jan", "Feb", "Mar"],
"questions": {
"Large choice of food": {
"US": [11, 15, 13],
"UK": [25, 24, 39],
"TK": [27, 23, 20]
},
"Food quality": {
"US": [11, 15, 13],
"UK": [25, 24, 40],
"TK": [27, 23, 20]
},
}
}
Here is something I put together but it isn't using D3, but vanilla JS. So I'm not sure if you want this but I'll throw it in anyway. Rather self explanatory: http://plnkr.co/edit/ckm45FB3RVhofGbUjdBl?p=preview
Main chunk of code :
var questionData = data.questions;
var monthData = data.dates;
var countryData = data.places;
//populate question drop down
var questionSelect = document.getElementById('questionSelect');
for(i=0;i<questionData.length;i++){
var option = document.createElement('option');
option.text = questionData[i];
option.value = questionData[i];
questionSelect.appendChild(option);
}
var submitButton = document.getElementById('submitButton');
submitButton.addEventListener('click', getData);
function getData(){
var thisQuestion = document.getElementById('questionSelect').value;
var thisCountry = document.getElementById('countrySelect').value;
var thisMonth = document.getElementById('monthSelect').value;
var questionIndex = questionData.indexOf(thisQuestion);
var countryIndex = countryData.indexOf(thisCountry);
var monthIndex = monthData.indexOf(thisMonth);
var getValue = data.values[questionIndex][monthIndex][countryIndex]; //this is the found value
console.log(getValue)
}

Set in kendogrid sparkline

I am going to use sparkline in the" usage" column, just in the way that the two sparkline chart cover each other
There is a problem because when I click on the button Edite "sparkline" disappears.
Or click on "usage column" think that happens.
Why tooltip as bad as it can be displayed tooltip not regular.
Why sparkline "usage column" in all rows, there is only one row
jsfiddle code
$(document).ready(function () {
//var ds = new kendo.data.DataSource({
// transport: {
// read: {
// url: '/api/clientssnapshot',
// dataType: 'json',
// type: 'get',
// cache: false
// },
// },
// batch: true,
// pageSize: 10,
// schema: {
// model: {
// fields: {
// Mac: { editable: false, nullable: true },
// RadioName: { type: "string", validation: { required: true } },
// ApName: { type: "string", validation: { required: true, min: 1 } },
// RemoteIp: { type: "boolean" },
// TX: { type: "number", validation: { min: 0, required: true } },
// RX: { type: "number", validation: { min: 0, required: true } },
// Signal: { type: "number", validation: { min: 0, required: true } },
// Uptime: { type: "number", validation: { min: 0, required: true } },
// }
// }
// }
//});
$('.table').kendoGrid({
dataSource: {
data: [{
"Mac": "D4:CA:6D:28:D1:05",
"RadioName": "D4CA6D28D105",
"ApName": "Om11",
"ApIp": "10.20.0.100",
"TX": 48,
"RX": 54,
"Signal": -64,
"Uptime": 797452,
"InRate": 0,
"OutRate": 0,
"AccountingId": 759,
"AccountingName": "فرشاد صفایی زاده",
"RemoteIp": "188.121.123.56",
"IsValidInScan": true,
"Comments": null,
"ApScanId": 26173,
"InRateHistory": "0, 0, 0, 0, 2, 0, 2, 16, 96, 16, 96, 16, 96, 113, 31, 113, 31, 113, 31, 0",
"OutRateHistory": "0, 5, 3, 5, 2, 5, 2, 35, 136, 35, 136, 35, 136, 164, 51, 164, 51, 164, 51, 4"
}, {
"Mac": "00:15:6D:BD:64:92",
"RadioName": "Behrooz Hoseyn",
"ApName": "Om11",
"ApIp": "10.20.0.100",
"TX": 48,
"RX": 18,
"Signal": -65,
"Uptime": 797446,
"InRate": 2,
"OutRate": 2,
"AccountingId": 750,
"AccountingName": "بهروز حسینی",
"RemoteIp": "188.121.123.48",
"IsValidInScan": true,
"Comments": null,
"ApScanId": 26173,
"InRateHistory": "0, 0, 0, 0, 2, 0, 2, 16, 96, 16, 96, 16, 96, 113, 31, 113, 31, 113, 31, 0",
"OutRateHistory": "0, 5, 3, 5, 2, 5, 2, 35, 136, 35, 136, 35, 136, 164, 51, 164, 51, 164, 51, 4"
}, {
"Mac": "00:15:6D:1E:B3:6C",
"RadioName": "UBNT",
"ApName": "Om11",
"ApIp": "10.20.0.100",
"TX": 54,
"RX": 24,
"Signal": -65,
"Uptime": 310336,
"InRate": 0,
"OutRate": 0,
"AccountingId": 820,
"AccountingName": "******",
"RemoteIp": "10.10.15.129",
"IsValidInScan": true,
"Comments": null,
"ApScanId": 26173,
"InRateHistory": "0, 0, 0, 0, 2, 0, 2, 16, 96, 16, 96, 16, 96, 113, 31, 113, 31, 113, 31, 0",
"OutRateHistory": "0, 5, 3, 5, 2, 5, 2, 35, 136, 35, 136, 35, 136, 164, 51, 164, 51, 164, 51, 4"
}, {
"Mac": "00:15:6D:1C:B1:89",
"RadioName": "Grous Tajhiz P",
"ApName": "Om11",
"ApIp": "10.20.0.100",
"TX": 48,
"RX": 6,
"Signal": -62,
"Uptime": 122116,
"InRate": 0,
"OutRate": 0,
"AccountingId": 595,
"AccountingName": "حمید شمس لواسانی",
"RemoteIp": "188.121.124.17",
"IsValidInScan": true,
"Comments": null,
"ApScanId": 26173,
"InRateHistory": "0, 0, 0, 0, 2, 0, 2, 16, 96, 16, 96, 16, 96, 113, 31, 113, 31, 113, 31, 0",
"OutRateHistory": "0, 5, 3, 5, 2, 5, 2, 35, 136, 35, 136, 35, 136, 164, 51, 164, 51, 164, 51, 4"
}, {
"Mac": "00:27:22:3E:91:12",
"RadioName": "Anbar Aminzade",
"ApName": "Om1",
"ApIp": "10.20.0.101",
"TX": 36,
"RX": 36,
"Signal": -68,
"Uptime": 1131461,
"InRate": 4,
"OutRate": 4,
"AccountingId": 977,
"AccountingName": "انبار شهید امین زاده ",
"RemoteIp": "188.121.123.31",
"IsValidInScan": true,
"Comments": null,
"ApScanId": 26173,
"InRateHistory": "0, 0, 0, 0, 2, 0, 2, 16, 96, 16, 96, 16, 96, 113, 31, 113, 31, 113, 31, 0",
"OutRateHistory": "0, 5, 3, 5, 2, 5, 2, 35, 136, 35, 136, 35, 136, 164, 51, 164, 51, 164, 51, 4"
}, {
"Mac": "00:15:6D:1A:59:D0",
"RadioName": "UBNT",
"ApName": "Om1",
"ApIp": "10.20.0.101",
"TX": 36,
"RX": 12,
"Signal": -73,
"Uptime": 734737,
"InRate": 2,
"OutRate": 2,
"AccountingId": 820,
"AccountingName": "******",
"RemoteIp": "10.10.15.76",
"IsValidInScan": true,
"Comments": null,
"ApScanId": 26173,
"InRateHistory": "0, 0, 0, 0, 2, 0, 2, 16, 96, 16, 96, 16, 96, 113, 31, 113, 31, 113, 31, 0",
"OutRateHistory": "0, 5, 3, 5, 2, 5, 2, 35, 136, 35, 136, 35, 136, 164, 51, 164, 51, 164, 51, 4"
}, {
"Mac": "00:15:6D:E2:2D:13",
"RadioName": "UBNT",
"ApName": "Om1",
"ApIp": "10.20.0.101",
"TX": 54,
"RX": 36,
"Signal": -72,
"Uptime": 848,
"InRate": 0,
"OutRate": 0,
"AccountingId": 820,
"AccountingName": "******",
"RemoteIp": "10.10.15.67",
"IsValidInScan": true,
"Comments": null,
"ApScanId": 26173,
"InRateHistory": "0, 0, 0, 0, 2, 0, 2, 16, 96, 16, 96, 16, 96, 113, 31, 113, 31, 113, 31, 0",
"OutRateHistory": "0, 5, 3, 5, 2, 5, 2, 35, 136, 35, 136, 35, 136, 164, 51, 164, 51, 164, 51, 4"
}, {
"Mac": "00:27:22:32:24:C9",
"RadioName": "UBNT",
"ApName": "Om7",
"ApIp": "10.20.0.100",
"TX": 36,
"RX": 24,
"Signal": -78,
"Uptime": 731588,
"InRate": 0,
"OutRate": 0,
"AccountingId": 820,
"AccountingName": "******",
"RemoteIp": "10.10.15.188",
"IsValidInScan": true,
"Comments": null,
"ApScanId": 26173,
"InRateHistory": "0, 0, 0, 0, 2, 0, 2, 16, 96, 16, 96, 16, 96, 113, 31, 113, 31, 113, 31, 0",
"OutRateHistory": "0, 5, 3, 5, 2, 5, 2, 35, 136, 35, 136, 35, 136, 164, 51, 164, 51, 164, 51, 4"
}, {
"Mac": "00:15:6D:FE:BB:E2",
"RadioName": "ketabforooshie",
"ApName": "Om7",
"ApIp": "10.20.0.100",
"TX": 54,
"RX": 36,
"Signal": -72,
"Uptime": 240361,
"InRate": 0,
"OutRate": 0,
"AccountingId": 533,
"AccountingName": "قاسم رضاپور",
"RemoteIp": "188.121.124.214",
"IsValidInScan": true,
"Comments": null,
"ApScanId": 26173,
"InRateHistory": "0, 0, 0, 0, 2, 0, 2, 16, 96, 16, 96, 16, 96, 113, 31, 113, 31, 113, 31, 0",
"OutRateHistory": "0, 5, 3, 5, 2, 5, 2, 35, 136, 35, 136, 35, 136, 164, 51, 164, 51, 164, 51, 4"
}, {
"Mac": "00:27:22:D2:86:56",
"RadioName": "UBNT",
"ApName": "Om7",
"ApIp": "10.20.0.100",
"TX": 48,
"RX": 12,
"Signal": -72,
"Uptime": 126430,
"InRate": 0,
"OutRate": 0,
"AccountingId": 1453,
"AccountingName": "حسن قربانی",
"RemoteIp": "188.121.123.154",
"IsValidInScan": true,
"Comments": null,
"ApScanId": 26173,
"InRateHistory": "0, 0, 0, 0, 2, 0, 2, 16, 96, 16, 96, 16, 96, 113, 31, 113, 31, 113, 31, 0",
"OutRateHistory": "0, 5, 3, 5, 2, 5, 2, 35, 136, 35, 136, 35, 136, 164, 51, 164, 51, 164, 51, 4"
}, {
"Mac": "00:27:22:78:A3:19",
"RadioName": "UBNT",
"ApName": "Om7",
"ApIp": "10.20.0.100",
"TX": 54,
"RX": 54,
"Signal": -56,
"Uptime": 58617,
"InRate": 0,
"OutRate": 0,
"AccountingId": 820,
"AccountingName": "******",
"RemoteIp": "10.10.15.39",
"IsValidInScan": true,
"Comments": null,
"ApScanId": 26173,
"InRateHistory": "0, 0, 0, 0, 2, 0, 2, 16, 96, 16, 96, 16, 96, 113, 31, 113, 31, 113, 31, 0",
"OutRateHistory": "0, 5, 3, 5, 2, 5, 2, 35, 136, 35, 136, 35, 136, 164, 51, 164, 51, 164, 51, 4"
}
]
},
sortable: true,
groupable: true,
selectable: true,
navigatable: true,
height: 500,
scrollable: true,
pageable: true,
columns: [{
field: "Mac",
title: "Mac",
width: 170
}, {
field: "RadioName",
title: "Radio",
width: 150
}, {
field: "ApName",
title: "Ap",
width: 80,
template: '#=ApName#'
}, {
field: "RemoteIp",
title: "Remote IP",
width: 160,
template: '#=RemoteIp#'
}, {
field: "AccountingName",
title: "Name",
width: 130,
template: ' #= AccountingName # '
}, {
field: "TX",
title: "TX",
width: 44
}, {
field: "RX",
title: "RX",
width: 50
}, {
field: "Signal",
title: "Signal",
width: 50
}, {
field: "Uptime",
title: "Uptime",
width: 78
}, {
field: "Usage",
title: "Usage",
template: '<span id="sparkline"></span>'
}, {
command: ["edit"],
title: " "
}],
editable: "popup",
});
$(".ref").click(function () {
$(".table").data("kendoGrid").dataSource.read();
});
$("#sparkline").kendoSparkline({
type: "area",
series: [{
name: "World",
data: [15.7, 16.7, 20, 23.5, 26.6, 24.8, 24.1, 20.1, 14.1, 8.6, 2.5, 3.5],
}, {
name: 'New York',
data: [0.7, 0.8, 5.7, 11.3, 17.0, 22.0, 24.8, 24.1, 20.1, 14.1, 8.6, 2.5],
}],
categoryAxis: {
categories: [2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015]
}
});
<div class="span6 box gradient main_stting">
<div class="dataTables_filter" id="txtSearch">
<label>Search:
<input type="text" aria-controls="DataTables_Table_0">
</label>
</div>
<div class="title">
<button class="btn ref" type="submit">Refresh</button>
<h3></h3>
</div>
<div class="content">
<div class="table"></div>
</div>
thank you
After edit, the HTML elements are destroyed and recreated when the Grid updates. You will need to recreate your sparklines. It is basically the same as this issue.

Resources