1 /*
2 * Copyright (C) 2013 Emweb bv, Herent, Belgium.
3 *
4 * See the LICENSE file for terms of use.
5 */
6
7 #include "Wt/Chart/WAbstractDataSeries3D.h"
8
9 #include "Wt/WAbstractItemModel.h"
10 #include "Wt/WApplication.h"
11 #include "Wt/WCanvasPaintDevice.h"
12 #include "Wt/WEnvironment.h"
13 #include "Wt/WPainter.h"
14 #include "Wt/Chart/WAbstractColorMap.h"
15 #include "Wt/Chart/WCartesian3DChart.h"
16
17 using namespace Wt;
18
19 namespace {
clearConnections(std::vector<Wt::Signals::connection> connections)20 void clearConnections(std::vector<Wt::Signals::connection> connections) {
21 for (unsigned i=0; i < connections.size(); i++)
22 connections[i].disconnect();
23 connections.clear();
24 }
25 }
26
27 namespace Wt {
28 namespace Chart {
29
WAbstractDataSeries3D(std::shared_ptr<WAbstractItemModel> model)30 WAbstractDataSeries3D::WAbstractDataSeries3D(std::shared_ptr<WAbstractItemModel> model)
31 : chart_(0),
32 rangeCached_(false),
33 pointSize_(2.0),
34 colormap_(0),
35 showColorMap_(false),
36 colorMapSide_(Side::Right),
37 legendEnabled_(true),
38 hidden_(false),
39 /* in webGL, the z-direction is out of the screen, in model coordinates
40 * it's the vertical direction */
41 mvMatrix_(1.0f, 0.0f, 0.0f, 0.0f,
42 0.0f, 0.0f, 1.0f, 0.0f,
43 0.0f, 1.0f, 0.0f, 0.0f,
44 0.0f, 0.0f, 0.0f, 1.0f)
45 {
46 model_ = model;
47 }
48
~WAbstractDataSeries3D()49 WAbstractDataSeries3D::~WAbstractDataSeries3D()
50 {
51 }
52
53 void WAbstractDataSeries3D
setModel(const std::shared_ptr<WAbstractItemModel> & model)54 ::setModel(const std::shared_ptr<WAbstractItemModel>& model)
55 {
56 if (model != model_) {
57 // handle previous model
58 if (model_ && chart_) {
59 clearConnections(connections_);
60 }
61 rangeCached_ = false;
62
63 // set new model
64 model_ = model;
65
66 if (model_ && chart_) {
67 chart_->updateChart(ChartUpdates::GLContext);
68 connections_.push_back
69 (model_->modelReset().connect
70 (chart_, std::bind(&WCartesian3DChart::updateChart, chart_,
71 ChartUpdates::GLTextures | ChartUpdates::GLContext)));
72 connections_.push_back
73 (model_->dataChanged().connect
74 (chart_, std::bind(&WCartesian3DChart::updateChart, chart_,
75 ChartUpdates::GLTextures | ChartUpdates::GLContext)));
76 connections_.push_back
77 (model_->rowsInserted().connect
78 (chart_, std::bind(&WCartesian3DChart::updateChart, chart_,
79 ChartUpdates::GLTextures | ChartUpdates::GLContext)));
80 connections_.push_back
81 (model_->columnsInserted().connect
82 (chart_, std::bind(&WCartesian3DChart::updateChart, chart_,
83 ChartUpdates::GLTextures | ChartUpdates::GLContext)));
84 connections_.push_back
85 (model_->rowsRemoved().connect
86 (chart_, std::bind(&WCartesian3DChart::updateChart, chart_,
87 ChartUpdates::GLTextures | ChartUpdates::GLContext)));
88 connections_.push_back
89 (model_->columnsRemoved().connect
90 (chart_, std::bind(&WCartesian3DChart::updateChart, chart_,
91 ChartUpdates::GLTextures | ChartUpdates::GLContext)));
92 }
93 }
94 }
95
setTitle(const WString & name)96 void WAbstractDataSeries3D::setTitle(const WString& name)
97 {
98 name_ = name;
99 if (chart_)
100 chart_->updateChart(ChartUpdates::GLTextures);
101 }
102
setPointSize(double size)103 void WAbstractDataSeries3D::setPointSize(double size)
104 {
105 if (size != pointSize_) {
106 pointSize_ = size;
107 if (chart_)
108 chart_->updateChart(ChartUpdates::GLContext | ChartUpdates::GLTextures);
109 }
110 }
111
setPointSprite(const std::string & image)112 void WAbstractDataSeries3D::setPointSprite(const std::string &image)
113 {
114 if (image != pointSprite_) {
115 pointSprite_ = image;
116 if (chart_)
117 chart_->updateChart(ChartUpdates::GLContext | ChartUpdates::GLTextures);
118 }
119 }
120
121 void WAbstractDataSeries3D
setColorMap(const std::shared_ptr<WAbstractColorMap> & colormap)122 ::setColorMap(const std::shared_ptr<WAbstractColorMap>& colormap)
123 {
124 colormap_ = colormap;
125 if (chart_)
126 chart_->updateChart(ChartUpdates::GLContext | ChartUpdates::GLTextures);
127 }
128
setColorMapVisible(bool enabled)129 void WAbstractDataSeries3D::setColorMapVisible(bool enabled)
130 {
131 if (showColorMap_ == enabled)
132 return;
133
134 showColorMap_ = enabled;
135 if (chart_)
136 chart_->updateChart(ChartUpdates::GLTextures);
137 }
138
setColorMapSide(Side side)139 void WAbstractDataSeries3D::setColorMapSide(Side side)
140 {
141 if (colorMapSide_ == side)
142 return;
143
144 colorMapSide_ = side;
145 if (chart_)
146 chart_->updateChart(ChartUpdates::GLTextures);
147 }
148
setHidden(bool enabled)149 void WAbstractDataSeries3D::setHidden(bool enabled)
150 {
151 if (enabled != hidden_) {
152 hidden_ = enabled;
153 if (chart_)
154 chart_->updateChart(ChartUpdates::GLContext | ChartUpdates::GLTextures);
155 }
156 }
157
colorTexture()158 WGLWidget::Texture WAbstractDataSeries3D::colorTexture()
159 {
160 std::unique_ptr<WPaintDevice> cpd;
161 if (!colormap_) {
162 cpd = chart_->createPaintDevice(WLength(1),WLength(1));
163 WColor seriesColor = chartpaletteColor();
164 WPainter painter(cpd.get());
165 painter.setPen(WPen(seriesColor));
166 painter.drawLine(0,0.5,1,0.5);
167 painter.end();
168 } else {
169 cpd = chart_->createPaintDevice(WLength(1),WLength(1024));
170 WPainter painter(cpd.get());
171 colormap_->createStrip(&painter);
172 painter.end();
173 }
174
175 WGLWidget::Texture tex = chart_->createTexture();
176 chart_->bindTexture(WGLWidget::TEXTURE_2D, tex);
177 chart_->pixelStorei(WGLWidget::UNPACK_FLIP_Y_WEBGL, 1);
178 chart_->texImage2D(WGLWidget::TEXTURE_2D, 0,
179 WGLWidget::RGBA, WGLWidget::RGBA,
180 WGLWidget::UNSIGNED_BYTE, cpd.get());
181
182 return tex;
183 }
184
pointSpriteTexture()185 WGLWidget::Texture WAbstractDataSeries3D::pointSpriteTexture()
186 {
187 WGLWidget::Texture tex = chart_->createTexture();
188 chart_->bindTexture(WGLWidget::TEXTURE_2D, tex);
189 if (pointSprite_.empty()) {
190 std::unique_ptr<WPaintDevice> cpd
191 = chart_->createPaintDevice(WLength(1), WLength(1));
192 WColor color = WColor(255, 255, 255, 255);
193 WPainter painter(cpd.get());
194 painter.setPen(WPen(color));
195 painter.drawLine(0,0.5,1,0.5);
196 painter.end();
197 chart_->texImage2D(WGLWidget::TEXTURE_2D, 0,
198 WGLWidget::RGBA, WGLWidget::RGBA,
199 WGLWidget::UNSIGNED_BYTE, cpd.get());
200 }
201
202 return tex;
203 }
204
205 void WAbstractDataSeries3D
loadPointSpriteTexture(const WGLWidget::Texture & tex)206 ::loadPointSpriteTexture(const WGLWidget::Texture &tex) const
207 {
208 chart_->bindTexture(WGLWidget::TEXTURE_2D, tex);
209 if (!pointSprite_.empty()) {
210 chart_->texImage2D(WGLWidget::TEXTURE_2D, 0, WGLWidget::RGBA,
211 WGLWidget::RGBA, WGLWidget::UNSIGNED_BYTE, pointSprite_);
212 }
213 }
214
setDefaultTitle(int i)215 void WAbstractDataSeries3D::setDefaultTitle(int i)
216 {
217 std::string tmp = std::string("dataset ");
218 tmp.append(std::to_string(i));
219 name_ = WString(tmp);
220 }
221
chartpaletteColor()222 WColor WAbstractDataSeries3D::chartpaletteColor() const
223 {
224 if (colormap_)
225 return WColor();
226
227 int index = 0;
228 for (unsigned i=0; i < chart_->dataSeries().size(); i++) { // which colorscheme
229 if (chart_->dataSeries()[i] == this) {
230 break;
231 } else if (chart_->dataSeries()[i]->colorMap() == 0) {
232 index++;
233 }
234 }
235 return chart_->palette()->brush(index).color();
236 }
237
setChart(WCartesian3DChart * chart)238 void WAbstractDataSeries3D::setChart(WCartesian3DChart *chart)
239 {
240 if (chart == chart_)
241 return;
242 else if (chart_)
243 chart_->removeDataSeries(this);
244
245 if (chart_ && model_)
246 clearConnections(connections_);
247
248 chart_ = chart;
249
250 if (chart_ && model_) {
251 connections_.push_back
252 (model_->modelReset().connect
253 (chart_, std::bind(&WCartesian3DChart::updateChart, chart_,
254 ChartUpdates::GLTextures | ChartUpdates::GLContext)));
255 connections_.push_back
256 (model_->dataChanged().connect
257 (chart_, std::bind(&WCartesian3DChart::updateChart, chart_,
258 ChartUpdates::GLTextures | ChartUpdates::GLContext)));
259 connections_.push_back
260 (model_->rowsInserted().connect
261 (chart_, std::bind(&WCartesian3DChart::updateChart, chart_,
262 ChartUpdates::GLTextures | ChartUpdates::GLContext)));
263 connections_.push_back
264 (model_->columnsInserted().connect
265 (chart_, std::bind(&WCartesian3DChart::updateChart, chart_,
266 ChartUpdates::GLTextures | ChartUpdates::GLContext)));
267 connections_.push_back
268 (model_->rowsRemoved().connect
269 (chart_, std::bind(&WCartesian3DChart::updateChart, chart_,
270 ChartUpdates::GLTextures | ChartUpdates::GLContext)));
271 connections_.push_back
272 (model_->columnsRemoved().connect
273 (chart_, std::bind(&WCartesian3DChart::updateChart, chart_,
274 ChartUpdates::GLTextures | ChartUpdates::GLContext)));
275 }
276 }
277
getGlObjects()278 std::vector<cpp17::any> WAbstractDataSeries3D::getGlObjects()
279 {
280 return std::vector<cpp17::any>();
281 }
282
283 }
284 }
285