I'm trying remove (or clean a canvas) from my div, but the event kill only removes the properties of the element but not the image. What I can do? This is my code:
var s = new sigma('container');
s.graph
.addNode({
id: 'n0',
label: 'Start',
x: 0,
y: 0.5,
size: 1,
color: '#f00'
})
.addNode({
id: 'n1',
label: 'End',
x: 1,
y: 0.5,
size: 1,
color: '#00f'
})
.addEdge({
id: 'e0',
source: 'n0',
target: 'n1'
});
s.settings({
edgeColor: 'default',
defaultEdgeColor: 'grey'
});
s.refresh();
$(function(){
$("#shape").click(function(){
//s.kill();
//s = new sigma('container');
s.graph
.addNode({
id: 'n3',
label: 'Start',
x: 0,
y: 0,
size: 1,
color: '#f00'
})
.addNode({
id: 'n4',
label: 'End',
x: 1,
y: 1,
size: 1,
color: '#00f'
})
.addEdge({
id: 'e1',
source: 'n3',
target: 'n4'
});
s.settings({
edgeColor: 'default',
defaultEdgeColor: 'grey'
});
s.refresh();
console.log("added!");
});
});
There's surely a better way to do this, but I have the same problem. I solved it by completely removing the DOM element containing the graph, and then recreating it:
HTML:
<div id="graph-container">
<div id="graph"></div>
</div>
JavaScript:
var sigma_graph = null;
function create_graph() {
sigma_graph = new sigma({ ... });
... populate graph ...
}
function refresh_graph() {
// to delete & refresh the graph
var g = document.querySelector('#graph');
var p = g.parentNode;
p.removeChild(g);
var c = document.createElement('div');
c.setAttribute('id', 'graph');
p.appendChild(c);
create_graph();
}
Note that I'm not using jQuery, otherwise it would have been something like:
$('#graph').remove();
$('#graph-container').html('<div id="graph"></div>');
While this method seems to work, I can't say if it's a good idea or not. (I'm using the canvas renderer, if that matters.)
You can re-use instances of sigma, you don't need to kill the instance completely. I had the same problem and this is how I solved it. Just have one sigma instance and clear it whenever you want a new graph.
s = new sigma({...});
//do stuff with the graph.
function clear_graph() {
//this gets rid of all the ndoes and edges
s.graph.clear();
//this gets rid of any methods you've attached to s.
s.graph.kill();
};
After clearing graph call refresh:
s.graph.clear();
s.refresh();
I'm using jquery
$("#graph").empty();
Related
I am using cytoscape.js for converting a raw txt data to cytoscape.js graph.
for that, first I make the graph with :
var cy = cytoscape({...})
without any elements.Then after reading nodes and edges from txt file, I add them with this for nodes :
cy.add({
data: {id: keys[i]}
}
);
and this for edges:
cy.add({
data: {
id: 'edge' + i,
source: edges[i].source,
target: edges[i].target,
label: edges[i].weight
}
});
Then i want to apply 'width': 'mapData(weight, 0, 100, 1, 6)'. how can I do that?
I tried these:
1) using mapData() in edge selector when making cy variable.(it doesnt works for added edges and nodes)
2) using mapData() for each edge after making each of them:
cy.$('#edge' + i).style('width','mapData(weight, 0, 100, 1, 6)');
3) using mapData() after making all nodes and edges :
cy.elements('edge').style('line-color','mapData(weight,1,6,blue,green)');
none of them works!
Maybe like this:
var cy = window.cy = cytoscape({
container: document.getElementById('cy'),
style: [
{
selector: 'node',
style: {
'label': 'data(name)',
'width': 'mapData(weight, 0, 100, 1, 6)',
'height': 'mapData(weight, 0, 100, 1, 6)',
}
}
]
});
cy.add([
{ group: "nodes", data: { id: "n0", name: "node0", weight: "x"} },
{ group: "nodes", data: { id: "n1", name: "node1", weight: "y"} },
{ group: "edges", data: { id: "e0", source: "n0", target: "n1" } }
]);
cy.ready(function () { // Wait for nodes to be added
cy.layout( // Call layout
name: 'yourDecision'
).run();
});
I define the cytoscape instance on initialization and there I define the style of the nodes/edges/... .
I am using Highcharts and it is working just amazing, i am stuck at a place where i want to plot a pie chart in which every pie slice (in a single pie chart) has a different radius.
Below is the image attached of the expexted pie chart.
You can skip making it a donout or designing it this specific. I just want to know how each pie slice can have different radius.
Each series in a pie chart can have their own size. So, I stacked a bunch of pie series calculating their begin and end angles. You'll have to do a little clean up to get the tooltips displaying the value instead of 100, but I think it's a workable solution.
Note: The following code makes a bad assumption that the data points add to 100. void fixes that assumption in his fiddle http://jsfiddle.net/58zfb8gy/1.
http://jsfiddle.net/58zfb8gy/
$(function() {
var data = [{
name: 'Thane',
y: 25,
color: 'red'
}, {
name: 'Nagpur',
y: 15,
color: 'blue'
}, {
name: 'Pune',
y: 30,
color: 'purple'
}, {
name: 'Mumbai',
y: 30,
color: 'green'
}];
var start = -90;
var series = [];
for (var i = 0; i < data.length; i++) {
var end = start + 360 * data[i].y / 100;
data[i].y = 100;
series.push({
type: 'pie',
size: 100 + 50 * i,
innerSize: 50,
startAngle: start,
endAngle: end,
data: [data[i]]
});
start = end;
};
$('#container').highcharts({
series: series
});
});
Another way I toyed with, that I didn't like as much, was having each series have invisible points:
series = [{
type: 'pie',
size: 100,
innerSize: 50,
data: [{y:25, color: 'red'}, {y:75, color:'rgba(0,0,0,0)'}]
},{
type: 'pie',
size: 150,
innerSize: 50,
data: [{y:25, color: 'rgba(0,0,0,0)'},{y:15, color: 'blue'}, {y:60, color:'rgba(0,0,0,0)'}]
}, ... ];
The variablepie series type, introduced in Highcharts 6.0.0, handles this with less code. In this series type you can specify a z-parameter for each data point to alter its z-size.
For example (JSFiddle, documentation):
Highcharts.chart('container', {
chart: {
type: 'variablepie'
},
title: {
text: 'Variable pie'
},
series: [{
minPointSize: 10,
innerSize: '20%',
zMin: 0,
name: 'countries',
data: [{
name: 'Pune',
y: 35,
z: 25
}, {
name: 'Mumbai',
y: 30,
z: 20
}, {
name: 'Nagpur',
y: 15,
z: 15
} , {
name: 'Thane',
y: 25,
z: 10
}]
}]
});
This requires including:
<script src="https://code.highcharts.com/modules/variable-pie.js"></script>
Sounds odd but I have these 3 charts in a single chart.
The problem is that if I use showInLegend:true to each series then I have 9 items in legend.
I want to display Urban, Rural, Nothing just one time each.
Here is my code:
http://jsfiddle.net/HpdwR/1298/
series: [{
data: [{
name: 'Urban',
color: 'red',
y: 4
}, {
name: 'Nothing',
color: 'blue',
y: 2
}, {
name: 'Rural',
color: 'green',
y: 4,
}],
size: '130px',
innerSize: '115px',
center: ['12%'],
name: 'first',
showInLegend: true
}, {
data: [{
color: 'red',
y: 1
}, {
color: 'blue',
y: 4
}, {
color: 'green',
y: 5
}],
size: '130px',
innerSize: '115px',
center: ['50%'],
name: 'second',
showInLegend: true
}, {
data: [{
color: 'red',
y: 6
}, {
color: 'blue',
y: 2
}, {
color: 'green',
y: 2
}],
size: '130px',
innerSize: '115px',
center: ['88%'],
name: 'third',
showInLegend: true
}]
I couldn't find an elegant way to do this, or a built-in solution (maybe there is one, but I couldn't find it...)
Here's a hack that hides the extra legends, and links the hover event. I've disabled the click events for simplicity.
// Legend Hack
$('g.highcharts-legend-item:nth-child(n+4)').css('visibility', 'hidden');
$('g.highcharts-legend-item').hover(function() {
var i = $(this).index();
$('g.highcharts-legend-item').eq(i+3).trigger('mouseover');
$('g.highcharts-legend-item').eq(i+6).trigger('mouseover');
}, function() {
var i = $(this).index();
$('g.highcharts-legend-item').eq(i+3).trigger('mouseout');
$('g.highcharts-legend-item').eq(i+6).trigger('mouseout');
});
$('g.highcharts-legend-item *').click(function() { return false; });
Fiddle: http://jsfiddle.net/HpdwR/1303/
I believe that the best option here would hide the extra legends so only one of them will be displayed. In order to have the control over the other charts with the displayed legend (that is currently controlling only one chart), you should write an event listener when clicking on the legend and ask it to have effect on the rest of the charts.
HOWEVER, the issue is that "legendItemClick" that is responsible for the event listener on the legend's click event is not working when using the pie chart. Therefore, you should catch it with jquery.. an example can be seen here https://stackoverflow.com/a/16099935/1138430
I'm trying to use datamaps charting library and came across this notation for data:
var map = new Datamap({
element: document.getElementById('container'),
fills: {
HIGH: '#afafaf',
LOW: '#123456',
MEDIUM: 'blue',
UNKNOWN: 'rgb(0,0,0)',
defaultFill: 'green'
},
data: {
IRL: {
fillKey: 'LOW',
numberOfThings: 2002
},
USA: {
fillKey: 'MEDIUM',
numberOfThings: 10381
}
}
});
If I want to place an object in the "data" attribute, I cannot - because the country code is not wrapped in quotes.
How do I build data for such scenarios?
[EDIT]
Here's the JSON that I create in a controller and send it back using a REST callout:
{"USA":{"value":"15000.0","countryName":"USA"}}
I am changing it to the following to match the way the library accepts data:
{USA:{fillKey : 'LOW'}}
For using JSON.parse(), needs the data to be in a proper JSON format, like:
{"USA":{"fillKey" : "LOW"}}
(note the absence of quotes around USA)
Currently, I'm using something like this to create the Datamap:
var dataForChart = buildDataForChart();// outputs a string "{USA:{fillKey : 'LOW'}}"
var map = new Datamap({
element: document.getElementById('container'),
fills: {
HIGH: '#afafaf',
LOW: '#123456',
MEDIUM: 'blue',
UNKNOWN: 'rgb(0,0,0)',
defaultFill: 'green'
},
data: dataForChart
});
But it doesn't seem to work.
Try
var options = {
element: ...,
fills: ...,
data: {
IRL: {
fillKey: 'LOW',
numberOfThings: 2002
},
USA: {
fillKey: 'MEDIUM',
numberOfThings: 10381
}
}
}
options.data.CAN = { fillKey: 'HIGH', numberOfThings: 4201 };
var map = new Datamap(options);
Hopefully someone can help me as I'm stuck at the moment after searching for a solution already for the last 2 days.
I decided to look into HighCharts yesterday for a new project and it does do what I'm after. However I'm trying to make the implementation option into my WordPress plugin as clean as possible and that's where I'm stuck at the moment.
This JSFiddle is working and shows what I like to get as output: http://jsfiddle.net/golabs/tpKU3/
But I would like to be able to create a new chart by just calling a function and supply the target div ID and the 2 dataArray's. My attempt can be found here: http://jsfiddle.net/golabs/rstpA/
or see the jscode here:
/**
* However this second section of code does NOT work as nothing is displayed in the container21 div...
* What am I doing wrong here?
* I like to be able to create a new chart by only supplying the target div ID and the dataArray's, this
* to have be able to manage the general settings centrally.
*
* This JSFIDDLE is related to: http://jsfiddle.net/golabs/tpKU3/
**/
$(function () {
var __catergories__ = ['AAA','BBB','CCC','DDD','EEE','FFF','GGG'];
var getChartConfig = function( renderId, dataArray1, dataArray2 ) {
var config = {};
config.chart = {
renderTo: renderId, polar: true, type: 'line', height: 254, width: 360, className: 'SpiderPolarChart', backgroundColor: 'rgba(101,101,101,.1)'
};
config.title = {
text: ''
};
config.legend = {
layout: 'horizontal', align: 'center', verticalAlign: 'bottom', y: -3,
};
config.credits = {
enabled: true, text: 'highcharts.com', href: 'http://highcharts.com/', position: {
verticalAlign: 'bottom',
x: -11,
}
};
config.pane = {
startAngle: -90, endAngle: 90, center: ['50%', '93%'], size: 300, background: null
};
config.xAxis = {
categories: __catergories__,
tickmarkPlacement: 'on', tickPixelInterval: 1, lineWidth: 0, labels: {
rotation: 'auto',
distance: 12
}, showLastLabel: true
};
config.yAxis = {
gridLineInterpolation: 'circle', gridLineDashStyle: 'LongDash', tickInterval: 1, lineWidth: 0, min: 0, max: 5, ceiling: 5, labels: {
x: 4, y: 15
}, showLastLabel: true
};
config.exporting = {
enabled: false
};
config.tooltip = {
shared: true, pointFormat: '<span style="color:{series.color}">{series.name}: <b>{point.y:,.0f}</b><br/>'
};
config.series = [{
name: 'Overall Rating', data: dataArray1, color: '#D4A539', type: 'area', pointPlacement: 'on', connectEnds: false, index: 1, legendIndex: 2
},{
name: 'Personal Rating', data: dataArray2, color: '#333', type: 'line', pointPlacement: 'on', connectEnds: false, index: 2, legendIndex: 1
}];
return config;
};
// ===========================================================================
charts.push(new Highcharts.Chart(
getChartConfig( "container21", [1.5,3,2,3,4,1,2], [1,4,1.5,3,2,3,1] )
));
});
I've run the code through JSHint.com so all typos should be tackled as it doesn't show any errors at the moment.
I hope someone can guide me into the right direction to get this to work.
Cheers!
** Updated the links to the JSFiddles **
** ISSUE RESOLVED, see below **
In this jsFiddle (http://jsfiddle.net/golabs/rstpA/) you are not telling it what chart is. You are trying to set the options for a chart that you have not created to update the options you are passing. It is sort of backwards.
Here is a quick "fix":
var newChart = new Highcharts.Chart(
getChartConfig( "container21", [1.5,3,2,3,4,1,2], [1,4,1.5,3,2,3,1] )
);
Now, I would think it would be better to setup a global option set and then merge in your new set (specific to chart you want to build) as in my linked SO answer. This may or may not give you more flexibility.
charts was not defined.
Is this the solution you are looking for?
var charts = [];
charts.push(new Highcharts.Chart(
getChartConfig( "container21", [1.5,3,2,3,4,1,2], [1,4,1.5,3,2,3,1] )
));
http://jsfiddle.net/37Gsv/1/
you may try this:
var charts = [];
var i=0;
for (i =1; i< 10; i++){
var o =i.toString();
charts.push(new Highcharts.Chart(
getChartConfig( "container2"+o, [1.5,3,2,3,4,1,2], [1,4,1.5,3,2,3,1] )
));
}
test link: http://jsfiddle.net/newpiseth/8u0tkkkL/5/