github.com/Ilhicas/nomad@v1.0.4-0.20210304152020-e86851182bc3/ui/stories/charts/line-chart.stories.js (about) 1 import hbs from 'htmlbars-inline-precompile'; 2 3 import EmberObject from '@ember/object'; 4 import { on } from '@ember/object/evented'; 5 import moment from 'moment'; 6 7 import DelayedArray from '../utils/delayed-array'; 8 9 export default { 10 title: 'Charts|Line Chart', 11 }; 12 13 let data1 = [ 14 { year: 2010, value: 10 }, 15 { year: 2011, value: 10 }, 16 { year: 2012, value: 20 }, 17 { year: 2013, value: 30 }, 18 { year: 2014, value: 50 }, 19 { year: 2015, value: 80 }, 20 { year: 2016, value: 130 }, 21 { year: 2017, value: 210 }, 22 { year: 2018, value: 340 }, 23 ]; 24 25 let data2 = [ 26 { year: 2010, value: 100 }, 27 { year: 2011, value: 90 }, 28 { year: 2012, value: 120 }, 29 { year: 2013, value: 130 }, 30 { year: 2014, value: 115 }, 31 { year: 2015, value: 105 }, 32 { year: 2016, value: 90 }, 33 { year: 2017, value: 85 }, 34 { year: 2018, value: 90 }, 35 ]; 36 37 export let Standard = () => { 38 return { 39 template: hbs` 40 <h5 class="title is-5">Line Chart</h5> 41 <div class="block" style="height:100px; width: 400px;"> 42 {{#if this.lineChartData}} 43 <LineChart @data={{this.lineChartData}} @xProp="year" @yProp="value"> 44 <:svg as |c|> 45 <c.Area @data={{this.lineChartData}} /> 46 </:svg> 47 </LineChart> 48 {{/if}} 49 </div> 50 <div class="block" style="height:100px; width: 400px;"> 51 {{#if this.lineChartMild}} 52 <LineChart @data={{this.lineChartMild}} @xProp="year" @yProp="value" @chartClass="is-info"> 53 <:svg as |c|> 54 <c.Area @data={{this.lineChartMild}} /> 55 </:svg> 56 </LineChart> 57 {{/if}} 58 </div> 59 `, 60 context: { 61 lineChartData: DelayedArray.create(data1), 62 lineChartMild: DelayedArray.create(data2), 63 }, 64 }; 65 }; 66 67 export let FluidWidth = () => { 68 return { 69 template: hbs` 70 <h5 class="title is-5">Fluid-width Line Chart</h5> 71 <div class="block" style="height:250px;"> 72 {{#if this.lineChartData}} 73 <LineChart @data={{this.lineChartData}} @xProp="year" @yProp="value" @chartClass="is-danger"> 74 <:svg as |c|> 75 <c.Area @data={{this.lineChartData}} /> 76 </:svg> 77 </LineChart> 78 {{/if}} 79 </div> 80 <div class="block" style="height:250px;"> 81 {{#if this.lineChartMild}} 82 <LineChart @data={{this.lineChartMild}} @xProp="year" @yProp="value" @chartClass="is-warning"> 83 <:svg as |c|> 84 <c.Area @data={{this.lineChartMild}} /> 85 </:svg> 86 </LineChart> 87 {{/if}} 88 </div> 89 <p class="annotation">A line chart will assume the width of its container. This includes the dimensions of the axes, which are calculated based on real DOM measurements. This requires a two-pass render: first the axes are placed with their real domains (in order to capture width and height of tick labels), second the axes are adjusted to make sure both the x and y axes are within the height and width bounds of the container.</p> 90 `, 91 context: { 92 lineChartData: DelayedArray.create(data1), 93 lineChartMild: DelayedArray.create(data2), 94 }, 95 }; 96 }; 97 98 export let LiveData = () => { 99 return { 100 template: hbs` 101 <h5 class="title is-5">Live data Line Chart</h5> 102 <div class="block" style="height:250px"> 103 {{#if this.controller.lineChartLive}} 104 <LineChart 105 @data={{this.controller.lineChartLive}} 106 @xProp="ts" 107 @yProp="val" 108 @timeseries={{true}} 109 @chartClass="is-primary" 110 @xFormat={{this.controller.secondsFormat}}> 111 <:svg as |c|> 112 <c.Area @data={{this.controller.lineChartLive}} /> 113 </:svg> 114 </LineChart> 115 {{/if}} 116 </div> 117 `, 118 context: { 119 controller: EmberObject.extend({ 120 startTimer: on('init', function() { 121 this.lineChartLive = []; 122 123 this.set( 124 'timer', 125 setInterval(() => { 126 this.incrementProperty('timerTicks'); 127 128 let ref = this.lineChartLive; 129 ref.addObject({ ts: Date.now(), val: Math.random() * 30 + 20 }); 130 if (ref.length > 60) { 131 ref.splice(0, ref.length - 60); 132 } 133 }, 500) 134 ); 135 }), 136 137 willDestroy() { 138 clearInterval(this.timer); 139 }, 140 141 get secondsFormat() { 142 return date => moment(date).format('HH:mm:ss'); 143 }, 144 }).create(), 145 }, 146 }; 147 }; 148 149 export let Gaps = () => { 150 return { 151 template: hbs` 152 <h5 class="title is-5">Line Chart data with gaps</h5> 153 <div class="block" style="height:250px"> 154 {{#if this.lineChartGapData}} 155 <LineChart @data={{this.lineChartGapData}} @xProp="year" @yProp="value" @chartClass="is-primary"> 156 <:svg as |c|> 157 <c.Area @data={{this.lineChartGapData}} /> 158 </:svg> 159 </LineChart> 160 {{/if}} 161 </div> 162 `, 163 context: { 164 lineChartGapData: DelayedArray.create([ 165 { year: 2010, value: 10 }, 166 { year: 2011, value: 10 }, 167 { year: 2012, value: null }, 168 { year: 2013, value: 30 }, 169 { year: 2014, value: 50 }, 170 { year: 2015, value: 80 }, 171 { year: 2016, value: null }, 172 { year: 2017, value: 210 }, 173 { year: 2018, value: 340 }, 174 ]), 175 }, 176 }; 177 }; 178 179 export let Annotations = () => { 180 return { 181 template: hbs` 182 <h5 class="title is-5">Line Chart data with annotations</h5> 183 <div class="block" style="height:250px"> 184 {{#if (and this.data this.annotations)}} 185 <LineChart 186 class="with-annotations" 187 @timeseries={{true}} 188 @xProp="x" 189 @yProp="y" 190 @data={{this.data}}> 191 <:svg as |c|> 192 <c.Area @data={{this.data}} @annotationClick={{action (mut this.activeAnnotation)}} /> 193 </:svg> 194 <:after as |c|> 195 <c.VAnnotations 196 @annotations={{this.annotations}} 197 @annotationClick={{action (mut this.activeAnnotation)}} 198 @activeAnnotation={{this.activeAnnotation}} /> 199 </:after> 200 </LineChart> 201 {{/if}} 202 </div> 203 <p style="margin:2em 0; padding: 1em; background:#FFEEAC">{{this.activeAnnotation.info}}</p> 204 <h5 class="title is-5">Line Chart data with staggered annotations</h5> 205 <div class="block" style="height:150px; width:450px"> 206 {{#if (and this.data this.annotations)}} 207 <LineChart 208 class="with-annotations" 209 @timeseries={{true}} 210 @xProp="x" 211 @yProp="y" 212 @data={{this.data}}> 213 <:svg as |c|> 214 <c.Area @data={{this.data}} @annotationClick={{action (mut this.activeAnnotation)}} /> 215 </:svg> 216 <:after as |c|> 217 <c.VAnnotations 218 @annotations={{this.annotations}} 219 @annotationClick={{action (mut this.activeAnnotation)}} 220 @activeAnnotation={{this.activeAnnotation}} /> 221 </:after> 222 </LineChart> 223 {{/if}} 224 </div> 225 `, 226 context: { 227 data: DelayedArray.create( 228 new Array(180).fill(null).map((_, idx) => ({ 229 y: Math.sin((idx * 4 * Math.PI) / 180) * 100 + 200, 230 x: moment() 231 .add(idx, 'd') 232 .toDate(), 233 })) 234 ), 235 annotations: [ 236 { 237 x: moment().toDate(), 238 type: 'info', 239 info: 'Far left', 240 }, 241 { 242 x: moment() 243 .add(90 / 4, 'd') 244 .toDate(), 245 type: 'error', 246 info: 'This is the max of the sine curve', 247 }, 248 { 249 x: moment() 250 .add(89, 'd') 251 .toDate(), 252 type: 'info', 253 info: 'This is the end of the first period', 254 }, 255 { 256 x: moment() 257 .add(96, 'd') 258 .toDate(), 259 type: 'info', 260 info: 'A close annotation for staggering purposes', 261 }, 262 { 263 x: moment() 264 .add((90 / 4) * 3, 'd') 265 .toDate(), 266 type: 'error', 267 info: 'This is the min of the sine curve', 268 }, 269 { 270 x: moment() 271 .add(179, 'd') 272 .toDate(), 273 type: 'info', 274 info: 'Far right', 275 }, 276 ], 277 }, 278 }; 279 }; 280 281 export let StepLine = () => { 282 return { 283 template: hbs` 284 <h5 class="title is-5">Line Chart with a Step Line</h5> 285 <div class="block" style="height:250px"> 286 {{#if this.data}} 287 <LineChart 288 @xProp="x" 289 @yProp="y" 290 @data={{this.data}}> 291 <:svg as |c|> 292 <c.Area @data={{this.data}} @curve="stepAfter" /> 293 </:svg> 294 </LineChart> 295 <p>{{this.activeAnnotation.info}}</p> 296 {{/if}} 297 </div> 298 `, 299 context: { 300 data: DelayedArray.create([ 301 { x: 1, y: 5 }, 302 { x: 2, y: 1 }, 303 { x: 3, y: 2 }, 304 { x: 4, y: 2 }, 305 { x: 5, y: 9 }, 306 { x: 6, y: 3 }, 307 { x: 7, y: 4 }, 308 { x: 8, y: 1 }, 309 { x: 9, y: 5 }, 310 ]), 311 }, 312 }; 313 };