I'm trying to make this http://gcuculi.com/cda/imagens/grafico.png with Cytoscape.js. I'm using the circle layout, but it isn't working. I will add more items dynamically. The first node always be closer than the second and so on for the others.
Here is the code:
$(function(){
var cy = cytoscape({
container: document.getElementById('grafico-constelacao'),
style: cytoscape.stylesheet()
.selector('node')
.css({
'content': 'data(name)',
'text-valign' : 'center',
'color' : 'white',
})
.selector('edge')
.css({
'width': 2,
'line-color': '#000'
})
.selector('#p')
.css({
'background-color': '#fff',
'width': '60px',
'height': '60px',
'border-width': '2px',
'border-style': 'solid',
'border-color ': '#888',
}),
elements: {
nodes: [
{
data: {id: 'p', weight: 1 },
group: 'nodes',
position: {
x: 500,
y: 150
},
classes: 'principal',
selected: false,
selectable: false,
locked: true,
grabbable: false
},
{ data: { id: 'atr1', name : 'A'} },
{ data: { id: 'atr2', name : 'B' } },
{ data: { id: 'atr3', name : 'C' } },
{ data: { id: 'atr4', name : 'D' } },
{ data: { id: 'atr5', name : 'E' } }
],
edges: [
{ data: { id: 'p-atr1', weight: 1, source: 'p', target: 'atr1' } },
{ data: { id: 'p-atr2', weight: 10, source: 'p', target: 'atr2' } },
{ data: { id: 'p-atr3', weight: 50, source: 'p', target: 'atr3' } },
{ data: { id: 'p-atr4', weight: 100, source: 'p', target: 'atr4' } },
{ data: { id: 'p-atr5', weight: 250, source: 'p', target: 'atr5' } }
]
},
layout: {
name: 'circle',
fit: true,
padding: 30,
boundingBox: undefined,
avoidOverlap: true,
radius: undefined,
startAngle: 10 * Math.PI,
counterclockwise: true,
sort: undefined,
animate: false,
animationDuration: 500,
ready: undefined,
stop: undefined
},
// interaction options:
zoomingEnabled: false,
userZoomingEnabled: false,
panningEnabled: false,
userPanningEnabled: false,
boxSelectionEnabled: false,
selectionType: 'single',
touchTapThreshold: 8,
desktopTapThreshold: 4,
autolock: false,
autoungrabify: false,
autounselectify: false,
});
});
There is a way to control the size of the edges forcing a value?
Run the circle layout on the outside nodes only, specifying your radius as desired and the bounding box centred around the centre node. Run whatever layout you like on the other nodes after init, so you have initial positions to base the secondary layouts on.
http://js.cytoscape.org/#collection/layout
Related
I have a react web application using echarts-for-react. I've set values that accurately reflect my UI requirements but the problem started when I made it responsive. The position, offset and distance for label are fixed numeric values and not percentage. So when I resize the screen and therefore chart also. The label position gets changed. Is there any way to fix it so that on changing the size, the position of label is changed properly without getting misplaced ???
`
import ReactEcharts from "echarts-for-react"
var builderJson = {
"all": 100,
"total": 1000,
"charts": {
"A": 10,
"B": 20,
"C": 30
},
};
const options = {
grid: {
containLabel: true,
height: '60%'
},
xAxis: {
show : false,
type: 'value'
},
yAxis: {
data: Object.keys(builderJson.charts),
type: 'category',
axisLabel: {
show: false,
},
splitLine: {
show: false
},
axisLine: {
show: false
},
axisTick: {
show: false,
}
},
series: [
{
color: 'blue',
type: 'bar',
barCategoryGap: '10%',
barWidth: '40%',
stack: 'total',
groupPadding: 3,
label: {
color: 'black',
position: [0, -16],
formatter: function(param) { return param.name },
show: true
},
itemStyle: {
borderRadius: [0, 2, 2, 0],
},
data: Object.keys(builderJson.charts).map(function (key) {
return builderJson.charts[key];
})
},
{
type: 'bar',
barWidth: '40%',
stack: 'total',
barCategoryGap: '10%',
color: 'whitesmoke',
groupPadding: 3,
label: {
show: true,
distance: 15,
position: 'insideBottomRight',
offset: [-50, 0],
color: 'grey',
formatter: function(params) { return builderJson.all - params.value + '%' }
},
data: Object.keys(builderJson.charts).map(function (key) {
return builderJson.all - builderJson.charts[key];
})
},
{
type: 'bar',
stack: 'total',
barWidth: '40%',
barCategoryGap: '10%',
color: 'whitesmoke',
groupPadding: 3,
label: {
show: true,
position: 'insideBottomRight',
offset: [20,-10],
formatter: function(params) { return builderJson.total }
},
data: Object.keys(builderJson.charts).map(function (key) {
return 0;
})
}
]
}
function App() {
return (
<ReactEcharts
option={options}
style={{
width: "100%", height: "100vw"
}}
></ReactEcharts>
)
}
export default App
`
Gives following output in certain height and width scaling :-
But when the height changes, the label get placed in wrong part :-
Any help on how to fix this??
For some reason, the data label isn't being displayed on my line graph by ApexChart.
Seems like the chart's JS is relatively simple:
var options = {
chart: {
height: 380,
type: 'line',
zoom: {
enabled: false
},
toolbar: {
show: false
},
dropShadow: {
enabled: true,
top: 10,
left: 0,
bottom: 0,
right: 0,
blur: 2,
color: '#45404a2e',
opacity: 0.35
},
},
colors: ['#1ecab8', '#56b9db', '#ffb66e', '#eb3131', '#373d3f'],
dataLabels: {
enabled: true,
},
stroke: {
width: [3, 3, 3, 3, 3],
curve: 'smooth'
},
series: [{
name: "Informational",
data: [5,10,15,20]
},
{
name: "Low",
data: [2,3,4,5]
},
{
name: "Medium",
data: [9,0,2,3]
},
{
name: "High",
data: [1,2,3,4]
},
{
name: "Critical",
data: [0,0,0,10]
}
],
title: {
text: 'Reported Findings',
align: 'left',
style: {
fontSize: "14px",
color: '#ffffff'
}
},
grid: {
row: {
colors: ['transparent', 'transparent'], // takes an array which will be repeated on columns
opacity: 0.2
},
borderColor: '#f1f3fa'
},
markers: {
style: 'inverted',
size: 6
},
xaxis: {
categories: <%= raw #series_months %>,
axisBorder: {
show: true,
color: '#bec7e0',
},
axisTicks: {
show: true,
color: '#bec7e0',
},
},
yaxis: {
min: 0,
max: 50
},
legend: {
position: 'top',
horizontalAlign: 'right',
floating: true,
offsetY: -25,
offsetX: 5
},
responsive: [{
breakpoint: 600,
options: {
chart: {
toolbar: {
show: false
}
},
legend: {
show: false
},
}
}]
}
var chart = new ApexCharts(
document.querySelector("#<%= #chart_id %>"),
options
);
chart.render();
What am I missing that is causing this to not display correctly? It doesn't make sense because if I change one of the first arrays from a 9 to a 10, then it shows up just fine:
Fixed this by updating the apexchart version from 3.15.6 to 3.19.3
I am using js.cytoscape, and need to generate a graph from left to right.
when I use the layouts, it generate the chart from top to the bottom
code.js file is as follows
var cy = window.cy = cytoscape({
container: document.getElementById('cy'),
boxSelectionEnabled: false,
autounselectify: true,
layout: {
name: 'dagre'
},
style: [
{
selector: 'node',
style: {
'content': 'data(id)',
'text-opacity': 0.5,
'text-valign': 'center',
'text-halign': 'right',
'background-color': '#11479e'
}
},
{
selector: 'edge',
style: {
'curve-style': 'bezier',
'width': 4,
'target-arrow-shape': 'triangle',
'line-color': '#9dbaea',
'target-arrow-color': '#9dbaea'
}
}
],
elements: {
nodes: [
{ data: { id: 'n0' } , position: { x: 0, y: 0 } },
{ data: { id: 'n1' } , position: { x: 100, y: 0 } },
{ data: { id: 'n2' } , position: { x: 200, y: 0 } }
],
edges: [
{ data: { source: 'n0', target: 'n1' } },
{ data: { source: 'n1', target: 'n2' } },
]
},
});
When you set the layout to 'preset' the chat is generated from left to right with the given positions. But it is not possible to position all the nodes when it supposed to generate chart dynamically using user given data.
Please suggest a solution.
Thank you
As of cytoscape.js-dagre documentation, there's a layout option that can change the direction of your graph. Simply add to layout:
layout: {
name: 'dagre'
rankDir: 'LR', // 'TB' for top to bottom flow, 'LR' for left to right. default is undefined, making it plot top-bottom
},
I refer to http://jsfiddle.net/VJsjg/2/
$(function() {
$('#container').highcharts('StockChart', {
chart: {
zoomType: 'x',
marginTop: 100, //avoid overlapping with navigator
spacingLeft: 0
},
scrollbar: {
enabled: false
},
navigator: {
enabled: true,
top: 40
},
rangeSelector: {
selected: 1
},
yAxis:[{
top:140,
height:150
}],
series: [{
id:'msft',
name: 'MSFT',
data: MSFT
}]
});
$('#button').click(function() {
var chart = $('#container').highcharts();
chart.addAxis({
id:'secondY',
top:300,
height:150
});
chart.addSeries({
id:'adbe',
yAxis:'secondY',
name: 'ADBE',
data: ADBE
});
$(this).attr('disabled', true);
chart.addSeries(
// the event marker flags
{
type : 'flags',
data : [{
x : Date.UTC(2011, 3, 25),
title : 'H',
text : 'Euro Contained by Channel Resistance'
}, {
x : Date.UTC(2011, 3, 28),
title : 'G',
text : 'EURUSD: Bulls Clear Path to 1.50 Figure'
}],
onSeries : 'adbe',
shape : 'circlepin',
width : 16
});
});
});
Notice that the circlepin H and C are at the correct position of the bottom series. However, when we do a mouseover, the position of the tooltip followed the top series instead.
Has anyone encountered the same problem before?
I fixed my own problem by adding a
tooltip: {
followPointer:true
}
to the series.
Refer to http://jsfiddle.net/VGj9q/ for the solution.
Tooltip can follow yAxis by adding followingPointer:true, but in this way, the tooltip shape became 'square', not 'callout'.
I think this is a bug of highcharts, some similar issues can be found on github. But seems they didn't fix it for 'flag' series.
Refer to http://jsfiddle.net/4jt9jxs1/2/ for this issue.
Highcharts.stockChart('container', {
chart: {
height: 600,
},
navigator: {
enabled: false
},
yAxis: [{
id: "1",
height: 200,
},{
id: "2",
top: 300,
height: 200,
}],
tooltip:{
shared: false
},
series: [{
name: 'USD to EUR',
id: 'dataseries',
data: usdeur,
yAxis: "1"
},{
name: 'USD to EUR1',
id: 's1',
data: usdeur,
yAxis:"2"
}, {
type: 'flags',
data: [{
x: Date.UTC(2011, 1, 14),
title: 'A',
text: 'Shape: "squarepin"'
}, {
x: Date.UTC(2011, 3, 28),
title: 'A',
text: 'Shape: "squarepin"'
}],
onSeries: 'dataseries',
shape: 'squarepin',
width: 16
}, {
type: 'flags',
data: [{
x: Date.UTC(2010, 2, 1),
text: 'Shape: "circlepin"'
}, {
x: Date.UTC(2010, 9, 1),
text: 'Shape: "circlepin"'
}],
shape: 'circlepin',
onSeries: 's1',
yAxis:"2",
title: 'B',
tooltip: {
followPointer: true,
},
width: 16
}, {
type: 'flags',
data: [{
x: Date.UTC(2012, 2, 10),
title: 'C',
text: 'Shape: "flag"'
}, {
x: Date.UTC(2013, 3, 11),
title: 'C',
text: 'Shape: "flag"'
}],
yAxis:"2",
color: '#5F86B3',
fillColor: '#5F86B3',
onSeries: 's1',
width: 16,
style: { // text style
color: 'white'
},
states: {
hover: {
fillColor: '#395C84' // darker
}
}
}]
});
<div id="container" style="height: 400px; min-width: 600px"></div>
<script src="https://code.highcharts.com/stock/highstock.js"></script>
<script src="https://code.highcharts.com/stock/modules/exporting.js"></script>
<script type="text/javascript" src="https://www.highcharts.com/samples/data/usdeur.js"></script>
I am developing a mixed charts component for Extjs, and the curves are like too sharp. I could not find a configuration for the curves to have radius. If you have dealt with something like can you provide some way to make the curves to me smooth a little. Here is my code:
Ext.define('Ext.vcops.rootCause.RootCauseScoreChart', {
extend : 'Ext.chart.Chart',
initMembers : function() {
this.store = Ext.create('Ext.data.JsonStore', {
fields: ['name', 'score', 'noiseIndex', 'line1', 'line2', 'line3'],
data: generateData()
});
this.axes = [{
type: 'Numeric',
minimum: 0,
maximum: 100,
constrain: false,
dashSize: 0,
majorTickSteps: 7,
position: 'left',
title: 'Score',
grid: true
},{
type: 'Category',
position: 'bottom',
grid: true,
label: {
renderer: function(name) {
return '';
}
}
}];
this.series = [{
type: 'area',
highlight: false,
axis: 'left',
xField: 'name',
yField: ['score'],
style: {
opacity: 1
}
}, {
type: 'line',
axis: 'left',
shadowAttributes: false,
xField: 'name',
yField: 'noiseIndex',
style: {
stroke: '#000000',
'stroke-width': 1,
opacity: 1,
'stroke-dasharray': 10
},
showMarkers: false
}, {
type: 'line',
axis: 'left',
shadowAttributes: false,
showInLegend: false,
xField: 'name',
yField: 'line1',
style: {
stroke: '#FFDD16',
'stroke-width': 2,
opacity: 1
},
showMarkers: false
}, {
type: 'line',
axis: 'left',
shadowAttributes: false,
showInLegend: false,
xField: 'name',
yField: 'line2',
style: {
stroke: '#F1592A',
'stroke-width': 2,
opacity: 1
},
showMarkers: false
}, {
type: 'line',
axis: 'left',
shadowAttributes: false,
showInLegend: false,
xField: 'name',
yField: 'line3',
style: {
stroke: '#EE1C25',
'stroke-width': 2,
opacity: 1
},
showMarkers: false
}];
this.themeAttrs.colors = ["#65B9E0", "#94ae0a", "#115fa6", "#a61120", "#ff8809", "#ffd13e", "#a61187", "#24ad9a", "#7c7474", "#a66111"];
},
initComponent : function() {
this.initMembers();
var config = {
insetPadding: 0,
legend: {
position: 'right',
boxStroke : 'transparent',
boxFill: 'transparent'
},
listeners: {
select: {
fn: function(me, selection) {
//TODO zoom logi here
}
}
}
};
Ext.apply(this, Ext.apply(config, this.initialConfig));
Ext.vcops.rootCause.RootCauseScoreChart.superclass.initComponent.apply(this, arguments);
}
});
I use line chart with fill=true, it's the same effect as area but with curved areas.
Ext.application({
name: 'Fiddle',
launch: function() {
Ext.application({
name: 'PanelHeaderItems',
launch: function() {
var graphStore = Ext.create('Ext.data.Store', {
fields: ['kg', 'ha'],
data: [{
"kg": "0.23",
"ha": "90"
}, {
"kg": "0.4",
"ha": "20"
}, {
"kg": "0.6",
"ha": "70"
}, {
"kg": "0.8",
"ha": "56"
}, {
"kg": "0.95",
"ha": "100"
}]
});
wizardStep3Chart = new Ext.chart.CartesianChart({
width: 400,
height: 300,
animation: true,
store: graphStore,
legend: {
position: 'right'
},
axes: [{
type: 'numeric',
position: 'left',
grid: true,
fields: ['ha'],
renderer: function(v) {
return v;
}
}, {
type: 'numeric',
position: 'bottom',
grid: true,
adjustByMajorUnit: false,
fields: ['kg'],
label: {
rotate: {
degrees: -45
}
}
}],
series: [{
type: 'line',//<-----------
smooth:true,//<-----------
fill:true,//<-----------
axis: 'left',
xField: 'kg',
yField: 'ha',
style: {
opacity: 0.80
},
highlight: {
fillStyle: '#125489',
lineWidth: 2,
strokeStyle: '#fff'
},
tooltip: {
trackMouse: true,
style: 'background: #fff',
renderer: function(storeItem, item) {
this.setHtml(storeItem.get('ha') + ': ' + storeItem.get('kg'));
}
}
}],
renderTo: Ext.getBody()
});
}
});
}
});
Use the smooth: true option on the line series.