From 51e6d4825a90fb9b12f94c91709b26a883a3454f Mon Sep 17 00:00:00 2001 From: Karl Rister Date: Thu, 9 May 2019 15:14:45 +0000 Subject: [PATCH 01/13] index.js: reorganize code to separate base chart setup from dataset handling --- jschart/index.js | 345 ++++++++++++++++++++++++----------------------- 1 file changed, 179 insertions(+), 166 deletions(-) diff --git a/jschart/index.js b/jschart/index.js index 4eba2b1..722e7eb 100644 --- a/jschart/index.js +++ b/jschart/index.js @@ -1548,7 +1548,7 @@ function navigate_to_chart(target) { } } -function complete_chart(chart) { +function create_chart_dataset_objects(chart) { update_domains(chart); if (chart.datasets.all.length < chart.dimensions.legend_properties.columns) { @@ -2239,7 +2239,9 @@ function create_table(chart) { .append("th") .attr("align", "right") .text("Samples"); +} +function table_add_datasets(chart) { for (var i = 0; i < chart.datasets.all.length; i++) { chart.datasets.all[i].dom.table.row = chart.dom.table.table .selectAll(".tablerow") @@ -2626,6 +2628,7 @@ function generate_chart( charts[charts_index].charts_index = charts_index; build_chart(charts[charts_index]); + load_datasets(charts[charts_index]); callback(); } @@ -3224,6 +3227,170 @@ function build_chart(chart) { return false; }); + chart.chart.zoomout = chart.chart.container + .append("g") + .classed("chartbutton", true) + .classed("hidden", true) + .on("click", function() { + zoom_it(chart, 1); + chart.state.user_x_zoomed = true; + chart.state.user_y_zoomed = true; + }) + .on("mouseout", function() { + chart.chart.viewport_controls.classed("hidden", true); + }) + .on("mouseover", function() { + chart.chart.viewport_controls.classed("hidden", false); + }); + + chart.chart.zoomout + .append("circle") + .attr("cx", 20) + .attr("cy", 20) + .attr("r", 11); + + chart.chart.zoomout + .append("text") + .classed("middletext", true) + .attr("x", 20) + .attr("y", 24) + .text("-"); + + chart.chart.zoomin = chart.chart.container + .append("g") + .classed("chartbutton", true) + .classed("hidden", true) + .on("click", function() { + zoom_it(chart, -1); + chart.state.user_x_zoomed = true; + chart.state.user_y_zoomed = true; + }) + .on("mouseout", function() { + chart.chart.viewport_controls.classed("hidden", true); + }) + .on("mouseover", function() { + chart.chart.viewport_controls.classed("hidden", false); + }); + + chart.chart.viewport_controls = d3.selectAll([ + chart.chart.zoomout.node(), + chart.chart.zoomin.node() + ]); + + chart.chart.zoomin + .append("circle") + .attr("cx", 50) + .attr("cy", 20) + .attr("r", 11); + + chart.chart.zoomin + .append("text") + .classed("middletext", true) + .attr("x", 50) + .attr("y", 24) + .text("+"); + + chart.chart.xcursorline = chart.chart.container + .append("line") + .classed("cursorline hidden", true) + .attr("x1", 0) + .attr("y1", 0) + .attr("x2", 1) + .attr("y2", 1); + + chart.chart.ycursorline = chart.chart.container + .append("line") + .classed("cursorline hidden", true) + .attr("x1", 0) + .attr("y1", 0) + .attr("x2", 1) + .attr("y2", 1); + + chart.chart.coordinates = chart.chart.container + .append("text") + .classed("coordinates endtext hidden", true) + .attr("x", chart.dimensions.viewport_width - 5) + .attr("y", 15) + .text("coordinates"); + + chart.chart.viewport_elements = d3.selectAll([ + chart.chart.xcursorline.node(), + chart.chart.ycursorline.node(), + chart.chart.coordinates.node() + ]); + + if (chart.options.live_update) { + chart.interval = window.setInterval(function() { + live_update(chart); + }, chart.options.update_interval * 1000); + + chart.chart.playpause = chart.chart.container + .append("g") + .classed("chartbutton", true) + .classed("hidden", true) + .on("click", function() { + if (chart.state.live_update) { + chart.state.live_update = false; + clearInterval(chart.interval); + } else { + chart.state.live_update = true; + chart.interval = window.setInterval(function() { + live_update(chart); + }, chart.options.update_interval * 1000); + } + }) + .on("mouseout", function() { + chart.chart.viewport_controls.classed("hidden", true); + }) + .on("mouseover", function() { + chart.chart.viewport_controls.classed("hidden", false); + }); + + chart.chart.viewport_controls = d3.selectAll([ + chart.chart.zoomout.node(), + chart.chart.zoomin.node(), + chart.chart.playpause.node() + ]); + + chart.chart.playpause + .append("circle") + .attr("cx", 35) + .attr("cy", 45) + .attr("r", 11); + + chart.chart.playpause + .append("polygon") + .classed("playicon", true) + .attr("points", "29,42 29,49 34,45"); + + chart.chart.playpause + .append("line") + .classed("pauseicon", true) + .attr("x1", 37) + .attr("y1", 41) + .attr("x2", 37) + .attr("y2", 50); + + chart.chart.playpause + .append("line") + .classed("pauseicon", true) + .attr("x1", 41) + .attr("y1", 41) + .attr("x2", 41) + .attr("y2", 50); + } + + console.log('Creating table for chart "' + chart.chart_title + '"...'); + create_table(chart); + console.log( + '...finished creating table for chart "' + chart.chart_title + '"' + ); +} + +function load_datasets(chart) { + var x_domain = chart.x.scale.chart.domain(); + var y_domain = chart.y.scale.chart.domain(); + chart.chart.loading = chart.chart.container .append("text") .classed("loadinglabel middletext", true) @@ -3279,12 +3446,14 @@ function build_chart(chart) { } } + console.log('Waiting for content to load for chart "' + chart.chart_title + '".'); + // block waiting for the queue processing to complete before completing the chart chart.datasets_queue.await(function(error, results) { chart.chart.loading.remove(); chart.chart.loading = null; - console.log('Content load complete for chart "' + chart.chart_title + '".'); + console.log('...content load complete for chart "' + chart.chart_title + '".'); if (chart.options.sort_datasets) { if (chart.data_model == "histogram") { @@ -3341,16 +3510,12 @@ function build_chart(chart) { chart.options.legend_entries.length) * chart.dimensions.legend_properties.row_height ); + console.log('...finished resizing SVG for chart "' + chart.chart_title + '".'); } - console.log('Creating table for chart "' + chart.chart_title + '"...'); - create_table(chart); - console.log( - '...finished adding table for chart "' + chart.chart_title + '"' - ); - console.log('Processing datasets for chart "' + chart.chart_title + '"...'); - complete_chart(chart); + create_chart_dataset_objects(chart); + table_add_datasets(chart); console.log( '...finished processing datasets for chart "' + chart.chart_title + '"' ); @@ -3358,160 +3523,7 @@ function build_chart(chart) { chart.x.slider.call(chart.x.brush.event); chart.y.slider.call(chart.y.brush.event); - chart.chart.zoomout = chart.chart.container - .append("g") - .classed("chartbutton", true) - .classed("hidden", true) - .on("click", function() { - zoom_it(chart, 1); - chart.state.user_x_zoomed = true; - chart.state.user_y_zoomed = true; - }) - .on("mouseout", function() { - chart.chart.viewport_controls.classed("hidden", true); - }) - .on("mouseover", function() { - chart.chart.viewport_controls.classed("hidden", false); - }); - - chart.chart.zoomout - .append("circle") - .attr("cx", 20) - .attr("cy", 20) - .attr("r", 11); - - chart.chart.zoomout - .append("text") - .classed("middletext", true) - .attr("x", 20) - .attr("y", 24) - .text("-"); - - chart.chart.zoomin = chart.chart.container - .append("g") - .classed("chartbutton", true) - .classed("hidden", true) - .on("click", function() { - zoom_it(chart, -1); - chart.state.user_x_zoomed = true; - chart.state.user_y_zoomed = true; - }) - .on("mouseout", function() { - chart.chart.viewport_controls.classed("hidden", true); - }) - .on("mouseover", function() { - chart.chart.viewport_controls.classed("hidden", false); - }); - - chart.chart.viewport_controls = d3.selectAll([ - chart.chart.zoomout.node(), - chart.chart.zoomin.node() - ]); - - chart.chart.zoomin - .append("circle") - .attr("cx", 50) - .attr("cy", 20) - .attr("r", 11); - - chart.chart.zoomin - .append("text") - .classed("middletext", true) - .attr("x", 50) - .attr("y", 24) - .text("+"); - - chart.chart.xcursorline = chart.chart.container - .append("line") - .classed("cursorline hidden", true) - .attr("x1", 0) - .attr("y1", 0) - .attr("x2", 1) - .attr("y2", 1); - - chart.chart.ycursorline = chart.chart.container - .append("line") - .classed("cursorline hidden", true) - .attr("x1", 0) - .attr("y1", 0) - .attr("x2", 1) - .attr("y2", 1); - - chart.chart.coordinates = chart.chart.container - .append("text") - .classed("coordinates endtext hidden", true) - .attr("x", chart.dimensions.viewport_width - 5) - .attr("y", 15) - .text("coordinates"); - - chart.chart.viewport_elements = d3.selectAll([ - chart.chart.xcursorline.node(), - chart.chart.ycursorline.node(), - chart.chart.coordinates.node() - ]); - console.log('...finished building chart "' + chart.chart_title + '"'); - - if (chart.options.live_update) { - chart.interval = window.setInterval(function() { - live_update(chart); - }, chart.options.update_interval * 1000); - - chart.chart.playpause = chart.chart.container - .append("g") - .classed("chartbutton", true) - .classed("hidden", true) - .on("click", function() { - if (chart.state.live_update) { - chart.state.live_update = false; - clearInterval(chart.interval); - } else { - chart.state.live_update = true; - chart.interval = window.setInterval(function() { - live_update(chart); - }, chart.options.update_interval * 1000); - } - }) - .on("mouseout", function() { - chart.chart.viewport_controls.classed("hidden", true); - }) - .on("mouseover", function() { - chart.chart.viewport_controls.classed("hidden", false); - }); - - chart.chart.viewport_controls = d3.selectAll([ - chart.chart.zoomout.node(), - chart.chart.zoomin.node(), - chart.chart.playpause.node() - ]); - - chart.chart.playpause - .append("circle") - .attr("cx", 35) - .attr("cy", 45) - .attr("r", 11); - - chart.chart.playpause - .append("polygon") - .classed("playicon", true) - .attr("points", "29,42 29,49 34,45"); - - chart.chart.playpause - .append("line") - .classed("pauseicon", true) - .attr("x1", 37) - .attr("y1", 41) - .attr("x2", 37) - .attr("y2", 50); - - chart.chart.playpause - .append("line") - .classed("pauseicon", true) - .attr("x1", 41) - .attr("y1", 41) - .attr("x2", 41) - .attr("y2", 50); - } }); } @@ -3565,10 +3577,11 @@ exports.create_jschart = function( }; exports.finish_page = function () { - // wait for chart generation to complete before logging that it is done and changing the page background + // wait for initial chart generation to complete before logging that it is done and changing the page background + // note: chart datasets may still be loading asynchronously charts_queue.await(function(error, results) { d3.select("body").classed("completedpage", true); - console.log("Finished generating all charts"); + console.log("Finished creating all charts"); }); } @@ -4816,13 +4829,13 @@ function apply_name_filter_hide(chart) { } function sort_table(chart) { - if (chart.options.sort_datasets) { + if (chart.options.sort_datasets && chart.dom.table.data_rows) { chart.dom.table.data_rows.sort(datarow_sort); } } function sort_table_by_value(chart) { - if (chart.options.sort_datasets) { + if (chart.options.sort_datasets && chart.dom.table.data_rows) { chart.dom.table.data_rows.sort(datarow_sort_by_value); } } From 91fb73f32f2c79320878fe1e056cb99a522924a6 Mon Sep 17 00:00:00 2001 From: Karl Rister Date: Thu, 9 May 2019 16:21:08 +0000 Subject: [PATCH 02/13] App.js: add dynamic chart demo --- tests/src/App.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/src/App.js b/tests/src/App.js index 96554a7..478046a 100644 --- a/tests/src/App.js +++ b/tests/src/App.js @@ -8,6 +8,18 @@ import jitter_data from './data/jitter.csv'; class App extends Component { componentDidMount = () => { + jschart.create_jschart( + 0, + "timeseries", + "jschart_dynamic", + "Dynamic Chart Demo", + "Time (secs.)", + null, + { + csvfiles: [ timeseries_data ], + dynamic_chart: true + } + ); jschart.create_jschart( 0, "timeseries", @@ -90,6 +102,7 @@ class App extends Component {

JSChart Demos



+
From 8d3730b95dbb1ce75879bd5a78060ddb764c04f3 Mon Sep 17 00:00:00 2001 From: Karl Rister Date: Thu, 9 May 2019 19:23:55 +0000 Subject: [PATCH 03/13] index.js: update error warning messages to use appropriate API call --- jschart/index.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/jschart/index.js b/jschart/index.js index 722e7eb..ed29592 100644 --- a/jschart/index.js +++ b/jschart/index.js @@ -17,7 +17,7 @@ function load_jschart_override_options() { if (imported_options.threshold !== undefined) { loaded_options.threshold = +imported_options.threshold; - console.log("Found override: threshold=%f", loaded_options.threshold); + console.warn("Found override: threshold=%f", loaded_options.threshold); } if (imported_options.threshold_invalidate_on_load !== undefined) { @@ -29,7 +29,7 @@ function load_jschart_override_options() { } else { loaded_options.threshold_invalidate_on_load = false; } - console.log( + console.warn( "Found override: threshold_invalidate_on_load=%s", loaded_options.threshold_invalidate_on_load ); @@ -355,7 +355,7 @@ function chart( this.options.sort_datasets = false; - console.log( + console.warn( 'Cannot enable dataset sorting for "' + this.chart_title + '" because it is not compatible with live updates.' @@ -1251,7 +1251,7 @@ function load_csv_files(url, chart, callback) { var index_base = chart.datasets.all.length; if (text === undefined || error !== null) { - console.log('ERROR: Loading "%s" resulted in error "%O".', url, error); + console.error('Loading "%s" resulted in error "%O".', url, error); // create an error object with minimal properties chart.datasets.all[index_base - 1] = new dataset( @@ -1468,7 +1468,7 @@ function load_plot_files(url, chart, index, callback) { // populating the graph, avoiding parallelism issues d3.text(url, "text/plain").get(function(error, text) { if (text === undefined || error !== null) { - console.log('ERROR: Loading "%s" resulted in error "%O".', url, error); + console.error('Loading "%s" resulted in error "%O".', url, error); // create an error object with minimal properties chart.datasets.all[index] = new dataset( @@ -2647,7 +2647,7 @@ function build_chart(chart) { '"' ); } else { - console.log( + console.error( 'An unsupported data_model ["' + chart.data_model + '"] was specified for chart "' + @@ -2662,7 +2662,7 @@ function build_chart(chart) { chart.dom.div = d3.select("#" + chart.location); if (chart.dom.div.empty()) { - console.log( + console.error( 'Failed to locate div for "' + chart.chart_title + '" identified by "' + @@ -3026,7 +3026,7 @@ function build_chart(chart) { } if (domain_check) { - console.log( + console.warn( 'Skipping application of X-Axis zoom from "' + chart.chart_title + '" to "' + @@ -3485,8 +3485,8 @@ function load_datasets(chart) { if (!chart.datasets.all[i].invalid) { chart.datasets.valid.push(chart.datasets.all[i]); } else { - console.log( - 'ERROR: Dataset "' + + console.error( + 'Dataset "' + chart.datasets.all[i].name + '" for chart "' + chart.chart_title + From c2cac8b54057e5b759f95e7fbcb38746b983e753 Mon Sep 17 00:00:00 2001 From: Karl Rister Date: Fri, 10 May 2019 00:19:39 +0000 Subject: [PATCH 04/13] index.js: create dynamic chart mode with reset/reload - Reset clears the chart of all dataset elements. - Reload loads the data back into the chart again, recreating the dataset elements. --- jschart/index.js | 142 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 111 insertions(+), 31 deletions(-) diff --git a/jschart/index.js b/jschart/index.js index ed29592..ef68ad4 100644 --- a/jschart/index.js +++ b/jschart/index.js @@ -103,7 +103,7 @@ function dataset(index, name, mean, median, values, chart) { points: null, cursor_point: null, markers: null, - legend: { rect: null, label: null } + legend: { rect: null, outline: null, label: null } }; this.values = []; this.values_index = -1; @@ -187,9 +187,9 @@ function chart( }, misc_controls: { table: null, - rows: { header: null, sorting: null }, + rows: { header: null, sorting: null, dynamic: null }, toggle_hide: null, - inputs: { sort_datasets: null } + inputs: { sort_datasets: null, reset_chart: null, reload_chart: null } } } }; @@ -211,7 +211,8 @@ function chart( mouse: null, view_port_table_controls_visible: true, misc_controls_table_controls_visible: true, - custom_domain: false + custom_domain: false, + reset: false }; this.functions = { area: null, stack: null, line: null }; @@ -241,7 +242,8 @@ function chart( scale: { linear: true, log: false, time: false } }, y: { min: null, max: null, scale: { linear: true, log: false } }, - scatterplot: false + scatterplot: false, + dynamic_chart: false }; this.interval = null; @@ -295,6 +297,10 @@ function chart( } } + if (options.dynamic_chart !== undefined && options.dynamic_chart) { + this.options.dynamic_chart = true; + } + if (options.y_log_scale !== undefined && options.y_log_scale) { this.options.y.scale.log = true; this.options.y.scale.linear = false; @@ -1580,7 +1586,10 @@ function create_chart_dataset_objects(chart) { chart.chart.legend .append("rect") - .classed("legendrectoutline", true) + .classed("legendrectoutline", function(d) { + d.dom.legend.outline = d3.select(this); + return true; + }) .attr("width", 16) .attr("height", 16) .style("stroke", function(d) { @@ -2163,6 +2172,35 @@ function create_table(chart) { }) .on("click", toggle_table_sort_datasets); + if (chart.options.dynamic_chart) { + chart.dom.table.misc_controls.rows.dynamic = chart.dom.table.misc_controls.table + .append("tr") + .classed("controls", true); + + chart.dom.table.misc_controls.rows.dynamic.append("th").text("Dynamic Chart"); + + var cell = chart.dom.table.misc_controls.rows.dynamic + .append("td") + .attr("colSpan", 3); + + chart.dom.table.misc_controls.inputs.reset_chart = cell + .selectAll(".reset_chart") + .data([chart]) + .enter() + .append("button") + .text("Reset") + .on("click", reset_chart); + + chart.dom.table.misc_controls.inputs.reset_chart = cell + .selectAll(".reload_chart") + .data([chart]) + .enter() + .append("button") + .text("Reload") + .on("click", reload_chart); + + } + toggle_hide_misc_controls_table_controls(chart); console.log( @@ -2783,18 +2821,7 @@ function build_chart(chart) { chart.dimensions.margin.left + chart.dimensions.margin.right ) - .attr( - "height", - chart.dimensions.viewport_height + - chart.dimensions.margin.top + - chart.dimensions.margin.bottom + - (Math.ceil( - chart.dataset_count / chart.dimensions.legend_properties.columns - ) - - 1 + - chart.options.legend_entries.length) * - chart.dimensions.legend_properties.row_height - ); + .attr("height", get_svg_height(chart)); chart.chart.defs = chart.chart.svg.append("defs"); if (!chart.options.scatterplot) { @@ -3497,19 +3524,7 @@ function load_datasets(chart) { if (chart.datasets.all.length > chart.dataset_count) { console.log('Resizing SVG for chart "' + chart.chart_title + '".'); - chart.chart.svg.attr( - "height", - chart.dimensions.viewport_height + - chart.dimensions.margin.top + - chart.dimensions.margin.bottom + - (Math.ceil( - chart.datasets.all.length / - chart.dimensions.legend_properties.columns - ) - - 1 + - chart.options.legend_entries.length) * - chart.dimensions.legend_properties.row_height - ); + chart.chart.svg.attr("height", get_svg_height(chart)); console.log('...finished resizing SVG for chart "' + chart.chart_title + '".'); } @@ -5016,10 +5031,16 @@ function toggle_hide_misc_controls_table_controls(chart) { if (chart.state.misc_controls_table_controls_visible) { chart.dom.table.misc_controls.toggle_hide.text("+ Misc. Controls"); chart.dom.table.misc_controls.rows.sorting.classed("nodisplay", true); + if (chart.options.dynamic_chart) { + chart.dom.table.misc_controls.rows.dynamic.classed("nodisplay", true); + } chart.state.misc_controls_table_controls_visible = false; } else { chart.dom.table.misc_controls.toggle_hide.text("- Misc. Controls"); chart.dom.table.misc_controls.rows.sorting.classed("nodisplay", false); + if (chart.options.dynamic_chart) { + chart.dom.table.misc_controls.rows.dynamic.classed("nodisplay", false); + } chart.state.misc_controls_table_controls_visible = true; } } @@ -5160,3 +5181,62 @@ function display_help() { console.log(help); alert(help); } + +function reset_chart(chart) { + console.warn("resetting chart '" + chart.chart_title + "'."); + + chart.chart.cursor_points.remove(); + chart.chart.cursor_points = null; + + chart.chart.legend.remove(); + chart.chart.legend = null; + + chart.chart.plot.remove(); + chart.chart.plot = null; + + chart.dom.table.data_rows.remove(); + chart.dom.table.data_rows = null; + + for (var i = chart.datasets.all.length - 1; i >= 0; i--) { + if (chart.options.scatterplot) { + chart.datasets.all[i].dom.markers.remove(); + } + } + + while (chart.datasets.valid.length) { + chart.datasets.valid.pop(); + } + + while (chart.datasets.all.length) { + chart.datasets.all.pop(); + } + + chart.dataset_count = 0; + + reset_axes_domains(chart); + + chart.chart.svg.attr("height", get_svg_height(chart)); + + chart.state.reset = true; +} + +function get_svg_height(chart) { + return chart.dimensions.viewport_height + + chart.dimensions.margin.top + + chart.dimensions.margin.bottom + + ( Math.ceil(chart.datasets.all.length / chart.dimensions.legend_properties.columns) - + 1 + chart.options.legend_entries.length + ) * chart.dimensions.legend_properties.row_height; +} + +function reload_chart(chart) { + if (!chart.state.reset) { + reset_chart(chart); + } + + console.warn("reloading chart '" + chart.chart_title + "'."); + + load_datasets(chart); + + chart.state.reset = false; +} From 614039cafb97da7b5e1e87e2e6267f595149261e Mon Sep 17 00:00:00 2001 From: Karl Rister Date: Fri, 10 May 2019 15:15:45 +0000 Subject: [PATCH 05/13] index.js: allow charts to be reloaded with alternative options (including datasets) --- jschart/index.js | 246 +++++++++++++++++++++++++++++------------------ 1 file changed, 150 insertions(+), 96 deletions(-) diff --git a/jschart/index.js b/jschart/index.js index ef68ad4..22ea90e 100644 --- a/jschart/index.js +++ b/jschart/index.js @@ -220,32 +220,6 @@ function chart( this.datasets_queue = null; this.datasets = { all: [], valid: [] }; - this.options = { - timezone: null, - legend_entries: null, - packed: 0, - plotfiles: null, - csvfiles: null, - plotfile: null, - json_plotfile: null, - json_object: null, - json_args: null, - raw_data_source: [], - update_interval: null, - live_update: false, - history_length: null, - hide_dataset_threshold: null, - sort_datasets: true, - x: { - min: null, - max: null, - scale: { linear: true, log: false, time: false } - }, - y: { min: null, max: null, scale: { linear: true, log: false } }, - scatterplot: false, - dynamic_chart: false - }; - this.interval = null; this.zoom_rate = 3; this.y_axis_overscale = 2; @@ -286,125 +260,151 @@ function chart( this.parsers = { space: d3.dsv(" ", "text/plain") }; + this.options = setup_chart_options(this, options); +} + +function setup_chart_options(chart, options) { + var the_options = { + timezone: null, + legend_entries: null, + packed: 0, + plotfiles: null, + csvfiles: null, + plotfile: null, + json_plotfile: null, + json_object: null, + json_args: null, + raw_data_source: [], + update_interval: null, + live_update: false, + history_length: null, + hide_dataset_threshold: null, + sort_datasets: true, + x: { + min: null, + max: null, + scale: { linear: true, log: false, time: false } + }, + y: { min: null, max: null, scale: { linear: true, log: false } }, + scatterplot: false, + dynamic_chart: false + }; + // option(s) "parsing" - if (this.data_model == "timeseries") { - this.options.x.scale.time = true; - this.options.x.scale.linear = false; + if (chart.data_model == "timeseries") { + the_options.x.scale.time = true; + the_options.x.scale.linear = false; } else { if (options.x_log_scale !== undefined && options.x_log_scale) { - this.options.x.scale.log = true; - this.options.x.scale.linear = false; + the_options.x.scale.log = true; + the_options.x.scale.linear = false; } } if (options.dynamic_chart !== undefined && options.dynamic_chart) { - this.options.dynamic_chart = true; + the_options.dynamic_chart = true; } if (options.y_log_scale !== undefined && options.y_log_scale) { - this.options.y.scale.log = true; - this.options.y.scale.linear = false; + the_options.y.scale.log = true; + the_options.y.scale.linear = false; } if (options.timeseries_timezone !== undefined) { - this.options.timezone = options.timeseries_timezone; + the_options.timezone = options.timeseries_timezone; } if (options.legend_entries !== undefined) { - this.options.legend_entries = options.legend_entries; + the_options.legend_entries = options.legend_entries; } else { - this.options.legend_entries = []; + the_options.legend_entries = []; } if (options.packed !== undefined) { - this.options.packed = options.packed; - this.dataset_count = this.options.packed; + the_options.packed = options.packed; + chart.dataset_count = the_options.packed; } else if (options.plotfiles !== undefined) { - this.options.plotfiles = options.plotfiles; - this.dataset_count = this.options.plotfiles.length; + the_options.plotfiles = options.plotfiles; + chart.dataset_count = the_options.plotfiles.length; } if (options.csvfiles !== undefined) { - this.options.csvfiles = options.csvfiles; + the_options.csvfiles = options.csvfiles; } if (options.plotfile !== undefined) { - this.options.plotfile = options.plotfile; + the_options.plotfile = options.plotfile; } if (options.plotfiles !== undefined) { - this.options.plotfiles = options.plotfiles; + the_options.plotfiles = options.plotfiles; } if (options.json_plotfile !== undefined) { - this.options.json_plotfile = options.json_plotfile; + the_options.json_plotfile = options.json_plotfile; } if (options.json_object !== undefined) { - this.options.json_object = options.json_object; + the_options.json_object = options.json_object; } if (options.json_args !== undefined) { - this.options.json_args = options.json_args; + the_options.json_args = options.json_args; } if (options.raw_data_sources !== undefined) { - this.options.raw_data_sources = options.raw_data_sources; + the_options.raw_data_sources = options.raw_data_sources; } else { - this.options.raw_data_sources = []; + the_options.raw_data_sources = []; } if (options.update_interval !== undefined) { - this.options.live_update = true; + the_options.live_update = true; - this.options.update_interval = options.update_interval; + the_options.update_interval = options.update_interval; - this.options.sort_datasets = false; + the_options.sort_datasets = false; - console.warn( - 'Cannot enable dataset sorting for "' + - this.chart_title + - '" because it is not compatible with live updates.' - ); + console.warn('Cannot enable dataset sorting for "' + chart.chart_title + '" because it is not compatible with live updates.'); } else if (options.sort_datasets !== undefined) { - this.options.sort_datasets = options.sort_datasets; + the_options.sort_datasets = options.sort_datasets; } if (options.history_length !== undefined) { - this.options.history_length = options.history_length; + the_options.history_length = options.history_length; } if (options.x_min !== undefined) { - this.options.x.min = options.x_min; + the_options.x.min = options.x_min; } if (options.x_max !== undefined) { - this.options.x.max = options.x_max; + the_options.x.max = options.x_max; } if (options.y_min !== undefined) { - this.options.y.min = options.y_min; + the_options.y.min = options.y_min; } if (options.y_max !== undefined) { - this.options.y.max = options.y_max; + the_options.y.max = options.y_max; } if (options.threshold !== undefined) { - this.options.hide_dataset_threshold = options.threshold; + the_options.hide_dataset_threshold = options.threshold; } - if ( - !this.stacked && - options.scatterplot !== undefined && - options.scatterplot - ) { - this.options.scatterplot = true; + if (!chart.stacked && + options.scatterplot !== undefined && + options.scatterplot) { + the_options.scatterplot = true; } if (jschart_override_options.threshold !== undefined) { - this.options.hide_dataset_threshold = jschart_override_options.threshold; + the_options.hide_dataset_threshold = jschart_override_options.threshold; } + + return the_options; } function compute_stacked_median(chart) { @@ -3415,23 +3415,7 @@ function build_chart(chart) { } function load_datasets(chart) { - var x_domain = chart.x.scale.chart.domain(); - var y_domain = chart.y.scale.chart.domain(); - - chart.chart.loading = chart.chart.container - .append("text") - .classed("loadinglabel middletext", true) - .attr( - "x", - (chart.x.scale.chart(x_domain[1]) - chart.x.scale.chart(x_domain[0])) / 2 - ) - .attr( - "y", - (chart.y.scale.chart(y_domain[0]) - chart.y.scale.chart(y_domain[1])) / - 2 + - 35 - ) - .text("Loading"); + var queued_datasets = 0; if (chart.options.csvfiles) { // this path can have no parallelism since it is unknown how @@ -3439,6 +3423,8 @@ function load_datasets(chart) { chart.datasets_queue = d3_queue.queue(1); for (var i = 0; i < chart.options.csvfiles.length; i++) { + queued_datasets++; + // add a dataset load to the queue chart.datasets_queue.defer( load_csv_files, @@ -3452,11 +3438,15 @@ function load_datasets(chart) { chart.datasets_queue = d3_queue.queue(512); if (chart.options.packed && chart.options.plotfile) { + queued_datasets++; + // add a packed dataset load to the queue chart.datasets_queue.defer(load_plot_file, chart.options.plotfile, chart); } else { if (chart.options.plotfiles) { for (var i = 0; i < chart.options.plotfiles.length; i++) { + queued_datasets++; + // add a dataset load to the queue chart.datasets_queue.defer( load_plot_files, @@ -3467,12 +3457,37 @@ function load_datasets(chart) { } } else { if (chart.options.json_plotfile || chart.options.json_object) { + queued_datasets++; + chart.datasets_queue.defer(load_json, chart); } } } } + if (queued_datasets == 0) { + console.warn("No datasets loaded for chart '" + chart.chart_title + "'.") + return; + } + + var x_domain = chart.x.scale.chart.domain(); + var y_domain = chart.y.scale.chart.domain(); + + chart.chart.loading = chart.chart.container + .append("text") + .classed("loadinglabel middletext", true) + .attr( + "x", + (chart.x.scale.chart(x_domain[1]) - chart.x.scale.chart(x_domain[0])) / 2 + ) + .attr( + "y", + (chart.y.scale.chart(y_domain[0]) - chart.y.scale.chart(y_domain[1])) / + 2 + + 35 + ) + .text("Loading"); + console.log('Waiting for content to load for chart "' + chart.chart_title + '".'); // block waiting for the queue processing to complete before completing the chart @@ -5183,19 +5198,31 @@ function display_help() { } function reset_chart(chart) { + if (chart.state.reset) { + return; + } + console.warn("resetting chart '" + chart.chart_title + "'."); - chart.chart.cursor_points.remove(); - chart.chart.cursor_points = null; + if (chart.chart.cursor_points) { + chart.chart.cursor_points.remove(); + chart.chart.cursor_points = null; + } - chart.chart.legend.remove(); - chart.chart.legend = null; + if (chart.chart.legend) { + chart.chart.legend.remove(); + chart.chart.legend = null; + } - chart.chart.plot.remove(); - chart.chart.plot = null; + if (chart.chart.plot) { + chart.chart.plot.remove(); + chart.chart.plot = null; + } - chart.dom.table.data_rows.remove(); - chart.dom.table.data_rows = null; + if (chart.dom.table.data_rows) { + chart.dom.table.data_rows.remove(); + chart.dom.table.data_rows = null; + } for (var i = chart.datasets.all.length - 1; i >= 0; i--) { if (chart.options.scatterplot) { @@ -5240,3 +5267,30 @@ function reload_chart(chart) { chart.state.reset = false; } + +exports.chart_reload = function(location, options) { + console.log("Attempting to reload chart at location '" + location + "'."); + + var chart = null; + for (var i = 0; i < charts.length; i++) { + if (charts[i].location == location) { + chart = charts[charts[i].charts_index]; + break; + } + } + + if (!chart) { + console.error("Could not locate chart at location '" + location + "'."); + return; + } + + console.log("Reloading chart '" + chart.chart_title + "' at location '" + chart.location + "'."); + + reset_chart(chart); + + chart.options = setup_chart_options(chart, options); + + load_datasets(chart); + + chart.state.reset = false; +} From 65ed830dadbf41a8f93537bc1172a81e8bac9a0f Mon Sep 17 00:00:00 2001 From: Karl Rister Date: Fri, 10 May 2019 15:16:57 +0000 Subject: [PATCH 06/13] App.js: expand the capabilities of the dynamic chart demo - The user can now alternate between multiple loaded dataset configurations on the same chart via a drop down selection. --- tests/src/App.js | 54 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/tests/src/App.js b/tests/src/App.js index 478046a..cf2fc88 100644 --- a/tests/src/App.js +++ b/tests/src/App.js @@ -6,8 +6,51 @@ import timeseries_data from './data/timeseries.csv'; import xy_data from './data/xy.csv'; import jitter_data from './data/jitter.csv'; +const d3 = require("d3"); + +var choices = [ + { + "label": "Null", + "object": { } + }, + { + "label": "Histogram", + "object": { csvfiles: [ histogram_data ] } + }, + { + "label": "Jitter", + "object": { csvfiles: [ jitter_data ] } + }, + { + "label": "Jitter - Scatter", + "object": { csvfiles: [ jitter_data ], scatterplot: true } + } +]; +for (var i = 0; i < choices.length; i++) { + choices[i].index = i; +} + +function change_selection() { + jschart.chart_reload("jschart_dynamic", choices[this.value].object); +} + +function setup_dynamic_chart_selection_box() { + var myselect = d3.select("#select_dataset") + .append("select") + .on("change", change_selection) + + myselect.selectAll(".options") + .data(choices) + .enter() + .append("option") + .attr("value", function(d) { return d.index; }) + .text(function(d) { return d.label; }); +} + class App extends Component { componentDidMount = () => { + setup_dynamic_chart_selection_box(); + jschart.create_jschart( 0, "timeseries", @@ -16,7 +59,6 @@ class App extends Component { "Time (secs.)", null, { - csvfiles: [ timeseries_data ], dynamic_chart: true } ); @@ -102,12 +144,20 @@ class App extends Component {

JSChart Demos



-
+
+

+ Dynamic Chart Dataset Selection: +

+
+
+
+
+
); From 14eaf6c68d74b1143f6f93361a6470cbbe756f94 Mon Sep 17 00:00:00 2001 From: Karl Rister Date: Fri, 10 May 2019 18:32:42 +0000 Subject: [PATCH 07/13] index.js: bugfix for maintaing proper legend column count with dynamic charts --- jschart/index.js | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/jschart/index.js b/jschart/index.js index 22ea90e..6886fc5 100644 --- a/jschart/index.js +++ b/jschart/index.js @@ -212,7 +212,8 @@ function chart( view_port_table_controls_visible: true, misc_controls_table_controls_visible: true, custom_domain: false, - reset: false + reset: false, + legend_columns: 5 }; this.functions = { area: null, stack: null, line: null }; @@ -226,7 +227,7 @@ function chart( this.dimensions = { margin: { top: 70, right: 87, bottom: 66, left: 65 }, - legend_properties: { columns: 5, row_height: 30, margin: { top: 37 } }, + legend_properties: { row_height: 30, margin: { top: 37 } }, total_width: 1000, total_height: 510, pixels_per_letter: 7.2 @@ -1557,8 +1558,8 @@ function navigate_to_chart(target) { function create_chart_dataset_objects(chart) { update_domains(chart); - if (chart.datasets.all.length < chart.dimensions.legend_properties.columns) { - chart.dimensions.legend_properties.columns = chart.datasets.all.length; + if (chart.datasets.all.length < chart.state.legend_columns) { + chart.state.legend_columns = chart.datasets.all.length; } chart.chart.legend = chart.chart.container @@ -1572,13 +1573,13 @@ function create_chart_dataset_objects(chart) { "translate(" + (-chart.dimensions.margin.left + 5 + - (i % chart.dimensions.legend_properties.columns) * + (i % chart.state.legend_columns) * (chart.dimensions.total_width / - chart.dimensions.legend_properties.columns)) + + chart.state.legend_columns)) + "," + (chart.dimensions.viewport_height + chart.dimensions.legend_properties.margin.top + - Math.floor(i / chart.dimensions.legend_properties.columns) * + Math.floor(i / chart.state.legend_columns) * chart.dimensions.legend_properties.row_height) + ")" ); @@ -1640,7 +1641,7 @@ function create_chart_dataset_objects(chart) { if ( label_width >= chart.dimensions.total_width / - chart.dimensions.legend_properties.columns - + chart.state.legend_columns - legend_label_offset ) { var label = d3.select(this); @@ -1668,7 +1669,7 @@ function create_chart_dataset_objects(chart) { chart.dimensions.legend_properties.margin.top + (Math.floor( chart.datasets.all.length / - chart.dimensions.legend_properties.columns + chart.state.legend_columns ) + i) * chart.dimensions.legend_properties.row_height) + @@ -5238,6 +5239,9 @@ function reset_chart(chart) { chart.datasets.all.pop(); } + chart.state.visible_datasets = 0; + chart.state.legend_columns = 5; + chart.dataset_count = 0; reset_axes_domains(chart); @@ -5251,7 +5255,7 @@ function get_svg_height(chart) { return chart.dimensions.viewport_height + chart.dimensions.margin.top + chart.dimensions.margin.bottom + - ( Math.ceil(chart.datasets.all.length / chart.dimensions.legend_properties.columns) - + ( Math.ceil(chart.datasets.all.length / chart.state.legend_columns) - 1 + chart.options.legend_entries.length ) * chart.dimensions.legend_properties.row_height; } From fac494c16afdf63d099d027a3e748603df317c38 Mon Sep 17 00:00:00 2001 From: Karl Rister Date: Fri, 10 May 2019 19:22:55 +0000 Subject: [PATCH 08/13] App.js: clean up the dynamic chart demo --- tests/src/App.js | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/tests/src/App.js b/tests/src/App.js index cf2fc88..5e990b2 100644 --- a/tests/src/App.js +++ b/tests/src/App.js @@ -13,10 +13,6 @@ var choices = [ "label": "Null", "object": { } }, - { - "label": "Histogram", - "object": { csvfiles: [ histogram_data ] } - }, { "label": "Jitter", "object": { csvfiles: [ jitter_data ] } @@ -53,11 +49,11 @@ class App extends Component { jschart.create_jschart( 0, - "timeseries", + "xy", "jschart_dynamic", "Dynamic Chart Demo", - "Time (secs.)", - null, + "Samples", + "Latency (ns)", { dynamic_chart: true } From 6328cc4dc2fcd6130820df970c97d7b53b3e221e Mon Sep 17 00:00:00 2001 From: Karl Rister Date: Mon, 20 May 2019 18:04:11 +0000 Subject: [PATCH 09/13] App.js: add specific datasets for Dynamic Chart Demo --- tests/src/App.js | 10 ++-- tests/src/data/ts1.csv | 120 +++++++++++++++++++++++++++++++++++++++++ tests/src/data/ts2.csv | 120 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 246 insertions(+), 4 deletions(-) create mode 100644 tests/src/data/ts1.csv create mode 100644 tests/src/data/ts2.csv diff --git a/tests/src/App.js b/tests/src/App.js index 5e990b2..e912534 100644 --- a/tests/src/App.js +++ b/tests/src/App.js @@ -5,6 +5,8 @@ import histogram_data from './data/histogram.csv'; import timeseries_data from './data/timeseries.csv'; import xy_data from './data/xy.csv'; import jitter_data from './data/jitter.csv'; +import dynamic_data_1 from './data/ts1.csv'; +import dynamic_data_2 from './data/ts2.csv'; const d3 = require("d3"); @@ -14,12 +16,12 @@ var choices = [ "object": { } }, { - "label": "Jitter", - "object": { csvfiles: [ jitter_data ] } + "label": "Dataset 1", + "object": { csvfiles: [ dynamic_data_1 ] } }, { - "label": "Jitter - Scatter", - "object": { csvfiles: [ jitter_data ], scatterplot: true } + "label": "Dataset 2", + "object": { csvfiles: [ dynamic_data_2 ] } } ]; for (var i = 0; i < choices.length; i++) { diff --git a/tests/src/data/ts1.csv b/tests/src/data/ts1.csv new file mode 100644 index 0000000..7054274 --- /dev/null +++ b/tests/src/data/ts1.csv @@ -0,0 +1,120 @@ +timestamp_ms,all,localhost-1,localhost-2 +1000,2545,2406,2684 +2000,2506.5,2381,2632 +3000,2482,2401,2563 +4000,2522,2433,2611 +5000,2544,2394,2694 +6000,2548.5,2377,2720 +7000,2567,2387,2747 +8000,2643,2429,2857 +9000,2634.5,2427,2842 +10000,2621.5,2445,2798 +11000,2559.5,2469,2650 +12000,2564.5,2469,2660 +13000,2610.5,2467,2754 +14000,2645.5,2459,2832 +15000,2656,2471,2841 +16000,2659.5,2473,2846 +17000,2654,2465,2843 +18000,2630.5,2466,2795 +19000,2526.5,2419,2634 +20000,2521,2394,2648 +21000,2538.5,2444,2633 +22000,2614,2470,2758 +23000,2603,2466,2740 +24000,2606,2454,2758 +25000,2634,2467,2801 +26000,2667,2469,2865 +27000,2647.5,2466,2829 +28000,2575.5,2464,2687 +29000,2573,2454,2692 +30000,2577.5,2418,2737 +31000,2585,2407,2763 +32000,2568,2435,2701 +33000,2581.5,2461,2702 +34000,2614,2498,2730 +35000,2615,2464,2766 +36000,2642.5,2471,2814 +37000,2664,2477,2851 +38000,2660,2461,2859 +39000,2660.5,2463,2858 +40000,2631.5,2474,2789 +41000,2616.5,2468,2765 +42000,2621.5,2477,2766 +43000,2619.5,2479,2760 +44000,2577.5,2438,2717 +45000,2572.5,2436,2709 +46000,2558,2419,2697 +47000,2531.5,2416,2647 +48000,2553.5,2469,2638 +49000,2627.5,2474,2781 +50000,2642,2442,2842 +51000,2647,2448,2846 +52000,2646,2441,2851 +53000,2612,2435,2789 +54000,2578,2452,2704 +55000,2597,2469,2725 +56000,2666.5,2475,2858 +57000,2671.5,2474,2869 +58000,2668.5,2481,2856 +59000,2666.5,2473,2860 +60000,2664.5,2468,2861 +61000,2659.5,2471,2848 +62000,2652.5,2467,2838 +63000,2657.5,2477,2838 +64000,2650,2484,2816 +65000,2565,2471,2659 +66000,2567.5,2477,2658 +67000,2591,2478,2704 +68000,2658.5,2461,2856 +69000,2665.5,2462,2869 +70000,2644,2460,2828 +71000,2522,2425,2619 +72000,2535,2458,2612 +73000,2587,2476,2698 +74000,2583.5,2471,2696 +75000,2614.5,2468,2761 +76000,2664.5,2478,2851 +77000,2669,2476,2862 +78000,2626,2475,2777 +79000,2563,2425,2701 +80000,2563.5,2426,2701 +81000,2624.5,2431,2818 +82000,2653,2461,2845 +83000,2658.5,2469,2848 +84000,2659,2474,2844 +85000,2633.5,2496,2771 +86000,2622.5,2470,2775 +87000,2628,2478,2778 +88000,2672,2487,2857 +89000,2665,2472,2858 +90000,2664.5,2479,2850 +91000,2645,2458,2832 +92000,2601,2432,2770 +93000,2620.5,2441,2800 +94000,2614,2455,2773 +95000,2598,2450,2746 +96000,2587,2425,2749 +97000,2611.5,2446,2777 +98000,2667,2464,2870 +99000,2653.5,2442,2865 +100000,2664.5,2471,2858 +101000,2666.5,2470,2863 +102000,2665.5,2477,2854 +103000,2669.5,2485,2854 +104000,2669,2475,2863 +105000,2686,2481,2891 +106000,2667.5,2488,2847 +107000,2657.5,2464,2851 +108000,2657,2463,2851 +109000,2639.5,2443,2836 +110000,2612,2411,2813 +111000,2646.5,2440,2853 +112000,2648.5,2445,2852 +113000,2642.5,2443,2842 +114000,2668,2470,2866 +115000,2666.5,2479,2854 +116000,2644.5,2415,2874 +117000,2648,2419,2877 +118000,2643,2436,2850 +119000,2609,2471,2747 diff --git a/tests/src/data/ts2.csv b/tests/src/data/ts2.csv new file mode 100644 index 0000000..d037fc5 --- /dev/null +++ b/tests/src/data/ts2.csv @@ -0,0 +1,120 @@ +timestamp_ms,all,localhost-1,localhost-2 +1000,3234.5,3192,3277 +2000,3231,3199,3263 +3000,3229.5,3199,3260 +4000,3246,3202,3290 +5000,3242.5,3199,3286 +6000,3238,3198,3278 +7000,3232.5,3190,3275 +8000,3226,3194,3258 +9000,3226.5,3186,3267 +10000,3230,3195,3265 +11000,3231.5,3192,3271 +12000,3230.5,3194,3267 +13000,3245.5,3206,3285 +14000,3244.5,3198,3291 +15000,3246.5,3205,3288 +16000,3247.5,3206,3289 +17000,3230,3185,3275 +18000,3237.5,3197,3278 +19000,3250,3213,3287 +20000,3242,3195,3289 +21000,3246.5,3205,3288 +22000,3248,3205,3291 +23000,3225.5,3187,3264 +24000,3225.5,3192,3259 +25000,3243.5,3203,3284 +26000,3247,3205,3289 +27000,3241.5,3211,3272 +28000,3239.5,3210,3269 +29000,3232.5,3193,3272 +30000,3233,3196,3270 +31000,3232.5,3192,3273 +32000,3223.5,3186,3261 +33000,3235,3202,3268 +34000,3235.5,3207,3264 +35000,3232,3200,3264 +36000,3231.5,3196,3267 +37000,3239.5,3199,3280 +38000,3243.5,3197,3290 +39000,3246,3209,3283 +40000,3250,3209,3291 +41000,3231.5,3190,3273 +42000,3235.5,3194,3277 +43000,3234,3188,3280 +44000,3224,3180,3268 +45000,3228,3183,3273 +46000,3235.5,3192,3279 +47000,3226,3193,3259 +48000,3230.5,3196,3265 +49000,3238,3201,3275 +50000,3237.5,3195,3280 +51000,3233.5,3195,3272 +52000,3245.5,3194,3297 +53000,3236.5,3184,3289 +54000,3240,3203,3277 +55000,3233.5,3204,3263 +56000,3220.5,3186,3255 +57000,3229.5,3194,3265 +58000,3247,3205,3289 +59000,3240.5,3192,3289 +60000,3243,3189,3297 +61000,3240,3192,3288 +62000,3225.5,3184,3267 +63000,3224.5,3177,3272 +64000,3231.5,3187,3276 +65000,3225.5,3191,3260 +66000,3231,3199,3263 +67000,3235.5,3206,3265 +68000,3228.5,3184,3273 +69000,3226,3185,3267 +70000,3236.5,3194,3279 +71000,3221,3184,3258 +72000,3224.5,3193,3256 +73000,3253,3205,3301 +74000,3262,3202,3322 +75000,3260,3194,3326 +76000,3263,3198,3328 +77000,3230,3195,3265 +78000,3230,3197,3263 +79000,3236,3202,3270 +80000,3227.5,3205,3250 +81000,3234.5,3209,3260 +82000,3233.5,3197,3270 +83000,3221,3184,3258 +84000,3222.5,3184,3261 +85000,3234.5,3199,3270 +86000,3233.5,3203,3264 +87000,3230.5,3205,3256 +88000,3241,3214,3268 +89000,3231,3186,3276 +90000,3240.5,3197,3284 +91000,3256,3200,3312 +92000,3263,3193,3333 +93000,3251.5,3204,3299 +94000,3243.5,3205,3282 +95000,3239,3260,3218 +96000,3236,3291,3181 +97000,3257,3290,3224 +98000,3259.5,3279,3240 +99000,3242,3279,3205 +100000,3235,3278,3192 +101000,3232,3281,3183 +102000,3225,3275,3175 +103000,3235,3277,3193 +104000,3238.5,3281,3196 +105000,3236,3279,3193 +106000,3244.5,3296,3193 +107000,3227.5,3273,3182 +108000,3231.5,3285,3178 +109000,3249.5,3280,3219 +110000,3254.5,3271,3238 +111000,3263,3279,3247 +112000,3253,3275,3231 +113000,3241,3283,3199 +114000,3239.5,3289,3190 +115000,3239.5,3291,3188 +116000,3228,3278,3178 +117000,3226,3275,3177 +118000,3238,3285,3191 +119000,3233,3283,3183 From 106a7b3e6c1c9af79d8e3758c863d5e7276ef50d Mon Sep 17 00:00:00 2001 From: Karl Rister Date: Mon, 20 May 2019 18:09:28 +0000 Subject: [PATCH 10/13] index.js: bugfix for dataset highlighting behavior with dynamic charts --- jschart/index.js | 1 + tests/src/App.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/jschart/index.js b/jschart/index.js index 6886fc5..e911dde 100644 --- a/jschart/index.js +++ b/jschart/index.js @@ -5241,6 +5241,7 @@ function reset_chart(chart) { chart.state.visible_datasets = 0; chart.state.legend_columns = 5; + chart.state.chart_selection = -1; chart.dataset_count = 0; diff --git a/tests/src/App.js b/tests/src/App.js index e912534..a20f8bf 100644 --- a/tests/src/App.js +++ b/tests/src/App.js @@ -55,7 +55,7 @@ class App extends Component { "jschart_dynamic", "Dynamic Chart Demo", "Samples", - "Latency (ns)", + "Latency (ms)", { dynamic_chart: true } From 1dd87a68cce43dd725813fd45136fba6bd74e26b Mon Sep 17 00:00:00 2001 From: Karl Rister Date: Mon, 20 May 2019 18:16:14 +0000 Subject: [PATCH 11/13] index.js: update console messages for chart reload/reset --- jschart/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jschart/index.js b/jschart/index.js index e911dde..8142b57 100644 --- a/jschart/index.js +++ b/jschart/index.js @@ -5203,7 +5203,7 @@ function reset_chart(chart) { return; } - console.warn("resetting chart '" + chart.chart_title + "'."); + console.log("Resetting chart '" + chart.chart_title + "'."); if (chart.chart.cursor_points) { chart.chart.cursor_points.remove(); @@ -5266,7 +5266,7 @@ function reload_chart(chart) { reset_chart(chart); } - console.warn("reloading chart '" + chart.chart_title + "'."); + console.log("Reloading chart '" + chart.chart_title + "'."); load_datasets(chart); From 9bfdebc5ceb30f298a1744313cdc827f01413e66 Mon Sep 17 00:00:00 2001 From: Karl Rister Date: Tue, 21 May 2019 22:10:35 +0000 Subject: [PATCH 12/13] update d3 dependency handling in demo app --- tests/package.json | 1 + tests/src/App.js | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/package.json b/tests/package.json index 469b73b..9899ca1 100644 --- a/tests/package.json +++ b/tests/package.json @@ -5,6 +5,7 @@ "license": "EPL-1.0", "dependencies": { "axios": "^0.18.0", + "d3": "3.5.17", "jschart": "file:../jschart", "react": "^16.5.1", "react-dom": "^16.5.1", diff --git a/tests/src/App.js b/tests/src/App.js index a20f8bf..815a2e7 100644 --- a/tests/src/App.js +++ b/tests/src/App.js @@ -1,5 +1,6 @@ import React, { Component } from "react"; import jschart from "jschart"; +import d3 from "d3"; import histogram_data from './data/histogram.csv'; import timeseries_data from './data/timeseries.csv'; @@ -8,8 +9,6 @@ import jitter_data from './data/jitter.csv'; import dynamic_data_1 from './data/ts1.csv'; import dynamic_data_2 from './data/ts2.csv'; -const d3 = require("d3"); - var choices = [ { "label": "Null", From c754a64be3c377a1fa3159b4383cc6647f5df258 Mon Sep 17 00:00:00 2001 From: Karl Rister Date: Tue, 21 May 2019 22:13:10 +0000 Subject: [PATCH 13/13] bump version numbers --- jschart/package.json | 2 +- tests/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jschart/package.json b/jschart/package.json index 2927ce8..f74da1d 100644 --- a/jschart/package.json +++ b/jschart/package.json @@ -1,6 +1,6 @@ { "name": "jschart", - "version": "1.0.6", + "version": "1.0.7", "description": "This is a Javascript library that renders SVG charts.", "keywords": [ "chart", diff --git a/tests/package.json b/tests/package.json index 9899ca1..7ee4f09 100644 --- a/tests/package.json +++ b/tests/package.json @@ -1,6 +1,6 @@ { "name": "jschart_test", - "version": "0.1.0", + "version": "0.2.0", "private": true, "license": "EPL-1.0", "dependencies": {