Tom Troppmann 4 years ago
parent
commit
4a7a9b6fd0

+ 5 - 5
README.md

@@ -6,7 +6,7 @@ A visualization tool for combinatorial optmization.
 | ------------ | ------------- | ------------- | ------ |
 | 17/12/2019 | MS0: License & IDE | Software should be able run on windows and linux | ☑ |
 | 20/12/2019 | MS1: Log-file import | The overall design and constrain off a log-file | ☐ |
-| --/--/2020 | MS2: Metrics | Calculate and display metrics for general metaheuristic and for population based ones |  ☐ |
+| 14/01/2020 | MS2: Metrics | Calculate and display metrics for general metaheuristic and for population based ones |  ☐ |
 
 
 #### Phases
@@ -14,7 +14,7 @@ A visualization tool for combinatorial optmization.
 | ------------ | ------------- | ------------- |
 | 16/12/2019 - 20/12/2019 | P0: Initialize the project | Preparing for future work and implement first two milestones(MS1, MS2) |
 | 21/12/2019 - 03/01/2020 | Winterbreak | |
-| 04/12/2020 - 08/01/2020 | P1: Metrics | Implementing all kind of metrics that present information for the User|
+| 04/01/2020 - 14/01/2020 | P1: Metrics | Implementing all kind of metrics that present information for the User|
 
 <!-- 	ballot box with check &#9745;  
 		Entity: ballot box unchecked &#9744;
@@ -23,8 +23,8 @@ A visualization tool for combinatorial optmization.
 | Milostone | Goal | Comment | Done |
 | --------- | ---- | ------- | ---- |
 | MS1		| G0: Memory layout | Save efficient bits in the memory | &#9745; |
-|			| G1: File Reader | File reader who can detinguish between real values and integer and the bitstring. Should be recognize labels. | &#9744; |
-| MS2		| G2: Dockable widget | To have a gui widget that can be docked and the state should be saved. | &#9744; |
+|			| G1: File Reader | File reader who can detinguish between real values and integer and the bitstring. Should be recognize labels. | &#9745; |
+| MS2		| G2: Dockable widget | To have a gui widget that can be docked and the state should be saved. | &#9745; |
 | 			| G3: Line Graph | A line graph with axis label should be implemented | &#9744; |
 | 			| G4: Light redraw | Save the intermediate values to not calculate them each redraw | &#9744; | 
 
@@ -37,6 +37,6 @@ These features are not in a milestone or a goal yet but can be in the future.
 | ------- | ------- |
 | FS0: Log-file in UTF-8 to binary data type | Saves disk space |
 | FS1: Multiple run view | Simmulateasly showing 2 or multiple runs to compare them |
-| FS2: Free up memory | Free up memory thats not needed when the visualization |
+| FS2: Free up memory | Free up memory thats not needed when the visualization  has been calculated |
 
 

+ 115 - 0
metavis/CustomLineGraph.cpp

@@ -0,0 +1,115 @@
+#include "CustomLineGraph.h"
+
+#include <QDebug>
+#include <QBrush>
+#include <random>
+#include <algorithm>
+
+CustomLineGraph::CustomLineGraph(QWidget* parent):QWidget(parent), linePen(Qt::blue), rectPen(Qt::red), axisPen(Qt::black)
+{
+	linePen.setWidth(3);
+	linePen.setJoinStyle(Qt::PenJoinStyle::RoundJoin);
+	LineGraphSeries lgs;
+	//Populate data with DummyData
+	//Draw Points
+	std::random_device rd;  //Will be used to obtain a seed for the random number engine
+	std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
+	std::uniform_int_distribution<> dis(-3, 3);
+	for (int randomSeries = 0; randomSeries < 2; randomSeries++) {
+		for (int i = 0; i < 21; i++) {
+			QPoint point(i * 50 + 500,i * 1 + dis(gen) - 10000);
+			lgs.data.push_back(point);
+		}
+
+		auto pairX = std::minmax_element(std::begin(lgs.data), std::end(lgs.data), [](const QPoint& a,const QPoint& b) -> bool {return a.x() < b.x(); });
+		lgs.minX = pairX.first->x();
+		lgs.maxX = pairX.second->x();
+		auto pairY = std::minmax_element(std::begin(lgs.data), std::end(lgs.data), [](const QPoint& a, const QPoint& b) -> bool {return a.y() < b.y(); });
+		lgs.minY = pairY.first->y();
+		lgs.maxY = pairY.second->y();
+		lgs.rangeX = std::abs(lgs.maxX - lgs.minX);
+		lgs.rangeY = std::abs(lgs.maxY - lgs.minY);
+		seriesVec.push_back(lgs);
+	}
+}
+
+CustomLineGraph::~CustomLineGraph()
+{
+}
+void CustomLineGraph::paintEvent(QPaintEvent* event)
+{
+	QPainter painter(this);
+	painter.setRenderHint(QPainter::RenderHint::HighQualityAntialiasing);
+	
+	//Calculate LineRect
+	QRect lineRect(rect());
+	lineRect.setBottom(lineRect.bottom() - 20);
+	lineRect.setLeft(lineRect.left() + 40);
+	lineRect.setTop(lineRect.top() + 20);
+	lineRect.setRight(lineRect.right() - 10);
+	lineRect.setWidth(lineRect.width() - (lineRect.width() % 10) + 1);
+	lineRect.setHeight(lineRect.height() - (lineRect.height() % 10) + 1);
+
+
+	//draw Title
+	painter.setPen(axisPen);
+	painter.setFont(QFont("Arial", 12));
+	QRect titleRect(QPoint(lineRect.left(), rect().top()), QPoint(lineRect.right(), lineRect.top()));
+	painter.drawText(titleRect, Qt::AlignCenter, "title");
+
+
+	//draw X-Axis
+	QRect xAxisRect(QPoint(lineRect.left(), lineRect.bottom()), QPoint(lineRect.right(), rect().bottom()));
+	QPainterPath xAxisPath;
+	xAxisPath.moveTo(xAxisRect.left(), xAxisRect.top());
+	xAxisPath.lineTo(xAxisRect.right(), xAxisRect.top());
+	int xGap = xAxisRect.width() / 10;
+	for (int i = 0; i < 11; i++) {
+		xAxisPath.moveTo(xAxisRect.left() + i * xGap, xAxisRect.top() + 5);
+		xAxisPath.lineTo(xAxisRect.left() + i * xGap, xAxisRect.top());
+	}
+	painter.drawPath(xAxisPath);
+
+	//draw Y-Axis
+	QRect yAxisRect(QPoint(rect().left(), lineRect.top()), QPoint(lineRect.left(), lineRect.bottom()));
+	QPainterPath yAxisPath;
+	yAxisPath.moveTo(yAxisRect.right(), yAxisRect.bottom() + 5);
+	yAxisPath.lineTo(yAxisRect.right(), yAxisRect.top());
+	int yGap = yAxisRect.height() / 10;
+	for (int i = 0; i < 11; i++) {
+		yAxisPath.moveTo(yAxisRect.right() - 5, yAxisRect.top() + i * yGap);
+		yAxisPath.lineTo(yAxisRect.right(), yAxisRect.top() + i * yGap);
+	}
+	painter.drawPath(yAxisPath);
+
+
+
+	
+	
+
+	painter.setPen(linePen);
+	for (LineGraphSeries series : seriesVec) {
+
+		double stregth_factorX = lineRect.width() / series.rangeX;
+		double stregth_factorY = lineRect.height() / series.rangeY;
+		QPointF translation(lineRect.left(), lineRect.top());
+		QPainterPath painterPath;
+		painterPath.moveTo(transformPoint(series.data[0], series, stregth_factorX, stregth_factorY));
+		for(int i = 1; i < seriesVec[0].data.size(); i++) {
+			painterPath.lineTo(transformPoint(series.data[i], series, stregth_factorX, stregth_factorY));
+		}
+		painterPath.translate(translation);
+		painter.drawPath(painterPath);
+		int radius;
+		for (int i = 0; i < seriesVec[0].data.size(); i++) {
+			painter.drawEllipse(transformPoint(series.data[i], series, stregth_factorX, stregth_factorY) + translation, 3, 3);
+		}
+	}
+	
+}
+
+QPoint CustomLineGraph::transformPoint(QPoint& point, LineGraphSeries& lgs, double stregth_factorX, double stregth_factorY)
+{
+	return QPoint((point.x() - lgs.minX)* stregth_factorX , (lgs.maxY - point.y()) * stregth_factorY);
+}
+

+ 35 - 0
metavis/CustomLineGraph.h

@@ -0,0 +1,35 @@
+#pragma once
+#include <QWidget>
+#include <QPaintEvent>
+#include <QPen>
+#include <QPainter>
+#include <vector>
+
+struct LineGraphSeries {
+	std::vector<QPoint> data;
+	double minX, maxX;
+	double minY, maxY;
+	double rangeX, rangeY;
+	QColor color;
+};
+
+//bool compTest(QPoint a, QPoint b) {
+//	return a.x() < b.x();
+//}
+
+class CustomLineGraph :public QWidget
+{
+	Q_OBJECT
+
+public:
+	CustomLineGraph(QWidget* parent);
+	~CustomLineGraph();
+	void CustomLineGraph::paintEvent(QPaintEvent* event);
+	
+private:
+	std::vector<LineGraphSeries> seriesVec;
+	QPen linePen, rectPen, axisPen;
+	QPoint transformPoint(QPoint& point, LineGraphSeries& lgs, double stregth_factorX, double stregth_factorY);
+
+};
+

+ 45 - 0
metavis/LineGraph.cpp

@@ -0,0 +1,45 @@
+#include "LineGraph.h"
+#include <QLabel>
+#include <QVBoxLayout>
+#include <QDebug>
+
+LineGraph::LineGraph(QWidget *parent)
+	: QWidget(parent)
+{
+	series = new QtCharts::QLineSeries();
+    std::random_device rd;  //Will be used to obtain a seed for the random number engine
+    std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
+    std::uniform_int_distribution<> dis(1, 100);
+
+    for (int i = 0; i < 100; i++) {
+        series->append(i, dis(gen));
+    }
+    //*series << QPointF(11, 1) << QPointF(13, 3) << QPointF(17, 6) << QPointF(18, 3) << QPointF(20, 2);
+    QtCharts::QLineSeries* ser2 = new QtCharts::QLineSeries();
+
+    for (int i = 0; i < 100; i++) {
+        ser2->append(i, dis(gen));
+    }
+    chart = new QtCharts::QChart();
+    chart->legend()->hide();
+    chart->addSeries(series);
+    chart->addSeries(ser2);
+    chart->createDefaultAxes();
+    chart->setTitle("Simple line chart example");
+    chartView = new QtCharts::QChartView(chart);
+    chartView->setRenderHint(QPainter::Antialiasing);
+    //chartView->setMinimumSize(200, 200);
+    QVBoxLayout* layout = new QVBoxLayout();
+    layout->addWidget(chartView);
+    this->setLayout(layout);
+
+}
+
+LineGraph::~LineGraph()
+{
+}
+
+void LineGraph::mouseMoveEvent(QMouseEvent* event)
+{
+    qDebug() << "MouseMoveEvent";
+}

+ 21 - 0
metavis/LineGraph.h

@@ -0,0 +1,21 @@
+#pragma once
+
+#include <QWidget>
+#include <QtCharts/QLineSeries>
+#include <QtCharts/QtCharts>
+#include <QtCharts/QChartView>
+
+class LineGraph : public QWidget
+{
+	Q_OBJECT
+
+private:
+	QtCharts::QLineSeries* series;
+	QtCharts::QChart* chart;
+	QtCharts::QChartView* chartView;
+public:
+	LineGraph(QWidget *parent);
+	~LineGraph();
+protected:
+	void mouseMoveEvent(QMouseEvent* event);
+};

+ 12 - 0
metavis/LineGraphZwei.h

@@ -0,0 +1,12 @@
+#pragma once
+
+#include <QWidget>
+
+class LineGraphZwei : public QWidget
+{
+	Q_OBJECT
+
+public:
+	LineGraphZwei(QWidget *parent);
+	~LineGraphZwei();
+};

File diff suppressed because it is too large
+ 1 - 0
metavis/d3.v5.min.js


+ 1 - 1
metavis/dataTest.cpp

@@ -1,5 +1,5 @@
 #include "dataTest.h"
-#include <qdebug.h>
+#include <QDebug>
 #include <sstream>
 dataTest::dataTest()
 {

+ 1 - 0
metavis/main.cpp

@@ -1,6 +1,7 @@
 #include "metavis.h"
 #include <QtWidgets/QApplication>
 #include "dataTest.h"
+#include <QtGui>
 
 /* entrance of the program */
 int main(int argc, char *argv[])

+ 77 - 3
metavis/metavis.cpp

@@ -1,8 +1,15 @@
 #include "metavis.h"
 #include "SettingDialog.h"
-#include <qstandardpaths.h>
-#include <qdebug.h>
-
+#include <QStandardPaths>
+#include <QDockwidget>
+#include <QLabel>
+#include <QLayout>
+#include <QDebug>
+#include <QStyleFactory>
+#include <QtWebChannel/QtWebChannel>
+#include <QtWebEngineWidgets/QWebEngineView>
+#include "LineGraph.h"
+#include "CustomLineGraph.h"
 
 metavis::metavis(QWidget *parent)
 	: QMainWindow(parent)
@@ -10,6 +17,15 @@ metavis::metavis(QWidget *parent)
 	ui.setupUi(this);
 	/* create settings object*/
 	settings = new QSettings(QSettings::IniFormat, QSettings::UserScope, "TK", "metavis", this);
+	setStyleSheet(styleSheet() + "QMainWindow::separator {background: rgb(200, 200, 200);width: 1px;height: 1px;}");
+	setStyleSheet(styleSheet() + "QTabBar::tab:selected {color: rgb(0, 122, 204);}");
+	setStyleSheet(styleSheet() + "QTabWidget::pane {border-top: 2px solid #C2C7CB;}");
+	
+	
+	createCustomWidget();
+	/*createCustomWidget();
+	createCustomWidget();
+	createCustomWidget();*/
 	readMainWindowSettings();
 }
 
@@ -25,6 +41,64 @@ metavis::~metavis()
 	writeActualMainWindowSettings();
 }
 
+
+
+void metavis::createChartWidget()
+{
+	QDockWidget* dock = new QDockWidget("Customers", this);
+	dock->setObjectName("TestWidget");
+	dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
+	LineGraph* widget = new LineGraph(dock);
+	
+	widget->setMinimumSize(100, 100);
+	dock->setBaseSize(300, 300);
+	QPalette pal;
+	pal.setColor(QPalette::Background, Qt::lightGray);
+	dock->setPalette(pal);
+	//widget->setPalette(pal);
+	dock->setWidget(widget);
+	addDockWidget(Qt::RightDockWidgetArea, dock);
+}
+
+void metavis::createWebEngineWidget()
+{
+
+	QDockWidget* dock = new QDockWidget("Customers", this);
+	dock->setObjectName("TestWidget");
+	dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
+	QWebEngineView* view = new QWebEngineView(dock);
+	view->load(QUrl("file:///web.html"));
+	//view->load(QUrl("http://youtube.de/"));
+	view->show();
+	view->setMinimumSize(200, 200);
+	dock->setBaseSize(300, 300);
+	QPalette pal;
+	pal.setColor(QPalette::Background, Qt::lightGray);
+	dock->setPalette(pal);
+	view->setPalette(pal);
+	dock->setWidget(view);
+	addDockWidget(Qt::LeftDockWidgetArea, dock);
+}
+
+void metavis::createCustomWidget()
+{
+	QDockWidget* dock = new QDockWidget("Customers", this);
+	dock->setObjectName("TestWidget");
+	dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
+	CustomLineGraph* widget = new CustomLineGraph(dock);
+	widget->setMinimumSize(200, 200);
+	widget->show();
+	widget->repaint();
+	dock->setBaseSize(300, 300);
+	dock->repaint();
+	QPalette pal;
+	pal.setColor(QPalette::Background, Qt::lightGray);
+	//dock->setPalette(pal);
+	//widget->setPalette(pal);
+	dock->setWidget(widget);
+	addDockWidget(Qt::LeftDockWidgetArea, dock);
+}
+
 void metavis::writeActualMainWindowSettings()
 {
 	settings->beginGroup("MainWindow");

+ 8 - 0
metavis/metavis.h

@@ -3,6 +3,7 @@
 #include <QtWidgets/QMainWindow>
 #include "ui_metavis.h"
 #include <qsettings.h>
+
 /**
  * Main class of the GUI.
  */
@@ -19,6 +20,13 @@ private:
 	QSettings* settings;
 
 private:
+	/* Widget functions */
+	void createChartWidget();
+	void createWebEngineWidget();
+	void createCustomWidget();
+
+
+	/* Setting functions*/
 	void writeActualMainWindowSettings();
 	void readMainWindowSettings();
 

+ 6 - 4
metavis/metavis.ui

@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>600</width>
-    <height>318</height>
+    <width>744</width>
+    <height>560</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -19,10 +19,13 @@
     <rect>
      <x>0</x>
      <y>0</y>
-     <width>600</width>
+     <width>744</width>
      <height>21</height>
     </rect>
    </property>
+   <property name="nativeMenuBar">
+    <bool>true</bool>
+   </property>
    <widget class="QMenu" name="menuFile">
     <property name="title">
      <string>File</string>
@@ -47,7 +50,6 @@
     <bool>false</bool>
    </attribute>
   </widget>
-  <widget class="QStatusBar" name="statusBar"/>
   <action name="actionOpen">
    <property name="text">
     <string>Open..</string>

+ 13 - 2
metavis/metavis.vcxproj

@@ -53,11 +53,11 @@
   </ImportGroup>
   <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
     <QtInstall>msvc2017_64</QtInstall>
-    <QtModules>core;gui;widgets</QtModules>
+    <QtModules>charts;core;datavisualization;gui;widgets;webchannel;webenginewidgets</QtModules>
   </PropertyGroup>
   <PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
     <QtInstall>msvc2017_64</QtInstall>
-    <QtModules>core;gui;widgets</QtModules>
+    <QtModules>charts;core;datavisualization;gui;widgets;webchannel;webenginewidgets</QtModules>
   </PropertyGroup>
   <ImportGroup Condition="Exists('$(QtMsBuild)\qt.props')">
     <Import Project="$(QtMsBuild)\qt.props" />
@@ -74,6 +74,8 @@
       <SubSystem>Windows</SubSystem>
       <OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
       <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>$(Qt_LIBS_);%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -87,10 +89,14 @@
       <SubSystem>Windows</SubSystem>
       <OutputFile>$(OutDir)\$(ProjectName).exe</OutputFile>
       <GenerateDebugInformation>false</GenerateDebugInformation>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>$(Qt_LIBS_);%(AdditionalDependencies)</AdditionalDependencies>
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup>
+    <ClCompile Include="CustomLineGraph.cpp" />
     <ClCompile Include="dataTest.cpp" />
+    <ClCompile Include="LineGraph.cpp" />
     <ClCompile Include="main.cpp" />
     <ClCompile Include="metavis.cpp" />
     <ClCompile Include="SettingDialog.cpp" />
@@ -112,7 +118,12 @@
     <QtMoc Include="SettingDialog.h" />
   </ItemGroup>
   <ItemGroup>
+    <QtMoc Include="CustomLineGraph.h" />
     <ClInclude Include="dataTest.h" />
+    <QtMoc Include="LineGraph.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="web.html" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">

+ 17 - 0
metavis/metavis.vcxproj.filters

@@ -37,6 +37,12 @@
     <ClCompile Include="dataTest.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="LineGraph.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="CustomLineGraph.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <QtMoc Include="metavis.h">
@@ -45,6 +51,12 @@
     <QtMoc Include="SettingDialog.h">
       <Filter>Header Files</Filter>
     </QtMoc>
+    <QtMoc Include="LineGraph.h">
+      <Filter>Header Files</Filter>
+    </QtMoc>
+    <QtMoc Include="CustomLineGraph.h">
+      <Filter>Header Files</Filter>
+    </QtMoc>
   </ItemGroup>
   <ItemGroup>
     <QtUic Include="metavis.ui">
@@ -67,4 +79,9 @@
       <Filter>Header Files</Filter>
     </ClInclude>
   </ItemGroup>
+  <ItemGroup>
+    <None Include="web.html">
+      <Filter>Resource Files</Filter>
+    </None>
+  </ItemGroup>
 </Project>

+ 135 - 0
metavis/web.html

@@ -0,0 +1,135 @@
+
+<!--
+<html>
+<body>
+
+sdasdasd
+</body>
+</html>
+-->
+
+ 
+<meta charset="utf-8">
+<html>
+<header><title>This is title</title></header>
+
+<style type="text/css">
+/* 13. Basic Styling with CSS */
+
+/* Style the lines by removing the fill and applying a stroke */
+.line {
+    fill: none;
+    stroke: #ffab00;
+    stroke-width: 3;
+}
+  
+.overlay {
+  fill: none;
+  pointer-events: all;
+}
+
+/* Style the dots by assigning a fill and stroke */
+.dot {
+    fill: #ffab00;
+    stroke: #fff;
+}
+  
+  .focus circle {
+  fill: none;
+  stroke: steelblue;
+}
+
+.dot-focus{
+  fill: #ffffff;
+  stroke: steelblue;
+}
+
+</style>
+
+
+<body>
+<script src="d3.v5.min.js"></script>
+<script>
+
+var margin = {top: 10, right: 50, bottom: 50, left: 50}
+  , width = window.innerWidth - margin.left - margin.right // Use the window's width 
+  , height = window.innerHeight - margin.top - margin.bottom; // Use the window's height
+
+// The number of datapoints
+var n = 101;
+
+// 5. X scale will use the index of our data
+var xScale = d3.scaleLinear()
+    .domain([0, n-1]) // input
+    .range([0, width]); // output
+
+// 6. Y scale will use the randomly generate number 
+var yScale = d3.scaleLinear()
+    .domain([0, 1]) // input 
+    .range([height, 0]); // output 
+
+// 7. d3's line generator
+var line = d3.line()
+    .x(function(d, i) { return xScale(i); }) // set the x values for the line generator
+    .y(function(d) { return yScale(d.y); }) // set the y values for the line generator 
+    .curve(d3.curveMonotoneX) // apply smoothing to the line
+
+// 8. An array of objects of length N. Each object has key -> value pair, the key being "y" and the value is a random number
+var dataset = d3.range(n).map(function(d) { return {"y": d3.randomUniform(1)() } })
+
+// 1. Add the SVG to the page and employ #2
+var svg = d3.select("body").append("svg")
+    .attr("width", width + margin.left + margin.right  -25)
+    .attr("height", height + margin.top + margin.bottom -25)
+	//.attr("preserveAspectRatio", "xMinYMin meet")
+	//.attr("viewBox", "0 0 " + width + " " + height)
+  .append("g")
+    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
+
+// 3. Call the x axis in a group tag
+svg.append("g")
+    .attr("class", "x axis")
+    .attr("transform", "translate(0," + height + ")")
+    .call(d3.axisBottom(xScale)); // Create an axis component with d3.axisBottom
+
+// 4. Call the y axis in a group tag
+svg.append("g")
+    .attr("class", "y axis")
+    .call(d3.axisLeft(yScale)); // Create an axis component with d3.axisLeft
+
+// 9. Append the path, bind the data, and call the line generator 
+var path = svg.append("path")
+    .datum(dataset) // 10. Binds data to the line 
+    .attr("class", "line") // Assign a class for styling 
+    .attr("d", line); // 11. Calls the line generator 
+
+// 12. Appends a circle for each datapoint 
+svg.selectAll(".dot")
+    .data(dataset)
+  .enter().append("circle") // Uses the enter().append() method
+    .attr("class", "dot") // Assign a class for styling
+    .attr("cx", function(d, i) { return xScale(i) })
+    .attr("cy", function(d) { return yScale(d.y) })
+    .attr("r", 5)
+      .on("mouseover", function(a, b, c) { 
+  			console.log(a) 
+        d3.select(this).attr('class', 'dot-focus')
+		})
+	  .on("mouseout", function(a, b, c) { 
+  			console.log(a) 
+        d3.select(this).attr('class', 'dot')
+		})
+function redraw(){
+	width = window.innerWidth - margin.left - margin.right;
+	height = window.innerHeight - margin.top - margin.bottom;
+	console.log("redraw w:" + width + " h:" + height);
+	//path.attr("d", line)
+	//.attr("transform", null)
+	//.transition()
+	//.attr("transform", "translate(" + "0" + ",100)")
+	//.duration(300);
+}
+window.addEventListener("resize", redraw);
+</script>
+</body>
+</html>

Some files were not shown because too many files changed in this diff