We are using ExtJS 4.2.1. The width/height attributes of the img won't change in below example when element is dragged beyond the +/-5px y-coordinate. Changes to attribute 'show' are also ignored. However, element can be destroyed and re-created, but this is not desired.
[panel]
var dndLinkSprite = me.surface.add({
type: 'image',
x: bBox.x,
y: bBox.y,
width: 16,
height: 16,
src: '/link.png'
})
...
dragAction: function(panel, e, diff, dndConfig) {
var spriteLink = panel.dndLinkSprite;
if ( diff[1] > 5 || diff[1] < -5 ) {
spriteLink.setAttributes(height, 16);
spriteLink.setAttributes(width, 16);
} else {
spriteLink.setAttributes(height, 0);
spriteLink.setAttributes(width, 0);
};
}
Thanks for your help!
Solved - wrong syntax:
Instead of:
spriteLink.setAttributes(height, 0);
spriteLink.setAttributes(width, 0);
use:
spriteLink.setAttributes({width: 0, height:0} , true);
spriteLink.getEl().dom.setAttribute(height, 16);
Related
I'm trying out HTML2PDF javascript.
function createPDF(){
var element = document.getElementById('printMe');
var opt = {
margin: 1,
filename: 'myfile.pdf',
image: { type: 'jpeg', quality: 0.98 },
html2canvas: { scale: 1 },
jsPDF: { unit: 'in', format: 'letter', orientation: 'portrait' }
};
When I use this the pdf converts etc but it appears halfway down the first page. All of the content is encapsulated in a div
<div id="printMe" style="padding: 20px;padding-right:30px;">.....</div>
I've tried setting the height and removing almost all the content but it still seems to be placing it in the middle of the page as the starting point.
Is there some way of forcing the code to start at the top of the page?
Add scrollY: 0 to the html2canvas object in the html2pdf options:
var opt = {
margin: 1,
filename: 'myfile.pdf',
image: { type: 'jpeg', quality: 0.98 },
html2canvas: { scale: 1, scrollY: 0 },
jsPDF: { unit: 'in', format: 'letter', orientation: 'portrait' }
};
I solved the issue.
The movement in position of the print is affected by the scroll position of the window. So if the button to create the PDF is at the top of the page and you click it places the text at the top of the PDF. If the button is placed in the visible area of the page and you scroll down until it is at the top of the page - the amount you've scrolled is added to the top of the PDF document.
document.body.scrollTop = 0; // For Safari
document.documentElement.scrollTop = 0; // For Chrome, Firefox, IE and Opera
I used this code snippet to solve the issue. When I go to print I scroll to the top of the document before creating the PDF.
A combination of scrollX, scrollY, x and y worked for me to force the PDF generation from the top left:
const opts = {
margin: 0,
filename 'result.pdf',
image: { type: 'jpeg', quality: 1 },
html2canvas: {
backgroundColor: "#fff",
scale: window.devicePixelRatio,
y: 0,
x: 0,
scrollY: 0,
scrollX: 0,
windowWidth: 800,
},
jsPDF: { unit: 'px', format: [800, 1600], orientation: 'portrait', precision: 32 }
};
A hack to enforce the same result over all devices is to temporarily set the screen width to the configured windowWidth (this case 800px), e.g., using document.body.style.width = '800px', before creating the PDF, and setting it back to 100% after creating the PDF.
In a grouped column chart of two groups, I would like to center the column when the other column has height 0.
So for example,
The bars for the years 2013 to 2016 should be centered on the year label. This is because the second value in the group is 0, so the height of the bar is 0, so no bar displays:
data = [
["2012", 900, 950],
["2013", 1000, 0],
["2014", 1170, 0],
["2015", 1250, 0],
["2016", 1530, 0]
];
How can I do this with google charts?
see following working snippet...
the bars are centered where their counterpart is blank.
however, it breaks once the user hovers a bar.
the bars are represented by <rect> elements,
which are used to draw the chart itself, the gridlines, the legend bars, etc.
3 <rect> elements are used to highlight the hovered bar.
this is what breaks the code below, it throws off the routine to find the bars.
here's how it works now...
there will be the same number of bars / <rect> elements as there are rows and series,
even if a bar is not visible.
they will be next to last in the list of elements.
the last <rect> element is the x-axis.
the code below works backwards, skipping the last element,
and counts the number of rows / series to gather the bars that may need to be moved.
when the users hovers, there are 3 elements inserted, so the routine will need to change to accommodate.
and they will also need to be moved in order to highlight properly.
otherwise, you can just turn off interactivity and be done...
enableInteractivity: false
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([
["Year", "Asia", "Mama"],
["2012", 900, 950],
["2013", 1000, 0],
["2014", 1170, 0],
["2015", 1250, 0],
["2016", 1530, 0]
]);
var options = {
chartArea: {
height: '100%',
width: '100%',
top: 32,
left: 48,
right: 128,
bottom: 48
},
height: 400,
width: '100%'
};
var container = document.getElementById('chart');
var chart = new google.visualization.ColumnChart(container);
google.visualization.events.addListener(chart, 'ready', function () {
// get chart layout
var chartLayout = chart.getChartLayoutInterface();
// create mutation observer
var observer = new MutationObserver(function () {
// get bar elements
var rects = container.getElementsByTagName('rect');
var barLength = data.getNumberOfRows() * (data.getNumberOfColumns() - 1);
var bars = [];
for (var i = rects.length - 1; i > ((rects.length - 1) - (barLength + 1)); i--) {
if (i < (rects.length - 1)) {
bars.unshift(rects[i]);
}
}
// process each row
for (var r = 0; r < data.getNumberOfRows(); r++) {
// process each series
for (var s = 1; s < data.getNumberOfColumns(); s++) {
// get chart element bounds
var boundsBar = chartLayout.getBoundingBox('bar#' + (s - 1) + '#' + r);
var boundsLabel = chartLayout.getBoundingBox('hAxis#0#label#' + r);
// determine if bar is hidden
if (boundsBar.height < 1) {
// determine series shown, new x coordinate
var seriesShown = (s === 1) ? 1 : 0;
var xCoord = boundsLabel.left + (boundsLabel.width / 2);
// move bar
bars[r + (data.getNumberOfRows() * seriesShown)].setAttribute('x', (xCoord - (boundsBar.width / 2)));
}
}
}
});
observer.observe(container, {
childList: true,
subtree: true
});
});
chart.draw(data, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart"></div>
I have a datatable created from database data that gets aggregated by google.visualization.data.group, then fed into a columnChart.
By default, the resulting chart's bars are all the same color but i would like to make the bars different colors (by iterating through the datatable and assigning a different color to each row in the datable).For now, i'll just try to assign the colour 'gold' to each bar, for simplicity.
This is the documentation for a columnChart and is the documentation for style roles.
I don't think my code can be far wrong:
var groupedCategoryData = new google.visualization.data.group(
stacked01Data, // arg 1 is the array of input data
[{ // arg 2 is the key (An array of numbers/objects being columns to group by)
column: 0, type: 'string'
}],
[{ 'column': 1, 'aggregation': google.visualization.data.avg, 'type': 'number' }]
);//group. col 1 = score
//*****************
groupedCategoryData.addColumn({ type: 'string', role: 'style' });
for (var i = 0; i < groupedCategoryData.length; i++) {
groupedCategoryData[i][2] = 'color: gold';
}//for
//*****************
var stacked01_options = {
width: 500,
height: 300
};//options
var stacked01 = new google.visualization.ColumnChart(document.getElementById('stackedChart01_div'));
stacked01.draw(groupedCategoryData, stacked01_options);
The result is a chart whose bars are all default blue. I admit this is my first foray into javascript. any help would be appreciated.
Yep, that did it. thanks WhiteHat. working code:
//include the bar color data
var colorsGreen = [
[0, 1, '#6AB293'],
[1, 2, '#449371'],
[2, 3, '#277553'],
[3, 4, '#115639'],
[4, 5, '#043822']
];
groupedCategoryData.addColumn('string', 'barColor');
var groupedCategoryDataView = new google.visualization.DataView(groupedCategoryData);
groupedCategoryDataView.setColumns([0, 1, {
calc: function (dt, row) {
var rowValue = dt.getValue(row, 1);
var color;
colorsGreen.forEach(function (range, index) {
if ((rowValue >= range[0]) && ((rowValue < range[1]) || (range[1] === null))) {
color = range[2];
}
});
return color;
},
role: 'style',
type: 'string'
}]);
var stacked01_options = {
width: 500,
height: 300
};//options
var stacked01 = new google.visualization.ColumnChart(document.getElementById('stackedChart01_div'));
stacked01.draw(groupedCategoryDataView, stacked01_options);
}
I have the following Radar chart using Chart.js v2.
My configuration:
legend: false,
scale: {
pointLabels :{
fontSize: 16,
fontStyle: "bold",
}
}
The problem here is the "Communication" label has 0 padding between the label and the number 100. How can I configure this padding and/or fix this issue?
Spent an hour and still can't find the proper label padding options.
My workaround is padding the labels with newlines and spaces:
['行業競爭情況', ''],
['擁有專利', ''],
' 成本控制',
' 現金流',
['', '回本期'],
['', '營運能力'],
['', '行業潛力'],
'行業網絡 ',
'團隊經驗 ',
['計劃的完整性', ''],
The outcome is acceptable:
Make it auto if you wish:
scale: {
pointLabels: {
callback: function (label, i, labels) {}...
I have the same problem as described in the question and also was unable to find a solution using known chart options.
However, here is another workaround to achieve a behaviour similar to the desired padding (although not exactly):
ticks: {
display: false,
max: 11, // notice how this is +1 more than what you actually want
},
gridLines: {
display: true,
color: [
"#dddddd", "#dddddd", "#dddddd", "#dddddd", "#dddddd",
"#dddddd", "#dddddd", "#dddddd", "#dddddd", "#dddddd",
"transparent" ], // notice how the last (additional) line is set to transparent
},
angleLines: {
display: true,
color: "#dddddd",
},
The idea is to add one additional grid line with a transparent color. While this does not cause any padding between the pointLabels and the angleLines, it does cause there to be one gridLine worth of space between the label and the next gridLine. To me, this at least looks a little better.
Note that this is only feasible if you do not need to display ticks (or if you are ok with your scale showing one additional tick value that you don't actually use).
I use chart.js 2.6.0.
I suffered from the same problem as you.
I use only the radar type chart and amended as follows.
// chart.js v2.6.0
function adjustPointPositionForLabelHeight(angle, textSize, position) {
console.log(position.y);
if (angle === 90 || angle === 270) {
position.y -= (textSize.h / 2);
} else if (angle > 270 || angle < 90) {
position.y -= textSize.h;
position.y -= 7; //add source
}
}
Whenever my PR will be merged, pointLabels.padding option will be added ;)
The PR request mentioned by #ketysek was finally merged as of March 2021.
pointLabels.padding
options: {{
scale: {
pointLabels: {
padding: 10, // Enter number here
},
}};
Usually problem occurs with the first pointLabel when it is single liner you can add the callback in options as follows
pointLabels: {
callback: function (label, index) {
/* Hack to add spacing between first pointLabel item and radar graph */
return index == 0 && label.length == 1? [''].concat(label): label;
}
Making pointLabel multi line text solves the problem.
EDIT:
Current version of chartjs is 2.7.3. Upcoming version will probably solves this problem.
var pointLabelPosition = scale.getPointPosition(i, outerDistance + 5);
-> var pointLabelPosition = scale.getPointPosition(i, outerDistance + 15);
Can anybody help me what I am showing in the image?
[1]: http://www.romualdorivera.com/three.js/dat.GUI_img_01.jpg
Here is my code:
var gui = new dat.GUI();
parameters = { x: 1, area: 1,}
gui.add(parameters, 'x', 1,400).name("Scale XY (in)").onChange();
gui.add(parameters, "area", value).name("Surface area=").onChange( x = x * 2);
If you have a plane on the XZ-plane (1 x 1):
var planeGeom = new THREE.PlaneGeometry(1, 1);
planeGeom.rotateX(-Math.PI / 2);
var plane = new THREE.Mesh(planeGeom, new THREE.MeshStandardMaterial({
color: "green"
}));
scene.add(plane);
then you can create an instance of dat.GUI and set its controllers like this:
parameters = {
x: 1,
area: 1,
}
var gui = new dat.GUI();
gui.add(parameters, 'x', 1, 400).name("Scale XY (in)").onChange(
function(value) {
plane.scale.set(value, 1, value);
parameters.area = value * value; // update the value of parameters.area
}
);
gui.add(parameters, "area", 1).name("Surface area=").listen(); // listen for updating of the value
It's based on the example of dat.GUI
jsfiddle example.