can you help me to place a Highchart inside a SVG element instead of an HTML . Cascaded elements work fine. I have already done it with the jquery SVG plot. But Highchart throws an error 13. What can i do?
Kind regards
Markus Breitinger
You can generate chart in div, which will have negative margin. Then use getSVG() function and paste it ot svg element.
http://api.highcharts.com/highcharts#Chart.getSVG()
Unfortunately it is not suppored, highcharts renders the chart in additional divs and adds elements like labels/datalabels as html objects.
But you can copy the SVG of highstock in you SVG. But you will lose all attached events.
Like drag and drop, click ....
Here an Example of it.
http://jsfiddle.net/L6SA4/10/
$.getJSON('http://www.highcharts.com/samples/data/jsonp.php?filename=aapl-c.json&callback=?', function(data) {
// Create a hidden and not attached div container.
var div = $('<div>This is an hidden unatached container.</div>');
// Create the chart
div.highcharts('StockChart', {
chart: {
width: 480,
height: 400,
events: {
load: function () {
// If hidden div was generated, take the svg content and put it into svg.
var stockSvg = $('svg', this.container);
var svgObj = $('#mySvg').svg();
// Force position of highstock
stockSvg.attr('x', 20);
stockSvg.attr('y', 30);
// Replace ugly rect with highstock
$('#container', svgObj).replaceWith(stockSvg);
}
}
},
series : [{
name : 'AAPL',
data : data,
tooltip: {
valueDecimals: 2
}
}]
});
});
Related
I am using OpenSeadragon to display a large image so that it scrolls infinitely as a mosaic. This is working fine, with the code listed below. However, the initial zoom level varies when opened in Chrome, Firefox or Opera, and the image is displayed from a random position within the image, instead of having the desired coordinates in the upper left corner.
Two related questions:
Are there properties to be set to specify the coordinates of the image that should be displayed in the upper left corner when the image is first loaded?
Is there a property to specify the zoom level when the image is first loaded? I set defaultZoomLevel to 0.6 but each browser seem to react differently to it, with Chrome being the only one to get it about right and the other two showing a much more zoomed out image.
Thanks for any help!
<body>
<div id="openseadragon1" style="width: 6560px; height: 3801px;"></div>
<script src="/openseadragon/openseadragon.min.js"></script>
<script type="text/javascript">
var viewer = OpenSeadragon({
id: "openseadragon1",
showNavigationControl: false,
wrapHorizontal: true,
wrapVertical: true,
visibilityRatio: 0,
zoomPerScroll: 1.2,
defaultZoomLevel: 0.6,
minZoomImageRatio: 0.6,
maxZoomPixelRatio: 2.5,
prefixUrl: "/openseadragon/images/",
tileSources: {
type: 'image',
url: '/myBigImage.png'
}
});
// -------------------------------------
// Edit based on iangilman's reply
// -------------------------------------
viewer.addHandler('open', function() {
var tiledImage = viewer.world.getItemAt(0);
var imageRect = new OpenSeadragon.Rect(10, 50, 1000, 1000);
var viewportRect = tiledImage.imageToViewportRectangle(imageRect);
viewer.viewport.fitBounds(viewportRect, true);
});
</script>
</body>
Yes, the zoom levels in OpenSeadragon are relative to the width of the viewport (a zoom of 1 means the image is exactly filling the viewport width-wise), which is probably why you're getting different results on different devices. If you want to choose a specific portion of the image, you'll have to convert from image coordinates to viewport coordinates. Either way, your best bet for reliable results is to explicitly choose the location after the image loads. For example:
viewer.addHandler('open', function() {
// Assuming you are interested in the first image in the viewer (or you only have one image)
var tiledImage = viewer.world.getItemAt(0);
var imageRect = new OpenSeadragon.Rect(0, 0, 1000, 1000); // Or whatever area you want to focus on
var viewportRect = tiledImage.imageToViewportRectangle(imageRect);
viewer.viewport.fitBounds(viewportRect, true);
});
I have the following code:
function preload() {
this.load.svg('table', 'assets/svg/table.svg');
}
function create {
this.add.image(400, 300, 'table');
}
How can I highlight this picture when I hover over it?
You can use the pointerover event like so:
First, declare a variable to hold the svg image.
let tableSvg;
Second, preload the svg image.
function preload() {
this.load.svg('table', 'assets/svg/table.svg');
}
Third, add the svg image to the variable.
tableSvg = this.add.image(400, 300, 'table');
Fourth, set the svg image to be interactive.
tableSvg.setInteractive();
Fifth, add an mouse over event listener like so:
tableSvg.on('pointerover', () => {
console.log(tableSvg)
});
Edit:
You can change the image's color like so:
tableSvg.on('pointerover', () => {
// setTint method takes a color value & change the image's color accordingly
tableSvg.setTint(185273)
});
I have 12 graphs and I want to generate pdf with 2 pages each page has 6 graphs.
However, when I convert svg to canvas, then the jspdf can only see part of both sub-dives.
$('#downloadx2').click(function() {
var svgElements = $("#body_id").find('svg');
//replace all svgs with a temp canvas
svgElements.each(function() {
var canvas, xml;
// canvg doesn't cope very well with em font sizes so find the calculated size in pixels and replace it in the element.
$.each($(this).find('[style*=em]'), function(index, el) {
$(this).css('font-size', getStylex(el, 'font-size'));
});
canvas = document.createElement("canvas");
canvas.className = "screenShotTempCanvas";
//convert SVG into a XML string
xml = (new XMLSerializer()).serializeToString(this);
// Removing the name space as IE throws an error
xml = xml.replace(/xmlns=\"http:\/\/www\.w3\.org\/2000\/svg\"/, '');
//draw the SVG onto a canvas
canvg(canvas, xml);
$(canvas).insertAfter(this);
//hide the SVG element
////this.className = "tempHide";
$(this).attr('class', 'tempHide');
$(this).hide();
});
var doc = new jsPDF("p", "mm");
var width = doc.internal.pageSize.width;
var height = doc.internal.pageSize.height;
html2canvas($("#div_pdf1"), {
onrendered: function(canvas) {
var imgData = canvas.toDataURL(
'image/png', 0.1);
doc.addImage(imgData, 'PNG', 5, 0, width, height/2,'','FAST');
doc.addPage();
}
});
html2canvas($("#div_pdf2"), {
onrendered: function(canvas2) {
var imgData2 = canvas2.toDataURL(
'image/png', 0.1);
doc.addImage(imgData2, 'PNG', 5, 0, width, height/2,'','FAST');
doc.save('.pdf');
}
});
});
<body id="body_id">
<div id="div_pdf1" >
<svg></svg>
<svg></svg>
<svg></svg>
</div>
<div id="div_pdf1" >
<svg></svg>
<svg></svg>
<svg></svg>
</div>
</body>
When I run this code, the generated pdf will view two pages with same canvas the first one (div_pdf1) div. So how to get both of them appearing in pdf as two pages.
You seem to be trying to run 2 parts in sequence but that's not how javascript works and actually runs your code.
No big deal, just a small misunderstanding between your mental model and the engine that executes the code.
A quick temporary debugging tool to see what's going on and verify that there is a discrepancy is to add console.log to key points and check the sequence of their printout once you run the code.
console.log('[1] just before: svgElements.each');
svgElements.each(function() {
console.log('[2] just after: svgElements.each');
And also around this part of the code:
console.log('[3] just before html2canvas-div_pdf1');
html2canvas($("#div_pdf1"), {
console.log('[4] just after html2canvas-div_pdf1');
Finally around this part of the code:
console.log('[5] just before html2canvas-div_pdf2');
html2canvas($("#div_pdf2"), {
console.log('[6] just after html2canvas-div_pdf2');
I suspect you'll see the code doesn't print the log lines in the order you think they will.
Next, you can try wrapping the 2 calls to html2canvas with one setTimeout function and force a delay in the execution of that code by an arbitrary amount of milliseconds.
Note that this is not the recommended final production quality solution but it will make the code output what you want.
i have i problem and tried different solutions, but no success.
I have an amChartXY chart, which has white labels and legend text is white, but when i want to build custom pdf report, i cannot convert those white text into black.
First i have a function which exports chart to base64 string, and i want there to convert the text color to black, but it won't work.
Here is a code snippet of a menu item, that converts to SVG that is saved to global array object.
menu: [
{
class: "",
label: "Save to draft",
click: function() {
var overrideObject = {
backgroundColor : "rgba(255,255,255,1)",
color : "#000",
legend : {
color : "#000"
}
};
var chartObject = this;
chartObject.capture(overrideObject, function () {
chartObject.toJPG({}, function (base64) {
// charts is global array
charts.push({
name: customName,
chart: base64
});
});
});
}
},
Here the overrideObject is changing the backgroundColor attribute with white ( before is was transparent ) but it's not changing font color. Also i have tried different attributes to add, but nothing seems to work.
Is this possible at capture time ?
Here are some images preview of what i want to accomplish :
AmChart for export isn't that well documented, so any feedback would be welcome
The overrideObject you're passing only accepts the same parameters listed in the list of export settings. If you need to change the appearance of specific elements on the chart, you need to use the reviver callback mentioned in the annotation settings section to selectively apply your modifications. For example, here's how to target the value axis labels:
"export": {
"enabled": true,
"reviver": function(nodeObj) {
if (nodeObj.className === 'amcharts-axis-label' && nodeObj.svg.parentNode.classList.contains('amcharts-value-axis')) {
nodeObj.fill = 'rgba(255,0,0,1)';
}
},
// ...
}
Note that you need to use SVG attributes to change the appearance, so you'll have to set the fill to change the color of the text element.
Codepen demo
I'm trying to accomplish two things:
Left Column: Steps are faded by default, but individual steps fade in to full color on hover.
Right Column: A different image is displayed based on the step being hovered in the left column. By default, the first image should be displayed.
I am using the fadeIn function, but I cant get it to work the way I'm hoping. Whats the best way to go about doing this?
Jsfiddle Example
$(document).ready(function() {
$('#step-one')
.hover(
function() {
$('#step-one-image-holder').fadeIn('slow');
}, function() {
$('#step-one-image-holder').fadeOut('fast');
}
);
$('#step-two')
.hover(
function() {
$('#step-two-image-holder').fadeIn('slow');
}, function() {
$('#step-two-image-holder').fadeOut('fast');
}
);
$('#step-three')
.hover(
function() {
$('#step-three-image-holder').fadeIn('slow');
}, function() {
$('#step-three-image-holder').fadeOut('fast');
}
);
});
If you use "hover" the images will disappear always when you leave the left column (I not sure if you want it). You may use "fadeIn" and "fadeOut" inside a "mouseenter" event:
(Maybe you need to put the images on absolute position to avoid the flickering)
//---Show images on mouseenter
$("div[id^='step-']").on("mouseenter", function(){
var image = $("img[id='" + $(this).attr("id") + "-image-holder']");
$("img[id^='step-']").not(image).fadeOut();
image.fadeIn();
});
//---Hide images by default
$("img[id^='step-']:gt(0)").hide();
jsfiddle