@testwellioviz/wellioviz
Version:
Provides functionality to visualize well logs, particularly those already converted to JSON, using d3.js visualization library.
643 lines (607 loc) • 99.8 kB
JavaScript
!function (e) {
"object" == typeof exports ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : "undefined" != typeof window ? window.commonJsModule = e() : "undefined" != typeof global ? global.commonJsModule = e() : "undefined" != typeof self && (self.commonJsModule = e());
}(function () {
var define, module, exports;
module = {exports: (exports = {})};
// Copyright 2019 Justin Gosses
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ///////////////////////////////
// /**
// * "WELLIOVIZ is a JavaScript library that provides functionality to visualize well logs,
// * particularly those already converted to JSON, using the d3.js visualization library."
// *
// * It is designed with a single central function curveBox, that returns SVGs.
// * A variety of helper functions take in differently formatted JSONs of information about the well
// * log curves to plot and how to plot them.
// *
// * The idea is that end users can provide their own functions to reformat their data into the template that is fed into curveBox.
// *
// * Some users would wnat to only send to the JavaScript the data they want to plot. Others might use wellio.js to convert a
// * whole LAS 2.0 formatted well log file to JSON and send that whole JSON along with instructions with how to plot some portion of it.
// *
// * Central to this idea is that how to plot and what to plot be put into a JSON template that has sensible defaults,
// * such that the end-user only has to understand what they want to change about the plotting, not the whole d3.js code.
// */
module.exports = {
/**
* This brings in wellio.js as a dependency used by wellioviz. It returns the object that contains all its functions as a module that is called like "module.exports.wellio.[insert a wellio.js function here]"
* @returns {obj} It returns the wellio.js object and all its functions as a module.
*/
wellio: require("wellio"),
/**
* This brings in d3.js as a dependency used by wellioviz. It returns the d3.js object and all its functions as a module that is called like "module.exports.d3.[insert a d3.js function here]"
* @returns {obj} It returns the d3.js object and all its functions as a module.
*/
d3: require("d3"),
TrackTemplate: require('./log_style_templates/log_curve_template'),
WellLogTemplate: require('./well_log_templates/well_log_template'),
WellSectionTemplate: require('./well_section_templates/well_section_templates'),
CurveFillTemplate: require('./fill_templates/curve_fill_template'),
LogCurveTemplate: require('./log_style_templates/log_curve_template'),
TripleCombo: require("./well_log_templates/triple_combo_template"),
BaseTemplate: require("./base_template"),
CaliperGRTrack: require("./track_templates/CaliperGR_track"),
GR: require("./log_style_templates/GR"),
CAL: require("./log_style_templates/CAL"),
DefaultSubTrack: require("./track_templates/default_sub_track"),
/**
* A function that directs users to the docs if they need help.
* @returns {string} It says = I'm really no help. Please check out the docs at https://justingosses.github.io/wellioviz/ or the main README.md at https://github.com/JustinGOSSES/wellioviz. \n If you would like to know what wellioviz does, try wellioviz.define(). \n If you would like to see an example template, try wellioviz.curveBoxTemplateExamples('example') \n If you would like to see an example template defintions, try wellioviz.curveBoxTemplateExamples('definitions') Best of luck.
*/
help: function () {
return "I'm really no help. Please check out the docs at https://justingosses.github.io/wellioviz/ or the main README.md at https://github.com/JustinGOSSES/wellioviz. \n If you would like to know what wellioviz does, try wellioviz.define(). \n If you would like to see an example template, try wellioviz.curveBoxTemplateExamples('example') \n If you would like to see an example template defintions, try wellioviz.curveBoxTemplateExamples('definitions') ";
},
/**
* A function that returns a short description of what the wellioviz library is all about.
* @returns {string} Returns a string that defines wellioviz.
*/
define_wellioviz: function () {
return "WELLIOVIZ is a JavaScript library that provides functionality to visualize well logs, particularly those already converted to JSON, using d3.js visualization library.";
},
///////////////////////////////
/**
* curveBoxTemplateExamples gives an example of the template giving to the plotting functions and definitions of the fields.
* A string of either "help" "example" or "definitions" is given as function argument and either a string or Object is returned depending on string provided as input parameter.
* This is used to help construct the JSON object that is given to the curveBox plotting function.
* Someone might run this function with "example" as the parameter, give back the JSON template, replace a few pieces with their own data or format choices and then pass it as the argument into the curveBox function.
* @param {string} string_of_either__help_example_definitions_mandatories A string of either "help" "example" or "definitions"
*/
curveBoxTemplateExamples: function (string_of_either__help_example_definitions_mandatories) {
let request_string = string_of_either__help_example_definitions_mandatories;
if (request_string == "help") {
return "The curveBoxTemplateExamples function returns example templates based on an input argument. Possible argument values are 'example' 'defintions' or 'mandatories'";
}
if (request_string == "example") {
return [{
"curve_box": {
"show_well_name": "yes", /// not built yet
"show_depth_type": "no", /// not built yet
"show_curve_units": "yes", /// not built yet
"curve_box_depth_min": -999, /// not built yet
"curve_box_depth_max": -999, /// not built yet
"take_out_null_or_visualize": "no", /// not built yet
"show_title": "no",
"width": 260,
"height": 500,
"height_multiplier_components": 2,
"margin": {"top": 10, "right": 10, "bottom": 30, "left": 60},
"title": {"text": "", "title_font_size": "10px"}, /// not built yet
"div_id": "well_holder_3", /// Should be skip-able // default=random str? What happens if div doesn't exist?
"order_of_component": ["curves", "rectanges", "lines"], /// not built yet
"lines_connected_across_curveboxes": "no", /// not built yet
"header_sep_svg_or_not": "yes",
"svg_header_height": "4em",
"gridlines": "yes",
"gridlines_color": "#D3D3D3",
"gridlines_stroke_width": 0.20,
"grouped_or_independent_x_scales": "independent",
//// variables for how to draw mouseover of hover box
"mouseover_yes_or_no": "yes", //// "yes" or "no"
"mouseover_depth_or_depth_and_curve": "depth_and_curve", /// options= "depth_and_curve", "depth", or "curve"
"mouseover_curvename": "default", //// default is first curve
"mouseover_color_or_default_which_is_curve_color": "default" /// default is default, which then uses curve color or black
},
"components": [{
"curves": [
{
"data_type": "curve",
"curve_names": ["RHOB"],
"curve_colors": ["black"],
"curve_stroke_dasharray": ["solid"],
"stroke_linecap": ["butt"],
"stroke_width": [1],
"fill": [
{
"curve_name": "RHOB",
"fill": "yes",
"fill_direction": "left",
"cutoffs": [0.21, 2.23, 2.24],
"fill_colors": ["gray", "beige", "white"],
"curve2": ""
}
],
"curve_units": ["g/cm3"],
"depth_limits": [{"min": "autocalculate", "max": "autocalculate"}],
"curve_limits": [{"curve_name": "", "min": -10000000, "max": 3}],
"data": [{"depth": 1598.3, "RHOB": 2.2322}, {
"depth": 1598.4,
"RHOB": 2.0513
}, {"depth": 1598.5, "RHOB": 2.2548}, {
"depth": 1598.6,
"RHOB": 2.9445
}, {"depth": 1598.7, "RHOB": 2.2223}, {
"depth": 1598.8,
"RHOB": 2.447
}, {"depth": 1598.9, "RHOB": 2.598}, {"depth": 1599, "RHOB": 2.8088}, {
"depth": 1599.1,
"RHOB": 2.2248
}, {"depth": 1599.2, "RHOB": 2.2399}, {
"depth": 1599.3,
"RHOB": 2.251
}, {"depth": 1599.4, "RHOB": 2.255}, {
"depth": 1599.5,
"RHOB": 2.2526
}, {"depth": 1599.6, "RHOB": 2.2322}, {
"depth": 1599.7,
"RHOB": 2.2513
}, {"depth": 1599.8, "RHOB": 2.2548}, {"depth": 1599.9, "RHOB": 2.2445}, {
"depth": 1600,
"RHOB": 2.2223
}, {"depth": 1600.1, "RHOB": 2.2047}, {"depth": 1600.2, "RHOB": 2.198}], /// not built yet
"depth_curve_name": "DEPT",/// not built yet
//////
"data_id": ["placeholder_data_id",], /// not built yet
"well_names": [""], /// not built yet
"scale_linear_log_or_yours": ["linear"],
"line_color": ["red"], /// not built yet
"max_depth": "autocalculate", /// not built yet
"min_depth": "autocalculate", /// not built yet
"depth_type_string": [""],
"depth_units_string": [""],
"null_value": [""], /// not built yet
}
],
"lines": [
{
"data_type": "line", /// not built yet
"label": "example", /// not built yet
"depth": -999, /// not built yet
"color": "red", /// not built yet
"stroke_width": "3px", /// not built yet
"stroke_style": "solid", /// not built yet
"transparency": 1.0, /// not built yet
"stroke_linecap": "butt"
}
],
"rectangles": [
{
"data_type": "rectangle",
"depth_top": 0,
"x_starting_upper_left_corner": 0,
"width": 100,
"height": 100,
"stroke_width": "2px",
"stroke_linecap": "butt",
"fill": "red",
"opacity": 0.5,
"label": "Core Example", // not built into plotting template yet
"label_orientation": "horizontal", // not built into plotting template yet
"lable_position": "right" // not built into plotting template yet
}
]
}]
}];
} else if (request_string == "defintions") {
return [{
"curve_box": {
"show_well_name": "yes or no. If '' is no", // not built yet
"show_depth_type": "yes or no. If '' is no", // not built yet /// Should be skip-able /// default=No
"show_curve_units": "yes or no. If '' is no", // not built yet /// Should be skip-able /// default=No
"curve_box_depth_min": "Should be a number. If string or -999, will be skipped and autocalculate used", // not built yet
"curve_box_depth_max": "Should be a number. If string or -999, will be skipped and autocalculate used", // not built yet
"take_out_null_or_visualize": "yes or no. If '' is no", // not built yet
"show_title": "yes or no. If '' is no", // not built yet
"width": "number, if blank default is 250",
"height": "number, if blank default is 500",
"height_multiplier_components": "An interger or float that multiplies the height to get the height of the curves inside the curvebox. If curves height is greater than height, then scroll behavior will result.",
"margin": " should be an object like {\"top\": 10, \"right\": 10, \"bottom\": 30, \"left\": 60} if missing will default to these values",
"title": "object like:{\"text\": \"\", \"title_font_size\": \"10px\"} if default, an empty string, \"\" will skill",
"div_id": "should be a string that equals a div id like: 'well_holder' Do not include the #", ///What happens if div doesn't exist?
"order_of_component": "Should be an array of strings that correlate to component types like:[\"curves\",\"rectangles\",\"lines\"]", // not built yet
"lines_connected_across_curveboxes": "yes or no. If '' is no", // not built yet
"header_sep_svg_or_not": "yes or no. 'no' will build the curvebox as a single SVG. 'yes' will build it as two SVGs within nested divs. The later better helps enable scrolling curves and stationary header",
"svg_header_height": "Example = 3em; A string representing the height of the header part of the curvebox when header & components part of curvebox are separate SVGs.",
"gridlines": "yes or no as strings. Default is 'yes'",
"gridlines_color": "Can be gray or any color in hex or rgb format. Default is ''#D3D3D3'",
"gridlines_stroke_width": "thickness of the line. Default is 0.20",
"grouped_or_independent_x_scales": "independent or grouped as exceptable answers as strings. When 'independent' the min and max value of each curve in a curvebox is used for x scale unless explicitly given for that curve. When 'grouped' is given, the max and min of all curves is calculated and used to create the x axis scale.",
//// variables for how to draw mouseover of hover box
"mouseover_yes_or_no": "yes", //// "yes" or "no"
"mouseover_depth_or_depth_and_curve": "depth_and_curve", /// options= "depth_and_curve", "depth", or "curve"
"mouseover_curvename": "default", //// default is first curve
"mouseover_color_or_default_which_is_curve_color": "default" /// default is default, which then uses curve color or black
},
"components": [{
"curves": [
{
"data_type": "requires one of possible strings: curve, line, rectangle if not one of acceptable string it just skips it.", // not built yet
"curve_names": "array of strings representing curve_names like: ['GR','RESD']",
"curve_colors": "array of strings representing colors using common names or rgb style like:[\"black\",\"rgb(205,0,0,1)\"]",
"curve_stroke_dasharray": "A style for the curve line. Can be solid or a string of integers separated by commas like '5,5' or '20,10,10,5,10,10'",
"stroke_width": "The width of the curve line. Example is '2px'. ",
"stroke_linecap": "Style of ending of line as a string. Options are 'butt' which is no ending, 'round', and 'square' as defined here: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linecap Default is butt.",
"fill": "an array of objects one for each curve like: [{\"curve_name\":\"RHOB\",\"fill\":\"yes\",\"fill_direction\":\"left\",\"cutoffs\":[0.21,2.23,2.24],\"fill_colors\":[\"gray\",\"beige\",\"white\"],\"curve2\":\"\"}]",
"curve_units": "an array of strings that are curve units like: [\"g/cm2\",\"API\",\"\"] must equal length other curve fields",
"depth_limits": "An array of objects that contains the min and max depth for each curve like: [{\"min\":\"autocalculate\",\"max\":\"autocalculate\"}]",
"curve_limits": "An array of objects that hold the min and max curve values allow to cut off spurious value spikes, like: [{\"curve_name\":\"GR\",\"min\":0,\"max\":100},{\"curve_name\":\"PDF\",\"min\":0,\"max\":100}]",
"data": "Should be an array of objects where the keys in key:value pairs in each object are curve_names or UWI like: [{\"UWI\":\"111aa\",\"DEPTH\":4140.5,\"GR\":0},{\"UWI\":\"111aa\",\"DEPTH\":4141,\"GR\":0}] for the entire depth of the well being showin the curve_box",
"depth_curve_name": "A string of the curve that is the depth being plotted, like: 'DEPT'. Should be the same name as the depth curve in the array of objects in the data key above.",
//////
"data_id": ["array of strings whose length must equal curve_units, curve_names, etc."], // not built yet
"well_names": "An array of strings that represent well names if multiple curves shown in same curve_box. If only one well name, only one is required.", // not built yet ///
"scale_linear_log_or_yours": "An array of either 'linear' or 'log' or {'yours':scale_obj} where scale_obj might be something like: scale_obj = d3.scaleLog().domain([min_all_curves,max_all_curves]).nice().range([margin.left, width - margin.right]) that uses any of the d3.js scales methods https://github.com/d3/d3/blob/master/API.md#scales-d3-scale",
////// Plotting things but need to be next to curve data or will be too confusing.
"line_color": "An array of strings that establish the color of the line of the curve. RGB or common color name, like 'red'. If absent, default is black",
"max_depth": "Any array of numbers where each represents the max depth each curve is allowed to have. If a string of 'autocalculate' is used instead of a number then the max depth is autocalculated from the max depth of the input data in the data field. This is default behavior.",
"min_depth": "Any array of numbers where each represents the min depth each curve is allowed to have. If a string of 'autocalculate' is used instead of a number then the min depth is autocalculated from the min depth of the input data in the data field. This is default behavior.",
"depth_type_string": "All the curves should be calculated and populated vs. this curve. Takes a string, like: 'DEPT'",
"depth_units_string": "units of depth, examples are meters,m., cm., feet, etc.",
"null_value": "An array of null values used for each curve. Default is no null values considered, but could be something like: ['-999.25','-999.25','-999.25','NA']"
}
],
"lines": [
{
"data_type": "must be string, will be ignored if not \"line\", \"curve\", or \"rectangle\"",
"label": "The label for horiztonal line in string form",
"depth": "number for the depth at which the line is placed",
"color": "string for the color of the line in common color name or RGB format. If '' then black will be used.",
"stroke_width": "A string with of px value for stroke width, like: '1px'. Default if absent is '1px'.",
"stroke_style": "Should be string, if not or doesnt exist will be treated as \"solid\"",
"stroke_width": "The width of the line. Example is '2px'. ",
"stroke_linecap": "Style of ending of line as a string. Options are 'butt' which is no ending, 'round', and 'square' as defined here: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linecap Default is butt.",
"transparency": "Should be float between 0.0 and 1.0. Otherwise default is 1.0."
}
],
"rectangles": [
{
"data_type": "rectangle",
"depth_top": "A number for the depth of the upper left corner of the rectangle", //
"x_starting_upper_left_corner": "A number for the x axis value of the upper left corner of the rectangle",
"width": "Width of rectangle as number",
"height": "Height of rectangle as number",
"stroke_width": "The width of the line. Example is '2px'. ",
"stroke_linecap": "Style of ending of line as a string. Options are 'butt' which is no ending, 'round', and 'square' as defined here: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linecap Default is butt.",
"fill": "String that represents the color of the rectangle fill in either common color name or RGB like, 'red'",
"opacity": "Float between 0 and 1 that represents the opacity of the fill, default is 0.5",
"label": "String that appears on end of line and likely represents a top name, like: 'Top Jurassic Final Final Final'", // not built into plotting template yet
"label_orientation": "A string that is either 'horizontal' or 'vertical'. If other values, will treat as horizontal label orientation", // not built into plotting template yet
"lable_position": "Exceptable strings are top, center, right, left, bottom. Default right." // not built into plotting template yet
}
]
}]
}];
} else if (request_string == "mandatories") {
return [
"This is not yet populated!!!!"
];
}
},
/**
* getFakeIncomingSparseDataExample is a function that takes nothing and returns a JSON of fake sparse incoming data.
* This is much less than the JSON wellio gives when it converts a LAS file into a JSON. This is one of the type examples of data input. It is an alternative to wellio.js style JSON.
* It is used next by funtion ____ and ___.
* @returns {array} returns an array that contains an object. probably just a single object? Many of the things like max and min depth that are auto-calculated when the input is a wellio JSON and instead explicitly defined here. This saves data transmission from a backend as well as front-end calculation time.
*/
getFakeIncomingSparseDataExample: function () {
input_sparse_style = [{
"single_curve_box_or_cross_section": "single",
"cross_section_title": "",
"width": 1040, /// not skippable, check if number // default if blank or missing =250 or autocalculate?
"height": 500, /// not skippable, check if number // default if blank or missing=500
////////////////////////////
"curve_boxes": [{
"curve_box": {
"show_well_name": "yes", // not built yet /// Should be skip-able /// default=No
"show_depth_type": "no", // not built yet /// Should be skip-able /// default=No
"show_curve_units": "yes", // not built yet /// Should be skip-able /// default=No
"curve_box_depth_min": -999, // not built yet /// Should be skip-able /// default=skip func if string or -999
"curve_box_depth_max": -999, // not built yet /// Should be skip-able /// default=skip func if string or -999
"take_out_null_or_visualize": "no", // not built yet /// Should be skip-able /// default=No
"show_title": "no", // not built into plotting template yet /// Should be skip-able /// default=No
"width": 260, /// not skippable, check if number // default if blank or missing =250
"height": 500, /// not skippable, check if number // default if blank or missing=500
"height_multiplier_components": 3, // default if missing is 0.95
"margin": {"top": 50, "right": 10, "bottom": 30, "left": 60}, /// not skippable, check if number // defaults used if blank, string, or missing. If string or blank, add message to error message to console stating what default was used.
"title": {"text": "", "title_font_size": "10px"}, /// Should be skip-able // default=skip
"div_id": "well_holder4", /// Should be skip-able // default=random str? What happens if div doesn't exist?
"order_of_component": ["curves", "rectangles", "lines"], // not built yet, default is curve, then line, then rectangle
"lines_connected_across_curve_boxes": "no", // not built yet, default is skip function
"header_sep_svg_or_not": "yes",
"svg_header_height": "4em",
"gridlines": "yes",
"gridlines_color": "#D3D3D3",
"gridlines_stroke_width": 0.20,
"grouped_or_independent_x_scales": "independent",
//// variables for how to draw mouseover of hover box
"mouseover_yes_or_no": "yes", //// "yes" or "no"
"mouseover_depth_or_depth_and_curve": "depth_and_curve", /// options= "depth_and_curve", "depth", or "curve"
"mouseover_curvename": "default", //// default is first curve
"mouseover_color_or_default_which_is_curve_color": "default" /// default is default, which then uses curve color or black
},
"components": [{
"curves": [
{
"data_type": "curve", // not built yet /// requires one of possible strings: curve, line, rectangle if not one of acceptable string it just skips it.
"data_id": "placeholder_data_id", // not built yet /// can be anything, just used for tracking & is optional
"well_name": "", // not built yet /// Ideally string. Will skip function if ""
"curve_type": "RHOB", // should be string. name of curve
"curve_values": [
2.2322, 2.2513, 2.2548, 2.2445, 2.2223, 2.2047, 2.198, 2.2088, 2.2248, 2.2399, 2.251, 2.255, 2.2526, 2.2322, 2.2513, 2.2548, 2.2445, 2.2223, 2.2047, 2.198, 2.2088, 2.2248, 2.2399, 2.251, 2.255, 2.2526, 2.2322, 2.2513, 2.2548, 2.2445, 2.2223, 2.2047, 2.198, 2.2088, 2.2248, 2.2399, 2.251, 2.255, 2.2526, 2.2322, 2.2513, 2.2548, 2.2445, 2.2223, 2.2047, 2.198, 2.2088, 2.2248, 2.2399, 2.251, 2.255, 2.2526, 2.2322, 2.2513, 2.2548, 2.2445, 2.2223, 2.2047, 2.198, 2.2088, 2.2248, 2.2399, 2.251, 2.255, 2.2526, 2.2322, 2.2513, 2.2548, 2.2445, 2.2223, 2.2047, 2.198, 2.2088, 2.2248, 2.2399, 2.251, 2.255, 2.2526, 2.2322, 2.2513, 2.2548, 2.2445, 2.2223, 2.2047, 2.198, 2.2088, 2.2248, 2.2399, 2.251, 2.255, 2.2526], /// Should be array. If not array, return error message?
"step": 0.1, /// Should be number. If not array, return error message?
"units": "g/cc", /// should be string but try to plot whatever as string. if greater than X length include error message in console about excessive length will look bad but still plot.
"scale_linear_log_or_yours": "linear",
////// Plotting things but need to be next to curve data or will be too confusing.
"line_color": "rgb(205,0,0,1)", /// Test for string, if string use. If not string "black"
"curve_stroke_dasharray": "5,5",
"stroke_linecap": "butt",
"stroke_width": 0.5,
"fill": {
"curve_name": "RHOB",
"fill": "yes",
"fill_direction": "left",
"cutoffs": [0.21, 2.23, 2.24],
"fill_colors": ["gray", "beige", "white"],
"curve2": ""
},
"data_ID": "",
"max_depth": "1607.3", /// should be number, if not number or doens't exit then "autocalculate"
"min_depth": "1598.3", /// should be number, if not number or doens't exit then "autocalculate"
"depth_type_string": "TVDSS", /// should be string, if not or doesn't exist, then skip func
"depth_units_string": "md",
"depth_curve_name": "DEPTH", /// should be string, ideally all depth curve names are the same
"null_value": "", // not built yet, can be anything. Skip if blank or "" or "unknown". If not skip, then look for any values that match after d3 style data object is generated and either take them out or give special value based on behavior defined for curvebox in key "take_out_null_or_visualize" above.
"x_max": 3, // not built yet /// should be number /// auto-calculate if not number or is "autocalculate"
"x_min": 2, // not built yet /// should be number /// auto-calculate if not number or is "autocalculate"
}
],
"lines": [
{
"data_type": "line", /// must be string, will be ignored if not "line", "curve", or "rectangle".
"label": "top 1", /// Ideally a string.
"depth": 1601.4, /// Should be Float or integer, attempt to convert to number if string. Otherwise skip this part entirely!
"color": "blue", /// should be string, if not or doesn't exist use "black"
"stroke_width": "3px", /// should be string, if not or doesn't exist use "1px"
"stroke_linecap": "butt",
"stroke_style": "solid", /// should be string, if not or doesn't exist use "solid"
"transparency": 1.0 /// should be number between 0 and 1, if not or doesn't exist use 1.
},
{
"data_type": "line", /// must be string, will be ignored if not "line", "curve", or "rectangle".
"label": "top 2", /// Ideally a string.
"depth": 1602.4, /// Should be Float or integer, attempt to convert to number if string. Otherwise skip this part entirely!
"color": "orange", /// should be string, if not or doesn't exist use "black"
"stroke_width": "5px", /// should be string, if not or doesn't exist use "1px"
"stroke_linecap": "butt",
"stroke_style": "solid", /// should be string, if not or doesn't exist use "solid"
"transparency": 0.5 /// should be number between 0 and 1, if not or doesn't exist use 1.
}
],
"rectangles": [
{
"data_type": "rectangle",
"depth_top": 1601,
"x_starting_upper_left_corner": 0,
"width": 100,
"height": 100,
"stroke_width": "2px",
"stroke_linecap": "butt",
"fill": "red",
"opacity": 0.5,
"label": "Core Example", // not built into plotting template yet
"label_orientation": "horizontal", // not built into plotting template yet
"lable_position": "right" // not built into plotting template yet
}
]
}]
}]
}];
return input_sparse_style;
}
,
///////////////////////////////
//// Functions for getting data from LAS files and reformatting to a wellio.js style JSON.
///////////////////////////////
/**
* convertWellJSONToObj is a function that takes in wellio style JSON of all LAS file well log information,
* array of curves names, and a string for UWI
* and returns the data array of objects that D3.js likes for data used in plotting.
* @param {object} well_log_json a full wellio style JSON
* @param {array} CurveNames array of curve names as strings
* @param {string} UWI a string the represents the well name
* @returns {array} returns array of objects that contain key:value pairs of curve name and value at each depth. Depth is also a key:value pair.
*/
convertWellJSONToObj: function (well_log_json, CurveNames, UWI, depth_curve_name) {
let depth = well_log_json["CURVES"][depth_curve_name];
let curve_data = [];
for (let eachCr in CurveNames) {
curve_data.push(well_log_json["CURVES"][CurveNames[eachCr]]);
}
let array_of_obj = [];
if (depth.length === well_log_json["CURVES"][CurveNames[0]].length) {
for (let eachPt = 0; eachPt < depth.length; eachPt++) {
let obj = {};
obj["UWI"] = UWI;
for (let i = 0; i < CurveNames.length; i++) {
obj[CurveNames[i]] = parseFloat(curve_data[i][eachPt]);
}
array_of_obj.push(obj);
}
} else {
console.log("depth didn't match curve length");
array_of_obj.push("depth didn't match curve length");
}
return array_of_obj;
},
///////////////////////////////
//// Functions for getting basic information out of wellio.js style JSON for plotting
///////////////////////////////
/////// this require wellio!
// fileToJSON:function (afile){
// return module.exports.wellio.las2json(afile)
// },
/////////
// turnFilesIntoTextIntoWellioJSON:function (files_array){
// //// For each well log file, turn into text, then convert text into wellio style JSON using wellio.js
// let logs_in_json = []
// for (let i = 0; i < files_array.length; i++) {
// logs_in_json.push(module.exports.fileToJSON(files_array[i]))
// }
// return logs_in_json
// },
/**
* fromJSONofWEllGetThingsForPlotting is a function that takes in wellio style JSON of all LAS file well log information,
* and returns an object that contains 3 things in an object format that are used in function ___ for plotting.
* the data array of objects that D3.js likes for data used in plotting.
* @param {object} jsonWell a full wellio style JSON
* @param {string} depth_curve_name String for the depth curve name
* @returns {array} returns an object of 3 things that will eventually be used in plotting. {"well_log_curves_reformatted_for_d3":well_log_curves_reformatted_for_d3,"curve_names":curve_names,"uwi":uwi}
*/
fromJSONofWEllGetThingsForPlotting: function (jsonWell, depth_curve_name) {
curve_names = Object.keys(jsonWell["CURVES"]);
uwi = jsonWell["WELL INFORMATION BLOCK"]["UWI"]["DATA"];
depth_curve_name = depth_curve_name;
well_log_curves_reformatted_for_d3 = module.exports.convertWellJSONToObj(jsonWell, curve_names, uwi, depth_curve_name);
return {
"well_log_curves_reformatted_for_d3": well_log_curves_reformatted_for_d3,
"curve_names": curve_names,
"uwi": uwi
};
},
///////////////////////////////
//// Functions for reformatting data other than wellio.js style JSON
///////////////////////////////
/**
* createDepthArray is a function that takes in a min float, max float, and step float value.
* and returns an array or depth values from the min to the max value going by the step value each step.
* This function is used to create a depth array for plotting when only the max, min, and depth is given explicitly in the input data. This might be done to avoid sending the depth curve from the backend to the front-end.
* @param {float} min a float or integer that represents the top depth of an eventual array of depth values that this function creates.
* @param {float} max a float or integer that represents the bottom depth of an array of depth values this function creates.
* @param {float} step a float or integer that represents the interval the depth curve increases as you go from the top to the bottom of the depth curve this function creates.
* @returns {array} returns an array of depth values from the min to the max by the step. AN EXAMPLE = [10,10.5,11,11.5,12]
*/
createDepthArray: function (min, max, step) {
//// Returns an array of depth values from min to max, including both, with each being different by step value
//// ran like: depthArray = createDepthArray(data2[0]["min_depth"],data2[0]["max_depth"],data2[0]["step"])
let depth = [];
min = parseFloat(min);
max = parseFloat(max);
step = parseFloat(step);
let number_of_points = ((max - min) / step) + 1;
let temp_depth = min;
for (let i = 0; i < number_of_points; i++) {
temp_depth = (min + (i * step)).toFixed(7);
depth.push(parseFloat(temp_depth));
}
return depth;
},
/**
* takeInArraysAndGetObjectOfCurveDataForPlotting is a function used to reformt arrays of curve values into a form that d3.js likes better, an array of objects.
* THIS FUNCTION NEEDS CHANGED IT IS TOO EXPLICIT !!!!!!!
*/
takeInArraysAndGetObjectOfCurveDataForPlotting: function (arraysOfCurvesAndNames, CurveName, DepthName) {
//// would be run like: reformattedForWelliovizCurveData = takeInArraysAndGetObjectOfCurveDataForPlotting([{"depth":depthArray,"RHOB":data2[0].curve_values}],"RHOB")
// [{"depth":[],"curveData":[]}]
// [{"depth":[],"curveData":[]}]
let curveObj = [];
// make sure the curve data arrays are the same lenght, if not add null values
// put them into object
let lengthOfCurve0 = arraysOfCurvesAndNames[0][DepthName].length;
for (let i = 0; i < lengthOfCurve0; i++) {
let newObj = {[DepthName]: 0, "RHOB": 0};
newObj[DepthName] = arraysOfCurvesAndNames[0][DepthName][i];
newObj[CurveName] = arraysOfCurvesAndNames[0][CurveName][i];
curveObj.push(newObj);
}
return curveObj;
},
/**
* convertWellJSONToObjV2 is a function that takes in sparse style JSON and other information and returns an array of that information properly packaged,
* array of curves names, and a string for UWI
* and returns the data array of objects that D3.js likes for data used in plotting.
* @param {array} depth An array of strings that can be parsed into floats that represents the depth along the well log curves in a curvebox.
* @param {array} curve_data An array of arrays of strings that can be parsed into floats that represents each of the well log curves in a curvebox.
* @param {string} UWI A string for the well log UWI ID
* @param {array} CurveNames An array of strings that represent curvenames, one for each well log curve in curve_data
* @returns {array} An array of objects properly formatted for next step ___.
*/
convertWellJSONToObjV2: function (depth, curve_data, UWI, CurveNames) {
depth = depth[0];
array_of_obj = [];
for (eachPt in depth) {
obj = {};
obj["UWI"] = UWI;
for (i in CurveNames) {
obj[CurveNames[i]] = parseFloat(curve_data[CurveNames[i]][eachPt]);
obj["DEPTH"] = parseFloat(depth[eachPt]);
}
array_of_obj.push(obj);
}
return array_of_obj;
},
///////////////////////////////
//// Functions that take in incoming sparse style JSON and a template and handle all the transformation into the JSON for plotting that is given to curveBox function.
///////////////////////////////
/**
* This function is used to put the incoming sparse style JSON information into the plotting tempalte JSON that is given to curveBox which then handles the plotting.
* @param {object} incoming_sparse This is a JSON object of incoming sparse style data & plotting instructions.
* @param {object} template This is a JSON example template of the type typically given to the curveBox function. The user will use if for defaults and replace the data and formatting options they want to change.
*/
putIncomingSparseJsonIntoPlottingTemplate: function (incoming_sparse, template) {
if (incoming_sparse[0]["single_curve_box_or_cross_section"] == "multiple") {
console.log("THERE WAS A PROBLEM IN THE FUNCTION putIncomingSparse_into_PlottingTemplate. THE CODE TO HANDLE CROSS SECTIONS HAS NOT BEEN WRITTEN YET!!!! BUT IT WOULD GO HERE ");
return "THE CODE TO HANDLE CROSS SECTIONS HAS NOT BEEN WRITTEN YET!!!! BUT IT WOULD GO HERE";
} else {
let curve_box_obj = incoming_sparse[0]["curve_boxes"][0];
let curve_box_overall = incoming_sparse[0]["curve_boxes"][0]["curve_box"];
let curve_box_components = incoming_sparse[0]["curve_boxes"][0]["components"];
template[0]["curve_box"] = curve_box_overall;
template[0]["components"][0]["lines"] = curve_box_components[0]["lines"];
template[0]["components"][0]["rectangles"] = curve_box_components[0]["rectangles"];
///// Establish template with empty arrays except for value that are shared for all curves
///// THESE HAVE A SINGLE VALUE ACROSS ALL CURVES IN A CURVEBOX
template[0]["components"][0]["curves"][0]["data_type"] = "curve";
template[0]["components"][0]["curves"][0]["depth_type_string"] = curve_box_components[0]["curves"][0]["depth_type_string"];
template[0]["components"][0]["curves"][0]["depth_units_string"] = curve_box_components[0]["curves"][0]["depth_units_string"];
template[0]["components"][0]["curves"][0]["depth_curve_name"] = curve_box_components[0]["curves"][0]["depth_curve_name"];
///// THESE HAVE MULTIPLE VALUES IN A CURVEBOX ONE PER CURVE.
template[0]["components"][0]["curves"][0]["curve_names"] = [];
template[0]["components"][0]["curves"][0]["curve_colors"] = [];
template[0]["components"][0]["curves"][0]["curve_stroke_dasharray"] = [];
template[0]["components"][0]["curves"][0]["stroke_width"] = [];
template[0]["components"][0]["curves"][0]["stroke_linecap"] = [];
template[0]["components"][0]["curves"][0]["fill"] = [];
template[0]["components"][0]["curves"][0]["data_id"] = [];
template[0]["components"][0]["curves"][0]["well_names"] = [];
template[0]["components"][0]["curves"][0]["scale_linear_log_or_yours"] = [];
template[0]["components"][0]["curves"][0]["line_color"] = [];
template[0]["components"][0]["curves"][0]["max_depth"] = [];
template[0]["components"][0]["curves"][0]["min_depth"] = [];
template[0]["components"][0]["curves"][0]["null_value"] = [];
template[0]["components"][0]["curves"][0]["data"] = [];
///// For each curve object in incoming data:
let array_individual_curves_and_depth_objects = [];
let all_depths_list = [];
let all_depths_set = [];
for (let i = 0; i < curve_box_components[0]["curves"].length; i++) {
let curve = curve_box_components[0]["curves"][i];
template[0]["components"][0]["curves"][0]["curve_names"].push(curve["curve_type"]);
template[0]["components"][0]["curves"][0]["curve_colors"].push(curve["line_color"]);
template[0]["components"][0]["curves"][0]["curve