Related
I'm trying to implement progress bar inside PDF using pdfmake js library.
Gone through working examples mentioned here vectors in pdfmake, but unable to find progress or partial filled canvas example.
I'm looking for workaround which depicts rectangular canvas with filled color based on dynamic value like below.
{
canvas: [
{
type: 'line',
x1: 40, y1: 100,
x2: 260, y2: 100,
lineWidth: 10,
lineCap: 'square',
lineColor: 'green',
// fillPercentage: 20
}
]
}
Found workaround.
solution_1:
stacking 2 lines.
{
canvas: [
{
type: 'line',
x1: 10, y1: 100,
x2: 100, y2: 100,
lineWidth: 15,
lineColor: '#eef2d7',
lineCap: 'round'
},
{
type: 'line',
x1: 10, y1: 100,
x2: 50, y2: 100, // 50 percent completion
lineWidth: 15,
lineColor: 'green',
lineCap: 'round'
}
]
}
solution_2:
stacking 2 rectangular.
{
canvas: [
{
type: 'rect',
x: 0,
y: 0,
w: 100,
h: 30,
opacity: 0.1,
color: 'white',
lineColor: 'black'
},
{
type: 'rect',
x: 0,
y: 0,
w: 70, // 70 percent completion
h: 30,
color: 'green',
lineColor: 'black'
},
]
}
I have an array of objects:
elements: [
{id: 1, type: "rectangle", x: 10, y: 10, w: 100, h: 60},
{id: 2, type: "rectangle", x: 200, y: 30, w: 100, h: 100},
{id: 3, type: "rectangle", x: 400, y: 0, w: 300, h: 200},
{id: 4, type: "rectangle", x: 10, y: 10, w: 100, h: 60},
{id: 5, type: "rectangle", x: 150, y: 30, w: 100, h: 100},
{id: 6, type: "rectangle", x: 150, y: 270, w: 300, h: 60},
]
I need to go through each object and group them according to their coordinates. The goal is to group them vertically (add rows) and horizontally (add columns).
From those objects I need to get this:
filteredElements: [
{id: 1, type: "row", parent_id: null, data: {}},
{id: 2, type: "row", parent_id: null, data: {}},
{id: 3, type: "column", parent_id: 1, data: {marginLeft: ?, marginTop: ?}},
{id: 4, type: "column", parent_id: 1, data: {marginLeft: ?, marginTop: ?}},
{id: 5, type: "column", parent_id: 1, data: {marginLeft: ?, marginTop: ?}},
{id: 6, type: "rectangle", parent_id: 3, data: {x: 10, y: 10, w: 100, h: 60,}},
{id: 7, type: "rectangle", parent_id: 4, data: {x: 200, y: 30, w: 100, h: 100,}},
{id: 8, type: "rectangle", parent_id: 5, data: {x: 400, y: 0, w: 300, h: 200,}},
{id: 9, type: "row", parent_id: 8, data: {}},
{id: 10, type: "column", parent_id: 9, data: {marginLeft: ?, marginTop: ?}},
{id: 11, type: "column", parent_id: 9, data: {marginLeft: ?, marginTop: ?}},
{id: 12, type: "rectangle", parent_id: 10, data: {x: 10, y: 10, w: 100, h: 60,}},
{id: 13, type: "rectangle", parent_id: 11, data: {x: 150, y: 30, w: 100, h: 100,}},
{id: 14, type: "rectangle", parent_id: 2, data: {x: 150, y: 270, w: 300, h: 60,}},
]
Please note that some "rectangles" might be inside others making them children.
So, I need to:
check how many rows a column has (starting with the root)
check how many columns a row has
define the parent_id according to the hierarchy of the objects
define the type of the new object (row or column?)
add left and right margin to column according to parent and siblings
Here's a visual example of what is pretended:
visual example
I understand this is more of a mathematical challenge but I'm not being able to wrap my brain on it.
Thanks in advance for all your help.
EDIT:
Here is my current logic for calculating columns:
elements: [{
id: 1,
type: "rectangle",
x: 10,
y: 10,
w: 100,
h: 60
},
{
id: 2,
type: "rectangle",
x: 200,
y: 30,
w: 100,
h: 100
},
{
id: 3,
type: "rectangle",
x: 400,
y: 0,
w: 300,
h: 200
},
{
id: 4,
type: "rectangle",
x: 10,
y: 10,
w: 100,
h: 60
},
{
id: 5,
type: "rectangle",
x: 150,
y: 30,
w: 100,
h: 100
},
{
id: 6,
type: "rectangle",
x: 150,
y: 270,
w: 300,
h: 60
},
]
for (var element of elements) {
if (!inserted_first) var compare = {
id: 1,
type: "column",
x0: element.x0,
x1: element.x1,
y0: element.y0,
y1: element.y1,
elements: []
};
inserted_first = true;
index++;
if (this.isBetween(element.x0, compare.x0, compare.x1)) {
(element.x1 > compare.x1) ? compare = {
type: "column",
x0: compare.x0,
x1: element.x1,
y0: element.y0,
y1: element.y1
}: compare = {
type: "column",
x0: compare.x0,
x1: compare.x1,
y0: element.y0,
y1: element.y1
};
if (index == length) this.pushCompareArray(compare, compare_index, destiny_array);
} else if (this.isOutside(element.x1, compare.x1, compare.x0)) {
(element.x0 < compare.x0) ? compare = {
type: "column",
x0: element.x0,
x1: compare.x1,
y0: element.y0,
y1: element.y1
}: compare = {
type: "column",
x0: compare.x0,
x1: compare.x1,
y0: element.y0,
y1: element.y1
};
if (index === length) this.pushCompareArray(compare, compare_index, destiny_array);
} else {
compare.id = compare_index;
compare.elements = [];
destiny_array.push(compare);
compare = {
type: "column",
x0: element.x0,
x1: element.x1,
y0: element.y0,
y1: element.y1
};
compare_index++;
if (index === length) this.pushCompareArray(compare, compare_index, destiny_array);
compare = {
type: "column",
x0: element.x0,
x1: element.x1,
y0: element.y0,
y1: element.y1
};
}
}
I feel this can be simplified...
I am trying to draw a plot with multiple factors. I hope these different factors are distinguished by color, size, and shape of the scatter. An example of this kind of plot is here https://github.com/slfan2013/tempPlot/blob/master/Rplot.png.
I'd like to use a javascript library to draw a similar plot. I usually use plotly.js to draw plots. But I think plotly can only handle one factor at a time (different colors). My question is can plotly handle multiple (nested) factors in one single plot (like color, size, and shape)? If not, if there is any javascript library can achieve these? How about CanvasJS?
#### EDIT.
I understand how to draw scatter with different color and different size (shape, etc) on the same plot. I just would like to have a multiple-factor legend on the plot, so that if I click "red", for example, then the red scatters would hide no matter what size it is AND if I click size "big", big scatters would hide no matter what color it is.
Thanks!
This can be done in CanvasJS using scatter chart and by controlling markerType and markerSize. Check the example shown below.
Refer these pages for markerType and markerSize.
http://canvasjs.com/docs/charts/chart-options/data/markertype/
http://canvasjs.com/docs/charts/chart-options/data/markersize/
var chart = new CanvasJS.Chart("chartContainer",
{
title: {
text: "Scatter Chart with Different Marker Types"
},
legend: {
horizontalAlign: "right",
verticalAlign: "center"
},
data: [
{
type: "scatter",
showInLegend: true,
legendText: "Circle",
dataPoints: [
{ x: 1, y: 91, markerSize: 10 },
{ x: 2, y: 75, markerSize: 20 },
{ x: 3, y: 70, markerSize: 30 },
{ x: 4, y: 85, markerSize: 40 },
{ x: 5, y: 75, markerSize: 50 }
]
},
{
type: "scatter",
markerType: "square", //default "circle"
showInLegend: true,
legendText: "Square",
dataPoints: [
{ x: 1, y: 71, markerSize: 10 },
{ x: 2, y: 55, markerSize: 20 },
{ x: 3, y: 50, markerSize: 30 },
{ x: 4, y: 65, markerSize: 40 },
{ x: 5, y: 55, markerSize: 50 }
]
},
{
type: "scatter",
markerType: "triangle",
showInLegend: true,
legendText: "Triangle",
dataPoints: [
{ x: 1, y: 51, markerSize: 10 },
{ x: 2, y: 35, markerSize: 20 },
{ x: 3, y: 30, markerSize: 30 },
{ x: 4, y: 45, markerSize: 40 },
{ x: 5, y: 35, markerSize: 50 }
]
},
{
type: "scatter",
markerType: "cross",
showInLegend: true,
legendText: "Cross",
dataPoints: [
{ x: 1, y: 31, markerSize: 10 },
{ x: 2, y: 15, markerSize: 20 },
{ x: 3, y: 10, markerSize: 30 },
{ x: 4, y: 25, markerSize: 40 },
{ x: 5, y: 15, markerSize: 50 }
]
}
]
});
chart.render();
<script src="http://canvasjs.com/assets/script/canvasjs.min.js"></script>
<div id="chartContainer" style="height: 300px; width: 100%;"></div>
You would just need to define multiple traces and set the parameters for each trace individually.
trace0 is just the default settings
trace1 has a custom color
trace2 has a custom color and custom size
trace3 has a custom color, custom size and custom symbol
var trace0 = {
x: [1, 2, 3],
y: [1, 2, 3],
type: 'scatter',
mode:'markers'};
var trace1 = {
x: [1, 2, 3],
y: [2, 1.8, 1],
type: 'scatter',
mode:'markers',
marker: {
color: 'red'
}};
var trace2 = {
x: [1, 2, 3],
y: [2.8, 2.3, 1.2],
type: 'scatter',
mode:'markers',
marker: {
color: 'green',
size: [10, 15, 20]
}};
var trace3 = {
x: [1, 2, 3],
y: [3, 2.5, 1],
type: 'scatter',
mode:'markers',
marker: {
color: 'pink',
size: [10, 15, 20],
symbol: 303
}};
Plotly.plot('myDiv', [trace0, trace1, trace2, trace3])
<div id='myDiv'></div>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
This is the pen that I found: http://codepen.io/GreenSock/pen/Krfod.
TweenMax.to(document.getElementById('creature'), 5, {
bezier: {
type: 'cubic',
values: [{ x: 100, y: 400 }, { x: 400, y: 100 }, { x: 500, y: 500 }, { x: 10, y: 400 }],
autoRotate: ['x', 'y', 'rotation', 0, true]
},
ease: Power1.easeInOut
});
I don't know how to reduce the frame, I mean the only part I need is:
TweenMax.to(document.getElementById('creature'), 5, {
bezier: {
type: 'cubic',
values: [{ x: 100, y: 400 }],
autoRotate: ['x', 'y', 'rotation', 0, true]
},
ease: Power1.easeInOut
});
But when I delete additional frames, it doesn't work. Any help would be great. Thanks.
How can I animate fillLinearGradientColorStops of a KineticJS Rect? I tried using a tween but surely it doesn't work.
The rectangle:
var rect = new Kinetic.Rect({
x: 20,
y: 20,
width: 100,
height: 100,
fillLinearGradientStartPoint: { x: -50, y: -50 },
fillLinearGradientEndPoint: { x: 50, y: 50 },
fillLinearGradientColorStops: [0, 'red', 1, 'yellow']
});
The tween:
var tween = new Kinetic.Tween({
node: rect,
duration: 2,
easing: Kinetic.Easings.Linear,
fillLinearGradientColorStops: [0, 'black', 1, 'green']
});
tween.play();
Please see the fiddle http://jsfiddle.net/ZdCmS/. Is it not possible?
From there: https://github.com/ericdrowell/KineticJS/issues/901
You can use an external tweening library, like GreenSock (http://www.greensock.com/gsap-js/) with it's ColorProps plugin (http://api.greensock.com/js/com/greensock/plugins/ColorPropsPlugin.html) to tween colors and then apply them to the Kinetic shape on each frame update: http://jsfiddle.net/ZH2AS/2/
No plans for direct support of tweening color stops on a gradient fill.
var stage = new Kinetic.Stage({
container: 'container',
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
var linearGradPentagon = new Kinetic.RegularPolygon({
x: 150,
y: stage.height() / 2,
sides: 5,
radius: 70,
fillLinearGradientStartPoint: {
x: -50,
y: -50
},
fillLinearGradientEndPoint: {
x: 50,
y: 50
},
fillLinearGradientColorStops: [0, 'white', 1, 'black'],
stroke: 'black',
strokeWidth: 4,
draggable: true
});
layer.add(linearGradPentagon);
stage.add(layer);
//activate ColorPropsPlugin
TweenPlugin.activate([ColorPropsPlugin]);
//object to store color values
var tmpColors = {
color0: 'white',
color1: 'black'
};
//tween the color values in tmpColors
TweenMax.to(tmpColors, 5, {
colorProps: {
color0: 'black',
color1: 'red'
},
yoyo: true,
repeat: 5,
ease:Linear.easeNone,
onUpdate: applyProps
});
function applyProps() {
linearGradPentagon.setAttrs({
fillLinearGradientColorStops: [0, tmpColors.color0, 1, tmpColors.color1]
});
layer.batchDraw();
}