0 votes
by (560 points)

Hi :)

I recently asked about how to load a graph library into twine (thanks to HiEv and greyelf for helping). I've got the following in my javascript:

if (window.hasOwnProperty("storyFormat")) {
	setup.Path = "file:///Users/nat/Documents/startdemo/";
} else {
	setup.Path = "";
}

setup.JSLoaded = false;
importStyles(setup.Path + "RGraph/css/animations.css", setup.Path + "RGraph/css/ModalDialog.css", setup.Path + "RGraph/css/website.css" );
importScripts([setup.Path + "RGraph/libraries/RGraph.common.core.js", setup.Path + "RGraph/libraries/RGraph.line.js"])
	.then(function() {
		setup.JSLoaded = true;
	}).catch(function(error) {
		alert(error);
	}
);

 

In the passage I have this, which is a copy and paste of one of their examples (if/when I get it working I'll edit in my own data):
 

<<script>>    
    new RGraph.Line({
        id: 'cvs',
        data: [8,7,6,5,8,7,9,8,6,5,8,3,4,1,1,9,5,7,8,5,6,9,8,7],
        options: {
            tickmarks: 'circle',
            tickmarksSize: 100,
            linewidth: 2,
            hmargin: 5,
            shadow: false,
            filled: true,
            backgroundGridVlines: false,
            backgroundGridBorder: false,
            noaxes: true,
            title: 'Sales figures for 2012',
            unitsPost: '%',
            gutterLeft: 50,
            labels: [
                '','Jan','',
                '','Feb','',
                '','Mar','',
                '','Apr','',
                '','May','',
                '','Jun','',
                '','Jul','',
                '','Aug','',
                '','Sep','',
                '','Oct','',
                '','Nov','',
                '','Dec',''
            ]
        }
    }).draw().exec(function (obj)
    {
        // The fill
        var grad = obj.context.createLinearGradient(0,15,0,275);
        grad.addColorStop(0, 'rgba(248,231,209,0.75)');
        grad.addColorStop(0.6, 'rgba(248,231,209,0.5)');
        grad.addColorStop(0.6, 'rgba(220,234,216,0.75)');
        grad.addColorStop(0.8, 'rgba(220,234,216,0.5)');
        grad.addColorStop(0.8, 'rgba(132,208,248,0.75)');
        grad.addColorStop(1.0, 'rgba(132,208,248,0.5)');
        
        obj.set({
            fillstyle: grad
        });

        // The stroke
        var grad2 = obj.context.createLinearGradient(0,25,0,275);
        grad2.addColorStop(0, 'orange');
        grad2.addColorStop(0.6, 'orange');
        grad2.addColorStop(0.6, 'green');
        grad2.addColorStop(0.8, 'green');
        grad2.addColorStop(0.8, 'blue');
        grad2.addColorStop(1.0, 'blue');
        
        obj.set({
            colors: [grad2]
        });
        
        RGraph.redraw();
    });
<</script>>

I'm not getting a general error message so it looks like the script is loading in fine, but every time I try and open the passage I have an error message saying:

Error: <<script>>: bad evaluation: Cannot read property 'getContext' of null

It's just to see if anyone knows what I'm doing wrong and how to get it working?

Thanks a lot,

Nat

1 Answer

+1 vote
by (157k points)
selected by
 
Best answer

You left one important piece of information out of question, the HTML structure of the #cvs ID'ed target that the graph using as its output. That would tell use if it is a SVG or Canvas based graph. I will assume that the passage with your RGraph related code contains HTML similar to the following in it.

<canvas id="cvs" width="1000" height="250">
    [No canvas support]
</canvas>


Your issue is one of 'timing', the cvs ID'ed element your RGraph code is targeting doesn't exist until all of the contents of the passage has finished being processed and the resulting HTML elements have been added to the current page.

To solve your issue you will need to use a Navigation Event or Task to delay the execution of your RGraph code, which the following example demostrates using the :passagedisplay event.

<<script>>
	$(document).one(':passagedisplay', function () {
		new RGraph.Line({
			id: 'cvs',
			data: [8,7,6,5,8,7,9,8,6,5,8,3,4,1,1,9,5,7,8,5,6,9,8,7],
			options: {
				tickmarks: 'circle',
				tickmarksSize: 100,
				linewidth: 2,
				hmargin: 5,
				shadow: false,
				filled: true,
				backgroundGridVlines: false,
				backgroundGridBorder: false,
				noaxes: true,
				title: 'Sales figures for 2012',
				unitsPost: '%',
				gutterLeft: 50,
				labels: [
					'','Jan','',
					'','Feb','',
					'','Mar','',
					'','Apr','',
					'','May','',
					'','Jun','',
					'','Jul','',
					'','Aug','',
					'','Sep','',
					'','Oct','',
					'','Nov','',
					'','Dec',''
				]
			}
		})
		.draw()
		.exec(function (obj) {
			// The fill
			var grad = obj.context.createLinearGradient(0,15,0,275);
			grad.addColorStop(0, 'rgba(248,231,209,0.75)');
			grad.addColorStop(0.6, 'rgba(248,231,209,0.5)');
			grad.addColorStop(0.6, 'rgba(220,234,216,0.75)');
			grad.addColorStop(0.8, 'rgba(220,234,216,0.5)');
			grad.addColorStop(0.8, 'rgba(132,208,248,0.75)');
			grad.addColorStop(1.0, 'rgba(132,208,248,0.5)');
			
			obj.set({
				fillstyle: grad
			});

			// The stroke
			var grad2 = obj.context.createLinearGradient(0,25,0,275);
			grad2.addColorStop(0, 'orange');
			grad2.addColorStop(0.6, 'orange');
			grad2.addColorStop(0.6, 'green');
			grad2.addColorStop(0.8, 'green');
			grad2.addColorStop(0.8, 'blue');
			grad2.addColorStop(1.0, 'blue');
			
			obj.set({
				colors: [grad2]
			});
			
			RGraph.redraw();
		});
	});
<</script>>

 

by (560 points)
Thanks so much for your help greyelf!! It's working perfectly in Twine itself and on chrome when I export it, however on safari it's coming up with an error message of:

"Apologies! An error has occurred. You may be able to continue, but some parts may not work properly.

Error: TypeError: Attempted to assign to readonly property.."

It's just to see if you know any way around that?

Thanks a lot! :)
by (157k points)
Sorry, but I don't run Safari.
Welcome to Twine Q&A, where you can ask questions and receive answers from other members of the community.

You can also find hints and information on Twine on the official wiki and the old forums archive.

See a spam question? Flag it instead of downvoting. A question flagged enough times will automatically be hidden while moderators review it.
...