class WidgetChart(QWidget): """ a widget displaying a chart stock as a svg in the local file """ def __init__(self, parent): """create the widget""" QWidget.__init__(self, parent) # fetching the chart # ================== # file to open self.file = "bar_chart.svg" if sys.platform == "linux2": self.directorySep = "/" else: self.directorySep = "\\" self.wd = os.getcwd() # displaying the chart # ==================== # scene for displaying the graphics self.scene = QGraphicsScene() # view widget where the graphics will be self.view = QGraphicsView(self.scene) #get the size of the svg self.br = QGraphicsSvgItem(self.wd + self.directorySep + self.file).boundingRect() # web that is to say the svg file self.webview = QGraphicsWebView() self.loadWidget() # add the chart in the scene self.scene.addItem(self.webview) # resize the view self.view.resize(self.br.width()+10, self.br.height()+10) #add the view to the parent layout self.setLayout(QVBoxLayout()) self.layout().addWidget(self.view) def loadWidget(self): self.webview.load(QUrl(self.wd + self.directorySep + self.file)) self.webview.setFlags(QGraphicsItem.ItemClipsToShape) # self.webview.setCacheMode(QGraphicsItem.NoCache) self.webview.resize(self.br.width(), self.br.height())
class Scene(QtGui.QGraphicsScene): def __init__(self): super(QtGui.QGraphicsScene, self).__init__() self.view = QtGui.QGraphicsView(self) self.webview = QGraphicsWebView() self.webview.setFlags(QtGui.QGraphicsItem.ItemClipsToShape) self.webview.setCacheMode(QtGui.QGraphicsItem.NoCache) self.addItem(self.webview) self.webview.loadFinished.connect(self.svgLoaded) def svgLoaded(self): frame = self.webview.page().mainFrame() fsize = frame.contentsSize() self.webview.resize(QtCore.QSizeF(fsize)) self.view.resize(fsize.width() + 10, fsize.height() + 10) self.webview.page().mainFrame().evaluateJavaScript(getJsScript('circle-test.js'))
class MapInput(QtGui.QWidget): def __init__(self): super(MapInput, self).__init__() self.initUI() def initUI(self): self.countries = [] self.existingChecks = [] self.K = Kartograph() self.CountryInput = QtGui.QLineEdit(self) #self.CountryList = QtGui.QTextEdit(self) #self.CountryList.setReadOnly(True) self.AddButton = QtGui.QPushButton("Add", self) self.AddButton.clicked.connect(self.buttonClicked) self.GenButton = QtGui.QPushButton('Generate', self) self.GenButton.clicked.connect(self.generateClicked) self.DispButton = QtGui.QPushButton('Display', self) self.DispButton.clicked.connect(self.displayClicked) self.statusBar = QtGui.QStatusBar(self) self.br = QtSvg.QGraphicsSvgItem("world.svg").boundingRect() self.scene = QtGui.QGraphicsScene() self.view = QtGui.QGraphicsView(self.scene) self.SvgItem = QtSvg.QGraphicsSvgItem("world.svg").boundingRect() self.webview = QGraphicsWebView() self.webview.load(QtCore.QUrl("world.svg")) self.webview.setFlags(QtGui.QGraphicsItem.ItemClipsToShape) self.webview.setCacheMode(QtGui.QGraphicsItem.NoCache) self.webview.resize(self.br.width(), self.br.height()) self.scene.addItem(self.webview) self.view.resize(self.br.width()+10, self.br.height()+10) self.grid = QtGui.QGridLayout() self.grid.setSpacing(10) self.bottomCheck = 4 self.grid.addWidget(self.AddButton, 1, 1) self.grid.addWidget(self.GenButton, 2, 1) self.grid.addWidget(self.DispButton, 3, 1) #grid.addWidget(self.CountryList, 4, 1) self.grid.addWidget(self.CountryInput, 1, 2) self.grid.addWidget(self.statusBar, 36, 0, 1, 3, QtCore.Qt.AlignBottom) self.grid.addWidget(self.view, 2, 2, 34, 50) self.setLayout(self.grid) #self.center() self.setWindowTitle('Map Display - Width ' + str(self.br.width()) + ', Height ' + str(self.br.height())) self.generateClicked() self.displayClicked() self.show() def buttonClicked(self): country = self.CountryInput.text() #add a check for if countries contains country #if not (self.countries.contains(country)): self.countries.append(country) self.generateClicked() self.displayClicked() self.CountryInput.setText('') self.countries = [c for c in self.countries if not c == ''] def generateClicked(self): self.generateMap(self.countries) #self.updateSB("Map generated.") self.statusBar.showMessage("Map generated.") def displayClicked(self): #add an SVG object to the main window, make this re-render that self.statusBar.showMessage("Displaying, please wait...") css = open('world2.css').read() cfg = options.read_map_config(open('world.json')) self.K.generate(cfg, outfile='world.svg', stylesheet=css, preview = False) self.webview.load(QtCore.QUrl("world.svg")) self.statusBar.showMessage("Map Displayed.") if self.CountryInput.text() and not self.CountryInput.text() in self.existingChecks: tempWidget = QtGui.QCheckBox(self.CountryInput.text(), self) tempWidget.toggle() tempWidget.stateChanged.connect(self.toggleDisplay) self.grid.addWidget(tempWidget, self.bottomCheck, 1) self.bottomCheck += 1 self.existingChecks.append(self.CountryInput.text()) self.updateCountryText() def generateMap(self, countrylist): self.generateCSS(countrylist) def generateCSS(self, countrylist): x = 0 css = open('world2.css', 'w') #print "css opened" css.write('#world {\n fill: #f5f3f2;\n},\n') css.write('#countries {\n fill: #f5f3f2;\n stroke: #882222;\n stroke-width: 0.5px;\n stroke-opacity: 0.4;\n}') for c in countrylist: countryString = ',\n#countries[name=%s]{\n fill: #ff0000;\n}' % c css.write(countryString) #print c #print x x+=x css.close() def toggleDisplay(self): senderText = self.sender().text() print self.sender().isChecked() if not self.sender().isChecked(): print self.sender().text() self.countries = [c for c in self.countries if not c == self.sender().text()] print self.countries if self.sender().isChecked(): self.countries.append(self.sender().text()) print self.countries self.buttonClicked() def updateCountryText(self): CountryList = self.countries displayString = QtCore.QString('') for country in CountryList: displayString.append(country) displayString.append('\n')
class ARPAP_SpatialReportDialogChart(QtGui.QDialog, FORM_CLASS): webview = None chartTypes = dict() algorithm = None reslayer = list() modelCategory = None modelValue = None validation = None chartGenerated = False mapChartType = {'bar':bar,'pie':pie} def __init__(self, parent=None): super(ARPAP_SpatialReportDialogChart, self).__init__(parent) self.parent = parent self.algorithm = parent.algorithm self.reslayer = parent.reslayer self.validation = ValidationInputdata(self,self.tr) self.setupUi(self) self.manageGui() def manageGui(self): self.chartGeneratorButton.setIcon(QtGui.QIcon(':/plugins/ARPAP_SpatialReport/icons/histogram.png')) self.statisticsGeneratorButton.setIcon(QtGui.QIcon(':/plugins/ARPAP_SpatialReport/icons/mActionOpenTable.png')) self.savePngFile.setIcon(QtGui.QIcon(':/plugins/ARPAP_SpatialReport/icons/mActionFileSave.png')) self.saveCSVFile.setIcon(QtGui.QIcon(':/plugins/ARPAP_SpatialReport/icons/mActionFileSave.png')) QObject.connect(self.chartGeneratorButton, SIGNAL('clicked()'),self.generateChart) QObject.connect(self.statisticsGeneratorButton, SIGNAL('clicked()'),self.generateStatistics) QObject.connect(self.savePngFile, SIGNAL('clicked()'),self.savepng) QObject.connect(self.saveCSVFile, SIGNAL('clicked()'),self.saveCSV) self.populateChartTypesCombo() self.populateCombosField() #manage resizeEvent QWebview def onResizeWebview(e): if self.chartGenerated: self.generateChart() self.graphicsView.resizeEvent = onResizeWebview def populateChartTypesCombo(self): self.chartTypes = { 'bar':self.tr('Bar (occurrences)'), 'pie':self.tr('Pie (distribution)'), } for type in self.chartTypes.keys(): self.selectChartType.addItem(self.chartTypes[type],type) def getChartType(self): return self.selectChartType.itemData(self.selectChartType.currentIndex()) def getSelectedListViewItem(self,listViewName): model_index = getattr(self,listViewName.lower()+'FieldListView').currentIndex() if model_index.row() != -1: return getattr(self,'model'+listViewName.capitalize()).itemFromIndex(model_index) def populateCombosField(self): layer = self.reslayer[0] #populate category listview self.modelCategory = QtGui.QStandardItemModel(self.categoryFieldListView) self.modelValue = QtGui.QStandardItemModel(self.valueFieldListView) self.categoryFieldListView.setModel(self.modelCategory) self.valueFieldListView.setModel(self.modelValue) for field in layer.pendingFields(): itemCategory = QtGui.QStandardItem(self.parent.formatFieldToString(field)) itemCategory.setData(field) itemValue = QtGui.QStandardItem(self.parent.formatFieldToString(field)) itemValue.setData(field) self.modelCategory.appendRow(itemCategory) self.modelValue.appendRow(itemValue) def _purificateValues(self,value): if type(value) == QDate: value = value.toString() elif type(value) == QPyNullVariant: value = None return value def generateChart(self): scene = QtGui.QGraphicsScene() self.graphicsView.setScene(scene) #select data adn chart type chartType = self.getChartType() if self.validation.validateChart(chartType): chart = self.mapChartType[chartType]() self.webview = QGraphicsWebView() self.webview.resize(self.graphicsView.width()-20,self.graphicsView.height()-20) path = os.path.dirname(__file__)+'/js/' chartData = getattr(self,chartType + 'ChartData' )() chart.setData(chartData) self.webview.setHtml(chart.getHTML(),baseUrl=QUrl().fromLocalFile(path)) self.webview.setFlags(QtGui.QGraphicsItem.ItemClipsToShape) self.webview.setCacheMode(QtGui.QGraphicsItem.NoCache) frame = self.webview.page().mainFrame() frame.setScrollBarPolicy(Qt.Vertical,Qt.ScrollBarAlwaysOff) frame.setScrollBarPolicy(Qt.Horizontal,Qt.ScrollBarAlwaysOff) scene.addItem(self.webview) self.graphicsView.show() self.savePngFile.setEnabled(True) self.chartGenerated = True else: self.showValidateErrors() def barChartData(self): categoryItem = self.getSelectedListViewItem('category') layer = self.reslayer[0] features = layer.getFeatures() occourences = dict() for f in features: value = self._purificateValues(f.attribute(categoryItem.data().name())) if value not in occourences: occourences[value] = 0 occourences[value] += 1 chartData = {'values':[{'label':k,'value':occourences[k]} for k in occourences.keys()]} return [chartData] def pieChartData(self): categoryItem = self.getSelectedListViewItem('category') valueItem = self.getSelectedListViewItem('value') layer = self.reslayer[0] features = layer.getFeatures() occourences = dict() totValue = 0 for f in features: key = f.attribute(categoryItem.data().name()) if not key: key = self.tr('Unknown') value = self._purificateValues(f.attribute(valueItem.data().name())) if key not in occourences: occourences[key] = 0 if not value: value = 0 occourences[key] += value totValue += value chartData = [{'key':k,'y':float(float(occourences[k])/float(totValue))} for k in occourences.keys()] return chartData def generateStatistics(self): categoryItem = self.getSelectedListViewItem('category') valueItem = self.getSelectedListViewItem('value') layer = self.reslayer[0] features = layer.getFeatures() occourences = dict() for f in features: key = self._purificateValues(f.attribute(categoryItem.data().name())) if not key: key = self.tr('Unknown') value = self._purificateValues(f.attribute(valueItem.data().name())) if key not in occourences: occourences[key] = list() if not value: value = 0 occourences[key].append(value) # statistics calcs self.statistics = dict() model = QtGui.QStandardItemModel(self.statisticsTableView) self.statisticsTableView.setModel(model) c = 0 self.headersFieldsTableMethods = { self.tr('Sum'):sum, self.tr('Min'):min, self.tr('Max'):max, self.tr('Median'):numpy.median, self.tr('Mean'):numpy.mean, self.tr('Standard deviation'):numpy.std } print occourences for columnName in self.headersFieldsTableMethods: model.setHorizontalHeaderItem(self.headersFieldsTableMethods.keys().index(columnName),QtGui.QStandardItem(columnName)) for key in occourences: if key not in self.statistics: self.statistics[key] = dict() rowToAppend = list() for func in self.headersFieldsTableMethods: self.statistics[key][func] = str(self.headersFieldsTableMethods[func](occourences[key])) rowToAppend.append(QtGui.QStandardItem(self.statistics[key][func])) model.appendRow(rowToAppend) model.setVerticalHeaderItem(c,QtGui.QStandardItem(str(key))) c += 1 self.saveCSVFile.setEnabled(True) def sum(self,data): return sum(data) def min(self,data): return min(data) def max(self,data): return max(data) def savepng(self): dialog = QtGui.QFileDialog() dialog.setAcceptMode(1) dialog.setDefaultSuffix("png") dialog.setNameFilters(["PNG files (*.png)", "All files (*)"]) if dialog.exec_() == 0: return pathFileToSave = dialog.selectedFiles()[0] p = QtGui.QPixmap.grabWidget(self.graphicsView) res = p.save(pathFileToSave) def saveCSV(self): dialog = QtGui.QFileDialog() dialog.setAcceptMode(1) dialog.setDefaultSuffix("csv") dialog.setNameFilters(["CSV files (*.csv)", "All files (*)"]) if dialog.exec_() == 0: return pathFileToSave = dialog.selectedFiles()[0] fileCSV = open(pathFileToSave, 'wb') compilatorCSV = csv.writer( fileCSV, delimiter=';' ) header = [''] header.extend(self.headersFieldsTableMethods.keys()) compilatorCSV.writerow(header) for i in self.statistics: row = [i] dataRow = [x.encode('utf-8') for x in self.statistics[i].values()] row.extend(dataRow) compilatorCSV.writerow(row) fileCSV.close() def showValidateErrors(self): QtGui.QMessageBox.warning( self, self.tr("ARPA Spatial Report"), self.tr( "Validation error:\n" ) + ';\n'.join(self.validation.getErrors()) )