amChart draggable pie chart rendering dummy slide - javascript

I am attempting to add a chart from amChart into my php project and everything seems to be going OK, I have two parameters and when I change them, it loads the data into my array.
I am using a new chat, a draggable pie chart and this chart seems to be making use of a "dummy" slide to do percentages and calculations.
The problem is, when my data first loads, it loads this dummy slide which of course throws off my dat and I have to manually drag it out for my chart to be correct.
I have inserted my code below, alot of the code is from the libary and my changes only involve the ajax code used to manipulate the data of the chart.
Grateful for any assistance.
<script>
// Themes begin
am4core.useTheme(am4themes_animated);
// Themes end
var data;
jQuery(document).ready(function () {
// appHandleUniform()
$('.datepicker').datepicker({
rtl: App.isRTL(),
autoclose: true,
weekStart: app_cfg_first_day_of_week,
format: 'yyyy-mm-dd',
clearBtn: true,
});
});
var pData;
var data = [{
"country": "Dummy",
"disabled": true,
"litres": 1000,
"color": am4core.color("#dadada"),
"opacity": 0.3,
"strokeDasharray": "4,4"
} /*{
"country": "Apple",
"litres": 501.9
}, {
"country": "Pest",
"litres": 301.9
}, {
"country": "Ireland",
"litres": 201.1
}, {
"country": "Germany",
"litres": 165.8
}, {
"country": "Australia",
"litres": 139.9
}, {
"country": "Austria",
"litres": 128.3
}*/ ];
// cointainer to hold both charts
var container = am4core.create("chartdiv", am4core.Container);
container.width = am4core.percent(100);
container.height = am4core.percent(100);
container.layout = "horizontal";
container.events.on("maxsizechanged", function () {
chart1.zIndex = 0;
separatorLine.zIndex = 1;
dragText.zIndex = 2;
chart2.zIndex = 3;
})
var chart1 = container.createChild(am4charts.PieChart);
chart1.validateData();
var startDate = endDate = "";
$("#start_date").change(function () {
startDate = $(this).val();
});
$("#end_date").change(function () {
endDate = $(this).val();
if (startDate != "" && endDate != "") {
$.ajax({
type: "POST",
url: '<?php echo url_for("charts/getEntryFormsData") ?>',
data: {startDate: startDate, endDate: endDate},
success: function (data) {
pData = $.parseJSON(data);
// or
//chart1.validateData();
chart1.data = [{
"country": "Dummy",
"disabled": true,
"litres": 1000,
"color": am4core.color("#dadada"),
"opacity": 0.3,
"strokeDasharray": "4,4"
},{
"country": "CTR",
"litres": pData["CTR"].length
}, {
"country": "DRFI",
"litres": pData["DRFI"].length
}, {
"country": "FIUIN",
"litres": pData["FIUIN"].length
}, {
"country": "RFA",
"litres": pData["RFA"].length
}, {
"country": "RFIR",
"litres": pData["RFIR"].length
}, {
"country": "TPR",
"litres": pData["TPR"].length
}];
}
});
} else {
alert("Choose Start Date First");
$("#end_date").val("");
}
});
// chart1.data=data;
chart1 .fontSize = 11;
chart1.hiddenState.properties.opacity = 0; // this makes initial fade in effect
//chart1.data = data;
//chart1.validateData();
chart1.radius = am4core.percent(70);
chart1.innerRadius = am4core.percent(40);
chart1.zIndex = 1;
var series1 = chart1.series.push(new am4charts.PieSeries());
series1.dataFields.value = "litres";
series1.dataFields.category = "country";
series1.colors.step = 2;
series1.alignLabels = false;
series1.labels.template.bent = true;
series1.labels.template.radius = 3;
series1.labels.template.padding(0,0,0,0);
var sliceTemplate1 = series1.slices.template;
sliceTemplate1.cornerRadius = 5;
sliceTemplate1.draggable = true;
sliceTemplate1.inert = true;
sliceTemplate1.propertyFields.fill = "color";
sliceTemplate1.propertyFields.fillOpacity = "opacity";
sliceTemplate1.propertyFields.stroke = "color";
sliceTemplate1.propertyFields.strokeDasharray = "strokeDasharray";
sliceTemplate1.strokeWidth = 1;
sliceTemplate1.strokeOpacity = 1;
var zIndex = 5;
sliceTemplate1.events.on("down", function (event) {
event.target.toFront();
// also put chart to front
var series = event.target.dataItem.component;
series.chart.zIndex = zIndex++;
})
series1.ticks.template.disabled = true;
sliceTemplate1.states.getKey("active").properties.shiftRadius = 0;
sliceTemplate1.events.on("dragstop", function (event) {
handleDragStop(event);
})
// separator line and text
var separatorLine = container.createChild(am4core.Line);
separatorLine.x1 = 0;
separatorLine.y2 = 300;
separatorLine.strokeWidth = 3;
separatorLine.stroke = am4core.color("#dadada");
separatorLine.valign = "middle";
separatorLine.strokeDasharray = "5,5";
var dragText = container.createChild(am4core.Label);
dragText.text = "Drag slices over the line";
dragText.rotation = 90;
dragText.valign = "middle";
dragText.align = "center";
dragText.paddingBottom = 5;
// second chart
var chart2 = container.createChild(am4charts.PieChart);
chart2.hiddenState.properties.opacity = 0; // this makes initial fade in effect
chart2 .fontSize = 11;
chart2.radius = am4core.percent(70);
// or
//chart1.validateData();
chart2.data = [{
"country": "Dummy",
"disabled": true,
"litres": 1000,
"color": am4core.color("#dadada"),
"opacity": 0.3,
"strokeDasharray": "4,4"
}, {
"country": "CTR",
"litres": 4
}, {
"country": "DRFI",
"litres":2
}, {
"country": "FIUIN",
"litres": 5
}, {
"country": "RFA",
"litres": 5
}, {
"country": "RFIR",
"litres":6
}, {
"country": "TPR",
"litres": 6
}];
chart2.validateData();
//chart2.data = data;
chart2.innerRadius = am4core.percent(40);
chart2.zIndex = 1;
var series2 = chart2.series.push(new am4charts.PieSeries());
series2.dataFields.value = "litres";
series2.dataFields.category = "country";
series2.colors.step = 2;
series2.alignLabels = false;
series2.labels.template.bent = true;
series2.labels.template.radius = 3;
series2.labels.template.padding(0,0,0,0);
series2.labels.template.propertyFields.disabled = "disabled";
var sliceTemplate2 = series2.slices.template;
sliceTemplate2.copyFrom(sliceTemplate1);
series2.ticks.template.disabled = true;
function handleDragStop(event) {
var targetSlice = event.target;
var dataItem1;
var dataItem2;
var slice1;
var slice2;
if (series1.slices.indexOf(targetSlice) != -1) {
slice1 = targetSlice;
slice2 = series2.dataItems.getIndex(targetSlice.dataItem.index).slice;
}
else if (series2.slices.indexOf(targetSlice) != -1) {
slice1 = series1.dataItems.getIndex(targetSlice.dataItem.index).slice;
slice2 = targetSlice;
}
dataItem1 = slice1.dataItem;
dataItem2 = slice2.dataItem;
var series1Center = am4core.utils.spritePointToSvg({ x: 0, y: 0 }, series1.slicesContainer);
var series2Center = am4core.utils.spritePointToSvg({ x: 0, y: 0 }, series2.slicesContainer);
var series1CenterConverted = am4core.utils.svgPointToSprite(series1Center, series2.slicesContainer);
var series2CenterConverted = am4core.utils.svgPointToSprite(series2Center, series1.slicesContainer);
// tooltipY and tooltipY are in the middle of the slice, so we use them to avoid extra calculations
var targetSlicePoint = am4core.utils.spritePointToSvg({ x: targetSlice.tooltipX, y: targetSlice.tooltipY }, targetSlice);
if (targetSlice == slice1) {
if (targetSlicePoint.x > container.pixelWidth / 2) {
var value = dataItem1.value;
dataItem1.hide();
var animation = slice1.animate([{ property: "x", to: series2CenterConverted.x }, { property: "y", to: series2CenterConverted.y }], 400);
animation.events.on("animationprogress", function (event) {
slice1.hideTooltip();
})
slice2.x = 0;
slice2.y = 0;
dataItem2.show();
}
else {
slice1.animate([{ property: "x", to: 0 }, { property: "y", to: 0 }], 400);
}
}
if (targetSlice == slice2) {
if (targetSlicePoint.x < container.pixelWidth / 2) {
var value = dataItem2.value;
dataItem2.hide();
var animation = slice2.animate([{ property: "x", to: series1CenterConverted.x }, { property: "y", to: series1CenterConverted.y }], 400);
animation.events.on("animationprogress", function (event) {
slice2.hideTooltip();
})
slice1.x = 0;
slice1.y = 0;
dataItem1.show();
}
else {
slice2.animate([{ property: "x", to: 0 }, { property: "y", to: 0 }], 400);
}
}
toggleDummySlice(series1);
toggleDummySlice(series2);
series1.hideTooltip();
series2.hideTooltip();
}
function toggleDummySlice(series) {
var show = true;
for (var i = 1; i < series.dataItems.length; i++) {
var dataItem = series.dataItems.getIndex(i);
if (dataItem.slice.visible && !dataItem.slice.isHiding) {
show = false;
}
}
var dummySlice = series.dataItems.getIndex(0);
if (show) {
dummySlice.show();
}
else {
dummySlice.hide();
}
}
series2.events.on("datavalidated", function () {
var dummyDataItem = series2.dataItems.getIndex(0);
dummyDataItem.show(0);
dummyDataItem.slice.draggable = false;
dummyDataItem.slice.tooltipText = undefined;
for (var i = 1; i < series2.dataItems.length; i++) {
series2.dataItems.getIndex(i).hide(0);
}
})
series1.events.on("datavalidated", function () {
var dummyDataItem = series1.dataItems.getIndex(0);
dummyDataItem.hide(0);
dummyDataItem.slice.draggable = false;
dummyDataItem.slice.tooltipText = undefined;
})
</script>

Related

How to loop over arrays to combine them into one JavaScript object?

I have three arrays, "lender", "names", "pageNumbers":
var lender = [
[
{ "name": "IFC", "amount": 50 },
{ "name": "ABC", "amount": 10 }
],
[
{ "name": "DEF", "amount": 40 },
{ "name": "GHI", "amount": 100 }
]
]
var names = ["Gary", "Neil", "Luke", "Ben"]
var pageNumbers = [["page 0"], ["page 1"]]
I want to combine these three arrays into one JavaScript object that looks like this:
page 0 = {
Gary = {
financiers = {
name = IFC
}
},
Neil = {
financiers = {
name = ABC
}
}
}, page 1 = {
Luke = {
financiers = {
name = DEF
}
},
Ben = {
financiers = {
name = GHI
}
}
}
}
I thought looping over the arrays and assigning them to a predefined object would be the best way to do that:
//Predefined Object
var lenderObj = {
"lenders": {
[pageNumbers]:{
[names]: {}
}
}
//Loop
for (var j = 0; j < pageNumbers.length;j++) {
for (var i = 0; i < names.length; i++) {
lenderObj.lenders[pageNumbers[j]] = {
[names[i]]: {
financiers:lender[j][i]
}
}
}
}
But I'm not getting the right result, seems to only give me the last name (Ben) and then NULL as the value for 'financiers'. I can't seem to see what is wrong with what I have written. Any help would be great. Thanks.
Do it as below -
var lender = [
[{
"name": "IFC",
"amount": 50
},
{
"name": "ABC",
"amount": 10
}
],
[{
"name": "DEF",
"amount": 40
},
{
"name": "GHI",
"amount": 100
}
]
];
var names = ["Gary", "Neil", "Luke", "Ben"];
var pageNumbers = [
["page 0"],
["page 1"]
];
var lenderObj = {
"lenders": {
}
}
//Loop
var nameIterator = 0;
for(var i = 0; i < lender.length; i++) {
lenderObj.lenders[pageNumbers[i]] = {};
var lenderItem = lender[i];
for(var j = 0; j < lenderItem.length; j++) {
lenderObj.lenders[pageNumbers[i]][names[nameIterator]] = {};
lenderObj.lenders[pageNumbers[i]][names[nameIterator]].financiers = lenderItem[j];
nameIterator++;
}
}
console.log(lenderObj);
Using forEach and destructuring
var lender = [
[
{ name: "IFC", amount: 50 },
{ name: "ABC", amount: 10 },
],
[
{ name: "DEF", amount: 40 },
{ name: "GHI", amount: 100 },
],
];
var names = ["Gary", "Neil", "Luke", "Ben"];
var pageNumbers = [["page 0"], ["page 1"]];
const output = { lenders: {} };
pageNumbers.forEach(([page], pi) => {
output.lenders[page] = {};
lender[pi].forEach(
({ name }, li) =>
(output.lenders[page][names[2 * pi + li]] = { financiers: { name } })
);
});
console.log(output);

How to validate for un-connected edges to cell in mxgraph

Hi i'm facing problem with validation for un-connected edges to cells in mxgraph
below image will show you my expectation:
Question: whenever i press validate button un-connected edges and cells must be highlighted with red color.
For full view Codepen:https://codepen.io/eabangalore/pen/pmELpL?editors=1100
NOTE: PLEASE SEE CODEPEN LINK (https://codepen.io/eabangalore/pen/pmELpL?editors=1100) as BELOW CODE IS NOT WORKING
Full Code:
<!--
Copyright (c) 2006-2013, JGraph Ltd
Dynamic toolbar example for mxGraph. This example demonstrates changing the
state of the toolbar at runtime.
-->
<html>
<head>
<title>Toolbar example for mxGraph</title>
<!-- Sets the basepath for the library if not in same directory -->
<script type="text/javascript">
mxBasePath = 'https://jgraph.github.io/mxgraph/javascript/src';
function setGraphData(){
var graphState ={"tagName":"mxGraphModel","children":[{"tagName":"root","children":[{"tagName":"mxCell","attributes":{"id":"0"}},{"tagName":"mxCell","attributes":{"id":"1","parent":"0"}},{"tagName":"mxCell","attributes":{"id":"2","value":"A","style":"","parent":"1","vertex":"1"},"children":[{"tagName":"mxGeometry","attributes":{"x":"271.56251525878906","y":"82.44792175292969","width":"100","height":"40","as":"geometry"}}]},{"tagName":"mxCell","attributes":{"id":"3","value":"B","style":"","parent":"1","vertex":"1"},"children":[{"tagName":"mxGeometry","attributes":{"x":"678.2291717529297","y":"106.89236450195312","width":"100","height":"40","as":"geometry"}}]},{"tagName":"mxCell","attributes":{"id":"4","value":"Bangalore","parent":"1","edge":"1"},"children":[{"tagName":"mxGeometry","attributes":{"x":"0.0511","y":"-20","relative":"1","as":"geometry"},"children":[{"tagName":"mxPoint","attributes":{"x":"370.06251525878906","y":"109.95338610053051","as":"sourcePoint"}},{"tagName":"mxPoint","attributes":{"x":"676.7291717529297","y":"128.3869001543523","as":"targetPoint"}},{"tagName":"mxPoint","attributes":{"as":"offset"}}]}]},{"tagName":"mxCell","attributes":{"id":"5","value":"C","style":"","parent":"1","vertex":"1"},"children":[{"tagName":"mxGeometry","attributes":{"x":"1013.7847747802734","y":"83.55902862548828","width":"100","height":"40","as":"geometry"}}]},{"tagName":"mxCell","attributes":{"id":"6","parent":"1","source":"3","target":"5","edge":"1"},"children":[{"tagName":"mxGeometry","attributes":{"relative":"1","as":"geometry"}}]},{"tagName":"mxCell","attributes":{"id":"7","value":"Not Connected","style":"","vertex":"1","parent":"1"},"children":[{"tagName":"mxGeometry","attributes":{"x":"552","y":"267.640625","width":"100","height":"40","as":"geometry"}}]},{"tagName":"mxCell","attributes":{"id":"8","value":"Edge Not connected must highlight in red color","edge":"1","parent":"1","source":"5"},"children":[{"tagName":"mxGeometry","attributes":{"relative":"1","as":"geometry"},"children":[{"tagName":"mxPoint","attributes":{"x":"740","y":"260","as":"targetPoint"}}]}]}]}]};
localStorage.setItem('graphState',JSON.stringify(graphState));
}
function html2json(html){
if(html.nodeType==3){
return {
"tagName":"#text",
"content":html.textContent
}
}
var element = {
"tagName":html.tagName
};
if(html.getAttributeNames().length>0){
element.attributes = html.getAttributeNames().reduce(
function(acc,at){acc[at]=html.getAttribute(at); return acc;},
{}
);
}
if(html.childNodes.length>0){
element.children = Array.from(html.childNodes)
.filter(
function(el){
return el.nodeType!=3
||el.textContent.trim().length>0
})
.map(function(el){return html2json(el);});
}
return element;
}
function json2html(json){
var xmlDoc = document.implementation.createDocument(null, json.tagName);
var addAttributes = function(jsonNode, node){
if(jsonNode.attributes){
Object.keys(jsonNode.attributes).map(
function(name){
node.setAttribute(name,jsonNode.attributes[name]);
}
);
}
}
var addChildren = function(jsonNode,node){
if(jsonNode.children){
jsonNode.children.map(
function(jsonChildNode){
json2htmlNode(jsonChildNode,node);
}
);
}
}
var json2htmlNode = function(jsonNode,parent){
if(jsonNode.tagName=="#text"){
return xmlDoc.createTextNode(jsonNode.content);
}
var node = xmlDoc.createElement(jsonNode.tagName);
addAttributes(jsonNode,node);
addChildren(jsonNode,node);
parent.appendChild(node);
}
addAttributes(json,xmlDoc.firstElementChild);
addChildren(json,xmlDoc.firstElementChild);
return xmlDoc;
}
</script>
<!-- Loads and initializes the library -->
<script type="text/javascript" src="https://jgraph.github.io/mxgraph/javascript/src/js/mxClient.js"></script>
<!-- Example code -->
<script type="text/javascript">
// Program starts here. Creates a sample graph in the
// DOM node with the specified ID. This function is invoked
// from the onLoad event handler of the document (see below).
function main()
{
setGraphData();
// Checks if browser is supported
if (!mxClient.isBrowserSupported())
{
// Displays an error message if the browser is
// not supported.
mxUtils.error('Browser is not supported!', 200, false);
}
else
{
// Defines an icon for creating new connections in the connection handler.
// This will automatically disable the highlighting of the source vertex.
mxConnectionHandler.prototype.connectImage = new mxImage('images/connector.gif', 16, 16);
// Creates the div for the toolbar
var tbContainer = document.createElement('div');
tbContainer.style.position = 'absolute';
tbContainer.style.overflow = 'hidden';
tbContainer.style.padding = '2px';
tbContainer.style.left = '0px';
tbContainer.style.top = '0px';
tbContainer.style.width = '24px';
tbContainer.style.bottom = '0px';
document.body.appendChild(tbContainer);
// Creates new toolbar without event processing
var toolbar = new mxToolbar(tbContainer);
toolbar.enabled = false
// Creates the div for the graph
var container = document.createElement('div');
container.style.position = 'absolute';
container.style.overflow = 'hidden';
container.style.left = '24px';
container.style.top = '0px';
container.style.right = '0px';
container.style.bottom = '0px';
container.style.background = 'url("editors/images/grid.gif")';
document.body.appendChild(container);
// Workaround for Internet Explorer ignoring certain styles
if (mxClient.IS_QUIRKS)
{
document.body.style.overflow = 'hidden';
new mxDivResizer(tbContainer);
new mxDivResizer(container);
}
// Creates the model and the graph inside the container
// using the fastest rendering available on the browser
var model = new mxGraphModel();
var graph = new mxGraph(container, model);
// Enables new connections in the graph
graph.setConnectable(true);
graph.setMultigraph(false);
// Stops editing on enter or escape keypress
var keyHandler = new mxKeyHandler(graph);
var rubberband = new mxRubberband(graph);
var addVertex = function(icon, w, h, style)
{
var vertex = new mxCell(null, new mxGeometry(0, 0, w, h), style);
vertex.setVertex(true);
var img = addToolbarItem(graph, toolbar, vertex, icon);
img.enabled = true;
graph.getSelectionModel().addListener(mxEvent.CHANGE, function()
{
var tmp = graph.isSelectionEmpty();
mxUtils.setOpacity(img, (tmp) ? 100 : 20);
img.enabled = tmp;
});
};
addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/rectangle.gif', 100, 40, '');
addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/rounded.gif', 100, 40, 'shape=rounded');
addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/ellipse.gif', 40, 40, 'shape=ellipse');
addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/rhombus.gif', 40, 40, 'shape=rhombus');
addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/triangle.gif', 40, 40, 'shape=triangle');
addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/cylinder.gif', 40, 40, 'shape=cylinder');
addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/actor.gif', 30, 40, 'shape=actor');
// read state on load
if(window.localStorage.graphState){
var doc = json2html(JSON.parse(localStorage.graphState));
var dec = new mxCodec(doc);
dec.decode(doc.documentElement, graph.getModel());
}
// save state on change
graph.getModel().addListener('change',function(){
var codec = new mxCodec();
window.localStorage.graphState = JSON.stringify(html2json(codec.encode(
graph.getModel()
)));
});
}
}
function addToolbarItem(graph, toolbar, prototype, image)
{
// Function that is executed when the image is dropped on
// the graph. The cell argument points to the cell under
// the mousepointer if there is one.
var funct = function(graph, evt, cell, x, y)
{
graph.stopEditing(false);
var vertex = graph.getModel().cloneCell(prototype);
vertex.geometry.x = x;
vertex.geometry.y = y;
graph.addCell(vertex);
graph.setSelectionCell(vertex);
}
// Creates the image which is used as the drag icon (preview)
var img = toolbar.addMode(null, image, function(evt, cell)
{
var pt = this.graph.getPointForEvent(evt);
funct(graph, evt, cell, pt.x, pt.y);
});
// Disables dragging if element is disabled. This is a workaround
// for wrong event order in IE. Following is a dummy listener that
// is invoked as the last listener in IE.
mxEvent.addListener(img, 'mousedown', function(evt)
{
// do nothing
});
// This listener is always called first before any other listener
// in all browsers.
mxEvent.addListener(img, 'mousedown', function(evt)
{
if (img.enabled == false)
{
mxEvent.consume(evt);
}
});
mxUtils.makeDraggable(img, graph, funct);
return img;
}
</script>
</head>
<!-- Calls the main function after the page has loaded. Container is dynamically created. -->
<body onload="main();" >
</body>
</html>
Please help me thanks in advance!!!
Edit: As per the comment, to validate the cells not connected to the parent cell or its branches, we can use a recursive function checking each connected edge starts from the parent cell and so on.
Due to the limit of characters, the original code snippet is removed.
.not_connected * {
color: red;
font-color: red;
stroke: red;
stroke-color: red;
}
<!--
Copyright (c) 2006-2013, JGraph Ltd
Dynamic toolbar example for mxGraph. This example demonstrates changing the
state of the toolbar at runtime.
-->
<html>
<head>
<title>Toolbar example for mxGraph</title>
</head>
<!-- Calls the main function after the page has loaded. Container is dynamically created. -->
<body onload="main();">
<button style="position:absolute; left:300px;padding:8px 40px;background:orangered;color:#fff;outline:none;border:none;z-index:100;" id="validate_btn">Validate</button>
</body>
</html>
<!-- Sets the basepath for the library if not in same directory -->
<script type="text/javascript">
mxBasePath = 'https://jgraph.github.io/mxgraph/javascript/src';
var graphStateJSON;
var graph;
function setGraphData() {
var graphState = {
"tagName": "mxGraphModel",
"children": [{
"tagName": "root",
"children": [{
"tagName": "mxCell",
"attributes": {
"id": "0"
}
}, {
"tagName": "mxCell",
"attributes": {
"id": "1",
"parent": "0"
}
}, {
"tagName": "mxCell",
"attributes": {
"id": "2",
"value": "A",
"style": "",
"vertex": "1",
"parent": "1"
},
"children": [{
"tagName": "mxGeometry",
"attributes": {
"x": "460",
"y": "80",
"width": "100",
"height": "40",
"as": "geometry"
}
}]
}, {
"tagName": "mxCell",
"attributes": {
"id": "3",
"value": "C",
"style": "",
"vertex": "1",
"parent": "1"
},
"children": [{
"tagName": "mxGeometry",
"attributes": {
"x": "460",
"y": "190",
"width": "100",
"height": "40",
"as": "geometry"
}
}]
}, {
"tagName": "mxCell",
"attributes": {
"id": "4",
"edge": "1",
"parent": "1",
"source": "2",
"target": "3"
},
"children": [{
"tagName": "mxGeometry",
"attributes": {
"relative": "1",
"as": "geometry"
}
}]
}, {
"tagName": "mxCell",
"attributes": {
"id": "5",
"value": "B",
"style": "",
"vertex": "1",
"parent": "1"
},
"children": [{
"tagName": "mxGeometry",
"attributes": {
"x": "280",
"y": "190",
"width": "100",
"height": "40",
"as": "geometry"
}
}]
}, {
"tagName": "mxCell",
"attributes": {
"id": "6",
"value": "D",
"style": "",
"vertex": "1",
"parent": "1"
},
"children": [{
"tagName": "mxGeometry",
"attributes": {
"x": "663",
"y": "193",
"width": "100",
"height": "40",
"as": "geometry"
}
}]
}, {
"tagName": "mxCell",
"attributes": {
"id": "7",
"edge": "1",
"parent": "1",
"source": "2",
"target": "5"
},
"children": [{
"tagName": "mxGeometry",
"attributes": {
"relative": "1",
"as": "geometry"
}
}]
}, {
"tagName": "mxCell",
"attributes": {
"id": "8",
"edge": "1",
"parent": "1",
"source": "2",
"target": "6"
},
"children": [{
"tagName": "mxGeometry",
"attributes": {
"relative": "1",
"as": "geometry"
}
}]
}, {
"tagName": "mxCell",
"attributes": {
"id": "9",
"value": "E",
"style": "",
"vertex": "1",
"parent": "1"
},
"children": [{
"tagName": "mxGeometry",
"attributes": {
"x": "660",
"y": "260",
"width": "100",
"height": "40",
"as": "geometry"
}
}]
}, {
"tagName": "mxCell",
"attributes": {
"id": "10",
"edge": "1",
"parent": "1",
"source": "6",
"target": "9"
},
"children": [{
"tagName": "mxGeometry",
"attributes": {
"relative": "1",
"as": "geometry"
}
}]
}, {
"tagName": "mxCell",
"attributes": {
"id": "11",
"value": "F",
"style": "",
"vertex": "1",
"parent": "1"
},
"children": [{
"tagName": "mxGeometry",
"attributes": {
"x": "280",
"y": "260",
"width": "100",
"height": "40",
"as": "geometry"
}
}]
}, {
"tagName": "mxCell",
"attributes": {
"id": "12",
"value": "G",
"style": "",
"vertex": "1",
"parent": "1"
},
"children": [{
"tagName": "mxGeometry",
"attributes": {
"x": "459",
"y": "257",
"width": "100",
"height": "40",
"as": "geometry"
}
}]
}, {
"tagName": "mxCell",
"attributes": {
"id": "13",
"edge": "1",
"parent": "1",
"source": "11",
"target": "12"
},
"children": [{
"tagName": "mxGeometry",
"attributes": {
"relative": "1",
"as": "geometry"
}
}]
}]
}]
};
graphStateJSON = JSON.stringify(graphState);
}
function html2json(html) {
if (html.nodeType == 3) {
return {
"tagName": "#text",
"content": html.textContent
}
}
var element = {
"tagName": html.tagName
};
if (html.getAttributeNames().length > 0) {
element.attributes = html.getAttributeNames().reduce(
function(acc, at) {
acc[at] = html.getAttribute(at);
return acc;
}, {}
);
}
if (html.childNodes.length > 0) {
element.children = Array.from(html.childNodes)
.filter(
function(el) {
return el.nodeType != 3 ||
el.textContent.trim().length > 0
})
.map(function(el) {
return html2json(el);
});
}
return element;
}
function json2html(json) {
var xmlDoc = document.implementation.createDocument(null, json.tagName);
var addAttributes = function(jsonNode, node) {
if (jsonNode.attributes) {
Object.keys(jsonNode.attributes).map(
function(name) {
node.setAttribute(name, jsonNode.attributes[name]);
}
);
}
}
var addChildren = function(jsonNode, node) {
if (jsonNode.children) {
jsonNode.children.map(
function(jsonChildNode) {
json2htmlNode(jsonChildNode, node);
}
);
}
}
var json2htmlNode = function(jsonNode, parent) {
if (jsonNode.tagName == "#text") {
return xmlDoc.createTextNode(jsonNode.content);
}
var node = xmlDoc.createElement(jsonNode.tagName);
addAttributes(jsonNode, node);
addChildren(jsonNode, node);
parent.appendChild(node);
}
addAttributes(json, xmlDoc.firstElementChild);
addChildren(json, xmlDoc.firstElementChild);
return xmlDoc;
}
</script>
<!-- Loads and initializes the library -->
<script type="text/javascript" src="https://jgraph.github.io/mxgraph/javascript/src/js/mxClient.js"></script>
<!-- Example code -->
<script type="text/javascript">
// Program starts here. Creates a sample graph in the
// DOM node with the specified ID. This function is invoked
// from the onLoad event handler of the document (see below).
var graph;
var graphView;
var notConnectedCells = [];
var parentCellId = "2";
function main() {
setGraphData();
// Checks if browser is supported
if (!mxClient.isBrowserSupported()) {
// Displays an error message if the browser is
// not supported.
mxUtils.error('Browser is not supported!', 200, false);
} else {
// Defines an icon for creating new connections in the connection handler.
// This will automatically disable the highlighting of the source vertex.
mxConnectionHandler.prototype.connectImage = new mxImage('images/connector.gif', 16, 16);
// Creates the div for the toolbar
var tbContainer = document.createElement('div');
tbContainer.style.position = 'absolute';
tbContainer.style.overflow = 'hidden';
tbContainer.style.padding = '2px';
tbContainer.style.left = '0px';
tbContainer.style.top = '0px';
tbContainer.style.width = '24px';
tbContainer.style.bottom = '0px';
document.body.appendChild(tbContainer);
// Creates new toolbar without event processing
var toolbar = new mxToolbar(tbContainer);
toolbar.enabled = false
// Creates the div for the graph
var container = document.createElement('div');
container.style.position = 'absolute';
container.style.overflow = 'hidden';
container.style.left = '24px';
container.style.top = '0px';
container.style.right = '0px';
container.style.bottom = '0px';
container.style.background = 'url("editors/images/grid.gif")';
document.body.appendChild(container);
// Workaround for Internet Explorer ignoring certain styles
if (mxClient.IS_QUIRKS) {
document.body.style.overflow = 'hidden';
new mxDivResizer(tbContainer);
new mxDivResizer(container);
}
// Creates the model and the graph inside the container
// using the fastest rendering available on the browser
var model = new mxGraphModel();
graph = new mxGraph(container, model);
// Enables new connections in the graph
graph.setConnectable(true);
graph.setMultigraph(false);
// Stops editing on enter or escape keypress
var keyHandler = new mxKeyHandler(graph);
var rubberband = new mxRubberband(graph);
var addVertex = function(icon, w, h, style) {
var vertex = new mxCell(null, new mxGeometry(0, 0, w, h), style);
vertex.setVertex(true);
var img = addToolbarItem(graph, toolbar, vertex, icon);
img.enabled = true;
graph.getSelectionModel().addListener(mxEvent.CHANGE, function() {
var tmp = graph.isSelectionEmpty();
mxUtils.setOpacity(img, (tmp) ? 100 : 20);
img.enabled = tmp;
});
};
addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/rectangle.gif', 100, 40, '');
addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/rounded.gif', 100, 40, 'shape=rounded');
addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/ellipse.gif', 40, 40, 'shape=ellipse');
addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/rhombus.gif', 40, 40, 'shape=rhombus');
addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/triangle.gif', 40, 40, 'shape=triangle');
addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/cylinder.gif', 40, 40, 'shape=cylinder');
addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/actor.gif', 30, 40, 'shape=actor');
// read state on load
if (graphStateJSON) {
var doc = json2html(JSON.parse(graphStateJSON));
var dec = new mxCodec(doc);
dec.decode(doc.documentElement, graph.getModel());
}
// save state on change
graph.getModel().addListener('change', function() {
var codec = new mxCodec();
graphStateJSON = JSON.stringify(html2json(codec.encode(
graph.getModel()
)));
});
}
}
function addToolbarItem(graph, toolbar, prototype, image) {
// Function that is executed when the image is dropped on
// the graph. The cell argument points to the cell under
// the mousepointer if there is one.
var funct = function(graph, evt, cell, x, y) {
graph.stopEditing(false);
var vertex = graph.getModel().cloneCell(prototype);
vertex.geometry.x = x;
vertex.geometry.y = y;
graph.addCell(vertex);
graph.setSelectionCell(vertex);
}
// Creates the image which is used as the drag icon (preview)
var img = toolbar.addMode(null, image, function(evt, cell) {
var pt = this.graph.getPointForEvent(evt);
funct(graph, evt, cell, pt.x, pt.y);
});
// Disables dragging if element is disabled. This is a workaround
// for wrong event order in IE. Following is a dummy listener that
// is invoked as the last listener in IE.
mxEvent.addListener(img, 'mousedown', function(evt) {
// do nothing
});
// This listener is always called first before any other listener
// in all browsers.
mxEvent.addListener(img, 'mousedown', function(evt) {
if (img.enabled == false) {
mxEvent.consume(evt);
}
});
mxUtils.makeDraggable(img, graph, funct);
return img;
}
function Validate(mxCell){
let isConnected = true;
// check each cell that each edge connected to
for(let i=0;i<mxCell.getEdgeCount();i++){
let edge = mxCell.getEdgeAt(i);
if(edge.target === null) continue; // no target
if(mxCell.getId() === edge.target.getId()) continue; // target is mxCell itself
isConnected = edge.source !== null && edge.target !== null;
if(isConnected){
// remove source cell if found and so on
let sourceIndex = notConnectedCells.findIndex(c=>c.id === edge.source.getId());
if(sourceIndex !== -1) notConnectedCells.splice(sourceIndex,1);
let targetIndex = notConnectedCells.findIndex(c=>c.id === edge.target.getId());
if(targetIndex !== -1) notConnectedCells.splice(targetIndex,1);
let edgeIndex = notConnectedCells.findIndex(c=>c.id === edge.getId());
if(edgeIndex !== -1) notConnectedCells.splice(edgeIndex,1);
// check next cell and its edges
Validate(edge.target);
}
}
}
function ResetColor(state){
state.shape.node.classList.remove("not_connected");
if(state.text)
state.text.node.classList.remove("not_connected");
}
function SetNotConnectedColor(state){
for(let i=0;i<notConnectedCells.length;i++){
let mxCell = notConnectedCells[i];
let state = graphView.getState(mxCell);
state.shape.node.classList.add("not_connected");
if(state.text)
state.text.node.classList.add("not_connected");
}
}
document.querySelector("#validate_btn").addEventListener("click", function() {
let cells = graph.getModel().cells;
graphView = graph.getView();
notConnectedCells.length = 0;
// create an array of cells and reset the color
for(let key in cells){
if(!cells.hasOwnProperty(key)) continue;
let mxCell = cells[key];
if(!mxCell.isVertex() && !mxCell.isEdge()) continue;
notConnectedCells.push(mxCell);
let state = graphView.getState(mxCell);
ResetColor(state);
}
// starts with the parent cell
let parentCell = notConnectedCells.find(c=>c.id === parentCellId);
Validate(parentCell);
SetNotConnectedColor();
})
</script>
First, set graph to a global variable. (var graph = new mxGraph(container, model);)
Then, get all cells(as an object) and graphView from graph and iterate all the cells checking if it's connected or not.
function Validate(){
let cells = graph.getModel().cells;
let graphView = graph.getView();
for(let key in cells){
if(!cells.hasOwnProperty(key)) continue;
let mxCell = cells[key];
if(!mxCell.isVertex() && !mxCell.isEdge()) continue;
let state = graphView.getState(mxCell);
ResetColor(state);
let notConnected = true;
if(mxCell.isVertex()){
for(let i=0;i<mxCell.getEdgeCount();i++){
let edge = mxCell.getEdgeAt(i);
// if any of an edge connected to both source and target, it's connected
if(edge.source !== null && edge.target !== null){
notConnected = false;
break;
}
}
}
else { // mxCell.isEdge()
notConnected = mxCell.source === null || mxCell.target === null;
}
if(notConnected) SetNotConnectedColor(state);
}
}
function ResetColor(state){
state.shape.node.classList.remove("not_connected");
if(state.text)
state.text.node.classList.remove("not_connected");
}
function SetNotConnectedColor(state){
state.shape.node.classList.add("not_connected");
if(state.text)
state.text.node.classList.add("not_connected");
}
document.querySelector("#validate_btn").addEventListener("click", function(){
Validate();
})
And here's the localStorage version code if you want(codepen)

How to find maximum and minimum difference between two consecutive objects in JSONArray

I have a JSON data like
{
"data": [{
"distance": "700",
"name": "xyz"
}, {
"distance": "680",
"name": "abc"
}, {
"distance": "670",
"name": "lmn"
}, {
"distance": "620",
"name": "pqr"
}, {
"distance": "400",
"name": "tuv"
}]
}
I want to find the maximum & minimum distance between two consecutive nodes.
I tried following code but I don't know what I'm missing
Here I'm trying to make use of jQuery sort to achieve it.
var min = data[0].distance - data[1].distance,
max = data[0].distance - data[1].distance;
data.sort(function (a, b) {
var temp = a.distance - b.distance;
if (temp > max)
max = temp;
if (temp < min)
min = temp;
});
I even tried using normal jQuery forEach loop
var min = data[0].distance - data[1].distance,
max = data[0].distance - data[1].distance;
data.forEach(function (d, i) {
var temp = data[i + 1].distance - d.distance;
if (temp > max)
max = temp;
if (temp < min)
min = temp;
});
You can do it something like this:
// Set default values to the max and min, to compare them later
var min = Number.MAX_VALUE,
max = Number.MIN_VALUE;
// Iterate over the data object
for (var i = obj.data.length - 2; i >= 0; i--) {
// Get the absolute(ignoring negatives) difference
var temp = Math.abs(obj.data[i].distance - obj.data[i + 1].distance);
// update values accordingly
min = Math.min(min, temp);
max = Math.max(max, temp);
}
console.log(min, max);
var obj = {
"data": [{
"distance": "700",
"name": "xyz"
}, {
"distance": "680",
"name": "abc"
}, {
"distance": "670",
"name": "lmn"
}, {
"distance": "620",
"name": "pqr"
}, {
"distance": "400",
"name": "tuv"
}]
};
var min = Number.MAX_VALUE,
max = Number.MIN_VALUE;
for (var i = obj.data.length - 2; i >= 0; i--) {
var temp = Math.abs(obj.data[i].distance - obj.data[i + 1].distance);
min = Math.min(min, temp);
max = Math.max(max, temp);
}
console.log(min, max);
try it.
var jsonData = {
"data": [{
"distance": "700",
"name": "xyz"
}, {
"distance": "680",
"name": "abc"
}, {
"distance": "670",
"name": "lmn"
}, {
"distance": "620",
"name": "pqr"
}, {
"distance": "400",
"name": "tuv"
}]
};
var maxData = 0;
var minData = 0;
var data = 0;
$.each(jsonData.data, function(i, obj) {
if(i==0)
{
minData = obj.distance;
}
else
{
data = jsonData.data[i-1].distance - obj.distance;
if(data > maxData)
maxData = data;
if(data < minData)
minData = data;
}
});
console.log("Max : "+maxData);
console.log("Min : "+minData);

Display Data from mysql database in Chart

I'm using AmCharts to create a pie chart.
I'm trying to assign data from my mysql database to the variable chartData
that has the fields country and liters. How can I assign my mysql data to chartdata?
<script>
var chart;
var legend;
var chartData = [{
"country": "Czech Republic",
"litres": 156.9
},
{
"country": "Ireland",
"litres": 131.1
},
{
"country": "Germany",
"litres": 115.8
},
{
"country": "Australia",
"litres": 109.9
},
{
"country": "Austria",
"litres": 108.3
},
{
"country": "UK",
"litres": 65
},
{
"country": "Belgium",
"litres": 50
}
];
AmCharts.ready(function () {
// PIE CHART
chart = new AmCharts.AmPieChart();
chart.dataProvider = chartData;
chart.titleField = "country";
chart.valueField = "litres";
// LEGEND
legend = new AmCharts.AmLegend();
legend.align = "center";
legend.markerType = "circle";
chart.balloonText = "[[title]]<br><span style='font-size:14px'><b>[[value]]</b> ([[percents]]%)</span>";
chart.addLegend(legend);
// WRITE
chart.write("chartdiv");
});
// changes label position (labelRadius)
function setLabelPosition() {
if (document.getElementById("rb1").checked) {
chart.labelRadius = 30;
chart.labelText = "[[title]]: [[value]]";
} else {
chart.labelRadius = -30;
chart.labelText = "[[percents]]%";
}
chart.validateNow();
}
// makes chart 2D/3D
function set3D() {
if (document.getElementById("rb3").checked) {
chart.depth3D = 10;
chart.angle = 10;
} else {
chart.depth3D = 0;
chart.angle = 0;
}
chart.validateNow();
}
// changes switch of the legend (x or v)
function setSwitch() {
if (document.getElementById("rb5").checked) {
legend.switchType = "x";
} else {
legend.switchType = "v";
}
legend.validateNow();
}
</script>
You cannot directly access your mysql database from javascript. You will have to ask your server for some data. Typicaly, you will want to get JSON formated data (using ajax) :
Javascript (using .getJSON()):
$.getJSON('/get-my-data.php', function(json) {
var chart;
var legend;
var chartData = json;
AmCharts.ready(function () {
chart = new AmCharts.AmPieChart();
chart.dataProvider = chartData;
// code ...
});
});
get-my-data.php (using mysqli) :
$mysqli = new mysqli("localhost", "my_user", "my_password", "my_database");
$stats = array();
$query = "
SELECT `country`, `litres`
FROM `mytable`
";
$statement = $mysqli->prepare($query);
$result = $statement->get_result();
while ($data = $result->fetch_assoc())
{
$stats[] = $data;
}
echo json_encode($stats);
If you don't want or can't use jQuery, there's a built-in solution using amCharts' own Data Loader plugin. To use it simply include plugins/dataloader/dataloader.min.js file from the same directory you include the rest of the amCharts js files, then add the following directive to your chart config:
AmCharts.makeChart("chartdiv", {
"type": "pie",
"dataLoader": {
"url": "data.php"
},
// the reset of your chart config
// ..
});
On the server-side you can use PHP function json_encode() to format your data as JSON. I.e.:
<?php
// load your data
// ...
// format as JSON
echo json_encode( $data );
?>
Here's more info about the plugin and how to get your data from MySQL server:
http://www.amcharts.com/tutorials/using-data-loader-to-connect-charts-to-mysql-data-base/

How to convert json formatting from Object to Array

Another issue :P, I'm trying to change the output of the JSON array but I can't workout why it won't render the other files.
Edit better explanation below.
Sorry i was not very clear if you look at the code in my gist, data[name] = { will render all the return names into there individual json files, But if i remove the [name] and its just data = { the individual files are not rendered and the all.json file is made from the rendered [name] files.
Hope this explains it a little better.
The code you gave me dose add "markets" [] to the all.json file as it should but without the other files all.json only has one return.
The reason why i want to remove [name] from the data[name] = is that it adds the name to the start of the string of every return eg { "Bitcoin": {"position": "1", "name":"Bitcoin",},{"Litecoin": {"position":"2", "name": "Litecoin", }, and so on.
So i guess what i am trying to do is move the [name] from the data[name] =
into the fs.writeFile function and only add "markets": at the start of the string and still be able to render the individual files into all.json.
The Node.js code that will not render the individual files.
This versions all.json only returns
{"position":"650","name":"Pennies","symbol":"CENT","icon":"pennies.png","market_cap":{"usd":"NaN","btc":"?"},"price":{"usd":"2.26018e-9","btc":"9.05947e-12"},"supply":"","volume":{"usd":"43.9142","btc":"0.176021"},"change1h":"0.05","change24h":"3.77","change1d":"-7.07","timestamp":1435559515.397}
and in the json folder
http://s21.postimg.org/xm7v01ujr/image.jpg
What I would like is the JSON format to be:
{
"markets": [
{
"position": "1",
"name": "Bitcoin",
"symbol": "BTC",
"icon": "bitcoin.png",
"market_cap": {
"usd": "3504403422",
"btc": "14319000.0"
},
"price": {
"usd": "244.738",
"btc": "1.0"
},
"supply": "14319000",
"volume": {
"usd": "13563600",
"btc": "55523.8"
},
"change1h": "0.26",
"change24h": "1.05",
"change1d": "1.21",
"timestamp": 1435401749.236
},
{
"position": "2",
"name": "Litecoin",
and so on.......
}
]
}
#!/usr/bin/nodejs
var request = require("request"),
cheerio = require("cheerio"),
fs = require("fs");
var currencies = ["usd", "btc"];
var currencyExchangeRates = Array();
var data = {};
request('http://coinmarketcap.com/all/views/all/', function (error, response, body) {
if (!error && response.statusCode == 200) {
$ = cheerio.load(body);
currencyExchangeRates = $("#currency-exchange-rates").data();
$("tr").each(function (i) {
if (i > 0) {
var td = $(this).find("td");
var position = td.eq(0).text().trim();
var icon = $(this).find("img.currency-logo").attr("src").replace("/static/img/coins/16x16/", "");
var name = td.eq(1).text().replace("/", "").trim();
var re = /\s([a-z]|[0-9])+\s/i;
var supplyText = td.eq(5).text();
var symbol = td.eq(2).text().trim();
var marketCap = currencyDictionary(td.eq(3));
var price = currencyDictionary(td.eq(4).find("a").eq(0));
var supply = td.eq(5).text().replace(/\D/g, "").trim(); // Replace all non digit characters with nothing
var volume = currencyDictionary(td.eq(6).find("a").eq(0));
var change1h = td.eq(7).text().replace("%", "").trim();
var change24h = td.eq(8).text().replace("%", "").trim();
var change1d = td.eq(9).text().replace("%", "").trim();
var timestamp = Date.now() / 1000;
data = [{
"position": position,
"name": name,
"symbol": symbol,
"icon": icon,
"market_cap": marketCap,
"price": price,
"supply": supply,
"volume": volume,
"change1h": change1h,
"change24h": change24h,
"change1d": change1d,
"timestamp": timestamp
}];
}
});
writeData();
}
});
function currencyDictionary(item) {
var resultArray = {};
currencies.forEach(function(currency) {
if (currency == "btc") {
var result = item.data("btc");
}
else {
var result = item.data("usd") / currencyExchangeRates[currency];
}
resultArray[currency] = result.toString().replace(/,/g,"");
});
return resultArray;
}
function writeData() {
dataDir = "/var/www/coinmarketcap/json/";
callback = function(error) {
if (error) {
console.log(error);
}
};
for (currency in data) {
info = data[currency];
fileName = dataDir + info["symbol"] + ".json";
fs.writeFile(fileName, JSON.stringify(info), callback);
}
fs.writeFile(dataDir + "all.json", JSON.stringify(data), callback);
}
This version will render all the files but adds the [name] to the all.json
this version json folder
http://s16.postimg.org/xicupqi85/image.jpg
The JSON format is:
{
"Bitcoin":
{
"position": "1",
"name": "Bitcoin",
"symbol": "BTC",
"icon": "bitcoin.png",
"market_cap": {
"usd": "3504403422",
"btc": "14319000.0"
},
"price": {
"usd": "244.738",
"btc": "1.0"
},
"supply": "14319000",
"volume": {
"usd": "13563600",
"btc": "55523.8"
},
"change1h": "0.26",
"change24h": "1.05",
"change1d": "1.21",
"timestamp": 1435401749.236
},
{
"Litecoin":
{
"position" "2",
"name": "Bitcoin",
and so on...
}
}
#!/usr/bin/nodejs
var request = require("request"),
cheerio = require("cheerio"),
fs = require("fs");
var currencies = ["usd", "btc"];
var currencyExchangeRates = Array();
var data = {};
request('http://coinmarketcap.com/all/views/all/', function (error, response, body) {
if (!error && response.statusCode == 200) {
$ = cheerio.load(body);
currencyExchangeRates = $("#currency-exchange-rates").data();
$("tr").each(function (i) {
if (i > 0) {
var td = $(this).find("td");
var position = td.eq(0).text().trim();
var icon = $(this).find("img.currency-logo").attr("src").replace("/static/img/coins/16x16/", "");
var name = td.eq(1).text().replace("/", "").trim();
var re = /\s([a-z]|[0-9])+\s/i;
var supplyText = td.eq(5).text();
var symbol = td.eq(2).text().trim();
var marketCap = currencyDictionary(td.eq(3));
var price = currencyDictionary(td.eq(4).find("a").eq(0));
var supply = td.eq(5).text().replace(/\D/g, "").trim(); // Replace all non digit characters with nothing
var volume = currencyDictionary(td.eq(6).find("a").eq(0));
var change1h = td.eq(7).text().replace("%", "").trim();
var change24h = td.eq(8).text().replace("%", "").trim();
var change1d = td.eq(9).text().replace("%", "").trim();
var timestamp = Date.now() / 1000;
data[name] = {
"position": position,
"name": name,
"symbol": symbol,
"icon": icon,
"market_cap": marketCap,
"price": price,
"supply": supply,
"volume": volume,
"change1h": change1h,
"change24h": change24h,
"change1d": change1d,
"timestamp": timestamp
};
}
});
writeData();
}
});
function currencyDictionary(item) {
var resultArray = {};
currencies.forEach(function(currency) {
if (currency == "btc") {
var result = item.data("btc");
}
else {
var result = item.data("usd") / currencyExchangeRates[currency];
}
resultArray[currency] = result.toString().replace(/,/g,"");
});
return resultArray;
}
function writeData() {
dataDir = "/var/www/coinmarketcap/json/";
callback = function(error) {
if (error) {
console.log(error);
}
};
for (currency in data) {
info = data[currency];
fileName = dataDir + info["symbol"] + ".json";
fs.writeFile(fileName, JSON.stringify(info), callback);
}
fs.writeFile(dataDir + "all.json", JSON.stringify(data), callback);
}
Try utilizing for...in loop
var data = {
"Bitcoin":
{
"position": "1",
"name": "Bitcoin",
"symbol": "BTC",
"icon": "bitcoin.png",
"market_cap": {
"usd": "3504403422",
"btc": "14319000.0"
},
"price": {
"usd": "244.738",
"btc": "1.0"
},
"supply": "14319000",
"volume": {
"usd": "13563600",
"btc": "55523.8"
},
"change1h": "0.26",
"change24h": "1.05",
"change1d": "1.21",
"timestamp": 1435401749.236
}
};
var res = {"markets":[]};
for (var prop in data) {
res.markets.push(data[prop])
};
document.getElementsByTagName("pre")[0].textContent = JSON.stringify(res, null, 4);
<pre></pre>
Worked it out, had to move the fs.writeFile for all.json out of the writeData function and give all.json its own function that is called after the writeData function had finished.

Categories

Resources