D3 Line graph is not rendering on IE8 - svg

We are using D3 library for creating line graph in a project. It is working as expected in modern browsers inlcuding mobile devices.
We are using Aight Library (https://github.com/shawnbot/aight) for IE8 compatibility but it is still not rendering the graph.
Any help or suggestion would be appreciated.
index.html :---
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<script src="jquery.min.js"></script>
<script src="aight.js"></script>
<!-- <script>aight.browser.ie8 = true;</script> -->
<script src="d3.v2.js"></script>
<script src="d3nvtooltip.js"></script>
<script src="d3legend.js"></script>
<script src="d3line.js"></script>
<script src="d3linewithlegend.js"></script>
<script src="graph.js"></script>
<script src="aight.d3.js"></script>
<link href="d3.css" rel="stylesheet" type="text/css">
<style>
#test1 {
margin: 0;
padding: 0;
overflow: none;
}
</style>
</head>
<body>
<div id="test1">
<svg></svg>
</div>
</body>
</html>
graph.js : ---
$(document).ready(function() {
var margin = {top: 30, right: 10, bottom: 50, left: 60},
chart = d3LineWithLegend()
.xAxis.label('xAxis')
.width(width(margin))
.height(height(margin))
.yAxis.label('yAxis');
var svg = d3.select('#test1 svg')
.datum(generateData())
svg.transition().duration(500)
.attr('width', width(margin))
.attr('height', height(margin))
.call(chart);
chart.dispatch.on('showTooltip', function(e) {
var offset = $('#test1').offset(), // { left: 0, top: 0 }
left = e.pos[0] + offset.left,
top = e.pos[1] + offset.top,
formatter = d3.format(".04f");
var content = '<h3>' + e.series.label + '</h3>' +
'<p>' +
'<span class="value">[' + e.point[0] + ', ' + formatter(e.point[1]) + ']</span>' +
'</p>';
nvtooltip.show([left, top], content);
});
chart.dispatch.on('hideTooltip', function(e) {
nvtooltip.cleanup();
});
$(window).resize(function() {
var margin = chart.margin();
chart
.width(width(margin))
.height(height(margin));
d3.select('#test1 svg')
.attr('width', width(margin))
.attr('height', height(margin))
.call(chart);
});
function width(margin) {
var w = 800 - 20;
return ( (w - margin.left - margin.right - 20) < 0 ) ? margin.left + margin.right + 2 : w;
}
function height(margin) {
var h = 500 - 20;
return ( h - margin.top - margin.bottom - 20 < 0 ) ? margin.top + margin.bottom + 2 : h;
}
//data
function generateData() {
var data1 = [[1,250000],[2,249318],[3,248634],[4,247948],[5,247260],[6,246569],[7,245876],[8,245181],[9,244483],[10,243783],[11,243081],[12,242376],[13,241669],[14,240960],[15,240248],[16,239534],[17,238817],[18,238098],[19,237377],[20,236653],[21,235927],[22,235199],[23,234468],[24,233734],[25,232998],[26,232260],[27,231519],[28,230776],[29,230031],[30,229282],[31,228532],[32,227778],[33,227023],[34,226265],[35,225504],[36,224741],[37,223975],[38,223206],[39,222435],[40,221662],[41,220886],[42,220107],[43,219326],[44,218542],[45,217756],[46,216967],[47,216175],[48,215380],[49,214583],[50,213784],[51,212981],[52,212176],[53,211369],[54,210558],[55,209745],[56,208929],[57,208111],[58,207290],[59,206466],[60,205639],[61,204809],[62,203977],[63,203142],[64,202304],[65,201464],[66,200620],[67,199774],[68,198925],[69,198073],[70,197219],[71,196361],[72,195501],[73,194637],[74,193771],[75,192902],[76,192030],[77,191155],[78,190278],[79,189397],[80,188513],[81,187627],[82,186737],[83,185845],[84,184949],[85,184051],[86,183149],[87,182245],[88,181337],[89,180427],[90,179513],[91,178597],[92,177677],[93,176754],[94,175829],[95,174900],[96,173968],[97,173033],[98,172095],[99,171153],[100,170209],[101,169261],[102,168310],[103,167357],[104,166399],[105,165439],[106,164476],[107,163509],[108,162539],[109,161566],[110,160590],[111,159610],[112,158627],[113,157641],[114,156651],[115,155659],[116,154662],[117,153663],[118,152660],[119,151654],[120,150645],[121,149632],[122,148616],[123,147596],[124,146573],[125,145547],[126,144517],[127,143484],[128,142447],[129,141407],[130,140363],[131,139316],[132,138266],[133,137212],[134,136154],[135,135093],[136,134028],[137,132960],[138,131889],[139,130813],[140,129734],[141,128652],[142,127566],[143,126476],[144,125383],[145,124286],[146,123185],[147,122081],[148,120973],[149,119861],[150,118745],[151,117626],[152,116503],[153,115377],[154,114246],[155,113112],[156,111974],[157,110833],[158,109687],[159,108538],[160,107385],[161,106228],[162,105067],[163,103902],[164,102734],[165,101561],[166,100385],[167,99204],[168,98020],[169,96832],[170,95640],[171,94443],[172,93243],[173,92039],[174,90831],[175,89619],[176,88403],[177,87182],[178,85958],[179,84730],[180,83497],[181,82260],[182,81020],[183,79775],[184,78526],[185,77273],[186,76015],[187,74754],[188,73488],[189,72218],[190,70944],[191,69665],[192,68382],[193,67095],[194,65804],[195,64509],[196,63209],[197,61904],[198,60596],[199,59283],[200,57965],[201,56644],[202,55318],[203,53987],[204,52652],[205,51313],[206,49969],[207,48620],[208,47267],[209,45910],[210,44548],[211,43182],[212,41811],[213,40435],[214,39055],[215,37670],[216,36281],[217,34887],[218,33488],[219,32085],[220,30677],[221,29264],[222,27847],[223,26424],[224,24998],[225,23566],[226,22130],[227,20688],[228,19242],[229,17792],[230,16336],[231,14875],[232,13410],[233,11940],[234,10465],[235,8985],[236,7500],[237,6010],[238,4515],[239,3015],[240,1510],[241,0]];
return [
{
data: data1,
label: "Label"
}
];
}
});

From the documentation of Aight:
Aight is a collection of shims and polyfills that get IE8 up to speed
with a bare minimum of HTML5 compatibility, providing all of the
interfaces necessary to do HTML-only DOM manipulation with d3.js (and
other libraries that rely on those interfaces)
Your graph is svg-based, so you're going to have to find another solution if you need it to render in IE8 and lower. One such possibility would be to shim the svg functionality with R2D3 (raphael.js for D3). That will be able to handle some cases by translating to VML (via raphaël).

Related

html2canvas does not print jsPlumb Connectors

How to print SVG elements that are built by jsPlumb.
Known that getting all SVG Elements drawen by jsPlumb is retrieved by this code :
var uiJsPlumbConnectors=jsPlumb.getAllConnections().map(function(conn){return conn.canvas;})
All connectors are SVG elements :
Using html2canvas to print all connectors (SVG), it does not work :
html2canvas(uiJsPlumbConnectors).then(function(c){
window.open(c.toDataURL('image/png'))
});
An image has been generated , however, it is an emply image .
FIDDLE
It seems that html2canvas does not support yet multi-elements drawing ?
Last time I checked html2canvas was not able to convert SVGs, you will need another script to handle that.
The steps:
transfer html elements to canvas
transfer svg elements to canvas
export canvas
I used https://code.google.com/p/canvg/ to export to the same canvas after using html2canvas. Hope that helps you.
I just implemented this
<%--stuff for printing--%>
<script type="text/javascript" src="../../../../Scripts/Print/html2canvas.js"></script>
<script src="<%=AdminPath%>Scripts/canvg/rgbcolor.js" type="text/javascript"></script>
<script src="<%=AdminPath%>Scripts/canvg/StackBlur.js" type="text/javascript"></script>
<script src="<%=AdminPath%>Scripts/canvg/canvg.js" type="text/javascript"></script>
jsplumb div
<div class="demo statemachine-demo" id="statemachine-demo" style="margin: 0px;">
</div>
hidden div for printing
<div id="canvasDiv" style='visibility:hidden;' >
</div>
function renderImage()
{
var statemachinediv = document.getElementById('statemachine-demo');
html2canvas([statemachinediv], {
onrendered: function (canvas) {
document.getElementById('canvasDiv').appendChild(canvas);
var svgList = $(statemachinediv).find( "svg" );
svgList.each(function(index, value) {
try
{
var svgExample = this;
var serializer = new XMLSerializer();
var svgMarkup = serializer.serializeToString(svgExample);
if(svgMarkup.indexOf("_jsPlumb_connector") > -1)
{
var leftIndex = svgMarkup.indexOf("left: ");
var endOfLeft = svgMarkup.indexOf("px", leftIndex);
var leftPosition = svgMarkup.substring(leftIndex+6, endOfLeft );
var left = parseInt(leftPosition);
var topIndex = svgMarkup.indexOf("top: ");
var endOfTop = svgMarkup.indexOf("px", topIndex);
var topPosition = svgMarkup.substring(topIndex+5, endOfTop );
var top = parseInt(topPosition);
svgMarkup = svgMarkup.replace('xmlns="http://www.w3.org/2000/svg"','');
var connectorCanvas = document.createElement('canvas');
canvg(connectorCanvas, svgMarkup); //add connector to canvas
var context = canvas.getContext('2d');
context.drawImage(connectorCanvas, left, top);
}
}
catch(err)
{
showBalloon('error in print');
}
});
var stateMachineName = $("#stateMachineDropDown option:selected").text();
var data = canvas.toDataURL('image/png');
var mywindow = window.open('', 'my div', 'height=400,width=600');
mywindow.document.write('<html><head><title>' + stateMachineName + '</title>');
mywindow.document.write('</head><body ><table><tr><td>');
mywindow.document.write('</td></tr></table><img src="' + data + '" />');
mywindow.document.write('</body></html>');
mywindow.print();
}
});
return false;
}
Its a old question, but, this helped me. Mode details.
$clone.find('.jtk-connector').each(function () {
// for every SVG element created by JsPlumb for connections...
var left = parseInt(this.style.left, 10) + 'px';
var top = parseInt(this.style.top, 10) + 'px';
this.removeAttribute('style');
this.removeAttribute('position');
this.setAttribute('width', parseInt(this.getAttribute('width'), 10) + 'px');
this.setAttribute('height', parseInt(this.getAttribute('height'), 10) + 'px');
this.setAttribute('preserveAspectRatio', 'xMidYMid meet');
this.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
// this.children[0] is the path for connection line
// this.children[1] is the path for connection arrow shape
this.children[0].setAttribute('xmlns', 'http://www.w3.org/2000/svg');
this.children[1].setAttribute('xmlns', 'http://www.w3.org/2000/svg');
this.setAttribute('viewbox', '0 0 ' + parseInt(this.getAttribute('width'), 10) + ' ' + parseInt(this.getAttribute('height'), 10));
this.children[0].setAttribute('stroke-width', '2px');
this.children[0].setAttribute('stroke', '#c9c9c9');
this.children[1].setAttribute('fill', '#c9c9c9');
this.children[1].setAttribute('stroke', '#c9c9c9');
$clone.find(this).wrap('<span style="position: absolute; left: ' + left + '; top: ' + top + ';"></span>');
});

Is it possible to change color of one pixel inside rectangle created with KineticJS?

This is my code:
var Editor = {
layer: new Kinetic.Layer(),
map: null,
init: function () {
var stage = new Kinetic.Stage({
container: 'board',
width: 800,
height: 800
})
this.map = new Kinetic.Shape({
sceneFunc: function(context) {
context.beginPath();
context.moveTo(0, 0);
context.lineTo(mapWidth, 0);
context.lineTo(mapWidth, mapHeight);
context.lineTo(0, mapHeight);
context.closePath();
context.fillStrokeShape(this);
},
x: 0,
y: 0,
fill: 'green',
draggable: true
})
this.layer.add(this.map)
stage.add(this.layer)
}
}
I want to change the colors of the pixels in the rectangle. Colors of pixels will be generated by the "diamond-square" algorithm. Is it possible to change the colors of individual pixels? If so, how can I do this?
[ Changed answer ]
Use an offscreen html canvas to overlay the pixels in your "diamond-square" algorithm.
Demo: http://jsfiddle.net/m1erickson/6mDSm/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Prototype</title>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v5.0.1.min.js"></script>
<style>
body{padding:20px;}
#container{
border:solid 1px #ccc;
margin-top: 10px;
width:350px;
height:350px;
}
</style>
<script>
$(function(){
var stage = new Kinetic.Stage({
container: 'container',
width: 350,
height: 350
});
var layer = new Kinetic.Layer();
stage.add(layer);
var mapWidth=50;
var mapHeight=75;
// use an offscreen canvas as a pixel-map overlaying the green map
var pixelCanvas=document.createElement("canvas");
var ctx=pixelCanvas.getContext("2d");
pixelCanvas.width=mapWidth;
pixelCanvas.height=mapHeight;
pixelCanvas.pixels=[]
pixelCanvas.setPixel=function(x,y,color){
ctx.fillStyle=color;
ctx.fillRect(x,y,1,1);
};
// create a group
// that holds the green map background and pixel-map overlay
var mapGroup=new Kinetic.Group({
x:30,
y:30,
width:mapWidth,
height:mapHeight,
draggable:true
});
layer.add(mapGroup);
// the green background
var map=new Kinetic.Rect({
x:0,
y:0,
width:mapWidth,
height:mapHeight,
fill:"green"
});
mapGroup.add(map);
// an image overlay that
// gets "live-updates" from an offscreen canvas
var pixels=new Kinetic.Image({
x:0,
y:0,
image:pixelCanvas
});
mapGroup.add(pixels);
layer.draw();
// testing
var y=15;
$("#add").click(function(){
for(var i=0;i<5;i++){
pixelCanvas.setPixel(15,y,"red");
pixelCanvas.setPixel(25,y,"gold");
pixelCanvas.setPixel(35,y++,"blue");
}
pixels.draw();
});
}); // end $(function(){});
</script>
</head>
<body>
<button id="add">Add test Pixels</button>
<div id="container"></div>
</body>
</html>
Note: my previous answer using Kinetic.Shape was leaving an undesirable "ghost"

Add material to mesh from node server

While I understand many of you may not have messed around with OWF (Ozone Widge Framework), it's merely wigetized html pages that communicate through a subscription service on the server.
Simple example I'm working with: http://blog.thematicmapping.org/2013/10/textural-terrains-with-threejs.html
I can successfully add a texture via THREE.ImageUtils.loadTexture() while navigating to the html page in Google Chrome. However, when I use OWF in Google Chrome and point my widget to the html page, I can only get it to load the mesh. If I attempt to load the texture, it's completely black. Therefore, it has nothing to do with (chrome --allow-file-access-from-files). I have verified this happens for the few examples I've tried from threejs.org. Obviously, it has something to do with the OWF implementation, but I was under the impression that these frameworks inherited the properties of the browser it was being run in (I could be completely wrong)... therefore, I assumed it would work.
EDIT: I made the poor mistake of assuming it was the widgetized framework causing the trouble. I linked one of the widgets directly to the node website and could not successfully render the terrain material. Then, I tried accessing it through a node.js server with no success.
Here's the code if anyone can tell me why it's black....
<!doctype html>
<html lang="en">
<head>
<title>three.js - Jotunheimen</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body { margin: 0; overflow: hidden; }
</style>
</head>
<body>
<div id="webgl"></div>
<script src="jsANDcss/3D/three.min.js"></script>
<script src="jsANDcss/3D/TrackballControls.js"></script>
<script src="jsANDcss/3D/TerrainLoader.js"></script>
<script>
window.addEventListener( 'resize', onWindowResize, false );
var width = window.innerWidth,
height = window.innerHeight;
var scene = new THREE.Scene();
/*scene.add(new THREE.AmbientLight(0xeeeeee));*/
var camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 1000);
camera.position.set(0, -30, 30);
var controls = new THREE.TrackballControls(camera);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
var material;
var texture;
var terrainLoader = new THREE.TerrainLoader();
terrainLoader.load('jsANDcss/3D/jotunheimen.bin', function(data) {
var geometry = new THREE.PlaneGeometry(60, 60, 199, 199);
for (var i = 0, l = geometry.vertices.length; i < l; i++) {
geometry.vertices[i].z = data[i] / 65535 * 5;
}
var texture = THREE.ImageUtils.loadTexture('jsANDcss/3D/jotunheimen-texture.jpg');
var material = new THREE.MeshPhongMaterial({
map: texture
/*wireframe: true*/
});
var plane = new THREE.Mesh(geometry, material);
material.needsUpdate = true;
scene.add(plane);
});
render();
document.getElementById('webgl').appendChild(renderer.domElement);
function render() {
controls.update();
requestAnimationFrame(render);
renderer.render(scene, camera);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
controls.handleResize();
}
</script>
</body>
</html>
If you use MeshPhongMaterial, you need to add a light to the scene. If you do not want to add a light, then use MeshBasicMaterial.
Also, do not set material.needsUpdate = true;. The loader does that for you. Loading is asynchronous, and the needsUpdate flag needs to be set at the right time.
Consider adding the plane to the scene in the loader callback, instead.
Also, if you are modifying the vertices, you need to recompute some things:
geometry.computeCentroids();
geometry.computeFaceNormals();
geometry.computeVertexNormals(); // required if you want your terrain "smooth"
three.js r.62

InfoWindow with google maps api

How can I display two Infowindow on my map.
in my code I can open only one InfoWindow, but I will display at same time twoo InfoWindow on my map what can I do. my code is:
function load() {
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng( 38.736946, 35.310059), 6);
map.openInfoWindow(new GLatLng( 38.582526, 42.846680),
document.createTextNode("Van Gölü"));
}
}
The Google Maps API v2 native InfoWindow only supports one per map. The Google Maps API v3 removes that limitation.
Either use a custom InfoWindow or migrate your application to the Google Maps API v3.
As #duncan observed, that Google Maps API v2 has been officially deprecated as of May 19, 2010 and will not be supported after May 19, 2013. New development in that API is strongly discouraged.
this code is working :
<!DOCTYPE html>
<html>
<head>
<META http-equiv=content-type content=text/html;charset=x-mac-turkish>
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0; padding: 0 }
#map_canvas { height: 100% }
</style>
<script src="js/jquery.js"></script>
<script type="text/javascript"
src="https://maps.googleapis.com/maps/api/js?key=mykey&sensor=false">
</script>
<script type="text/javascript">
var map;
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(39.078908,35.244141),
zoom: 6,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"),
mapOptions);
infoWindow = new google.maps.InfoWindow();
var windowLatLng = new google.maps.LatLng(38.668356,33.376465);
infoWindow.setOptions({
content: "Tuz Golu",
position: windowLatLng,
});
infoWindow.open(map);
infoWindow2 = new google.maps.InfoWindow();
var windowLatLng2 = new google.maps.LatLng(38.565348,42.868652);
infoWindow2.setOptions({
content: "Van Golu",
position: windowLatLng2,
});
infoWindow2.open(map);
}
</script>
</head>
<body onload="initialize()">
<div id="map_canvas" style="width:65%; height:40%"></div>
</body>
</html>

Raphael -- Changing the letter color of text string

(using Raphael_2.01, WindowsXP, Firefox8.0.1)
Hello,
I'm trying to change the letter color of text by referring to "Drawing Text" of
http://www.html5rocks.com/en/tutorials/raphael/intro/ .
I can display the text "HTML5ROCKS" but I can't change the color.
var t = paper.text(50, 10, "HTML5ROCKS");
var letters = paper.print(50, 50, "HTML5ROCKS", paper.getFont("Courier"), 40);
// I think "Vegur" is Mac font. So I change it to "Courier".
letters[4].attr({fill:"orange"});
for (var i = 5; i < letters.length; i++) {
letters[i].attr({fill: "#3D5C9D", "stroke-width": "2", stroke: "#3D5C9D"});
}
What happened ?
As the tutorial states (not as clearly as it should), you need to convert the font into the "cufon" format if you want to treat the individual letters as unique SVG paths. If you do that, the paper.print function works as expected. Without that the print function returns an empty array (and the "letters[4]" crashes).
Experimentally, I grabbed the two missing font files from html5rocks:
<script src="Vegur.font.js"></script>
<script src="cufon.js"></script>
and added them to a sample HTML page:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Raphaël—JavaScript Library</title>
</head>
<body>
<div id="demo-1"></div>
<script src="raphael.js" type="text/javascript"></script>
<script src="Scripts/jquery-1.7.1.min.js" type="text/javascript"></script>
<script src="Scripts/Vegur.font.js" type="text/javascript"></script>
<script src="Scripts/cufon.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
var paper = Raphael("demo-1", 320, 200);
var t = paper.text(50, 10, "HTML5ROCKS");
var letters = paper.print(50, 50, "HTML5ROCKS", paper.getFont("Vegur"), 40);
letters[4].attr({ fill: "orange" });
for (var i = 5; i < letters.length; i++) {
letters[i].attr({ fill: "#3D5C9D", "stroke-width": "2", stroke: "#3D5C9D" });
}
});
</script>
</body>
</html>
The second HTML5ROCKS text is colored as expected (as shown on the original tutorial page).

Resources