UNPKG

newdavinci-blockly

Version:
281 lines (257 loc) 7.94 kB
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Blockly Demo: Graph</title> <script src="https://www.google.com/jsapi"></script> <script src="../../blockly_compressed.js"></script> <script src="../../blocks_compressed.js"></script> <script src="../../javascript_compressed.js"></script> <script src="../../msg/js/en.js"></script> <style> body { background-color: #fff; font-family: sans-serif; } h1 { font-weight: normal; font-size: 140%; } #funcText { margin-top: 1em; margin-left: 1.5em; font-family: sans-serif; } #funcText>img { height: 3px; width: 15px; vertical-align: middle; margin-right: .5em; } #y1 { background-color: #36c; } </style> </head> <body> <h1><a href="https://developers.google.com/blockly/">Blockly</a> &gt; <a href="../index.html">Demos</a> &gt; Graph</h1> <p>This is a demo of giving instant feedback as blocks are changed.</p> <p>&rarr; More info on <a href="https://developers.google.com/blockly/installation/code-generators#realtime_generation">Realtime generation</a>...</p> <table> <tr> <td> <div id="visualization" style="width: 400px"></div> </td> <td> <div id="blocklyDiv" style="height: 400px"></div> </td> </tr> </table> <div id="funcText"> <img id="y1" src="../../media/1x1.gif"> ... </div> <xml id="toolbox" style="display: none"> <category name="Math"> <block type="math_number"></block> <block type="math_arithmetic"></block> <block type="math_single"></block> <block type="math_trig"></block> <block type="math_constant"></block> <block type="math_number_property"></block> <block type="math_round"></block> <block type="math_modulo"></block> <block type="math_constrain"> <value name="LOW"> <block type="math_number"> <field name="NUM">1</field> </block> </value> <value name="HIGH"> <block type="math_number"> <field name="NUM">100</field> </block> </value> </block> <block type="math_random_int"> <value name="FROM"> <block type="math_number"> <field name="NUM">1</field> </block> </value> <value name="TO"> <block type="math_number"> <field name="NUM">100</field> </block> </value> </block> <block type="math_random_float"></block> </category> <category name="Variables"> <block type="graph_get_x"></block> </category> <category name="Logic"> <block type="logic_compare"></block> <block type="logic_operation"></block> <block type="logic_negate"></block> <block type="logic_boolean"></block> <block type="logic_ternary"></block> </category> </xml> <xml id="startBlocks" style="display: none"> <block type="graph_set_y" deletable="false" x="100" y="100"> <value name="VALUE"> <block type="math_arithmetic"> <field name="OP">POWER</field> <value name="A"> <block type="graph_get_x"></block> </value> <value name="B"> <block type="math_number"> <field name="NUM">2</field> </block> </value> </block> </value> </block> </xml> <script> // Load the Google Chart Tools Visualization API and the chart package. if (typeof google == 'object') { google.load('visualization', '1', {packages: ['corechart']}); } else { alert('Unable to load Google\'s chart API.\n' + 'Are you connected to the Internet?'); } // Define the custom blocks and their JS generators. Blockly.Blocks['graph_get_x'] = { // x variable getter. init: function() { this.setHelpUrl(Blockly.Msg.VARIABLES_GET_HELPURL); this.setColour(330); this.appendDummyInput() .appendField('x'); this.setOutput(true, 'Number'); this.setTooltip(Blockly.Msg.VARIABLES_GET_TOOLTIP); } }; Blockly.JavaScript['graph_get_x'] = function(block) { // x variable getter. return ['x', Blockly.JavaScript.ORDER_ATOMIC]; }; Blockly.Blocks['graph_set_y'] = { // y variable setter. init: function() { this.setHelpUrl(Blockly.Msg.VARIABLES_SET_HELPURL); this.setColour(330); this.appendValueInput('VALUE') .appendField('y =') .setCheck('Number'); this.setTooltip(Blockly.Msg.VARIABLES_SET_TOOLTIP); } }; Blockly.JavaScript['graph_set_y'] = function(block) { // y variable setter. var argument0 = Blockly.JavaScript.valueToCode(block, 'VALUE', Blockly.JavaScript.ORDER_ASSIGNMENT) || ''; return 'y = ' + argument0 + ';'; }; /** * Create a namespace for the application. */ var Graph = {}; /** * Cached copy of the function string. * @type ?string * @private */ Graph.oldFormula_ = null; /** * Drawing options for the Chart API. * @type !Object * @private */ Graph.options_ = { //curveType: 'function', width: 400, height: 400, chartArea: {left: '10%', width: '85%', height: '85%'} }; /** * Visualize the graph of y = f(x) using Google Chart Tools. * For more documentation on Google Chart Tools, see this linechart example: * https://developers.google.com/chart/interactive/docs/gallery/linechart */ Graph.drawVisualization = function() { var formula = Blockly.JavaScript.workspaceToCode(); if (formula === Graph.oldFormula_) { // No change in the formula, don't recompute. return; } Graph.oldFormula_ = formula; // Create and populate the data table. var data = google.visualization.arrayToDataTable(Graph.plot(formula)); // Create and draw the visualization, passing in the data and options. new google.visualization.LineChart(document.getElementById('visualization')). draw(data, Graph.options_); // Create the "y = ..." label. Find the relevant part of the code. formula = formula.substring(formula.indexOf('y = ')); formula = formula.substring(0, formula.indexOf(';')); var funcText = document.getElementById('funcText'); funcText.replaceChild(document.createTextNode(formula), funcText.lastChild); }; /** * Plot points on the function y = f(x). * @param {string} code JavaScript code. * @return {!Array.<!Array>} 2D Array of points on the graph. */ Graph.plot = function(code) { // Initialize a table with two column headings. var table = []; var y; // TODO: Improve range and scale of graph. for (var x = -10; x <= 10; x = Math.round((x + 0.1) * 10) / 10) { try { eval(code); } catch (e) { y = NaN; } if (!isNaN(y)) { // Prevent y from being displayed inconsistently, some in decimals, some // in scientific notation, often when y has accumulated rounding errors. y = Math.round(y * Math.pow(10, 14)) / Math.pow(10, 14); table.push([x, y]); } } // Add column heading to table. if (table.length) { table.unshift(['x', 'y']); } else { // If the table is empty, add a [0, 0] row to prevent graph error. table.unshift(['x', 'y'], [0, 0]); } return table; }; /** * Force Blockly to resize into the available width. */ Graph.resize = function() { var width = Math.max(window.innerWidth - 440, 250); document.getElementById('blocklyDiv').style.width = width + 'px'; }; /** * Initialize Blockly and the graph. Called on page load. */ Graph.init = function() { Blockly.inject(document.getElementById('blocklyDiv'), {toolbox: document.getElementById('toolbox')}); Blockly.Xml.domToWorkspace(Blockly.mainWorkspace, document.getElementById('startBlocks')); // When Blockly changes, update the graph. Blockly.addChangeListener(Graph.drawVisualization); } window.addEventListener('load', Graph.init); window.addEventListener('resize', Graph.resize); </script> </body> </html>