I'm working with Google Core charts to plot my data. I had specific custom requirement for the chart, which is donet chart with labeled legends.
I have achieved the same but the issue is when there are certain value on the pie close to each other the one of the legend goes missing.
Below is the jsfiddle example :
https://jsfiddle.net/mudass1rk/270cdraq/1/
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Task', 'Hours per Day'],
['Work', 98],
['Eat', 2],
['Commute', 4],
['Watch TV', 5]
]);
var options = {
pieHole: 0.75,
backgroundColor: { fill: 'transparent'},
pieSliceBorderColor: "black",
legend: {
position: 'labeled',
textStyle:{
color: 'white'
},
alignment: 'center'
},
pieSliceText: 'none',
pieStartAngle: 0,
height: 300,
//width: 300,
chartArea:{top:40},
// tooltip: {trigger: 'selection'},
slices: [{color: '#00DBD1'}, {color: '#61F28F'}, {color: '#61F28F'}, {color: '#FFD100'}, {color: '#FF6B1A'}, {color: '#EB1212'}]
};
var chart = new google.visualization.PieChart(document.getElementById('piechart'));
chart.draw(data, options);
}
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<div id="piechart" style="width: 900px; height: 500px;"></div>
Thanks a lot in advance.
this is a limitation of the chart.
not much you can do but make the chart bigger.
the chart does not automatically adjust to the max size available on the container.
in this case, you have the container set to 900 x 500.
you can adjust the chart area option to provide more room,
along with the height and width options...
chartArea: {
top: 40,
height: '100%',
width: '100%',
left: 100,
right: 100
},
height: '100%',
width: '100%',
see following working snippet...
google.charts.load('current', {
'packages': ['corechart']
});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Task', 'Hours per Day'],
['Work', 98],
['Eat', 2],
['Commute', 4],
['Watch TV', 5]
]);
var options = {
pieHole: 0.75,
backgroundColor: {
fill: 'transparent'
},
pieSliceBorderColor: "black",
legend: {
position: 'labeled',
textStyle: {
color: 'white'
},
alignment: 'center'
},
pieSliceText: 'none',
pieStartAngle: 0,
chartArea: {
top: 40,
height: '100%',
width: '100%',
left: 100,
right: 100
},
height: '100%',
width: '100%',
slices: [{
color: '#00DBD1'
}, {
color: '#61F28F'
}, {
color: '#61F28F'
}, {
color: '#FFD100'
}, {
color: '#FF6B1A'
}, {
color: '#EB1212'
}],
};
var chart = new google.visualization.PieChart(document.getElementById('piechart'));
chart.draw(data, options);
}
#piechart {
height: 500px;
width: 900px;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="piechart"></div>
Related
I'm trying to make a restriction: when a group of objects is selected, some specific object must not be included in the selection.
F.e. we create 3 rectangles. If we select the group and the red one is inside of it, it must be removed from selection:
function addRect(){
var redRect = new fabric.Rect({
left: 50,
top: 50,
fill: 'red',
width: 50,
height: 50
});
var greenRect = new fabric.Rect({
left: 100,
top: 100,
fill: 'green',
width: 50,
height: 50
});
var blueRect = new fabric.Rect({
left: 150,
top: 150,
fill: 'blue',
width: 50,
height: 50
});
canvas.add(redRect);
canvas.add(greenRect);
canvas.add(blueRect);
}
function createCanvas(id){
canvas = new fabric.Canvas(id);
addRect();
canvas.on('selection:created', function(e) {
for (var i = 0; i < canvas.getActiveObjects().length; i++) {
if(canvas.getActiveObjects()[i].fill == "red"){
//somehow remove the red one from selection
};
}
});
return canvas;
}
discardActiveObject() will remove the whole selection.
"selected = false" also doesn't work.
Any ideas?
There are two ways to achieve this using selectable property
http://fabricjs.com/docs/fabric.Rect.html#selectable
By setting selectable: false within the call back function
By setting selectable: false during object creation.
function addRect() {
var redRect = new fabric.Rect({
left: 50,
top: 50,
fill: "red",
width: 50,
height: 50,
selectable: false
});
var greenRect = new fabric.Rect({
left: 100,
top: 100,
fill: "green",
width: 50,
height: 50
});
var blueRect = new fabric.Rect({
left: 150,
top: 150,
fill: "blue",
width: 50,
height: 50
});
canvas.add(redRect);
canvas.add(greenRect);
canvas.add(blueRect);
}
function createCanvas(id) {
canvas = new fabric.Canvas(id, {
height: 500,
width: 800,
backgroundColor: "rgb(100,100,200)",
selectionColor: "blue"
});
addRect();
canvas.on("selection:created", function(e) {
for (var i = 0; i < canvas.getActiveObjects().length; i++) {
if (canvas.getActiveObjects()[i].fill == "red") {
canvas.getActiveObjects()[i].selectable = false;
canvas.renderAll();
}
}
});
return canvas;
}
createCanvas("c");
<script src="https://cdn.jsdelivr.net/npm/fabric#5.2.4-browser/dist/fabric.min.js"></script>
<canvas id="c"> </canvas>
function addRect() {
var redRect = new fabric.Rect({
left: 50,
top: 50,
fill: "red",
width: 50,
height: 50,
selectable: false
});
var greenRect = new fabric.Rect({
left: 100,
top: 100,
fill: "green",
width: 50,
height: 50
});
var blueRect = new fabric.Rect({
left: 150,
top: 150,
fill: "blue",
width: 50,
height: 50
});
canvas.add(redRect);
canvas.add(greenRect);
canvas.add(blueRect);
}
function createCanvas(id) {
canvas = new fabric.Canvas(id, {
height: 500,
width: 800,
backgroundColor: "rgb(100,100,200)",
selectionColor: "blue"
});
addRect();
canvas.on("selection:created", function (e) {
for (var i = 0; i < canvas.getActiveObjects().length; i++) {
if (canvas.getActiveObjects()[i].fill == "red") {
//somehow remove the red one from selection
}
}
});
return canvas;
}
createCanvas("c");
<script src="https://cdn.jsdelivr.net/npm/fabric#5.2.4-browser/dist/fabric.min.js"></script>
<canvas id="c"> </canvas>
I am not able to identify click event on object which present inside the group at the time of rendering the json.
add = new fabric.Rect({
width: 200, height: 100, left: 10, top: 10, angle: 0, stroke: 'black', strokeWidth: 0.2,
fill: 'white'
});
var group = new fabric.Group([add], {
relationid: countsub,
objecttype: 'Subnet',
subTargetCheck: true,
left: 10,
top: 10,
angle: 0
});
this.canvas.add(group);
fabric.Image.fromURL('assets/images/AWS#2x.png', function(oImg) {
oImg.set({
id: 'img',
left: 5,
top: 5,
selectable: true,
hasBorders: false,
hasControls: false,
hasRotatingPoint: false,
backgroundColor: 'white'
});
oImg.scaleToWidth(25);
oImg.scaleToHeight(15);
group.addWithUpdate(oImg);
});
I want to know is there any way to know click on the image which is part of one group.here image is 'assets/images/AWS#2x.png'
You're absolutely right, subTargetCheck: true is the way to go. Then you just attach an appropriate event listener (mousedown if you want to detect a click) to your group and check the subTargets property of the event. It contains an array of sub-targets, if any:
const canvas = new fabric.Canvas('c');
const add = new fabric.Rect({
width: 200, height: 100, left: 10, top: 10, angle: 0, stroke: 'black',
fill: 'white'
});
const group = new fabric.Group([add], {
subTargetCheck: true,
left: 20,
top: 20,
});
canvas.add(group);
fabric.Image.fromURL('https://via.placeholder.com/50x50', (oImg) => {
oImg.set({
left: 0,
top: 0,
});
group.addWithUpdate(oImg);
canvas.requestRenderAll();
});
group.on('mousedown', (e) => {
if (e.subTargets[0] && e.subTargets[0].type === 'image') {
console.log('clicked on image')
}
});
body {
background: ivory;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.4.0/fabric.min.js"></script>
<canvas id="c" width="250" height="200"></canvas>
The documentation of Fabric.js on animation mentions this onChange callback:
onChange: canvas.renderAll.bind(canvas)
However, when I try to substitute this with a custom function, the animation does not show. See this example; the down animation does not show, only the up animation. What is wrong with this code?
var canvas = new fabric.Canvas('canvas');
fabric.Object.prototype.set({
hasControls: false,
selectable: false,
hoverCursor: 'default',
originX: 'center',
originY: 'center'
});
rect1 = new fabric.Rect({
left: 200,
top: 0,
width: 50,
height: 50,
fill: 'red',
opacity: 0
});
canvas.add(rect1);
var button01 = new fabric.Circle({
left: 20,
top: 20,
radius: 10,
fill: '#c0c0c0',
strokeWidth: 1,
stroke: '#808080',
hoverCursor: 'pointer'
});
canvas.add(button01);
button01.on('mousedown', function(options) {
animate_down()
});
var text1 = new fabric.Text("Animate", {
fontFamily: 'Arial',
fontSize: 12,
fill: 'black',
left: 58,
top: 20,
});
canvas.add(text1);
function animate_down() {
rect1.animate({
'top': 300,
'opacity': 1
}, {
onChange: function() {
canvas.renderAll.bind(canvas)
/* some other code */
},
onComplete: animate_up,
duration: 2000,
});
}
function animate_up() {
rect1.animate({
'top': 0,
'opacity': 0
}, {
onChange: canvas.renderAll.bind(canvas),
duration: 2000,
});
}
#canvas {
border:1px solid #000000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.3.5/fabric.min.js"></script>
<canvas id="canvas" width="300" height="300"></canvas>
You need to call canvas.requestRenderAll(); inside your callback. As you are just binding canvas to canvas.renderAll, but never called. Docs
DEMO
var canvas = new fabric.Canvas('canvas');
fabric.Object.prototype.set({
hasControls: false,
selectable: false,
hoverCursor: 'default',
originX: 'center',
originY: 'center'
});
rect1 = new fabric.Rect({
left: 200,
top: 0,
width: 50,
height: 50,
fill: 'red',
opacity: 0
});
canvas.add(rect1);
var button01 = new fabric.Circle({
left: 20,
top: 20,
radius: 10,
fill: '#c0c0c0',
strokeWidth: 1,
stroke: '#808080',
hoverCursor: 'pointer'
});
canvas.add(button01);
button01.on('mousedown', function(options) {
animate_down()
});
var text1 = new fabric.Text("Animate", {
fontFamily: 'Arial',
fontSize: 12,
fill: 'black',
left: 58,
top: 20,
});
canvas.add(text1);
function animate_down() {
rect1.animate({
'top': 300,
'opacity': 1
}, {
onChange: function() {
canvas.requestRenderAll();
/* some other code */
},
onComplete: animate_up,
duration: 2000,
});
}
function animate_up() {
rect1.animate({
'top': 0,
'opacity': 0
}, {
onChange: canvas.requestRenderAll.bind(canvas),
duration: 2000,
});
}
#canvas {
border:1px solid #000000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.3.5/fabric.min.js"></script>
<canvas id="canvas" width="300" height="300"></canvas>
image = new joint.shapes.basic.Image({
position : {
x : 250,
y : 250
},
size : {
width : 90,
height : 90
},
attrs : {
image : {
"xlink:href" : image_link,
width : 100,
height : 100
}
}
});
I want to add ports to image element of joint js
You can use the below code which is in one of the examples in the demo folder of jointjs npm package.
joint.shapes.devs.MyImageModel = joint.shapes.devs.Model.extend({
markup: '<g class="rotatable"><g class="scalable"><rect class="body"/></g><image/><text class="label"/><g class="inPorts"/><g class="outPorts"/></g>',
defaults: joint.util.deepSupplement({
type: 'devs.MyImageModel',
size: { width: 70, height: 50 },
attrs: {
'.port-body': {
r: 5,
magnet: true,
stroke: '#000000'
},
// rect: { stroke: '#d1d1d1', fill: { type: 'linearGradient', stops: [{offset: '0%', color: 'white'}, {offset: '50%', color: '#d1d1d1'}], attrs: { x1: '0%', y1: '0%', x2: '0%', y2: '100%' } } },
// circle: { stroke: 'gray' },
'.inPorts circle': { fill: '' },
'.outPorts circle': { fill: '' },
image: { 'xlink:href': '/images/rout6.gif', width: 70, height: 50, 'ref-x': .5, 'ref-y': .5, ref: 'rect', 'x-alignment': 'middle', 'y-alignment': 'middle' }
}
}, joint.shapes.devs.Model.prototype.defaults)
});
joint.shapes.devs.MyImageModelView = joint.shapes.devs.ModelView;
// Usage:
var imageModel = new joint.shapes.devs.MyImageModel({
position: { x: 10, y: 190 },
size: { width: 70, height: 50 },
inPorts: [''],
outPorts: ['']
});
stencilGraph.addCell(imageModel);
How do I add a shadow to a group of objects, this is not work
var canvas = new fabric.Canvas('container');
var text = new fabric.Text('hello world', {
fontSize: 30
});
//create circle
var circle = new fabric.Circle({
radius: 100,
fill: '#eef',
scaleY: 0.5,
});
var circle2 = new fabric.Circle({
radius: 50,
left: 100,
fill: '#345666',
scaleY: 0.5,
});
//create group
var group = new fabric.Group([circle,circle2], {
angle: -10,
shadow:{ color:"rgb(0,0,0)",blur:20,offsetX:10,offsetY:10 }
});
canvas.add(group);
I know this was a while ago, but it seems shadows on fabric.Group objects is not possible, only on individual objects. Instead why not apply the shadow on the object that forms the background. So in this case it would be:
var newCanvas = new fabric.Canvas('c', {
isDrawingMode: false
});
newCanvas.setWidth(460);
newCanvas.setHeight(365);
var circle = new fabric.Circle({
radius: 100,
fill: '#990000',
originX: 'center',
originY: 'center',
shadow: 'rgba(0,0,0,0.4) 5px 5px 7px'
});
var circle2 = new fabric.Circle({
radius: 50,
fill: '#000000',
originX: 'center',
originY: 'center',
});
var group = new fabric.Group([circle, circle2], {
originX: 'center',
originY: 'center',
left: 225,
top: 185
});
newCanvas.add(group);
newCanvas.renderAll();
* {
box-sizing: border-box;
}
canvas {
border: 1px solid #000000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/fabric.js/1.4.8/fabric.min.js"></script>
<body>
<div>
<canvas id="c"></canvas>
</div>
</body>