openstudio-workflow 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -1
  3. data/README.md +24 -63
  4. data/lib/openstudio/extended_runner.rb +94 -0
  5. data/lib/openstudio/workflow/adapter.rb +10 -0
  6. data/lib/openstudio/workflow/adapters/mongo.rb +1 -1
  7. data/lib/openstudio/workflow/jobs/lib/apply_measures.rb +12 -17
  8. data/lib/openstudio/workflow/jobs/{run_openstudio → run_energyplus}/monthly_report.idf +8 -4
  9. data/lib/openstudio/workflow/jobs/run_energyplus/run_energyplus.rb +132 -21
  10. data/lib/openstudio/workflow/jobs/run_openstudio/run_openstudio.rb +6 -11
  11. data/lib/openstudio/workflow/jobs/run_postprocess/run_postprocess.rb +7 -6
  12. data/lib/openstudio/workflow/jobs/run_preflight/run_preflight.rb +2 -1
  13. data/lib/openstudio/workflow/jobs/run_reporting_measures/run_reporting_measures.rb +27 -148
  14. data/lib/openstudio/workflow/jobs/run_runmanager/run_runmanager.rb +31 -10
  15. data/lib/openstudio/workflow/jobs/run_xml/run_xml.rb +4 -3
  16. data/lib/openstudio/workflow/run.rb +4 -5
  17. data/lib/openstudio/workflow/version.rb +1 -1
  18. data/lib/openstudio-workflow.rb +6 -10
  19. metadata +9 -12
  20. data/lib/openstudio/workflow/jobs/run_reporting_measures/packaged_measures/README.md +0 -5
  21. data/lib/openstudio/workflow/jobs/run_reporting_measures/packaged_measures/StandardReports/measure.rb +0 -206
  22. data/lib/openstudio/workflow/jobs/run_reporting_measures/packaged_measures/StandardReports/measure.xml +0 -53
  23. data/lib/openstudio/workflow/jobs/run_reporting_measures/packaged_measures/StandardReports/resources/report.html.erb +0 -298
@@ -1,206 +0,0 @@
1
- require 'erb'
2
- require 'fileutils'
3
-
4
- # start the measure
5
- class StandardReports < OpenStudio::Ruleset::ReportingUserScript
6
- # define the name that a user will see, this method may be deprecated as
7
- # the display name in PAT comes from the name field in measure.xml
8
- def name
9
- 'Standard Reports'
10
- end
11
-
12
- # define the arguments that the user will input
13
- def arguments
14
- args = OpenStudio::Ruleset::OSArgumentVector.new
15
-
16
- args
17
- end # end the arguments method
18
-
19
- # sql_query method
20
- def sql_query(sql, report_name, query)
21
- val = 10e9
22
- result = sql.execAndReturnFirstDouble("SELECT Value FROM TabularDataWithStrings WHERE ReportName='#{report_name}' AND #{query}")
23
- unless result.empty?
24
- val = result.get
25
- end
26
- val
27
- end
28
-
29
- # define what happens when the measure is run
30
- def run(runner, user_arguments)
31
- super(runner, user_arguments)
32
-
33
- # use the built-in error checking
34
- unless runner.validateUserArguments(arguments, user_arguments)
35
- return false
36
- end
37
-
38
- os_version = OpenStudio::VersionString.new(OpenStudio.openStudioVersion)
39
- min_version_feature1 = OpenStudio::VersionString.new('1.2.3')
40
-
41
- # get the last model and sql file
42
- model = runner.lastOpenStudioModel
43
- if model.empty?
44
- runner.registerError('Cannot find last model.')
45
- return false
46
- end
47
- model = model.get
48
-
49
- sqlFile = runner.lastEnergyPlusSqlFile
50
- if sqlFile.empty?
51
- runner.registerError('Cannot find last sql file.')
52
- return false
53
- end
54
- sqlFile = sqlFile.get
55
- model.setSqlFile(sqlFile)
56
-
57
- # put data into variables, these are available in the local scope binding
58
- # building_name = model.getBuilding.name.get
59
-
60
- web_asset_path = OpenStudio.getSharedResourcesPath / OpenStudio::Path.new('web_assets')
61
-
62
- energy = "var consumption = {\n"
63
- fuel_type = ''
64
- units = ''
65
-
66
- site_energy_use = 0.0
67
- OpenStudio::EndUseFuelType.getValues.each do |fuel_type|
68
- energy << "\t\""
69
- fuel_type = OpenStudio::EndUseFuelType.new(fuel_type).valueDescription
70
- energy << OpenStudio::EndUseFuelType.new(fuel_type).valueDescription # append this to remove whitespace between words ".delete(' ')"
71
- energy << " Consumption\":{\n\t\t\"units\":"
72
- if fuel_type == 'Electricity'
73
- units = "\"kWh\""
74
- unit_str = 'kWh'
75
- else
76
- units = "\"Million Btu\""
77
- unit_str = 'MBtu'
78
- end
79
- fuel_type_aggregation = 0.0
80
- energy << units
81
- energy << ",\n\t\t\"data\":{\n\t\t\t\""
82
- OpenStudio::EndUseCategoryType.getValues.each do |category_type|
83
- fuel_and_category_aggregation = 0.0
84
- category_str = OpenStudio::EndUseCategoryType.new(category_type).valueDescription
85
- energy << category_str # append this to remove whitespace between words ".delete(' ')"
86
- energy << "\":["
87
- OpenStudio::MonthOfYear.getValues.each do |month|
88
- if month >= 1 and month <= 12
89
- if not sqlFile.energyConsumptionByMonth(OpenStudio::EndUseFuelType.new(fuel_type),
90
- OpenStudio::EndUseCategoryType.new(category_type),
91
- OpenStudio::MonthOfYear.new(month)).empty?
92
- valInJ = sqlFile.energyConsumptionByMonth(OpenStudio::EndUseFuelType.new(fuel_type),
93
- OpenStudio::EndUseCategoryType.new(category_type),
94
- OpenStudio::MonthOfYear.new(month)).get
95
- fuel_and_category_aggregation += valInJ
96
- valInUnits = OpenStudio.convert(valInJ, 'J', unit_str).get
97
- temp = sprintf '%.3f', valInUnits
98
- energy << temp.to_s
99
- energy << ','
100
- if os_version >= min_version_feature1
101
- month_str = OpenStudio::MonthOfYear.new(month).valueDescription
102
- prefix_str = OpenStudio.toUnderscoreCase("#{fuel_type}_#{category_str}_#{month_str}")
103
- runner.registerValue("#{prefix_str}_si", valInJ, 'J')
104
- runner.registerValue("#{prefix_str}_ip", valInUnits, unit_str)
105
- end
106
- else
107
- energy << '0,'
108
- end
109
- end
110
- end
111
- energy = energy[0..-2]
112
- energy << "],\n\t\t\t\""
113
- if (os_version >= min_version_feature1)
114
- prefix_str = OpenStudio.toUnderscoreCase("#{fuel_type}_#{category_str}")
115
- runner.registerValue("#{prefix_str}_si", fuel_and_category_aggregation, 'J')
116
- runner.registerValue("#{prefix_str}_ip", OpenStudio.convert(fuel_and_category_aggregation, 'J', unit_str).get, unit_str)
117
- end
118
- fuel_type_aggregation += fuel_and_category_aggregation
119
- end
120
- energy = energy[0..-7]
121
- energy << "\n\t\t}\n\t},\n"
122
- if (os_version >= min_version_feature1)
123
- runner.registerValue(OpenStudio.toUnderscoreCase("#{fuel_type}_si"), fuel_type_aggregation, 'J')
124
- runner.registerValue(OpenStudio.toUnderscoreCase("#{fuel_type}_ip"),
125
- OpenStudio.convert(fuel_type_aggregation, 'J', unit_str).get,
126
- unit_str)
127
- end
128
- site_energy_use += fuel_type_aggregation
129
- end
130
- energy = energy[0..-3]
131
- energy << "\n};\n"
132
- if (os_version >= min_version_feature1)
133
- runner.registerValue('site_energy_use_si', OpenStudio.convert(site_energy_use, 'J', 'GJ').get, 'GJ')
134
- runner.registerValue('site_energy_use_ip', OpenStudio.convert(site_energy_use, 'J', 'MBtu').get, 'MBtu')
135
-
136
- # queries that don't have API methods yet
137
- total_building_area = sql_query(sqlFile, 'AnnualBuildingUtilityPerformanceSummary', "TableName='Building Area' AND RowName='Total Building Area' AND ColumnName='Area'")
138
- runner.registerValue('total_building_area', total_building_area, 'm2')
139
-
140
- net_conditioned_building_area = sql_query(sqlFile, 'AnnualBuildingUtilityPerformanceSummary', "TableName='Building Area' AND RowName='Net Conditioned Building Area' AND ColumnName='Area'")
141
- runner.registerValue('net_conditioned_building_area', net_conditioned_building_area, 'm2')
142
-
143
- unconditioned_building_area = sql_query(sqlFile, 'AnnualBuildingUtilityPerformanceSummary', "TableName='Building Area' AND RowName='Unconditioned Building Area' AND ColumnName='Area'")
144
- runner.registerValue('unconditioned_building_area', unconditioned_building_area, 'm2')
145
-
146
- total_site_energy_eui = sql_query(sqlFile, 'AnnualBuildingUtilityPerformanceSummary', "TableName='Site and Source Energy' AND RowName='Total Site Energy' AND ColumnName='Energy Per Conditioned Building Area'")
147
- runner.registerValue('total_site_energy_eui', total_site_energy_eui, 'MJ/m2')
148
-
149
- total_source_energy_eui = sql_query(sqlFile, 'AnnualBuildingUtilityPerformanceSummary', "TableName='Site and Source Energy' AND RowName='Total Source Energy' AND ColumnName='Energy Per Conditioned Building Area'")
150
- runner.registerValue('total_source_energy_eui', total_source_energy_eui, 'MJ/m2')
151
-
152
- time_setpoint_not_met_during_occupied_heating = sql_query(sqlFile, 'AnnualBuildingUtilityPerformanceSummary', "TableName='Comfort and Setpoint Not Met Summary' AND RowName='Time Setpoint Not Met During Occupied Heating' AND ColumnName='Facility'")
153
- runner.registerValue('time_setpoint_not_met_during_occupied_heating', time_setpoint_not_met_during_occupied_heating, 'hr')
154
-
155
- time_setpoint_not_met_during_occupied_cooling = sql_query(sqlFile, 'AnnualBuildingUtilityPerformanceSummary', "TableName='Comfort and Setpoint Not Met Summary' AND RowName='Time Setpoint Not Met During Occupied Cooling' AND ColumnName='Facility'")
156
- runner.registerValue('time_setpoint_not_met_during_occupied_cooling', time_setpoint_not_met_during_occupied_cooling, 'hr')
157
-
158
- time_setpoint_not_met_during_occupied_hours = time_setpoint_not_met_during_occupied_heating + time_setpoint_not_met_during_occupied_cooling
159
- runner.registerValue('time_setpoint_not_met_during_occupied_hours', time_setpoint_not_met_during_occupied_hours, 'hr')
160
-
161
- total_life_cycle_cost = sql_query(sqlFile, 'Life-Cycle Cost Report', "TableName='Present Value by Category' AND RowName='Grand Total' AND ColumnName='Present Value'")
162
- runner.registerValue('total_life_cycle_cost', total_life_cycle_cost, '$')
163
-
164
- end
165
-
166
- # echo out our values
167
- # runner.registerInfo("This building is named #{building_name}.")
168
-
169
- # read in template
170
- html_in_path = "#{File.dirname(__FILE__)}/resources/report.html.erb"
171
- if File.exist?(html_in_path)
172
- html_in_path = html_in_path
173
- else
174
- html_in_path = "#{File.dirname(__FILE__)}/report.html.erb"
175
- end
176
-
177
- # configure template with variable values
178
- renderer = ERB.new(File.read(html_in_path))
179
- html_out = renderer.result(binding)
180
-
181
- # write html file
182
- html_out_path = './report.html'
183
-
184
- File.open(html_out_path, 'w') do |file|
185
- file << html_out
186
-
187
- # make sure data is written to the disk one way or the other
188
- begin
189
- file.fsync
190
- rescue
191
- file.flush
192
- end
193
- end
194
-
195
- # closing the sql file
196
- sqlFile.close
197
-
198
- # reporting final condition
199
- runner.registerFinalCondition('Standard Report generated successfully.')
200
-
201
- true
202
- end # end the run method
203
- end # end the measure
204
-
205
- # this allows the measure to be use by the application
206
- StandardReports.new.registerWithApplication
@@ -1,53 +0,0 @@
1
- <measure>
2
- <name>Standard Reports</name>
3
- <uid>fc337100-8634-404e-8966-01243d292a79</uid>
4
- <version_id>4f1230e3-0954-43ab-a772-c345030ab14b</version_id>
5
- <description>Change me</description>
6
- <modeler_description>Change me</modeler_description>
7
- <provenances/>
8
- <tags>
9
- <tag>Reporting.QAQC</tag>
10
- </tags>
11
- <attributes>
12
- <attribute>
13
- <name>Measure Type</name>
14
- <value>ReportingMeasure</value>
15
- <datatype>string</datatype>
16
- </attribute>
17
- <attribute>
18
- <name>Uses SketchUp API</name>
19
- <value>false</value>
20
- <datatype>boolean</datatype>
21
- </attribute>
22
- </attributes>
23
- <files>
24
- <file>
25
- <filename>ExampleModel.osm</filename>
26
- <filetype>osm</filetype>
27
- <usage_type>test</usage_type>
28
- <checksum>0D4162D2</checksum>
29
- </file>
30
- <file>
31
- <filename>report.html.erb</filename>
32
- <filetype>in</filetype>
33
- <usage_type>resource</usage_type>
34
- <checksum>093FE760</checksum>
35
- </file>
36
- <file>
37
- <filename>StandardReports_Test.rb</filename>
38
- <filetype>rb</filetype>
39
- <usage_type>test</usage_type>
40
- <checksum>6790E2F5</checksum>
41
- </file>
42
- <file>
43
- <version>
44
- <software_program>OpenStudio</software_program>
45
- <identifier>1.1.2</identifier>
46
- </version>
47
- <filename>measure.rb</filename>
48
- <filetype>rb</filetype>
49
- <usage_type>script</usage_type>
50
- <checksum>4263B498</checksum>
51
- </file>
52
- </files>
53
- </measure>
@@ -1,298 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8">
5
- <title>Results | OpenStudio</title>
6
- <link href="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/css/bootstrap.min.css" rel="stylesheet">
7
- <link href="file:///<%= web_asset_path %>/bootstrap.min.css" rel="stylesheet">
8
- <style type="text/css">
9
- body {
10
- font: 10px sans-serif;
11
- min-width: 1280px;
12
- }
13
- table {
14
- max-width:800px;
15
- }
16
- .axis path, .axis line {
17
- fill: none;
18
- stroke: #000;
19
- shape-rendering: crispEdges;
20
- }
21
- .bar {
22
- fill: steelblue;
23
- }
24
- .x.axis path {
25
- display: none;
26
- }
27
- .d3-tip {
28
- line-height: 1;
29
- font-weight: bold;
30
- padding: 12px;
31
- background: rgba(0, 0, 0, 0.8);
32
- color: #fff;
33
- border-radius: 2px;
34
- }
35
- /* Creates a small triangle extender for the tooltip */
36
- .d3-tip:after {
37
- box-sizing: border-box;
38
- display: inline;
39
- font-size: 10px;
40
- width: 100%;
41
- line-height: 1;
42
- color: rgba(0, 0, 0, 0.8);
43
- content:"\25BC";
44
- position: absolute;
45
- text-align: center;
46
- }
47
- /* Style northward tooltips differently */
48
- .d3-tip.n:after {
49
- margin: -1px 0 0 0;
50
- top: 100%;
51
- left: 0;
52
- }
53
- </style>
54
- <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
55
- <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/d3/3.3.9/d3.min.js"></script>
56
- <script type="text/javascript" src="file:///<%= web_asset_path %>/jquery.min.js"></script>
57
- <script type="text/javascript" src="file:///<%= web_asset_path %>/d3.min.js"></script>
58
- <script type="text/javascript">
59
- // http://labratrevenge.com/d3-tip/javascripts/d3.tip.min.js
60
- d3.tip=function(){function t(t){v=m(t),w=v.createSVGPoint(),document.body.appendChild(x)}function e(){return"n"}function n(){return[0,0]}function r(){return" "}function o(){var t=p();return{top:t.n.y-x.offsetHeight,left:t.n.x-x.offsetWidth/2}}function s(){var t=p();return{top:t.s.y,left:t.s.x-x.offsetWidth/2}}function l(){var t=p();return{top:t.e.y-x.offsetHeight/2,left:t.e.x}}function u(){var t=p();return{top:t.w.y-x.offsetHeight/2,left:t.w.x-x.offsetWidth}}function f(){var t=p();return{top:t.nw.y-x.offsetHeight,left:t.nw.x-x.offsetWidth}}function i(){var t=p();return{top:t.ne.y-x.offsetHeight,left:t.ne.x}}function a(){var t=p();return{top:t.sw.y,left:t.sw.x-x.offsetWidth}}function c(){var t=p();return{top:t.se.y,left:t.e.x}}function d(){var t=d3.select(document.createElement("div"));return t.style({position:"absolute",opacity:0,pointerEvents:"none",boxSizing:"border-box"}),t.node()}function m(t){return t=t.node(),"svg"==t.tagName.toLowerCase()?t:t.ownerSVGElement}function p(){var t=d3.event.target,e={},n=t.getScreenCTM(),r=t.getBBox(),o=r.width,s=r.height,l=r.x,u=r.y,f=document.body.scrollTop,i=document.body.scrollLeft;return document.documentElement&&document.documentElement.scrollTop&&(f=document.documentElement.scrollTop,i=document.documentElement.scrollLeft),w.x=l+i,w.y=u+f,e.nw=w.matrixTransform(n),w.x+=o,e.ne=w.matrixTransform(n),w.y+=s,e.se=w.matrixTransform(n),w.x-=o,e.sw=w.matrixTransform(n),w.y-=s/2,e.w=w.matrixTransform(n),w.x+=o,e.e=w.matrixTransform(n),w.x-=o/2,w.y-=s/2,e.n=w.matrixTransform(n),w.y+=s,e.s=w.matrixTransform(n),e}var y=e,g=n,h=r,x=d(),v=null,w=null;t.show=function(){var e,n=h.apply(this,arguments),r=g.apply(this,arguments),o=y.apply(this,arguments),s=d3.select(x),l=0;for(s.html(n).style({opacity:1,pointerEvents:"all"});l--;)s.classed(E[l],!1);return e=T.get(o).apply(this),s.classed(o,!0).style({top:e.top+r[0]+"px",left:e.left+r[1]+"px"}),t},t.hide=function(){return nodel=d3.select(x),nodel.style({opacity:0,pointerEvents:"none"}),t},t.attr=function(e){if(2>arguments.length&&"string"==typeof e)return d3.select(x).attr(e);var n=Array.prototype.slice.call(arguments);return d3.selection.prototype.attr.apply(d3.select(x),n),t},t.style=function(e){if(2>arguments.length&&"string"==typeof e)return d3.select(x).style(e);var n=Array.prototype.slice.call(arguments);return d3.selection.prototype.style.apply(d3.select(x),n),t},t.direction=function(e){return arguments.length?(y=null==e?e:d3.functor(e),t):y},t.offset=function(e){return arguments.length?(g=null==e?e:d3.functor(e),t):g},t.html=function(e){return arguments.length?(h=null==e?e:d3.functor(e),t):h};var T=d3.map({n:o,s:s,e:l,w:u,nw:f,ne:i,sw:a,se:c}),E=T.keys();return t};
61
- </script>
62
- </head>
63
- <body>
64
- <div class="row-fluid">
65
- <div class="span5">
66
- <h4 id="title-0"></h4>
67
- <div id="chart-0"></div>
68
- </div>
69
- <div class="span7">
70
- <h4 id="title-1"></h4>
71
- <div id="chart-1"></div>
72
- </div>
73
- </div>
74
- <script type="text/javascript">
75
- function numFormat(n) {
76
- var parts = n.toString().split(".");
77
- return parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",") + (parts[1] ? "." + parts[1] : "");
78
- }
79
-
80
- var months = [
81
- "Jan",
82
- "Feb",
83
- "Mar",
84
- "Apr",
85
- "May",
86
- "Jun",
87
- "Jul",
88
- "Aug",
89
- "Sep",
90
- "Oct",
91
- "Nov",
92
- "Dec"];
93
-
94
- <%= energy %>
95
-
96
- function outputTable(name, units, obj) {
97
- if (name == "Electricity Consumption" | name == "Natural Gas Consumption" | name == "District Cooling Consumption" | name == "District Heating Consumption") {
98
- $('<h4>').text(name + " (" + units + ")").appendTo('body');
99
- var $table = $('<table id="' + name.toLowerCase().replace(/ /g, '-') + '">').addClass("table table-striped table-bordered table-condensed");
100
- $table.append('<thead>').children('thead').append('<tr />').children('tr').append('<th>&nbsp;</th><th>Jan</th><th>Feb</th><th>Mar</th><th>Apr</th><th>May</th><th>Jun</th><th>Jul</th><th>Aug</th><th>Sep</th><th>Oct</th><th>Nov</th><th>Dec</th><th>Total</th>');
101
- var $tbody = $table.append('<tbody />').children('tbody');
102
- var key;
103
- var totalTotal = 0;
104
- var columnTotal = [];
105
- for (key in obj) {
106
- if (obj.hasOwnProperty(key)) {
107
- var $row = $tbody.append('<tr />').children('tr:last');
108
- $row.append("<td>" + key + "</td>");
109
- var total = 0;
110
- for (i = 0; i < obj[key].length; i++) {
111
- if (columnTotal[i] === undefined) columnTotal[i] = 0;
112
- $row.append("<td>" + (obj[key][i] === 0 ? "&mdash;" : numFormat(obj[key][i])) + "</td>");
113
- total += obj[key][i];
114
- columnTotal[i] += obj[key][i];
115
- }
116
- totalTotal += total;
117
- $row.append("<td>" + (total === 0 ? "&mdash;" : numFormat(total.toFixed(3))) + "</td>");
118
- }
119
- }
120
- // Append column totals as new, last row of table
121
- if (columnTotal[columnTotal.length] === undefined) columnTotal[columnTotal.length] = 0;
122
- columnTotal[columnTotal.length - 1] = totalTotal;
123
- var $row = $tbody.append('<tr />').children('tr:last');
124
- $row.append("<td>Total</td>");
125
- for (i = 0; i < columnTotal.length; i++) {
126
- $row.append("<td>" + (columnTotal[i] === 0 ? "&mdash;" : numFormat(columnTotal[i].toFixed(3))) + "</td>");
127
- }
128
- $table.appendTo('body');
129
- }
130
- }
131
-
132
- $.each(consumption, function (key, obj) {
133
- outputTable(key, obj.units, obj.data);
134
- });
135
-
136
- var margin = {
137
- top: 20.5,
138
- right: 20,
139
- bottom: 30,
140
- left: 40.5
141
- },
142
- width = 560 - margin.left - margin.right,
143
- height = 300 - margin.top - margin.bottom;
144
-
145
- var x = d3.scale.ordinal()
146
- .rangeRoundBands([0, width], 0.1);
147
-
148
- var y = d3.scale.linear()
149
- .rangeRound([height, 0]);
150
-
151
- var color = d3.scale.ordinal()
152
- .range(["#EF1C21", "#0071BD", "#F7DF10", "#DEC310", "#4A4D4A", "#B5B2B5", "#FF79AD", "#632C94", "#F75921", "#293094", "#CE5921", "#FFB239", "#29AAE7", "#8CC739"]);
153
-
154
- var xAxis = d3.svg.axis()
155
- .scale(x)
156
- .orient("bottom");
157
-
158
- var yAxis = d3.svg.axis()
159
- .scale(y)
160
- .orient("left")
161
- .tickFormat(d3.format(".2s"));
162
-
163
- var tip = d3.tip()
164
- .attr('class', 'd3-tip')
165
- .offset([-10, 0])
166
- .html(function (d) {
167
- return "<strong>" + d.name + ":</strong> <span style='color:red'>" + (d.y1 - d.y0).toFixed(2) + "</span>";
168
- });
169
-
170
- var charts = ["Electricity Consumption", "Natural Gas Consumption"];
171
-
172
- for (var c in charts) {
173
-
174
- if (c == charts.length - 1) {
175
- margin.right = 125;
176
- }
177
-
178
- $('#title-' + c).text(charts[c]);
179
-
180
- var svg = d3.select("#chart-" + c).append("svg")
181
- .attr("width", width + margin.left + margin.right)
182
- .attr("height", height + margin.top + margin.bottom)
183
- .append("g")
184
- .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
185
- svg.call(tip);
186
-
187
- data = [];
188
- for (var enduse in consumption[charts[c]].data) {
189
- var enduse_data = consumption[charts[c]].data[enduse];
190
- for (var month = 0; month < months.length; month++) {
191
- if (data.length < months.length) {
192
- var temp = {
193
- "Month": months[month]
194
- };
195
- temp[enduse] = enduse_data[month];
196
- data.push(temp);
197
- } else {
198
- data[month][enduse] = enduse_data[month];
199
- }
200
- }
201
- }
202
- color.domain(d3.keys(data[0]).filter(function (key) {
203
- return key !== "Month";
204
- }));
205
-
206
- data.forEach(function (d) {
207
- var y0 = 0;
208
- d.consumption = color.domain().map(function (name) {
209
- return {
210
- name: name,
211
- y0: y0,
212
- y1: y0 += +d[name]
213
- };
214
- });
215
- d.total = d.consumption[d.consumption.length - 1].y1;
216
- });
217
-
218
- //data.sort(function(a, b) { return b.total - a.total; });
219
-
220
- x.domain(data.map(function (d) {
221
- return d.Month;
222
- }));
223
- y.domain([0, d3.max(data, function (d) {
224
- return d.total;
225
- })]);
226
-
227
- svg.append("g")
228
- .attr("class", "x axis")
229
- .attr("transform", "translate(0," + height + ")")
230
- .call(xAxis);
231
-
232
- svg.append("g")
233
- .attr("class", "y axis")
234
- .call(yAxis)
235
- .append("text")
236
- .attr("transform", "rotate(-90)")
237
- .attr("y", -36)
238
- .attr("dy", ".71em")
239
- .style("text-anchor", "end")
240
- .text(consumption[charts[c]].units);
241
-
242
- var month = svg.selectAll(".month")
243
- .data(data)
244
- .enter().append("g")
245
- .attr("class", "g")
246
- .attr("transform", function (d) {
247
- return "translate(" + x(d.Month) + ",0)";
248
- });
249
-
250
- month.selectAll("rect")
251
- .data(function (d) {
252
- return d.consumption;
253
- })
254
- .enter().append("rect")
255
- .attr("width", x.rangeBand())
256
- .attr("y", function (d) {
257
- return y(d.y1);
258
- })
259
- .attr("height", function (d) {
260
- return y(d.y0) - y(d.y1);
261
- })
262
- .style("fill", function (d) {
263
- return color(d.name);
264
- })
265
- .on('mouseover', tip.show)
266
- .on('mouseout', tip.hide);
267
-
268
- if (c == charts.length - 1) {
269
- var legend = svg.selectAll(".legend")
270
- .data(color.domain().slice())
271
- .enter().append("g")
272
- .attr("class", "legend")
273
- .attr("transform", function (d, i) {
274
- return "translate(0," + i * 20 + ")";
275
- });
276
-
277
- legend.append("rect")
278
- .attr("x", width + 105)
279
- .attr("width", 18)
280
- .attr("height", 18)
281
- .style("fill", color);
282
-
283
- legend.append("text")
284
- .attr("x", width + 105 - 3)
285
- .attr("y", 9)
286
- .attr("dy", ".35em")
287
- .style("text-anchor", "end")
288
- .text(function (d) {
289
- return d;
290
- });
291
- }
292
-
293
- svg.selectAll(".g").attr("stroke", "black")
294
- .attr("stroke-width", "1");
295
- }
296
- </script>
297
- </body>
298
- </html>