diff --git a/package.json b/package.json index 276b2ee5a..14b3498d6 100644 --- a/package.json +++ b/package.json @@ -69,8 +69,9 @@ "dependencies": { "chalk": "^1.1.3", "d3": "3.5.17", + "d3-textwrap": "^2.0.0", "dagre": "^0.7.4", - "dagre-d3-renderer": "0.1.2", + "dagre-d3-renderer": "0.1.6", "he": "^1.1.1", "lodash": "^4.17.4", "minimist": "^1.2.0", diff --git a/src/d3.js b/src/d3.js index 5b0910518..9f9f5e4bb 100644 --- a/src/d3.js +++ b/src/d3.js @@ -24,463 +24,464 @@ if (!d3) { // } // log.debug('window'); // log.debug(window); -module.exports = d3; +module.exports = d3 /* jshint ignore:start */ -/* - D3 Text Wrap - By Vijith Assar - http://www.vijithassar.com - http://www.github.com/vijithassar - @vijithassar +require('d3-textwrap') - Detailed instructions at http://www.github.com/vijithassar/d3textwrap +// D3 Text Wrap +// By Vijith Assar +// http://www.vijithassar.com +// http://www.github.com/vijithassar +// @vijithassar - */ +// Detailed instructions at http://www.github.com/vijithassar/d3textwrap -(function () { - // set this variable to a string value to always force a particular - // wrap method for development purposes, for example to check tspan - // rendering using a foreignobject-enabled browser. set to 'tspan' to - // use tspans and 'foreignobject' to use foreignobject - var force_wrap_method = false // by default no wrap method is forced - force_wrap_method = 'tspans' // uncomment this statement to force tspans - // force_wrap_method = 'foreignobjects'; // uncomment this statement to force foreignobjects +// */ - // exit immediately if something in this location - // has already been defined; the plugin will defer to whatever - // else you're doing in your code - if (d3.selection.prototype.textwrap) { - return false - } +// (function () { +// // set this variable to a string value to always force a particular +// // wrap method for development purposes, for example to check tspan +// // rendering using a foreignobject-enabled browser. set to 'tspan' to +// // use tspans and 'foreignobject' to use foreignobject +// var force_wrap_method = false // by default no wrap method is forced +// force_wrap_method = 'tspans' // uncomment this statement to force tspans +// // force_wrap_method = 'foreignobjects'; // uncomment this statement to force foreignobjects - // double check the force_wrap_method flag - // and reset if someone screwed up the above - // settings - if (typeof force_wrap_method === 'undefined') { - var force_wrap_method = false - } +// // exit immediately if something in this location +// // has already been defined; the plugin will defer to whatever +// // else you're doing in your code +// if (d3.selection.prototype.textwrap) { +// return false +// } - // create the plugin method twice, both for regular use - // and again for use inside the enter() selection - d3.selection.prototype.textwrap = d3.selection.enter.prototype.textwrap = function (bounds, padding) { - // default value of padding is zero if it's undefined - var padding = parseInt(padding) || 0 +// // double check the force_wrap_method flag +// // and reset if someone screwed up the above +// // settings +// if (typeof force_wrap_method === 'undefined') { +// var force_wrap_method = false +// } - // save callee into a variable so we can continue to refer to it - // as the function scope changes - var selection = this +// // create the plugin method twice, both for regular use +// // and again for use inside the enter() selection +// d3.selection.prototype.textwrap = d3.selection.enter.prototype.textwrap = function (bounds, padding) { +// // default value of padding is zero if it's undefined +// var padding = parseInt(padding) || 0 - // create a variable to store desired return values in - var return_value +// // save callee into a variable so we can continue to refer to it +// // as the function scope changes +// var selection = this - // extract wrap boundaries from any d3-selected rect and return them - // in a format that matches the simpler object argument option - var extract_bounds = function (bounds) { - // discard the nested array wrappers added by d3 - var bounding_rect = bounds[0][0] - // sanitize the svg element name so we can test against it - var element_type = bounding_rect.tagName.toString() - // if it's not a rect, exit - if (element_type !== 'rect') { - return false - // if it's a rect, proceed to extracting the position attributes - } else { - var bounds_extracted = {} - bounds_extracted.x = d3.select(bounding_rect).attr('x') || 0 - bounds_extracted.y = d3.select(bounding_rect).attr('y') || 0 - bounds_extracted.width = d3.select(bounding_rect).attr('width') || 0 - bounds_extracted.height = d3.select(bounding_rect).attr('height') || 0 - // also pass along the getter function - bounds_extracted.attr = bounds.attr - } - return bounds_extracted - } +// // create a variable to store desired return values in +// var return_value - // double check the input argument for the wrapping - // boundaries to make sure it actually contains all - // the information we'll need in order to wrap successfully - var verify_bounds = function (bounds) { - // quickly add a simple getter method so you can use either - // bounds.x or bounds.attr('x') as your notation, - // the latter being a common convention among D3 - // developers - if (!bounds.attr) { - bounds.attr = function (property) { - if (this[property]) { - return this[property] - } - } - } - // if it's an associative array, make sure it has all the - // necessary properties represented directly - if ( - (typeof bounds === 'object') && - (typeof bounds.x !== 'undefined') && - (typeof bounds.y !== 'undefined') && - (typeof bounds.width !== 'undefined') && - (typeof bounds.height !== 'undefined') - // if that's the case, then the bounds are fine - ) { - // return the lightly modified bounds - return bounds - // if it's a numerically indexed array, assume it's a - // d3-selected rect and try to extract the positions - } else if ( - // first try to make sure it's an array using Array.isArray - ( - (typeof Array.isArray === 'function') && - (Array.isArray(bounds)) - ) || - // but since Array.isArray isn't always supported, fall - // back to casting to the object to string when it's not - (Object.prototype.toString.call(bounds) === '[object Array]') - ) { - // once you're sure it's an array, extract the boundaries - // from the rect - var extracted_bounds = extract_bounds(bounds) - return extracted_bounds - } else { - // but if the bounds are neither an object nor a numerical - // array, then the bounds argument is invalid and you'll - // need to fix it - return false - } - } +// // extract wrap boundaries from any d3-selected rect and return them +// // in a format that matches the simpler object argument option +// var extract_bounds = function (bounds) { +// // discard the nested array wrappers added by d3 +// var bounding_rect = bounds[0][0] +// // sanitize the svg element name so we can test against it +// var element_type = bounding_rect.tagName.toString() +// // if it's not a rect, exit +// if (element_type !== 'rect') { +// return false +// // if it's a rect, proceed to extracting the position attributes +// } else { +// var bounds_extracted = {} +// bounds_extracted.x = d3.select(bounding_rect).attr('x') || 0 +// bounds_extracted.y = d3.select(bounding_rect).attr('y') || 0 +// bounds_extracted.width = d3.select(bounding_rect).attr('width') || 0 +// bounds_extracted.height = d3.select(bounding_rect).attr('height') || 0 +// // also pass along the getter function +// bounds_extracted.attr = bounds.attr +// } +// return bounds_extracted +// } - var apply_padding = function (bounds, padding) { - var padded_bounds = bounds - if (padding !== 0) { - padded_bounds.x = parseInt(padded_bounds.x) + padding - padded_bounds.y = parseInt(padded_bounds.y) + padding - padded_bounds.width -= padding * 2 - padded_bounds.height -= padding * 2 - } - return padded_bounds - } +// // double check the input argument for the wrapping +// // boundaries to make sure it actually contains all +// // the information we'll need in order to wrap successfully +// var verify_bounds = function (bounds) { +// // quickly add a simple getter method so you can use either +// // bounds.x or bounds.attr('x') as your notation, +// // the latter being a common convention among D3 +// // developers +// if (!bounds.attr) { +// bounds.attr = function (property) { +// if (this[property]) { +// return this[property] +// } +// } +// } +// // if it's an associative array, make sure it has all the +// // necessary properties represented directly +// if ( +// (typeof bounds === 'object') && +// (typeof bounds.x !== 'undefined') && +// (typeof bounds.y !== 'undefined') && +// (typeof bounds.width !== 'undefined') && +// (typeof bounds.height !== 'undefined') +// // if that's the case, then the bounds are fine +// ) { +// // return the lightly modified bounds +// return bounds +// // if it's a numerically indexed array, assume it's a +// // d3-selected rect and try to extract the positions +// } else if ( +// // first try to make sure it's an array using Array.isArray +// ( +// (typeof Array.isArray === 'function') && +// (Array.isArray(bounds)) +// ) || +// // but since Array.isArray isn't always supported, fall +// // back to casting to the object to string when it's not +// (Object.prototype.toString.call(bounds) === '[object Array]') +// ) { +// // once you're sure it's an array, extract the boundaries +// // from the rect +// var extracted_bounds = extract_bounds(bounds) +// return extracted_bounds +// } else { +// // but if the bounds are neither an object nor a numerical +// // array, then the bounds argument is invalid and you'll +// // need to fix it +// return false +// } +// } - // verify bounds - var verified_bounds = verify_bounds(bounds) +// var apply_padding = function (bounds, padding) { +// var padded_bounds = bounds +// if (padding !== 0) { +// padded_bounds.x = parseInt(padded_bounds.x) + padding +// padded_bounds.y = parseInt(padded_bounds.y) + padding +// padded_bounds.width -= padding * 2 +// padded_bounds.height -= padding * 2 +// } +// return padded_bounds +// } - // modify bounds if a padding value is provided - if (padding) { - verified_bounds = apply_padding(verified_bounds, padding) - } +// // verify bounds +// var verified_bounds = verify_bounds(bounds) - // check that we have the necessary conditions for this function to operate properly - if ( - // selection it's operating on cannot be not empty - (selection.length == 0) || - // d3 must be available - (!d3) || - // desired wrapping bounds must be provided as an input argument - (!bounds) || - // input bounds must validate - (!verified_bounds) - ) { - // try to return the calling selection if possible - // so as not to interfere with methods downstream in the - // chain - if (selection) { - return selection - // if all else fails, just return false. if you hit this point then you're - // almost certainly trying to call the textwrap() method on something that - // doesn't make sense! - } else { - return false - } - // if we've validated everything then we can finally proceed - // to the meat of this operation - } else { - // reassign the verified bounds as the set we want - // to work with from here on; this ensures that we're - // using the same data structure for our bounds regardless - // of whether the input argument was a simple object or - // a d3 selection - bounds = verified_bounds +// // modify bounds if a padding value is provided +// if (padding) { +// verified_bounds = apply_padding(verified_bounds, padding) +// } - // wrap using html and foreignObjects if they are supported - var wrap_with_foreignobjects = function (item) { - // establish variables to quickly reference target nodes later - var parent = d3.select(item[0].parentNode) - var text_node = parent.select('text') - var styled_line_height = text_node.style('line-height') - // extract our desired content from the single text element - var text_to_wrap = text_node.text() - // remove the text node and replace with a foreign object - text_node.remove() - var foreign_object = parent.append('foreignObject') - // add foreign object and set dimensions, position, etc - foreign_object - .attr('requiredFeatures', 'http://www.w3.org/TR/SVG11/feature#Extensibility') - .attr('x', bounds.x) - .attr('y', bounds.y) - .attr('width', bounds.width) - .attr('height', bounds.height) - // insert an HTML div - var wrap_div = foreign_object - .append('xhtml:div') - // this class is currently hardcoded - // probably not necessary but easy to - // override using .classed() and for now - // it's nice to avoid a litany of input - // arguments - .attr('class', 'wrapped') - // set div to same dimensions as foreign object - wrap_div - .style('height', bounds.height) - .style('width', bounds.width) - // insert text content - .html(text_to_wrap) - if (styled_line_height) { - wrap_div.style('line-height', styled_line_height) - } - return_value = parent.select('foreignObject') - } +// // check that we have the necessary conditions for this function to operate properly +// if ( +// // selection it's operating on cannot be not empty +// (selection.length == 0) || +// // d3 must be available +// (!d3) || +// // desired wrapping bounds must be provided as an input argument +// (!bounds) || +// // input bounds must validate +// (!verified_bounds) +// ) { +// // try to return the calling selection if possible +// // so as not to interfere with methods downstream in the +// // chain +// if (selection) { +// return selection +// // if all else fails, just return false. if you hit this point then you're +// // almost certainly trying to call the textwrap() method on something that +// // doesn't make sense! +// } else { +// return false +// } +// // if we've validated everything then we can finally proceed +// // to the meat of this operation +// } else { +// // reassign the verified bounds as the set we want +// // to work with from here on; this ensures that we're +// // using the same data structure for our bounds regardless +// // of whether the input argument was a simple object or +// // a d3 selection +// bounds = verified_bounds - // wrap with tspans if foreignObject is undefined - var wrap_with_tspans = function (item) { - // operate on the first text item in the selection - var text_node = item[0] - var parent = text_node.parentNode - var text_node_selected = d3.select(text_node) - // measure initial size of the text node as rendered - var text_node_height = text_node.getBBox().height - var text_node_width = text_node.getBBox().width - // figure out the line height, either from rendered height - // of the font or attached styling - var line_height - var rendered_line_height = text_node_height - var styled_line_height = text_node_selected.style('line-height') - if ( - (styled_line_height) && - (parseInt(styled_line_height)) - ) { - line_height = parseInt(styled_line_height.replace('px', '')) - } else { - line_height = rendered_line_height - } - // only fire the rest of this if the text content - // overflows the desired dimensions - if (text_node_width > bounds.width) { - // store whatever is inside the text node - // in a variable and then zero out the - // initial content; we'll reinsert in a moment - // using tspan elements. - var text_to_wrap = text_node_selected.text() - text_node_selected.text('') - if (text_to_wrap) { - // keep track of whether we are splitting by spaces - // so we know whether to reinsert those spaces later - var break_delimiter - // split at spaces to create an array of individual words - var text_to_wrap_array - if (text_to_wrap.indexOf(' ') !== -1) { - var break_delimiter = ' ' - text_to_wrap_array = text_to_wrap.split(' ') - } else { - // if there are no spaces, figure out the split - // points by comparing rendered text width against - // bounds and translating that into character position - // cuts - break_delimiter = '' - var string_length = text_to_wrap.length - var number_of_substrings = Math.ceil(text_node_width / bounds.width) - var splice_interval = Math.floor(string_length / number_of_substrings) - if ( - !(splice_interval * number_of_substrings >= string_length) - ) { - number_of_substrings++ - } - var text_to_wrap_array = [] - var substring - var start_position - for (var i = 0; i < number_of_substrings; i++) { - start_position = i * splice_interval - substring = text_to_wrap.substr(start_position, splice_interval) - text_to_wrap_array.push(substring) - } - } +// // wrap using html and foreignObjects if they are supported +// var wrap_with_foreignobjects = function (item) { +// // establish variables to quickly reference target nodes later +// var parent = d3.select(item[0].parentNode) +// var text_node = parent.select('text') +// var styled_line_height = text_node.style('line-height') +// // extract our desired content from the single text element +// var text_to_wrap = text_node.text() +// // remove the text node and replace with a foreign object +// text_node.remove() +// var foreign_object = parent.append('foreignObject') +// // add foreign object and set dimensions, position, etc +// foreign_object +// .attr('requiredFeatures', 'http://www.w3.org/TR/SVG11/feature#Extensibility') +// .attr('x', bounds.x) +// .attr('y', bounds.y) +// .attr('width', bounds.width) +// .attr('height', bounds.height) +// // insert an HTML div +// var wrap_div = foreign_object +// .append('xhtml:div') +// // this class is currently hardcoded +// // probably not necessary but easy to +// // override using .classed() and for now +// // it's nice to avoid a litany of input +// // arguments +// .attr('class', 'wrapped') +// // set div to same dimensions as foreign object +// wrap_div +// .style('height', bounds.height) +// .style('width', bounds.width) +// // insert text content +// .html(text_to_wrap) +// if (styled_line_height) { +// wrap_div.style('line-height', styled_line_height) +// } +// return_value = parent.select('foreignObject') +// } - // new array where we'll store the words re-assembled into - // substrings that have been tested against the desired - // maximum wrapping width - var substrings = [] - // computed text length is arguably incorrectly reported for - // all tspans after the first one, in that they will include - // the width of previous separate tspans. to compensate we need - // to manually track the computed text length of all those - // previous tspans and substrings, and then use that to offset - // the miscalculation. this then gives us the actual correct - // position we want to use in rendering the text in the SVG. - var total_offset = 0 - // object for storing the results of text length computations later - var temp = {} - // loop through the words and test the computed text length - // of the string against the maximum desired wrapping width - for (var i = 0; i < text_to_wrap_array.length; i++) { - var word = text_to_wrap_array[i] - var previous_string = text_node_selected.text() - var previous_width = text_node.getComputedTextLength() - // initialize the current word as the first word - // or append to the previous string if one exists - var new_string - if (previous_string) { - new_string = previous_string + break_delimiter + word - } else { - new_string = word - } - // add the newest substring back to the text node and - // measure the length - text_node_selected.text(new_string) - var new_width = text_node.getComputedTextLength() - // adjust the length by the offset we've tracked - // due to the misreported length discussed above - var test_width = new_width - total_offset - // if our latest version of the string is too - // big for the bounds, use the previous - // version of the string (without the newest word - // added) and use the latest word to restart the - // process with a new tspan - if (new_width > bounds.width) { - if ( - (previous_string) && - (previous_string !== '') - ) { - total_offset = total_offset + previous_width - temp = {string: previous_string, width: previous_width, offset: total_offset} - substrings.push(temp) - text_node_selected.text('') - text_node_selected.text(word) - // Handle case where there is just one more word to be wrapped - if (i == text_to_wrap_array.length - 1) { - new_string = word - text_node_selected.text(new_string) - new_width = text_node.getComputedTextLength() - } - } - } - // if we're up to the last word in the array, - // get the computed length as is without - // appending anything further to it - if (i == text_to_wrap_array.length - 1) { - text_node_selected.text('') - var final_string = new_string - if ( - (final_string) && - (final_string !== '') - ) { - if ((new_width - total_offset) > 0) { new_width = new_width - total_offset } - temp = {string: final_string, width: new_width, offset: total_offset} - substrings.push(temp) - } - } - } +// // wrap with tspans if foreignObject is undefined +// var wrap_with_tspans = function (item) { +// // operate on the first text item in the selection +// var text_node = item[0] +// var parent = text_node.parentNode +// var text_node_selected = d3.select(text_node) +// // measure initial size of the text node as rendered +// var text_node_height = text_node.getBBox().height +// var text_node_width = text_node.getBBox().width +// // figure out the line height, either from rendered height +// // of the font or attached styling +// var line_height +// var rendered_line_height = text_node_height +// var styled_line_height = text_node_selected.style('line-height') +// if ( +// (styled_line_height) && +// (parseInt(styled_line_height)) +// ) { +// line_height = parseInt(styled_line_height.replace('px', '')) +// } else { +// line_height = rendered_line_height +// } +// // only fire the rest of this if the text content +// // overflows the desired dimensions +// if (text_node_width > bounds.width) { +// // store whatever is inside the text node +// // in a variable and then zero out the +// // initial content; we'll reinsert in a moment +// // using tspan elements. +// var text_to_wrap = text_node_selected.text() +// text_node_selected.text('') +// if (text_to_wrap) { +// // keep track of whether we are splitting by spaces +// // so we know whether to reinsert those spaces later +// var break_delimiter +// // split at spaces to create an array of individual words +// var text_to_wrap_array +// if (text_to_wrap.indexOf(' ') !== -1) { +// var break_delimiter = ' ' +// text_to_wrap_array = text_to_wrap.split(' ') +// } else { +// // if there are no spaces, figure out the split +// // points by comparing rendered text width against +// // bounds and translating that into character position +// // cuts +// break_delimiter = '' +// var string_length = text_to_wrap.length +// var number_of_substrings = Math.ceil(text_node_width / bounds.width) +// var splice_interval = Math.floor(string_length / number_of_substrings) +// if ( +// !(splice_interval * number_of_substrings >= string_length) +// ) { +// number_of_substrings++ +// } +// var text_to_wrap_array = [] +// var substring +// var start_position +// for (var i = 0; i < number_of_substrings; i++) { +// start_position = i * splice_interval +// substring = text_to_wrap.substr(start_position, splice_interval) +// text_to_wrap_array.push(substring) +// } +// } - // append each substring as a tspan - var current_tspan - var tspan_count - // double check that the text content has been removed - // before we start appending tspans - text_node_selected.text('') - for (var i = 0; i < substrings.length; i++) { - var substring = substrings[i].string - if (i > 0) { - var previous_substring = substrings[i - 1] - } - // only append if we're sure it won't make the tspans - // overflow the bounds. - if ((i) * line_height < bounds.height - (line_height * 1.5)) { - current_tspan = text_node_selected.append('tspan') - .text(substring) - // vertical shift to all tspans after the first one - current_tspan - .attr('dy', function (d) { - if (i > 0) { - return line_height - } - }) - // shift left from default position, which - // is probably based on the full length of the - // text string until we make this adjustment - current_tspan - .attr('x', function () { - var x_offset = bounds.x - if (padding) { x_offset += padding } - return x_offset - }) -// .attr('dx', function() { -// if(i == 0) { -// var render_offset = 0; -// } else if(i > 0) { -// render_offset = substrings[i - 1].width; -// render_offset = render_offset * -1; -// } -// return render_offset; -// }); - } - } - } - } - // position the overall text node, whether wrapped or not - text_node_selected.attr('y', function () { - var y_offset = bounds.y - // shift by line-height to move the baseline into - // the bounds – otherwise the text baseline would be - // at the top of the bounds - if (line_height) { y_offset += line_height } - // shift by padding, if it's there - if (padding) { y_offset += padding } - return y_offset - }) - // shift to the right by the padding value - text_node_selected.attr('x', function () { - var x_offset = bounds.x - if (padding) { x_offset += padding } - return x_offset - }) +// // new array where we'll store the words re-assembled into +// // substrings that have been tested against the desired +// // maximum wrapping width +// var substrings = [] +// // computed text length is arguably incorrectly reported for +// // all tspans after the first one, in that they will include +// // the width of previous separate tspans. to compensate we need +// // to manually track the computed text length of all those +// // previous tspans and substrings, and then use that to offset +// // the miscalculation. this then gives us the actual correct +// // position we want to use in rendering the text in the SVG. +// var total_offset = 0 +// // object for storing the results of text length computations later +// var temp = {} +// // loop through the words and test the computed text length +// // of the string against the maximum desired wrapping width +// for (var i = 0; i < text_to_wrap_array.length; i++) { +// var word = text_to_wrap_array[i] +// var previous_string = text_node_selected.text() +// var previous_width = text_node.getComputedTextLength() +// // initialize the current word as the first word +// // or append to the previous string if one exists +// var new_string +// if (previous_string) { +// new_string = previous_string + break_delimiter + word +// } else { +// new_string = word +// } +// // add the newest substring back to the text node and +// // measure the length +// text_node_selected.text(new_string) +// var new_width = text_node.getComputedTextLength() +// // adjust the length by the offset we've tracked +// // due to the misreported length discussed above +// var test_width = new_width - total_offset +// // if our latest version of the string is too +// // big for the bounds, use the previous +// // version of the string (without the newest word +// // added) and use the latest word to restart the +// // process with a new tspan +// if (new_width > bounds.width) { +// if ( +// (previous_string) && +// (previous_string !== '') +// ) { +// total_offset = total_offset + previous_width +// temp = {string: previous_string, width: previous_width, offset: total_offset} +// substrings.push(temp) +// text_node_selected.text('') +// text_node_selected.text(word) +// // Handle case where there is just one more word to be wrapped +// if (i == text_to_wrap_array.length - 1) { +// new_string = word +// text_node_selected.text(new_string) +// new_width = text_node.getComputedTextLength() +// } +// } +// } +// // if we're up to the last word in the array, +// // get the computed length as is without +// // appending anything further to it +// if (i == text_to_wrap_array.length - 1) { +// text_node_selected.text('') +// var final_string = new_string +// if ( +// (final_string) && +// (final_string !== '') +// ) { +// if ((new_width - total_offset) > 0) { new_width = new_width - total_offset } +// temp = {string: final_string, width: new_width, offset: total_offset} +// substrings.push(temp) +// } +// } +// } - // assign our modified text node with tspans - // to the return value - return_value = d3.select(parent).selectAll('text') - } +// // append each substring as a tspan +// var current_tspan +// var tspan_count +// // double check that the text content has been removed +// // before we start appending tspans +// text_node_selected.text('') +// for (var i = 0; i < substrings.length; i++) { +// var substring = substrings[i].string +// if (i > 0) { +// var previous_substring = substrings[i - 1] +// } +// // only append if we're sure it won't make the tspans +// // overflow the bounds. +// if ((i) * line_height < bounds.height - (line_height * 1.5)) { +// current_tspan = text_node_selected.append('tspan') +// .text(substring) +// // vertical shift to all tspans after the first one +// current_tspan +// .attr('dy', function (d) { +// if (i > 0) { +// return line_height +// } +// }) +// // shift left from default position, which +// // is probably based on the full length of the +// // text string until we make this adjustment +// current_tspan +// .attr('x', function () { +// var x_offset = bounds.x +// if (padding) { x_offset += padding } +// return x_offset +// }) +// // .attr('dx', function() { +// // if(i == 0) { +// // var render_offset = 0; +// // } else if(i > 0) { +// // render_offset = substrings[i - 1].width; +// // render_offset = render_offset * -1; +// // } +// // return render_offset; +// // }); +// } +// } +// } +// } +// // position the overall text node, whether wrapped or not +// text_node_selected.attr('y', function () { +// var y_offset = bounds.y +// // shift by line-height to move the baseline into +// // the bounds – otherwise the text baseline would be +// // at the top of the bounds +// if (line_height) { y_offset += line_height } +// // shift by padding, if it's there +// if (padding) { y_offset += padding } +// return y_offset +// }) +// // shift to the right by the padding value +// text_node_selected.attr('x', function () { +// var x_offset = bounds.x +// if (padding) { x_offset += padding } +// return x_offset +// }) - // variable used to hold the functions that let us - // switch between the wrap methods - var wrap_method +// // assign our modified text node with tspans +// // to the return value +// return_value = d3.select(parent).selectAll('text') +// } - // if a wrap method if being forced, assign that - // function - if (force_wrap_method) { - if (force_wrap_method == 'foreignobjects') { - wrap_method = wrap_with_foreignobjects - } else if (force_wrap_method == 'tspans') { - wrap_method = wrap_with_tspans - } - } +// // variable used to hold the functions that let us +// // switch between the wrap methods +// var wrap_method - // if no wrap method is being forced, then instead - // test for browser support of foreignobject and - // use whichever wrap method makes sense accordingly - if (!force_wrap_method) { - if (typeof SVGForeignObjectElement !== 'undefined') { - wrap_method = wrap_with_foreignobjects - } else { - wrap_method = wrap_with_tspans - } - } +// // if a wrap method if being forced, assign that +// // function +// if (force_wrap_method) { +// if (force_wrap_method == 'foreignobjects') { +// wrap_method = wrap_with_foreignobjects +// } else if (force_wrap_method == 'tspans') { +// wrap_method = wrap_with_tspans +// } +// } - // run the desired wrap function for each item - // in the d3 selection that called .textwrap() - for (var i = 0; i < selection.length; i++) { - var item = selection[i] - wrap_method(item) - } +// // if no wrap method is being forced, then instead +// // test for browser support of foreignobject and +// // use whichever wrap method makes sense accordingly +// if (!force_wrap_method) { +// if (typeof SVGForeignObjectElement !== 'undefined') { +// wrap_method = wrap_with_foreignobjects +// } else { +// wrap_method = wrap_with_tspans +// } +// } - // return the modified nodes so we can chain other - // methods to them. - return return_value - } - } -})() -/* jshint ignore:end */ +// // run the desired wrap function for each item +// // in the d3 selection that called .textwrap() +// for (var i = 0; i < selection.length; i++) { +// var item = selection[i] +// wrap_method(item) +// } + +// // return the modified nodes so we can chain other +// // methods to them. +// return return_value +// } +// } +// })() +// /* jshint ignore:end */ diff --git a/yarn.lock b/yarn.lock index e0cecb35c..6f5baf3f9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2113,25 +2113,31 @@ custom-event@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/custom-event/-/custom-event-1.0.1.tgz#5d02a46850adf1b4a317946a3928fccb5bfd0425" +d3-selection@^1.0.2: + version "1.0.5" + resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-1.0.5.tgz#948c73b41a44e28d1742ae2ff207c2aebca2734b" + +d3-textwrap@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/d3-textwrap/-/d3-textwrap-2.0.0.tgz#29d54d2cdc32ce806d63921b8740e473f059b653" + dependencies: + d3-selection "^1.0.2" + d3@3.5.17: version "3.5.17" resolved "https://registry.yarnpkg.com/d3/-/d3-3.5.17.tgz#bc46748004378b21a360c9fc7cf5231790762fb8" -d3@3.5.6: - version "3.5.6" - resolved "https://registry.yarnpkg.com/d3/-/d3-3.5.6.tgz#9451c651ca733fb9672c81fb7f2655164a73a42d" - d@1: version "1.0.0" resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" dependencies: es5-ext "^0.10.9" -dagre-d3-renderer@0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/dagre-d3-renderer/-/dagre-d3-renderer-0.1.2.tgz#543fc06f6a7c9acc916c507c4b33b837705ad5cf" +dagre-d3-renderer@0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/dagre-d3-renderer/-/dagre-d3-renderer-0.1.6.tgz#97e807c4b7462d0af1d3000b7e537488648fc195" dependencies: - d3 "3.5.6" + d3 "3.5.17" dagre "^0.7.4" graphlib "^2.1.1" lodash "^4.17.4"