diff --git a/Chart/AreaChart.js b/Chart/AreaChart.js new file mode 100644 index 0000000..6f6f831 --- /dev/null +++ b/Chart/AreaChart.js @@ -0,0 +1,25 @@ +(function (jsOMS) +{ + "use strict"; + + jsOMS.Chart.AreaChart = function (id) + { + this.chart = new jsOMS.Chart.LineChart(id); + this.chart.getChart().subtype = 'area'; + }; + + jsOMS.Chart.AreaChart.prototype.getChart = function () + { + return this.chart.getChart(); + }; + + jsOMS.Chart.AreaChart.prototype.setData = function (data) + { + this.chart.setData(data); + }; + + jsOMS.Chart.AreaChart.prototype.draw = function () + { + return this.chart.draw(); + }; +}(window.jsOMS = window.jsOMS || {})); diff --git a/Chart/StackedChart.js b/Chart/BoxplotChart.js similarity index 100% rename from Chart/StackedChart.js rename to Chart/BoxplotChart.js diff --git a/Chart/CalendarChart.js b/Chart/CalendarChart.js new file mode 100644 index 0000000..e69de29 diff --git a/Chart/CandlestickChart.js b/Chart/CandlestickChart.js new file mode 100644 index 0000000..e69de29 diff --git a/Chart/Chart.js b/Chart/ChartAbstract.js similarity index 86% rename from Chart/Chart.js rename to Chart/ChartAbstract.js index 3074766..1a9738b 100644 --- a/Chart/Chart.js +++ b/Chart/ChartAbstract.js @@ -1,8 +1,11 @@ (function (jsOMS) { "use strict"; + + /** @namespace jsOMS.Chart */ + jsOMS.Autoloader.defineNamespace('jsOMS.Chart'); - jsOMS.Chart = function (id) + jsOMS.Chart.ChartAbstract = function (id) { this.chartId = id; this.chartSelect = d3.select('#' + this.chartId); @@ -59,7 +62,7 @@ this.clean(); }; - jsOMS.Chart.prototype.calculateHorizontalPosition = function (position) + jsOMS.Chart.ChartAbstract.prototype.calculateHorizontalPosition = function (position) { let x = 0; if (position === 'center') { @@ -77,7 +80,7 @@ return x; }; - jsOMS.Chart.prototype.calculateVerticalPosition = function (position) + jsOMS.Chart.ChartAbstract.prototype.calculateVerticalPosition = function (position) { let y = 0; if (position === 'center') { @@ -97,17 +100,17 @@ return y; }; - jsOMS.Chart.prototype.setColor = function (color) + jsOMS.Chart.ChartAbstract.prototype.setColor = function (color) { this.color = color; }; - jsOMS.Chart.prototype.getColor = function () + jsOMS.Chart.ChartAbstract.prototype.getColor = function () { return this.color; }; - jsOMS.Chart.prototype.setAxis = function (id, axis) + jsOMS.Chart.ChartAbstract.prototype.setAxis = function (id, axis) { this.axis[id] = jsOMS.merge(this.axis[id], axis); @@ -123,95 +126,95 @@ } }; - jsOMS.Chart.prototype.setMargin = function (top, right, bottom, left) + jsOMS.Chart.ChartAbstract.prototype.setMargin = function (top, right, bottom, left) { this.margin = {top: top, right: right, bottom: bottom, left: left}; }; - jsOMS.Chart.prototype.setDimension = function (width, height) + jsOMS.Chart.ChartAbstract.prototype.setDimension = function (width, height) { this.dimension = {width: width, height: height}; }; - jsOMS.Chart.prototype.getDimension = function () + jsOMS.Chart.ChartAbstract.prototype.getDimension = function () { return this.dimension; }; - jsOMS.Chart.prototype.setDimensionRelative = function (relative) + jsOMS.Chart.ChartAbstract.prototype.setDimensionRelative = function (relative) { this.relative = relative; }; - jsOMS.Chart.prototype.setTitle = function (title) + jsOMS.Chart.ChartAbstract.prototype.setTitle = function (title) { this.title = jsOMS.merge(this.title, title); }; - jsOMS.Chart.prototype.getTitle = function () + jsOMS.Chart.ChartAbstract.prototype.getTitle = function () { return this.title; }; - jsOMS.Chart.prototype.setSubtitle = function (subtitle) + jsOMS.Chart.ChartAbstract.prototype.setSubtitle = function (subtitle) { this.subtitle = subtitle; }; - jsOMS.Chart.prototype.getSubtitle = function () + jsOMS.Chart.ChartAbstract.prototype.getSubtitle = function () { return this.subtitle; }; - jsOMS.Chart.prototype.setFooter = function (footer) + jsOMS.Chart.ChartAbstract.prototype.setFooter = function (footer) { this.footer = footer; }; - jsOMS.Chart.prototype.getFooter = function () + jsOMS.Chart.ChartAbstract.prototype.getFooter = function () { return this.footer; }; - jsOMS.Chart.prototype.setSubtype = function (subtype) + jsOMS.Chart.ChartAbstract.prototype.setSubtype = function (subtype) { this.subtype = subtype; }; - jsOMS.Chart.prototype.getSubtype = function () + jsOMS.Chart.ChartAbstract.prototype.getSubtype = function () { return this.subtype; }; - jsOMS.Chart.prototype.setLegend = function (legend) + jsOMS.Chart.ChartAbstract.prototype.setLegend = function (legend) { this.legend = jsOMS.merge(this.legend, legend); }; - jsOMS.Chart.prototype.getLegend = function () + jsOMS.Chart.ChartAbstract.prototype.getLegend = function () { if (!this.legend) { - this.legend = new jsOMS.ChartLegend(); + this.legend = new jsOMS.Chart.ChartAbstractLegend(); } return this.legend; }; - jsOMS.Chart.prototype.addDataset = function (dataset) + jsOMS.Chart.ChartAbstract.prototype.addDataset = function (dataset) { this.dataset.push(dataset); this.findAxisDomain(); }; - jsOMS.Chart.prototype.setData = function (data) + jsOMS.Chart.ChartAbstract.prototype.setData = function (data) { this.dataset = data; this.findAxisDomain(); }; - jsOMS.Chart.prototype.findAxisDomain = function () + jsOMS.Chart.ChartAbstract.prototype.findAxisDomain = function () { for (let id in this.axis) { this.axis[id].max = d3.max(this.dataset, function (m) @@ -232,12 +235,12 @@ } }; - jsOMS.Chart.prototype.getData = function () + jsOMS.Chart.ChartAbstract.prototype.getData = function () { return this.dataset; }; - jsOMS.Chart.prototype.drawLegend = function (svg, dataPointEnter, dataPoint) + jsOMS.Chart.ChartAbstract.prototype.drawLegend = function (svg, dataPointEnter, dataPoint) { let self = this; @@ -281,7 +284,7 @@ } }; - jsOMS.Chart.prototype.drawMarker = function (svg, x, y, dataPointEnter, dataPoint) + jsOMS.Chart.ChartAbstract.prototype.drawMarker = function (svg, x, y, dataPointEnter, dataPoint) { let self = this, temp; @@ -329,7 +332,7 @@ } }; - jsOMS.Chart.prototype.drawText = function (svg) + jsOMS.Chart.ChartAbstract.prototype.drawText = function (svg) { let temp, pos = 0, topmargin = 0; @@ -402,7 +405,7 @@ } }; - jsOMS.Chart.prototype.drawAxis = function (svg, xAxis1, yAxis1) + jsOMS.Chart.ChartAbstract.prototype.drawAxis = function (svg, xAxis1, yAxis1) { // draw clipper let defs = svg.append('svg').attr('width', 0).attr('height', 0).append('defs'), pos = 0, temp; @@ -478,7 +481,7 @@ } }; - jsOMS.Chart.prototype.drawGrid = function (svg, xGrid, yGrid) + jsOMS.Chart.ChartAbstract.prototype.drawGrid = function (svg, xGrid, yGrid) { if (this.grid.x !== undefined && this.grid.x.visible) { svg.append("g") @@ -494,7 +497,7 @@ } }; - jsOMS.Chart.prototype.clean = function () + jsOMS.Chart.ChartAbstract.prototype.clean = function () { this.margin = {top: 0, right: 0, bottom: 0, left: 0}; this.dimension = {width: 0, height: 0}; diff --git a/Chart/ColumnChart.js b/Chart/ColumnChart.js index 2c01c05..03214fd 100644 --- a/Chart/ColumnChart.js +++ b/Chart/ColumnChart.js @@ -4,7 +4,7 @@ jsOMS.Chart.ColumnChart = function (id) { - this.chart = new jsOMS.Chart(id); + this.chart = new jsOMS.Chart.ChartAbstract(id); // Setting default chart values this.chart.margin = {top: 5, right: 0, bottom: 0, left: 0}; @@ -62,6 +62,11 @@ return this.chart; }; + jsOMS.Chart.ColumnChart.prototype.setData = function (data) + { + this.chart.setData(data); + }; + jsOMS.Chart.ColumnChart.prototype.draw = function () { let rect, svg, x, xAxis1, xAxis2, y, yAxis1, yAxis2, xGrid, yGrid, zoom, self = this, box = this.chart.chartSelect.node().getBoundingClientRect(); @@ -288,48 +293,3 @@ .attr("width", x.rangeBand()); }; }(window.jsOMS = window.jsOMS || {})); - -var chart; - -var n = 3, // number of layers - m = 30, // number of samples per layer - stack = d3.layout.stack(), - layers = stack(d3.range(n).map(function () - { - return bumpLayer(m, .1); - })); - -function bumpLayer(n, o) -{ - function bump(a) - { - var x = 1 / (.1 + Math.random()), - y = 2 * Math.random() - .5, - z = 10 / (.1 + Math.random()); - - for (var i = 0; i < n; i++) { - var w = (i / n - y) * z; - a[i] += x * Math.exp(-w * w); - } - } - - var a = [], i; - for (i = 0; i < n; ++i) a[i] = o + o * Math.random(); - for (i = 0; i < 5; ++i) bump(a); - return a.map(function (d, i) - { - return {x: i, y: Math.max(0, d)}; - }); -} - -for (let i = 0; i < layers.length; i++) { - layers[i] = { - id: i, - name: 'Dataset ' + i, - points: layers[i] - }; -} - -var mychart = new jsOMS.Chart.ColumnChart('chart'); -mychart.getChart().setData(layers); -mychart.draw(); diff --git a/Chart/DiffAreaChart.js b/Chart/DiffAreaChart.js new file mode 100644 index 0000000..e69de29 diff --git a/Chart/DonutChart.js b/Chart/DonutChart.js index e69de29..97f8ce0 100644 --- a/Chart/DonutChart.js +++ b/Chart/DonutChart.js @@ -0,0 +1,28 @@ +(function (jsOMS) +{ + "use strict"; + + jsOMS.Chart.DonutChart = function (id) + { + this.chart = new jsOMS.Chart.PieChart(id); + + // Setting default chart values + this.chart.getChart().dataSettings.style.strokewidth = 0.3; + this.chart.getChart().subtype = 'donut'; + }; + + jsOMS.Chart.DonutChart.prototype.getChart = function () + { + return this.chart.getChart(); + }; + + jsOMS.Chart.DonutChart.prototype.setData = function (data) + { + this.chart.setData(data); + }; + + jsOMS.Chart.DonutChart.prototype.draw = function () + { + this.chart.draw(); + }; +}(window.jsOMS = window.jsOMS || {})); diff --git a/Chart/FillGougeChart.js b/Chart/FillGougeChart.js new file mode 100644 index 0000000..e69de29 diff --git a/Chart/GanttChart.js b/Chart/GanttChart.js new file mode 100644 index 0000000..e69de29 diff --git a/Chart/GougeChart.js b/Chart/GougeChart.js new file mode 100644 index 0000000..e69de29 diff --git a/Chart/GroupedColumnChart.js b/Chart/GroupedColumnChart.js new file mode 100644 index 0000000..1a26903 --- /dev/null +++ b/Chart/GroupedColumnChart.js @@ -0,0 +1,25 @@ +(function (jsOMS) +{ + "use strict"; + + jsOMS.Chart.GroupedColumnChart = function (id) + { + this.chart = new jsOMS.Chart.ColumnChart(id); + this.chart.getChart().subtype = 'grouped'; + }; + + jsOMS.Chart.GroupedColumnChart.prototype.getChart = function () + { + return this.chart.getChart(); + }; + + jsOMS.Chart.GroupedColumnChart.prototype.setData = function (data) + { + this.chart.setData(data); + }; + + jsOMS.Chart.GroupedColumnChart.prototype.draw = function () + { + this.chart.draw(); + }; +}(window.jsOMS = window.jsOMS || {})); diff --git a/Chart/LineChart.js b/Chart/LineChart.js index 321aed0..86c2888 100644 --- a/Chart/LineChart.js +++ b/Chart/LineChart.js @@ -4,7 +4,7 @@ jsOMS.Chart.LineChart = function (id) { - this.chart = new jsOMS.Chart(id); + this.chart = new jsOMS.Chart.ChartAbstract(id); // Setting default chart values this.chart.margin = {top: 5, right: 0, bottom: 0, left: 0}; @@ -61,6 +61,11 @@ return this.chart; }; + jsOMS.Chart.LineChart.prototype.setData = function (data) + { + this.chart.setData(data); + }; + jsOMS.Chart.LineChart.prototype.draw = function () { let line, svg, x, xAxis1, xAxis2, y, yAxis1, yAxis2, xGrid, yGrid, zoom, self = this, box = this.chart.chartSelect.node().getBoundingClientRect(); @@ -279,62 +284,3 @@ ).call(zoom); }; }(window.jsOMS = window.jsOMS || {})); - -var c, chart, data, dataGen, i, k, count; - -dataGen = (function () -{ - return (function (id) - { - return function () - { - var tempData, j, nums, y1Seed; - nums = Math.ceil(Math.random() * 50) + 4; - y1Seed = Math.round(Math.random() * 20); - tempData = { - id: id, - name: "Dataset " + id, - points: (function () - { - var k, ref, results, prev, counter = 0; - results = []; - for (j = k = 1, ref = nums; 1 <= ref ? k <= ref : k >= ref; j = 1 <= ref ? ++k : --k) { - if (data.length > 0) { - if (typeof data[count - 2].points !== 'undefined' && data[count - 2].points.length > counter && typeof data[count - 2].points[counter].y !== 'undefined') { - prev = data[count - 2].points[counter].y; - } else { - prev = 0; - } - } else { - prev = 0; - } - - counter++; - - results.push({ - x: j, - y: y1Seed + Math.round(Math.random() * 5), - y0: prev - }); - } - - return results; - })() - }; - id = id + 1; - return tempData; - }; - })(1); -})(); - -data = []; - -for (i = k = 1; k <= 3; i = ++k) { - count = i; - data.push(dataGen()); -} -/* -var mychart = new jsOMS.Chart.LineChart('chart'); -mychart.getChart().setData(data); -mychart.draw(); -*/ \ No newline at end of file diff --git a/Chart/PieChart.js b/Chart/PieChart.js index 92beedf..d43f334 100644 --- a/Chart/PieChart.js +++ b/Chart/PieChart.js @@ -4,12 +4,12 @@ jsOMS.Chart.PieChart = function (id) { - this.chart = new jsOMS.Chart(id); + this.chart = new jsOMS.Chart.ChartAbstract(id); // Setting default chart values this.chart.margin = {top: 5, right: 0, bottom: 0, left: 0}; this.chart.color = d3.scale.category10(); - this.chart.dataSettings.style.strokewidth = 0.3; + this.chart.dataSettings.style.strokewidth = 1; this.chart.dataSettings.style.padding = 3; this.chart.subtype = 'pie'; }; @@ -59,6 +59,11 @@ } }; + jsOMS.Chart.PieChart.prototype.setData = function (data) + { + this.chart.setData(data); + }; + jsOMS.Chart.PieChart.prototype.redraw = function () { this.chart.shouldRedraw = false; @@ -102,52 +107,3 @@ return [dataPointEnter, dataPoint]; }; }(window.jsOMS = window.jsOMS || {})); - -var c, chart, data, dataGen, i, k, count; - -dataGen = (function () -{ - return (function (id) - { - return function () - { - var tempData, j, nums, y1Seed; - nums = Math.ceil(Math.random() * 5) + 2; - y1Seed = Math.round(Math.random() * 10); - tempData = { - id: id, - name: "Dataset " + id, - points: (function () - { - var k, ref, results, prev; - results = []; - for (j = k = 1, ref = nums; 1 <= ref ? k <= ref : k >= ref; j = 1 <= ref ? ++k : --k) { - results.push({ - name: 'Name ' + j, - value: y1Seed + Math.round(Math.random() * 5), - }); - } - - return results; - })() - }; - id = id + 1; - return tempData; - }; - })(1); -})(); - -data = []; - -for (i = k = 1; k <= 1; i = ++k) { - count = i; - data.push(dataGen()); -} - -/* - -var mychart = new jsOMS.Chart.PieChart('chart'); -mychart.getChart().setData(data); -mychart.draw(); - -*/ diff --git a/Chart/PyramidChart.js b/Chart/PyramidChart.js new file mode 100644 index 0000000..6c04039 --- /dev/null +++ b/Chart/PyramidChart.js @@ -0,0 +1,200 @@ +(function (jsOMS) +{ + "use strict"; + + jsOMS.Chart.PyramidChart = function (id) + { + this.chart = new jsOMS.Chart.ChartAbstract(id); + + // Setting default chart values + this.chart.margin = {top: 5, right: 0, bottom: 0, left: 0}; + this.chart.color = d3.scale.category10(); + this.chart.axis = { + x: { + visible: true, + label: { + visible: true, + text: 'X-Axis', + position: "center", + anchor: 'middle' + }, + tick: { + prefix: '', + orientation: 'bottom', + size: 7 + }, + min: 0, + max: 0 + }, + y: { + visible: true, + label: { + visible: true, + text: 'Y-Axis', + position: 'center', + anchor: 'middle' + }, + tick: { + prefix: '', + orientation: 'bottom', + size: 7 + }, + min: 0, + max: 0 + } + }; + + this.chart.grid = { + x: { + visible: false + }, + y: { + visible: true + } + }; + this.chart.subtype = 'waterfall'; + }; + + jsOMS.Chart.PyramidChart.prototype.getChart = function () + { + return this.chart; + }; + + jsOMS.Chart.PyramidChart.prototype.setData = function (data) + { + let dataset = [{id: 1, name: 'Dataset', points: []}], + length = data.length, + add = 0; + + // todo: remove value since positive and negative can be checked by looking at the diff of y-y0 + for(let i = 0; i < length - 1; i++) { + dataset[0].points[i] = { name: data[i].name, y0: add, y: data[i].value + add }; + add += data[i].value; + } + + dataset[0].points[length - 1] = { name: data[length - 1].name, y0: 0, y: add }; + + this.chart.setData(dataset); + }; + + jsOMS.Chart.PyramidChart.prototype.draw = function () + { + let bar, svg, x, xAxis1, xAxis2, y, yAxis1, yAxis2, xGrid, yGrid, zoom, self = this, box = this.chart.chartSelect.node().getBoundingClientRect(); + + this.chart.dimension = { + width: box.width, + height: box.height + }; + + x = d3.scale.ordinal().rangeRoundBands([ + 0, + this.chart.dimension.width + - this.chart.margin.right + - this.chart.margin.left + ], 0.3); + + y = d3.scale.linear().range([ + this.chart.dimension.height + - this.chart.margin.top + - this.chart.margin.bottom, + 10 + ]); + + xAxis1 = d3.svg.axis().scale(x).tickFormat(function (d) + { + return self.chart.axis.x.tick.prefix + d; + }).orient("bottom").outerTickSize(this.chart.axis.x.tick.size) + .innerTickSize(this.chart.axis.x.tick.size).tickPadding(7); + + yAxis1 = d3.svg.axis().scale(y).tickFormat(function (d) + { + return self.chart.axis.y.tick.prefix + d; + }).orient("left").outerTickSize(this.chart.axis.y.tick.size) + .innerTickSize(this.chart.axis.y.tick.size).tickPadding(7); + + xGrid = d3.svg.axis() + .scale(x) + .orient("bottom") + //.ticks(0) + .tickSize( + -(this.chart.dimension.height + - this.chart.margin.top - 10 + - this.chart.margin.bottom), 0, 0) + .tickFormat(""); + + yGrid = d3.svg.axis() + .scale(y) + .orient("left") + //.ticks(0) + .tickSize( + -this.chart.dimension.width + + this.chart.margin.right + + this.chart.margin.left, 0, 0) + .tickFormat(""); + + x.domain(this.chart.dataset[0].points.map(function(d) { return d.name; })); + y.domain([0, d3.max(this.chart.dataset[0].points, function(d) { return d.y*1.05; })]); + + svg = this.chart.chartSelect.append("svg") + .attr("width", this.chart.dimension.width) + .attr("height", this.chart.dimension.height) + .append("g").attr("transform", "translate(" + + (this.chart.margin.left) + "," + + (this.chart.margin.top) + ")"); + + this.chart.drawGrid(svg, xGrid, yGrid); + + let dataPoint, dataPointEnter, + temp = this.drawData(svg, x, y, dataPointEnter, dataPoint); + dataPointEnter = temp[0]; + dataPoint = temp[1]; + + this.chart.drawText(svg); + this.chart.drawAxis(svg, xAxis1, yAxis1); + + if (this.chart.shouldRedraw) { + this.redraw(); + } + }; + + jsOMS.Chart.PyramidChart.prototype.redraw = function () + { + this.chart.shouldRedraw = false; + this.chart.chartSelect.select("*").remove(); + this.draw(); + }; + + jsOMS.Chart.PyramidChart.prototype.drawData = function (svg, x, y, dataPointEnter, dataPoint) + { + let self = this; + + dataPoint = svg.selectAll(".dataPoint").data(this.chart.dataset[0].points, function (c) + { + return c.name; + }); + + dataPointEnter = dataPoint.enter().append("g") + .attr("class", function(d) { return "dataPoint " + (d.y < d.y0 ? 'negative' : 'positive'); }) + .attr("transform", function(d) { return "translate(" + x(d.name) + ",0)"; }); + + dataPointEnter.append("rect") + .attr("y", function(d) { return y( Math.max(d.y0, d.y) ); }) + .attr("height", function(d) { return Math.abs( y(d.y0) - y(d.y) ); }) + .attr("width", x.rangeBand()); + + dataPointEnter.append("text") + .attr("x", x.rangeBand() / 2) + .attr("y", function(d) { return y(d.y) + 5; }) + .attr("dy", function(d) { return ((d.y < d.y0) ? '-' : '') + ".75em" }) + .text(function(d) { return d.y - d.y0; }); + + dataPointEnter.filter(function(d) { return d.class != "total" }).append("line") + .attr("class", "connector") + .attr("x1", x.rangeBand() + 5 ) + .attr("y1", function(d) { return y(d.y) } ) + .attr("x2", x.rangeBand() / ( 1 - 5) - 5 ) + .attr("y2", function(d) { return y(d.y) } ); + + return [dataPointEnter, dataPoint]; + }; +}(window.jsOMS = window.jsOMS || {})); diff --git a/Chart/ScatterplotChart.js b/Chart/ScatterplotChart.js new file mode 100644 index 0000000..428a877 --- /dev/null +++ b/Chart/ScatterplotChart.js @@ -0,0 +1,182 @@ +(function (jsOMS) +{ + "use strict"; + + jsOMS.Chart.ScatterplotChart = function (id) + { + this.chart = new jsOMS.Chart.ChartAbstract(id); + + // Setting default chart values + this.chart.margin = {top: 5, right: 0, bottom: 0, left: 0}; + this.chart.color = d3.scale.category10(); + this.chart.axis = { + x: { + visible: true, + label: { + visible: true, + text: 'X-Axis', + position: "center", + anchor: 'middle' + }, + tick: { + prefix: '', + orientation: 'bottom', + size: 7 + }, + min: 0, + max: 0 + }, + y: { + visible: true, + label: { + visible: true, + text: 'Y-Axis', + position: 'center', + anchor: 'middle' + }, + tick: { + prefix: '', + orientation: 'bottom', + size: 7 + }, + min: 0, + max: 0 + } + }; + + this.chart.grid = { + x: { + visible: true + }, + y: { + visible: true + } + }; + this.chart.subtype = 'scatterplot'; + }; + + jsOMS.Chart.ScatterplotChart.prototype.getChart = function () + { + return this.chart; + }; + + jsOMS.Chart.ScatterplotChart.prototype.setData = function (data) + { + this.chart.setData(data); + }; + + jsOMS.Chart.ScatterplotChart.prototype.draw = function () + { + let bar, svg, x, xAxis1, xAxis2, y, yAxis1, yAxis2, xGrid, yGrid, zoom, self = this, box = this.chart.chartSelect.node().getBoundingClientRect(); + + this.chart.dimension = { + width: box.width, + height: box.height + }; + + x = d3.scale.linear().range([ + 0, + this.chart.dimension.width + - this.chart.margin.right + - this.chart.margin.left + ]); + + y = d3.scale.linear().range([ + this.chart.dimension.height + - this.chart.margin.top + - this.chart.margin.bottom, + 10 + ]); + + xAxis1 = d3.svg.axis().scale(x).tickFormat(function (d) + { + return self.chart.axis.x.tick.prefix + d; + }).orient("bottom").outerTickSize(this.chart.axis.x.tick.size) + .innerTickSize(this.chart.axis.x.tick.size).tickPadding(7); + + yAxis1 = d3.svg.axis().scale(y).tickFormat(function (d) + { + return self.chart.axis.y.tick.prefix + d; + }).orient("left").outerTickSize(this.chart.axis.y.tick.size) + .innerTickSize(this.chart.axis.y.tick.size).tickPadding(7); + + xGrid = d3.svg.axis() + .scale(x) + .orient("bottom") + //.ticks(0) + .tickSize( + -(this.chart.dimension.height + - this.chart.margin.top - 10 + - this.chart.margin.bottom), 0, 0) + .tickFormat(""); + + yGrid = d3.svg.axis() + .scale(y) + .orient("left") + //.ticks(0) + .tickSize( + -this.chart.dimension.width + + this.chart.margin.right + + this.chart.margin.left, 0, 0) + .tickFormat(""); + + x.domain([this.chart.axis.x.min, this.chart.axis.x.max + 1]); + y.domain([this.chart.axis.y.min - 1, this.chart.axis.y.max + 1]); + + svg = this.chart.chartSelect.append("svg") + .attr("width", this.chart.dimension.width) + .attr("height", this.chart.dimension.height) + .append("g").attr("transform", "translate(" + + (this.chart.margin.left) + "," + + (this.chart.margin.top) + ")"); + + this.chart.drawGrid(svg, xGrid, yGrid); + + let dataPoint, dataPointEnter, + temp = this.drawData(svg, x, y, dataPointEnter, dataPoint); + dataPointEnter = temp[0]; + dataPoint = temp[1]; + + this.chart.drawLegend(svg, dataPointEnter, dataPoint); + this.chart.drawText(svg); + this.chart.drawAxis(svg, xAxis1, yAxis1); + + if (this.chart.shouldRedraw) { + this.redraw(); + } + }; + + jsOMS.Chart.ScatterplotChart.prototype.redraw = function () + { + this.chart.shouldRedraw = false; + this.chart.chartSelect.select("*").remove(); + this.draw(); + }; + + jsOMS.Chart.ScatterplotChart.prototype.drawData = function (svg, x, y, dataPointEnter, dataPoint) + { + let self = this; + + dataPoint = svg.selectAll(".dataPoint").data(this.chart.dataset, function (c) + { + return c.id; + }); + + dataPointEnter = dataPoint.enter().append("g") + .attr("class", "dataPoint") + .style("fill", function(d) { return self.chart.color(d.name); }); + + dataPointEnter.selectAll("circle") + .data(function (d) + { + return d.points; + }) + .enter().append("circle") + .attr("class", "dataPoint") + .attr("r", function(d) { return d.y0; }) + .attr("cx", function(d) { return x(d.x); }) + .attr("cy", function(d) { return y(d.y); }); + + return [dataPointEnter, dataPoint]; + }; +}(window.jsOMS = window.jsOMS || {})); diff --git a/Chart/StackedAreaChart.js b/Chart/StackedAreaChart.js new file mode 100644 index 0000000..b9c2487 --- /dev/null +++ b/Chart/StackedAreaChart.js @@ -0,0 +1,25 @@ +(function (jsOMS) +{ + "use strict"; + + jsOMS.Chart.StackedAreaChart = function (id) + { + this.chart = new jsOMS.Chart.LineChart(id); + this.chart.getChart().subtype = 'stacked'; + }; + + jsOMS.Chart.StackedAreaChart.prototype.getChart = function () + { + return this.chart.getChart(); + }; + + jsOMS.Chart.StackedAreaChart.prototype.setData = function (data) + { + this.chart.setData(data); + }; + + jsOMS.Chart.StackedAreaChart.prototype.draw = function () + { + return this.chart.draw(); + }; +}(window.jsOMS = window.jsOMS || {})); diff --git a/Chart/StackedColumnChart.js b/Chart/StackedColumnChart.js new file mode 100644 index 0000000..15ed0a0 --- /dev/null +++ b/Chart/StackedColumnChart.js @@ -0,0 +1,25 @@ +(function (jsOMS) +{ + "use strict"; + + jsOMS.Chart.StackedColumnChart = function (id) + { + this.chart = new jsOMS.Chart.ColumnChart(id); + this.chart.getChart().subtype = 'stacked'; + }; + + jsOMS.Chart.StackedColumnChart.prototype.getChart = function () + { + return this.chart.getChart(); + }; + + jsOMS.Chart.StackedColumnChart.prototype.setData = function (data) + { + this.chart.setData(data); + }; + + jsOMS.Chart.StackedColumnChart.prototype.draw = function () + { + this.chart.draw(); + }; +}(window.jsOMS = window.jsOMS || {})); diff --git a/Chart/TreeChart.js b/Chart/TreeChart.js new file mode 100644 index 0000000..e69de29 diff --git a/Chart/WaterfallChart.js b/Chart/WaterfallChart.js new file mode 100644 index 0000000..9b09f28 --- /dev/null +++ b/Chart/WaterfallChart.js @@ -0,0 +1,200 @@ +(function (jsOMS) +{ + "use strict"; + + jsOMS.Chart.WaterfallChart = function (id) + { + this.chart = new jsOMS.Chart.ChartAbstract(id); + + // Setting default chart values + this.chart.margin = {top: 5, right: 0, bottom: 0, left: 0}; + this.chart.color = d3.scale.category10(); + this.chart.axis = { + x: { + visible: true, + label: { + visible: true, + text: 'X-Axis', + position: "center", + anchor: 'middle' + }, + tick: { + prefix: '', + orientation: 'bottom', + size: 7 + }, + min: 0, + max: 0 + }, + y: { + visible: true, + label: { + visible: true, + text: 'Y-Axis', + position: 'center', + anchor: 'middle' + }, + tick: { + prefix: '', + orientation: 'bottom', + size: 7 + }, + min: 0, + max: 0 + } + }; + + this.chart.grid = { + x: { + visible: false + }, + y: { + visible: true + } + }; + this.chart.subtype = 'waterfall'; + }; + + jsOMS.Chart.WaterfallChart.prototype.getChart = function () + { + return this.chart; + }; + + jsOMS.Chart.WaterfallChart.prototype.setData = function (data) + { + let dataset = [{id: 1, name: 'Dataset', points: []}], + length = data.length, + add = 0; + + // todo: remove value since positive and negative can be checked by looking at the diff of y-y0 + for(let i = 0; i < length - 1; i++) { + dataset[0].points[i] = { name: data[i].name, y0: add, y: data[i].value + add }; + add += data[i].value; + } + + dataset[0].points[length - 1] = { name: data[length - 1].name, y0: 0, y: add }; + + this.chart.setData(dataset); + }; + + jsOMS.Chart.WaterfallChart.prototype.draw = function () + { + let bar, svg, x, xAxis1, xAxis2, y, yAxis1, yAxis2, xGrid, yGrid, zoom, self = this, box = this.chart.chartSelect.node().getBoundingClientRect(); + + this.chart.dimension = { + width: box.width, + height: box.height + }; + + x = d3.scale.ordinal().rangeRoundBands([ + 0, + this.chart.dimension.width + - this.chart.margin.right + - this.chart.margin.left + ], 0.3); + + y = d3.scale.linear().range([ + this.chart.dimension.height + - this.chart.margin.top + - this.chart.margin.bottom, + 10 + ]); + + xAxis1 = d3.svg.axis().scale(x).tickFormat(function (d) + { + return self.chart.axis.x.tick.prefix + d; + }).orient("bottom").outerTickSize(this.chart.axis.x.tick.size) + .innerTickSize(this.chart.axis.x.tick.size).tickPadding(7); + + yAxis1 = d3.svg.axis().scale(y).tickFormat(function (d) + { + return self.chart.axis.y.tick.prefix + d; + }).orient("left").outerTickSize(this.chart.axis.y.tick.size) + .innerTickSize(this.chart.axis.y.tick.size).tickPadding(7); + + xGrid = d3.svg.axis() + .scale(x) + .orient("bottom") + //.ticks(0) + .tickSize( + -(this.chart.dimension.height + - this.chart.margin.top - 10 + - this.chart.margin.bottom), 0, 0) + .tickFormat(""); + + yGrid = d3.svg.axis() + .scale(y) + .orient("left") + //.ticks(0) + .tickSize( + -this.chart.dimension.width + + this.chart.margin.right + + this.chart.margin.left, 0, 0) + .tickFormat(""); + + x.domain(this.chart.dataset[0].points.map(function(d) { return d.name; })); + y.domain([0, d3.max(this.chart.dataset[0].points, function(d) { return d.y*1.05; })]); + + svg = this.chart.chartSelect.append("svg") + .attr("width", this.chart.dimension.width) + .attr("height", this.chart.dimension.height) + .append("g").attr("transform", "translate(" + + (this.chart.margin.left) + "," + + (this.chart.margin.top) + ")"); + + this.chart.drawGrid(svg, xGrid, yGrid); + + let dataPoint, dataPointEnter, + temp = this.drawData(svg, x, y, dataPointEnter, dataPoint); + dataPointEnter = temp[0]; + dataPoint = temp[1]; + + this.chart.drawText(svg); + this.chart.drawAxis(svg, xAxis1, yAxis1); + + if (this.chart.shouldRedraw) { + this.redraw(); + } + }; + + jsOMS.Chart.WaterfallChart.prototype.redraw = function () + { + this.chart.shouldRedraw = false; + this.chart.chartSelect.select("*").remove(); + this.draw(); + }; + + jsOMS.Chart.WaterfallChart.prototype.drawData = function (svg, x, y, dataPointEnter, dataPoint) + { + let self = this; + + dataPoint = svg.selectAll(".dataPoint").data(this.chart.dataset[0].points, function (c) + { + return c.id; + }); + + dataPointEnter = dataPoint.enter().append("g") + .attr("class", function(d) { return "dataPoint " + (d.y < d.y0 ? 'negative' : 'positive'); }) + .attr("transform", function(d) { return "translate(" + x(d.name) + ",0)"; }); + + dataPointEnter.append("rect") + .attr("y", function(d) { return y( Math.max(d.y0, d.y) ); }) + .attr("height", function(d) { return Math.abs( y(d.y0) - y(d.y) ); }) + .attr("width", x.rangeBand()); + + dataPointEnter.append("text") + .attr("x", x.rangeBand() / 2) + .attr("y", function(d) { return y(d.y) + 5; }) + .attr("dy", function(d) { return ((d.y < d.y0) ? '-' : '') + ".75em" }) + .text(function(d) { return d.y - d.y0; }); + + dataPointEnter.filter(function(d) { return d.class != "total" }).append("line") + .attr("class", "connector") + .attr("x1", x.rangeBand() + 5 ) + .attr("y1", function(d) { return y(d.y) } ) + .attr("x2", x.rangeBand() / ( 1 - 5) - 5 ) + .attr("y2", function(d) { return y(d.y) } ); + + return [dataPointEnter, dataPoint]; + }; +}(window.jsOMS = window.jsOMS || {}));